diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..8fa7520 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,45 @@ +--- +name: "\U0001F6D1 Report a bug in the DaoCloud Enterprise Documents" +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** + +A clear and concise description of what the bug is. + +**To Reproduce** + +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '...' +3. Scroll down to '...' +4. See error + +**Expected behavior** + +A clear and concise description of what you expected to happen. + +**Screenshots** + +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] + +**Smartphone (please complete the following information):** + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] + +**Additional context** + +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..e8123b1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,123 @@ +name: Bug Report +description: Create a report to identify and fix a bug +title: "Bug: " +labels: ["bug", "gitauto"] +# assignees: [""] + +body: + - type: textarea + id: bug_behavior + attributes: + label: Bug Behavior + description: What is the bug? What is currently happening? + placeholder: "Example: 'When I try to upload a file (over 100MB), the process fails with a timeout error. This disrupts my workflow and causes delays in my project.'" + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Logs + description: Include any logs such as error objects, stack traces, or console logs. + placeholder: "Example: 'Error: TimeoutError: The request timed out after 30 seconds'" + validations: + required: true + + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: Add any screenshots such as error messages or unexpected behavior. + placeholder: "Attach it here" + validations: + required: false + + - type: input + id: when_it_occurred + attributes: + label: When It Occurred + description: When did the issue last occur? + placeholder: "Example: 'Jul 10, 2024 12:08:00 AM UTC'" + validations: + required: true + + - type: textarea + id: steps_to_reproduce + attributes: + label: Steps to Reproduce + description: How can we reproduce the bug? + placeholder: | + Example: + 1. Go to "Upload" + 2. Click on "Select File" + 3. Choose a large file (over 100MB) + 4. Click "Upload" + 5. See error + value: | + 1. + validations: + required: true + + - type: textarea + id: expected_behavior + attributes: + label: Expected Behavior + description: What do you expect to happen? + placeholder: "Example: 'The file should upload successfully without any errors even if it's over 100MB.'" + validations: + required: true + + - type: textarea + id: possible_cause + attributes: + label: Possible Cause + description: If you have any idea what might be causing the issue, describe it. + placeholder: "Example: 'The issue may be related to the new file upload library introduced in version 1.2.3.'" + validations: + required: false + + - type: input + id: device + attributes: + label: Device + description: Describe your device or server. + placeholder: "MacBook Pro, 14-inch, 2023 (Check in 'About This Mac')" + validations: + required: true + + - type: input + id: os + attributes: + label: OS + description: | + Describe your operating system. + - For Mac, check in "About This Mac". + - For Windows, check in "Settings" > "System" > "About". + - For iOS, check in "Settings" > "General" > "About" > "iOS Version". + - For Linux, run `uname -a` in the terminal. + - For your server, specify the provider such as AWS EC2, AWS Lambda, or etc. + placeholder: "Sonoma 14.5" + validations: + required: true + + - type: input + id: browser + attributes: + label: Browser + description: | + Describe your browser. + - For Chrome, "Chrome, Version 126.0.6478.127 (Official Build) (arm64)". Check in "3 dots" on the top right > "Help" > "About Google Chrome". + - For Safari, "Safari, Version 17.5 (19618.2.12.11.6)". Check in "Safari" on the top left > "About Safari". + - For non-browser issues, type "Server-side" or "Mobile App". + placeholder: "Chrome, Version 126.0.6478.127 (Official Build) (arm64)" + validations: + required: true + + - type: textarea + id: additional_information + attributes: + label: Additional Information + description: Include any other context or information. + placeholder: "Describe it here" + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..91d5746 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: ✅ Connect US when your having questions. + url: https://www.daocloud.io + about: If you have questions about DaoCloud product or need support building applicaion, please ask us \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..a623c6f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: "\U0001F7E1 Request a feature in the DaoCloud Enterprise Documents" +about: If you have feature idea for DaoCloud Enterprise Documents +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..183b84d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,51 @@ +name: Feature Request +description: Share your problem and suggest a new feature +title: "Feature Request: " +labels: ["enhancement", "gitauto"] +# assignees: [""] + +body: + - type: textarea + id: problem + attributes: + label: Problem + description: What issue are you facing? + placeholder: "Example: 'When I try to upload large files (over 100MB), the process succeeds but takes more than 10 minutes. This disrupts my workflow and causes delays in my project.'" + validations: + required: true + + - type: textarea + id: current_solution + attributes: + label: Current Solution + description: How are you currently solving this problem? + placeholder: "Example: 'To work around this, I'm splitting the files into smaller parts (less than 50MB each) and uploading them individually. This is time-consuming and mistake-prone.'" + validations: + required: true + + - type: textarea + id: proposed_solution + attributes: + label: Proposed Solution + description: What do you want to happen? + placeholder: "Example: 'I would like a feature that supports seamless uploading of large files, more than 100MB, without any timeouts or delays. This will help me save time and improve my productivity.'" + validations: + required: true + + - type: textarea + id: attachments + attributes: + label: Screenshots or Diagrams + description: Add any screenshots or diagrams that can help us understand the feature request. + placeholder: "Attach it here" + validations: + required: false + + - type: textarea + id: additional_information + attributes: + label: Additional Information + description: Include any other information or screenshots. + placeholder: "Describe it here" + validations: + required: false diff --git a/.github/workflows/auto-label-pr.yaml b/.github/workflows/auto-label-pr.yaml new file mode 100644 index 0000000..fdbb119 --- /dev/null +++ b/.github/workflows/auto-label-pr.yaml @@ -0,0 +1,18 @@ +name: Auto Labels PR + +# how usage: https://github.com/marketplace/actions/labeler + +on: +- pull_request_target + +jobs: + triage: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: .github/labeler.yml # update role in this file diff --git a/.github/workflows/auto-size-pr.yaml b/.github/workflows/auto-size-pr.yaml new file mode 100644 index 0000000..fccc682 --- /dev/null +++ b/.github/workflows/auto-size-pr.yaml @@ -0,0 +1,33 @@ +name: Size labeler + +on: +- pull_request_target + +jobs: + size-labeler: + permissions: + issues: write + pull-requests: write + runs-on: ubuntu-latest + name: Label the PR size + steps: + - uses: codelytv/pr-size-labeler@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + xs_label: "size/xs" + xs_max_size: "9" + s_label: "size/s" + s_max_size: "29" + m_label: "size/m" + m_max_size: "99" + l_label: "size/l" + l_max_size: "499" + xl_label: "size/xl" + xl_max_size: "999" + xll_label: "size/xll" + xll_max_size: "1999" + fail_if_xll: "false" + message_if_xll: > + This PR exceeds the recommended size of 2000 lines. + Please make sure you are NOT addressing multiple issues with one PR. + Note this PR might be rejected due to its size. diff --git a/.github/workflows/corrupted-hyperlink.yml b/.github/workflows/corrupted-hyperlink.yml new file mode 100644 index 0000000..d0c3d00 --- /dev/null +++ b/.github/workflows/corrupted-hyperlink.yml @@ -0,0 +1,69 @@ +# This is a basic workflow to help you get started with Actions + +name: find corrupted hyperlink + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build-test: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Required for mkdocs to be able to display pages last update info + - uses: actions/setup-python@v2 + with: + python-version: 3.x + + # Runs a single command using the runners shell + - run: pip install mkdocs-material \ + mkdocs-git-revision-date-plugin \ + mkdocs-mermaid2-plugin \ + mkdocs-rss-plugin \ + mkdocs-minify-plugin \ + mkdocs-macros-plugin \ + mkdocs-git-revision-date-localized-plugin \ + mkdocs-awesome-pages-plugin \ + mkdocs-redirects \ + mkdocs-print-site-plugin \ + mkdocs-swagger-ui-tag \ + pyyaml + + # add custom plugin with pdf support + - run: pip install git+https://github.com/SAMZONG/mkdocs-with-pdf-support-material-v8 + + # check corrupted hyperlink + - run: pwd + - run: mkdocs build -f docs/zh/mkdocs.yml -d ../../public/ >> zh_build.log + - run: mkdocs build -f docs/en/mkdocs.yml -d ../../public/en/ >> en_build.log + - run: ls -lha + - run: echo "# zh_build.log" >> issue-body.txt + - run: grep -e 'WARNING.*\.md.*contains a link to.*not found' zh_build.log >> issue-body.txt + - run: echo "# en_build.log" >> issue-body.txt + - run: grep -e 'WARNING.*\.md.*contains a link to.*not found' en_build.log >> issue-body.txt + + # Create an issue if there are any warnings + - name: Create issue + uses: peter-evans/create-issue-from-file@v2 + with: + title: 'Corrupted document hyperlink' + body: | + ${{ steps.get_issue_body.outputs.body }} + labels: | + bug + corrupted-hyperlink + assignees: | + windsonsea + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ISSUE_BODY_PATH: ./issue-body.txt + id: get_issue_body \ No newline at end of file diff --git a/.github/workflows/main.path.yml b/.github/workflows/main.path.yml new file mode 100644 index 0000000..c5f9748 --- /dev/null +++ b/.github/workflows/main.path.yml @@ -0,0 +1,91 @@ +# This is a basic workflow to help you get started with Actions + +name: deploy-for-main-path + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + UCLOUD_PUBLICKEY : ${{ secrets.UCLOUD_PUBLICKEY }} + UCLOUD_PRIVATEKEY : ${{ secrets.UCLOUD_PRIVATEKEY }} + UCLOUD_REGION : ${{ secrets.UCLOUD_REGION }} + UCLOUD_BUCKET : ${{ secrets.UCLOUD_BUCKET }} + CI: 1 + PIP_CONSTRAINT: /home/runner/work/DaoCloud-docs/DaoCloud-docs/constraints.txt + +concurrency: + group: ${{ github.workflow_ref }} + cancel-in-progress: true + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + deploy: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for mkdocs to be able to display pages last update info + + # Clone + - name: Checkout public repository + uses: actions/checkout@v4 + with: + repository: daocloud/daocloud-api-docs + path: dao-openapi + fetch-depth: 0 # Required for mkdocs to be able to display pages last update info + + - uses: actions/setup-python@v5 + with: + python-version: 3.x +# cache: 'pip' + + # Add ssh private key + - name: Setup SSH + uses: MrSquaare/ssh-setup-action@v1 + with: + host: github.com + private-key: ${{ secrets.SSH_PRIVATE_KEY }} + +# - run: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + + # Install mkdocs-material-insiders + - run: git clone git@github.com:DaoCloud/mkdocs-material-insiders.git mkdocs-material + - run: pip install -e mkdocs-material + + # Runs a single command using the runners shell + - run: pip install -r requirements.txt -c $PIP_CONSTRAINT + + # add custom plugin with pdf support + - run: pip install git+https://github.com/SAMZONG/mkdocs-with-pdf-support-material-v8 + + # merged openapi docs + - run: cp -av dao-openapi/docs/openapi docs/zh/docs/ + - run: python scripts/merged_nav.py + + # build docs + - run: pwd + - run: mkdocs build -f docs/zh/mkdocs.path.yaml -d ../../public/ + - run: mkdocs build -f docs/en/mkdocs.path.yaml -d ../../public/en/ + + # upload to ucloud bucket + - run: cd public && pwd && python ../scripts/upload-ucloud.py \ + public_key=$UCLOUD_PUBLICKEY \ + private_key=$UCLOUD_PRIVATEKEY \ + region=$UCLOUD_REGION \ + bucket=$UCLOUD_BUCKET + + # refresh docs site cdn cache + - run: python scripts/refresh_cdn_cache.py \ + publickey=$UCLOUD_PUBLICKEY \ + privatekey=$UCLOUD_PRIVATEKEY diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..b886575 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,92 @@ +# This is a basic workflow to help you get started with Actions + +name: deploy-for-main + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + UCLOUD_PUBLICKEY : ${{ secrets.UCLOUD_PUBLICKEY }} + UCLOUD_PRIVATEKEY : ${{ secrets.UCLOUD_PRIVATEKEY }} + UCLOUD_REGION : ${{ secrets.UCLOUD_REGION }} + UCLOUD_BUCKET : ${{ secrets.UCLOUD_BUCKET }} + CI: 1 + PIP_CONSTRAINT: /home/runner/work/DaoCloud-docs/DaoCloud-docs/constraints.txt + +concurrency: + group: ${{ github.workflow_ref }} + cancel-in-progress: true + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + deploy: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Required for mkdocs to be able to display pages last update info + + # Clone + - name: Checkout public repository + uses: actions/checkout@v2 + with: + repository: daocloud/daocloud-api-docs + path: dao-openapi + fetch-depth: 0 # Required for mkdocs to be able to display pages last update info + + - uses: actions/setup-python@v2 +# - uses: actions/setup-python@v4 + with: + python-version: 3.x +# cache: 'pip' + + # Add ssh private key + - name: Setup SSH + uses: MrSquaare/ssh-setup-action@v1 + with: + host: github.com + private-key: ${{ secrets.SSH_PRIVATE_KEY }} + +# - run: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple + + # Install mkdocs-material-insiders + - run: git clone git@github.com:DaoCloud/mkdocs-material-insiders.git mkdocs-material + - run: pip install -e mkdocs-material + + # Runs a single command using the runners shell + - run: pip install -r requirements.txt -c $PIP_CONSTRAINT + + # add custom plugin with pdf support + - run: pip install git+https://github.com/SAMZONG/mkdocs-with-pdf-support-material-v8 + + # merged openapi docs + - run: cp -av dao-openapi/docs/openapi docs/zh/docs/ + - run: python scripts/merged_nav.py + + # build docs + - run: pwd + - run: mkdocs build -f docs/zh/mkdocs.yml -d ../../public/ + - run: mkdocs build -f docs/en/mkdocs.yml -d ../../public/en/ + + # upload to ucloud bucket + - run: cd public && pwd && python ../scripts/upload-ucloud.py \ + public_key=$UCLOUD_PUBLICKEY \ + private_key=$UCLOUD_PRIVATEKEY \ + region=$UCLOUD_REGION \ + bucket=$UCLOUD_BUCKET + + # refresh docs site cdn cache + - run: python scripts/refresh_cdn_cache.py \ + publickey=$UCLOUD_PUBLICKEY \ + privatekey=$UCLOUD_PRIVATEKEY diff --git a/.github/workflows/pull-request-test.yaml b/.github/workflows/pull-request-test.yaml new file mode 100644 index 0000000..f9051e9 --- /dev/null +++ b/.github/workflows/pull-request-test.yaml @@ -0,0 +1,56 @@ +# This is a basic workflow to help you get started with Actions + +name: pull-request-test + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + pull_request: + branches: + - main + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + PIP_CONSTRAINT: /home/runner/work/DaoCloud-docs/DaoCloud-docs/constraints.txt + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build-test: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Required for mkdocs to be able to display pages last update info + - uses: actions/setup-python@v5 + with: + python-version: 3.x + + # # Add ssh private key + # - name: Setup SSH + # uses: MrSquaare/ssh-setup-action@v1 + # with: + # host: github.com + # private-key: ${{ secrets.SSH_PRIVATE_KEY }} + + # # Install mkdocs-material-insiders + # - run: git clone git@github.com:DaoCloud/mkdocs-material-insiders.git mkdocs-material + # - run: pip install -e mkdocs-material + + + # Runs a single command using the runners shell + - run: pip install -r requirements.txt -c $PIP_CONSTRAINT + + # add custom plugin with pdf support + - run: pip install git+https://github.com/SAMZONG/mkdocs-with-pdf-support-material-v8 + + # build docs + - run: pwd + - run: mkdocs build -f docs/zh/mkdocs.yml -d ../../public/ + - run: mkdocs build -f docs/en/mkdocs.yml -d ../../public/en/ diff --git a/.github/workflows/sync_from_upstream.yml b/.github/workflows/sync_from_upstream.yml new file mode 100644 index 0000000..3a2ff4d --- /dev/null +++ b/.github/workflows/sync_from_upstream.yml @@ -0,0 +1,41 @@ +name: Upstream Sync + +permissions: + contents: write + +on: + schedule: + - cron: "0 * * * *" # every hour + workflow_dispatch: + +jobs: + sync_latest_from_upstream: + name: Sync latest commits from upstream repo + runs-on: ubuntu-latest + if: ${{ github.event.repository.fork }} + + steps: + # Step 1: run a standard checkout action + - name: Checkout target repo + uses: actions/checkout@v3 + + # Step 2: run the sync action + - name: Sync upstream changes + id: sync + uses: aormsby/Fork-Sync-With-Upstream-action@v3.4 + with: + # set your upstream repo and branch + upstream_sync_repo: DaoCloud/DaoCloud-docs + upstream_sync_branch: main + target_sync_branch: main + target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set + + # Set test_mode true to run tests instead of the true action!! + test_mode: false + + - name: Sync check + if: failure() + run: | + echo "::error::由于权限不足,导致同步失败(这是预期的行为),请前往仓库首页手动执行[Sync fork]。" + echo "::error::Due to insufficient permissions, synchronization failed (as expected). Please go to the repository homepage and manually perform [Sync fork]." + exit 1 diff --git a/.gitignore b/.gitignore index 02eac69..fe86a26 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,17 @@ -### AL ### -#Template for AL projects for Dynamics 365 Business Central -#launch.json folder +.venv +builds +temp_dir +.DS_Store +_book/ +.idea/ .vscode/ -#Cache folder -.alcache/ -#Symbols folder -.alpackages/ -#Snapshots folder -.snapshots/ -#Testing Output folder -.output/ -#Extension App-file -*.app -#Rapid Application Development File -rad.json -#Translation Base-file -*.g.xlf -#License-file -*.flf -#Test results file -TestResults.xml \ No newline at end of file +public/ +scripts/config.py +__pycache__ +.VSCodeCounter +docs/zh/site/ +docs/en/site/ +*.docx +ufile.log +.env +.obsidian/ diff --git a/README.md b/README.md index 8755479..d932b09 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# michaelyao -This is a personal website about Michael Yao, a CNCF ambassador, a maintainer of CNCF projects +# Michael Yao + +This is a personal website about Michael Yao, a CNCF ambassador, a maintainer of CNCF projects. diff --git a/constraints.txt b/constraints.txt new file mode 100644 index 0000000..0685d33 --- /dev/null +++ b/constraints.txt @@ -0,0 +1 @@ +setuptools<72 \ No newline at end of file diff --git a/docs/en/docs/baize/developer/dataset/create-use-delete.md b/docs/en/docs/baize/developer/dataset/create-use-delete.md new file mode 100644 index 0000000..b0de9cc --- /dev/null +++ b/docs/en/docs/baize/developer/dataset/create-use-delete.md @@ -0,0 +1,89 @@ +--- +MTPE: windsonsea +date: 2024-05-21 +--- + +# Create, Use and Delete Datasets + +AI Lab provides comprehensive dataset management functions needed for model development, +training, and inference processes. Currently, it supports unified access to various data sources. + +With simple configurations, you can connect data sources to AI Lab, achieving unified data management, +preloading, dataset management, and other functionalities. + +## Create a Dataset + +1. In the left navigation bar, click **Data Management** -> **Dataset List**, and then click the **Create** button + on the right. + + ![Click Create](../../images/dataset01.png) + +2. Select the worker cluster and namespace to which the dataset belongs, then click **Next**. + + ![Fill in Parameters](../../images/dataset02.png) + +3. Configure the data source type for the target data, then click **OK**. + + ![Task Resource Configuration](../../images/dataset03.png) + + Currently supported data sources include: + + - GIT: Supports repositories such as GitHub, GitLab, and Gitee + - S3: Supports object storage like Amazon Cloud + - HTTP: Directly input a valid HTTP URL + - PVC: Supports pre-created Kubernetes PersistentVolumeClaim + - NFS: Supports NFS shared storage + +4. Upon successful creation, the dataset will be returned to the dataset list. + You can perform more actions by clicking **┇** on the right. + + ![Dataset List](../../images/dataset04.png) + +!!! info + + The system will automatically perform a one-time data preloading after the dataset is successfully created; the dataset cannot be used until the preloading is complete. + +## Use a Dataset + +Once the dataset is successfully created, it can be used in tasks such as model training and inference. + +### Use in Notebook + +In creating a Notebook, you can directly use the dataset; the usage is as follows: + +- Use the dataset as training data mount +- Use the dataset as code mount + +![Dataset List](../../images/dataset05.png) + +### Use in Training obs + +- Use the dataset to specify job output +- Use the dataset to specify job input +- Use the dataset to specify TensorBoard output + +![jobs](../../images/dataset06.png) + +### Use in Inference Services + +- Use the dataset to mount a model + +![Inference Service](../../images/dataset07.png) + +## Delete a Dataset + +If you find a dataset to be redundant, expired, or no longer needed, you can delete it from the dataset list. + +1. Click the **┇** on the right side of the dataset list, then choose **Delete** from the dropdown menu. + + ![Delete](../../images/ds-delete01.png) + +2. In the pop-up window, confirm the dataset you want to delete, enter the dataset name, and then click **Delete**. + + ![Confirm](../../images/ds-delete02.png) + +3. A confirmation message will appear indicating successful deletion, and the dataset will disappear from the list. + +!!! caution + + Once a dataset is deleted, it cannot be recovered, so please proceed with caution. diff --git a/docs/en/docs/baize/developer/dataset/environments.md b/docs/en/docs/baize/developer/dataset/environments.md new file mode 100644 index 0000000..6c41bf6 --- /dev/null +++ b/docs/en/docs/baize/developer/dataset/environments.md @@ -0,0 +1,95 @@ +--- +MTPE: windsonsea +date: 2024-06-17 +--- + +# Manage Python Environment Dependencies + +This document aims to guide users on managing environment dependencies using AI platform. Below are the specific steps and considerations. + +1. [Overview of Environment Management](#overview) +2. [Create New Environment](#creat-new-environment) +3. [Configure Environment](#configure-environment) +4. [Troubleshooting](#troubleshooting) + +## Overview + +Traditionally, Python environment dependencies are built into an image, which includes the Python version +and dependency packages. This approach has high maintenance costs and is inconvenient to update, often requiring a complete rebuild of the image. + +In AI Lab, users can manage pure environment dependencies through the +**Environment Management** module, decoupling this part from the image. The advantages include: + +- One environment can be used in multiple places, such as in Notebooks, distributed training tasks, and even inference services. +- Updating dependency packages is more convenient; you only need to update the environment dependencies without rebuilding the image. + +The main components of the environment management are: + +- **Cluster** : Select the cluster to operate on. +- **Namespace** : Select the namespace to limit the scope of operations. +- **Environment List** : Displays all environments and their statuses under the current cluster and namespace. + +![Environment Management](../../images/conda01.png) + +### Explanation of Environment List Fields + +- **Name** : The name of the environment. +- **Status** : The current status of the environment (normal or failed). New environments undergo a warming-up process, after which they can be used in other tasks. +- **Creation Time** : The time the environment was created. + +## Creat New Environment + +On the **Environment Management** interface, click the **Create** button at the top right +to enter the environment creation process. + +![Environment Management](../../images/conda02.png) + +Fill in the following basic information: + +- **Name** : Enter the environment name, with a length of 2-63 characters, + starting and ending with lowercase letters or numbers. +- **Deployment Location**: + - **Cluster** : Select the cluster to deploy, such as `gpu-cluster`. + - **Namespace** : Select the namespace, such as `default`. +- **Remarks** (optional): Enter remarks. +- **Labels** (optional): Add labels to the environment. +- **Annotations** (optional): Add annotations to the environment. After completing the information, + click **Next** to proceed to environment configuration. + +## Configure Environment + +In the environment configuration step, users need to configure the Python version and dependency management tool. + +![Environment Management](../../images/conda03.png) + +### Environment Settings + +- **Python Version** : Select the required Python version, such as `3.12.3`. +- **Package Manager** : Choose the package management tool, either `PIP` or `CONDA`. +- **Environment Data** : + - If `PIP` is selected: Enter the dependency package list in `requirements.txt` format in the editor below. + - If `CONDA` is selected: Enter the dependency package list in `environment.yaml` format in the editor below. +- **Other Options** (optional): + - **Additional pip Index URLs** : Configure additional pip index URLs; suitable for internal enterprise private repositories or PIP acceleration sites. + - **GPU Configuration** : Enable or disable GPU configuration; some GPU-related dependency packages + need GPU resources configured during preloading. + - **Associated Storage** : Select the associated storage configuration; environment dependency packages + will be stored in the associated storage. **Note: Storage must support `ReadWriteMany`.** + +After configuration, click the **Create** button, and the system will automatically create and configure the new Python environment. + +## Troubleshooting + +- If environment creation fails: + - Check if the network connection is normal. + - Verify that the Python version and package manager configuration are correct. + - Ensure the selected cluster and namespace are available. + +- If dependency preloading fails: + - Check if the `requirements.txt` or `environment.yaml` file format is correct. + - Verify that the dependency package names and versions are correct. If other issues arise, + contact the platform administrator or refer to the platform help documentation for more support. + +--- + +These are the basic steps and considerations for managing Python dependencies in AI Lab. diff --git a/docs/en/docs/baize/developer/index.md b/docs/en/docs/baize/developer/index.md new file mode 100644 index 0000000..6e0a798 --- /dev/null +++ b/docs/en/docs/baize/developer/index.md @@ -0,0 +1,8 @@ +--- +hide: + - toc +--- + +# Developer Console + +The developer console is a console for developers to perform tasks such as AI inference and training large models on a daily basis. diff --git a/docs/en/docs/baize/developer/inference/models.md b/docs/en/docs/baize/developer/inference/models.md new file mode 100644 index 0000000..3a14090 --- /dev/null +++ b/docs/en/docs/baize/developer/inference/models.md @@ -0,0 +1,55 @@ +# Model Support + +With the rapid iteration of AI Lab, we have now supported various model inference services. +Here, you can see information about the supported models. + +- AI Lab v0.3.0 launched model inference services, facilitating users to directly use + the inference services of AI Lab without worrying about model deployment and maintenance + for traditional deep learning models. +- AI Lab v0.6.0 supports the complete version of vLLM inference capabilities, + supporting many large language models such as `LLama`, `Qwen`, `ChatGLM`, and more. + +!!! note + + The support for inference capabilities is related to the version of AI Lab. + Refer to the [Release Notes](../../intro/release-notes.md) to understand the latest version and update timely. + +You can use GPU types that have been verified by AI platform in AI Lab. +For more details, refer to the [GPU Support Matrix](../../../kpanda/user-guide/gpu/gpu_matrix.md). + +![Click to Create](../../images/inference-interface.png) + +## Triton Inference Server + +Through the Triton Inference Server, traditional deep learning models can be well supported. +Currently, AI Lab supports mainstream inference backend services: + +| Backend | Supported Model Formats | Description | +| ------- | ----------------------- | ----------- | +| pytorch | TorchScript, PyTorch 2.0 formats | [triton-inference-server/pytorch_backend](https://github.com/triton-inference-server/pytorch_backend) | +| tensorflow | TensorFlow 2.x | [triton-inference-server/tensorflow_backend](https://github.com/triton-inference-server/tensorflow_backend) | +| vLLM (Deprecated) | TensorFlow 2.x | [triton-inference-server/tensorflow_backend](https://github.com/triton-inference-server/tensorflow_backend) | + +!!! danger + + The use of Triton's Backend vLLM method has been deprecated. + It is recommended to use the latest support for vLLM to deploy your large language models. + +## vLLM + +With vLLM, we can quickly use large language models. Here, +you can see the list of models we support, which generally aligns with the `vLLM Support Models`. + +- HuggingFace Models: We support most of HuggingFace's models. You can see more models at the + [HuggingFace Model Hub](https://huggingface.co/models). +- The [vLLM Supported Models](https://docs.vllm.ai/en/stable/models/supported_models.html) + list includes supported large language models and vision-language models. +- Models fine-tuned using the vLLM support framework. + +### New Features of vLLM + +Currently, AI Lab also supports some new features when using vLLM as an inference tool: + +- Enable `Lora Adapter` to optimize model inference services during inference. +- Provide a compatible `OpenAPI` interface with `OpenAI`, making it easy for users + to switch to local inference services at a low cost and quickly transition. diff --git a/docs/en/docs/baize/developer/inference/triton-inference.md b/docs/en/docs/baize/developer/inference/triton-inference.md new file mode 100644 index 0000000..8d4cd96 --- /dev/null +++ b/docs/en/docs/baize/developer/inference/triton-inference.md @@ -0,0 +1,183 @@ +# Create Inference Service Using Triton Framework + +The AI Lab currently offers Triton and vLLM as inference frameworks. Users can quickly start a high-performance inference service with simple configurations. + +!!! danger + + The use of Triton's Backend vLLM method has been deprecated. + It is recommended to use the latest support for vLLM to deploy your large language models. + +## Introduction to Triton + +Triton is an open-source inference server developed by NVIDIA, designed to simplify the deployment and inference of machine learning models. It supports a variety of deep learning frameworks, including TensorFlow and PyTorch, enabling users to easily manage and deploy different types of models. + +## Prerequisites + +Prepare model data: Manage the model code in dataset management and ensure that the data is successfully preloaded. The following example illustrates the PyTorch model for mnist handwritten digit recognition. + +!!! note + + The model to be inferred must adhere to the following directory structure within the dataset: + + ```bash + + └── + └── + └── + ``` + +The directory structure in this example is as follows: + +```bash + model-repo + └── mnist-cnn + └── 1 + └── model.pt +``` + +## Create Inference Service + +Currently, form-based creation is supported, allowing you to create services with field prompts in the interface. + +![点击创建](../../images/triton-infer-0.png) + +### Configure Model Path + +The model path `model-repo/mnist-cnn/1/model.pt` must be consistent with the directory structure of the dataset. + +## Model Configuration + +![点击创建](../../images/triton-infer-1.png) + +### Configure Input and Output Parameters + +!!! note + + The first dimension of the input and output parameters defaults to `batchsize`, setting it to `-1` allows for the automatic calculation of the batchsize based on the input inference data. The remaining dimensions and data type must match the model's input. + +### Configure Environment + +You can import the environment created in [Manage Python Environment Dependencies](../dataset/environments.md) to serve as the runtime environment for inference. + +## Advanced Settings + +![点击创建](../../images/triton-infer-2.png) + +### Configure Authentication Policy + +Supports API key-based request authentication. Users can customize and add authentication parameters. + +### Affinity Scheduling + +Supports automated affinity scheduling based on GPU resources and other node configurations. It also allows users to customize scheduling policies. + +## Access + +![点击创建](../../images/triton-infer-3.png) + + + +### API Access + +- Triton provides a REST-based API, allowing clients to perform model inference via HTTP POST requests. +- Clients can send requests with JSON-formatted bodies containing input data and related metadata. + +#### HTTP Access + +1. **Send HTTP POST Request**: Use tools like `curl` or HTTP client libraries (e.g., Python's `requests` library) to send POST requests to the Triton Server. + +2. **Set HTTP Headers**: Configuration generated automatically based on user settings, include metadata about the model inputs and outputs in the HTTP headers. + +3. **Construct Request Body**: The request body usually contains the input data for inference and model-specific metadata. + + +##### Example curl Command + +```bash + curl -X POST "http://:/v2/models//infer" \ + -H "Content-Type: application/json" \ + -d '{ + "inputs": [ + { + "name": "model_input", + "shape": [1, 1, 32, 32], + "datatype": "FP32", + "data": [ + [0.1234, 0.5678, 0.9101, ... ] + ] + } + ] + }' +``` + +- `` is the host address where the Triton Inference Server is running. +- `` is the port where the Triton Inference Server is running. +- `` is the name of the inference service that has been created. +- `"name"` must match the `name` of the input parameter in the model configuration. +- `"shape"` must match the `dims` of the input parameter in the model configuration. +- `"datatype"` must match the `Data Type` of the input parameter in the model configuration. +- `"data"` should be replaced with the actual inference data. + + + +Please note that the above example code needs to be adjusted according to your specific model and environment. The format and content of the input data must also comply with the model's requirements. + + \ No newline at end of file diff --git a/docs/en/docs/baize/developer/inference/vllm-inference.md b/docs/en/docs/baize/developer/inference/vllm-inference.md new file mode 100644 index 0000000..b67d5a5 --- /dev/null +++ b/docs/en/docs/baize/developer/inference/vllm-inference.md @@ -0,0 +1,49 @@ +# Create Inference Service Using vLLM Framework + +AI Lab supports using vLLM as an inference service, offering all the capabilities of vLLM while fully adapting to the OpenAI interface definition. + +## Introduction to vLLM + +vLLM is a fast and easy-to-use library for inference and services. It aims to significantly improve the throughput and memory efficiency of language model services in real-time scenarios. vLLM boasts several features in terms of speed and flexibility: + +- Continuous batching of incoming requests. +- Efficiently manages attention keys and values memory using PagedAttention. +- Seamless integration with popular HuggingFace models. +- Compatible with OpenAI's API server. + +## Prerequisites + +Prepare model data: Manage the model code in dataset management and ensure that the data is successfully preloaded. + +## Create Inference Service + +1. Select the `vLLM` inference framework. In the model module selection, choose the pre-created model dataset `hdd-models` and fill in the `path` information where the model is located within the dataset. + + This guide uses the ChatGLM3 model for creating the inference service. + + + +2. Configure the resources for the inference service and adjust the parameters for running the inference service. + + + + | Parameter Name | Description | + | -- | -- | + | GPU Resources | Configure GPU resources for inference based on the model scale and cluster resources. | + | Allow Remote Code | Controls whether vLLM trusts and executes code from remote sources. | + | LoRA | **LoRA** is a parameter-efficient fine-tuning technique for deep learning models. It reduces the number of parameters and computational complexity by decomposing the original model parameter matrix into low-rank matrices.

1. `--lora-modules`: Specifies specific modules or layers for low-rank approximation.
2. `max_loras_rank`: Specifies the maximum rank for each adapter layer in the LoRA model. For simpler tasks, a smaller rank value can be chosen, while more complex tasks may require a larger rank value to ensure model performance.
3. `max_loras`: Indicates the maximum number of LoRA layers that can be included in the model, customized based on model size and inference complexity.
4. `max_cpu_loras`: Specifies the maximum number of LoRA layers that can be handled in a CPU environment. | + | Associated Environment | Selects predefined environment dependencies required for inference. | + + !!! info + + For models that support LoRA parameters, refer to [vLLM Supported Models](https://docs.vllm.ai/en/latest/models/supported_models.html). + +3. In the **Advanced Configuration** , support is provided for automated affinity scheduling based on GPU resources and other node configurations. Users can also customize scheduling policies. + +## Verify Inference Service + +Once the inference service is created, click the name of the inference service to enter the details and view the API call methods. Verify the execution results using Curl, Python, and Node.js. + +Copy the `curl` command from the details and execute it in the terminal to send a model inference request. The expected output should be: + + diff --git a/docs/en/docs/baize/developer/jobs/create.md b/docs/en/docs/baize/developer/jobs/create.md new file mode 100644 index 0000000..4244ee5 --- /dev/null +++ b/docs/en/docs/baize/developer/jobs/create.md @@ -0,0 +1,45 @@ +--- +MTPE: ModetaNiu +Date: 2024-07-08 +hide: + - toc +--- + +# Create Job + +Job management refers to the functionality of creating and managing job lifecycles through job scheduling +and control components. + +AI platform Smart Computing Capability adopts Kubernetes' Job mechanism to schedule various AI inference and +training jobs. + +1. Click **Job Center** -> **Jobs** in the left navigation bar to enter the job list. Click the **Create** button + on the right. + + ![Create a Job](../../images/job01.png) + +2. The system will pre-fill basic configuration data, including the cluster, namespace, type, queue, and priority. + Adjust these parameters and click **Next**. + + ![Bacis Info](../../images/job02.png) + +3. Configure the URL, runtime parameters, and associated datasets, then click **Next**. + + ![Resource config](../../images/job03.png) + +4. Optionally add labels, annotations, runtime env variables, and other job parameters. Select a scheduling policy + and click **Confirm**. + + ![Advanced settings](../../images/job04.png) + +5. After the job is successfully created, it will have several running statuses: + + - Running + - Queued + - Submission successful, Submission failed + - Successful, Failed + +## Next Steps + +- [View Job Load](./view.md) +- [Delete Job](./delete.md) diff --git a/docs/en/docs/baize/developer/jobs/delete.md b/docs/en/docs/baize/developer/jobs/delete.md new file mode 100644 index 0000000..13f9267 --- /dev/null +++ b/docs/en/docs/baize/developer/jobs/delete.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# Delete Job + +If you find a job to be redundant, expired, or no longer needed for any other reason, you can delete it from the job list. + +1. Click the **┇** on the right side of the job in the job list, then choose **Delete** from the dropdown menu. + + + +2. In the pop-up window, confirm the job you want to delete, enter the job name, and then click **Delete**. + + + +3. A confirmation message will appear indicating successful deletion, and the job will disappear from the list. + + + +!!! caution + + Once a job is deleted, it cannot be recovered, so please proceed with caution. diff --git a/docs/en/docs/baize/developer/jobs/pytorch.md b/docs/en/docs/baize/developer/jobs/pytorch.md new file mode 100644 index 0000000..feb2b91 --- /dev/null +++ b/docs/en/docs/baize/developer/jobs/pytorch.md @@ -0,0 +1,227 @@ +# Pytorch Jobs + +Pytorch is an open-source deep learning framework that provides a flexible environment for training and deployment. +A Pytorch job is a job that uses the Pytorch framework. + +In the AI Lab platform, we provide support and adaptation for Pytorch jobs. Through a graphical interface, you can quickly create Pytorch jobs and perform model training. + +## Job Configuration + +- Job types support both `Pytorch Single` and `Pytorch Distributed` modes. +- The runtime image already supports the Pytorch framework by default, so no additional installation is required. + +## Job Runtime Environment + +Here we use the `baize-notebook` base image and the `associated environment` as the basic runtime environment for the job. + +> To learn how to create an environment, refer to [Environments](../dataset/environments.md). + +## Create Jobs + +### Pytorch Single Jobs + + + +1. Log in to the AI Lab platform, click **Job Center** in the left navigation bar to enter the **Jobs** page. +2. Click the **Create** button in the upper right corner to enter the job creation page. +3. Select the job type as `Pytorch Single` and click **Next** . +4. Fill in the job name and description, then click **OK** . + +#### Parameters + +- Start command: `bash` +- Command parameters: + +```python +import torch +import torch.nn as nn +import torch.optim as optim + +# Define a simple neural network +class SimpleNet(nn.Module): + def __init__(self): + super(SimpleNet, self).__init__() + self.fc = nn.Linear(10, 1) + + def forward(self, x): + return self.fc(x) + +# Create model, loss function, and optimizer +model = SimpleNet() +criterion = nn.MSELoss() +optimizer = optim.SGD(model.parameters(), lr=0.01) + +# Generate some random data +x = torch.randn(100, 10) +y = torch.randn(100, 1) + +# Train the model +for epoch in range(100): + # Forward pass + outputs = model(x) + loss = criterion(outputs, y) + + # Backward pass and optimization + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if (epoch + 1) % 10 == 0: + print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}') + +print('Training finished.') +``` + +#### Results + +Once the job is successfully submitted, we can enter the job details to see the resource usage. From the upper right corner, go to **Workload Details** to view the log output during the training process. + +```bash +[HAMI-core Warn(1:140244541377408:utils.c:183)]: get default cuda from (null) +[HAMI-core Msg(1:140244541377408:libvgpu.c:855)]: Initialized +Epoch [10/100], Loss: 1.1248 +Epoch [20/100], Loss: 1.0486 +Epoch [30/100], Loss: 0.9969 +Epoch [40/100], Loss: 0.9611 +Epoch [50/100], Loss: 0.9360 +Epoch [60/100], Loss: 0.9182 +Epoch [70/100], Loss: 0.9053 +Epoch [80/100], Loss: 0.8960 +Epoch [90/100], Loss: 0.8891 +Epoch [100/100], Loss: 0.8841 +Training finished. +[HAMI-core Msg(1:140244541377408:multiprocess_memory_limit.c:468)]: Calling exit handler 1 +``` + +### Pytorch Distributed Jobs + +1. Log in to the AI Lab platform, click **Job Center** in the left navigation bar to enter the **Jobs** page. +2. Click the **Create** button in the upper right corner to enter the job creation page. +3. Select the job type as `Pytorch Distributed` and click **Next**. +4. Fill in the job name and description, then click **OK**. + +#### Parameters + +- Start command: `bash` +- Command parameters: + +```python +import os +import torch +import torch.distributed as dist +import torch.nn as nn +import torch.optim as optim +from torch.nn.parallel import DistributedDataParallel as DDP + +class SimpleModel(nn.Module): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = nn.Linear(10, 1) + + def forward(self, x): + return self.fc(x) + +def train(): + # Print environment information + print(f'PyTorch version: {torch.__version__}') + print(f'CUDA available: {torch.cuda.is_available()}') + if torch.cuda.is_available(): + print(f'CUDA version: {torch.version.cuda}') + print(f'CUDA device count: {torch.cuda.device_count()}') + + rank = int(os.environ.get('RANK', '0')) + world_size = int(os.environ.get('WORLD_SIZE', '1')) + + print(f'Rank: {rank}, World Size: {world_size}') + + # Initialize distributed environment + try: + if world_size > 1: + dist.init_process_group('nccl') + print('Distributed process group initialized successfully') + else: + print('Running in non-distributed mode') + except Exception as e: + print(f'Error initializing process group: {e}') + return + + # Set device + try: + if torch.cuda.is_available(): + device = torch.device(f'cuda:{rank % torch.cuda.device_count()}') + print(f'Using CUDA device: {device}') + else: + device = torch.device('cpu') + print('CUDA not available, using CPU') + except Exception as e: + print(f'Error setting device: {e}') + device = torch.device('cpu') + print('Falling back to CPU') + + try: + model = SimpleModel().to(device) + print('Model moved to device successfully') + except Exception as e: + print(f'Error moving model to device: {e}') + return + + try: + if world_size > 1: + ddp_model = DDP(model, device_ids=[rank % torch.cuda.device_count()] if torch.cuda.is_available() else None) + print('DDP model created successfully') + else: + ddp_model = model + print('Using non-distributed model') + except Exception as e: + print(f'Error creating DDP model: {e}') + return + + loss_fn = nn.MSELoss() + optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) + + # Generate some random data + try: + data = torch.randn(100, 10, device=device) + labels = torch.randn(100, 1, device=device) + print('Data generated and moved to device successfully') + except Exception as e: + print(f'Error generating or moving data to device: {e}') + return + + for epoch in range(10): + try: + ddp_model.train() + outputs = ddp_model(data) + loss = loss_fn(outputs, labels) + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if rank == 0: + print(f'Epoch {epoch}, Loss: {loss.item():.4f}') + except Exception as e: + print(f'Error during training epoch {epoch}: {e}') + break + + if world_size > 1: + dist.destroy_process_group() + +if __name__ == '__main__': + train() +``` + +#### Number of Job Replicas + +Note that `Pytorch Distributed` training jobs will create a group of `Master` and `Worker` training Pods, +where the `Master` is responsible for coordinating the training job, and the `Worker` is responsible for the actual training work. + +!!! note + + In this demonstration: `Master` replica count is 1, `Worker` replica count is 2; + Therefore, we need to set the replica count to 3 in the **Job Configuration** , + which is the sum of `Master` and `Worker` replica counts. + Pytorch will automatically tune the roles of `Master` and `Worker`. + +#### Results + +Similarly, we can enter the job details to view the resource usage and the log output of each Pod. diff --git a/docs/en/docs/baize/developer/jobs/tensorboard.md b/docs/en/docs/baize/developer/jobs/tensorboard.md new file mode 100644 index 0000000..f7f27a7 --- /dev/null +++ b/docs/en/docs/baize/developer/jobs/tensorboard.md @@ -0,0 +1,140 @@ +# Job Analysis + +AI Lab provides important visualization analysis tools provided for the model development +process, used to display the training process and results of machine learning models. This document will +introduce the basic concepts of Job Analysis (Tensorboard), its usage in the AI Lab system, +and how to configure the log content of datasets. + +!!! note + + Tensorboard is a visualization tool provided by TensorFlow, used to display the + training process and results of machine learning models. + It can help developers more intuitively understand the training dynamics of + their models, analyze model performance, debug issues, and more. + + + +The role and advantages of Tensorboard in the model development process: + +- **Visualize Training Process** : Display metrics such as training and validation loss, and accuracy + through charts, helping developers intuitively observe the training effects of the model. +- **Debug and Optimize Models** : By viewing the weights and gradient distributions of different layers, + help developers discover and fix issues in the model. +- **Compare Different Experiments** : Simultaneously display the results of multiple experiments, + making it convenient for developers to compare the effects of different models and hyperparameter configurations. +- **Track Training Data** : Record the datasets and parameters used during training to + ensure the reproducibility of experiments. + +## How to Create Tensorboard + +In the AI Lab system, we provide a convenient way to create and manage Tensorboard. +Here are the specific steps: + +### Enable Tensorboard When Creating a Notebook + +1. **Create a Notebook** : Create a new Notebook on the AI Lab platform. +2. **Enable Tensorboard** : On the Notebook creation page, enable the **Tensorboard** + option and specify the dataset and log path. + + + +### Enable Tensorboard After Creating and Completing a Distributed Job + +1. **Create a Distributed Job** : Create a new distributed training job on the AI Lab platform. +2. **Configure Tensorboard** : On the job configuration page, enable the **Tensorboard** + option and specify the dataset and log path. +3. **View Tensorboard After Job Completion** : After the job is completed, you can view + the Tensorboard link on the job details page. Click the link to see the visualized results + of the training process. + + + +### Directly Reference Tensorboard in a Notebook + +In a Notebook, you can directly start Tensorboard through code. Here is a sample code snippet: + +```python +# Import necessary libraries +import tensorflow as tf +import datetime + +# Define log directory +log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + +# Create Tensorboard callback +tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1) + +# Build and compile model +model = tf.keras.models.Sequential([ + tf.keras.layers.Flatten(input_shape=(28, 28)), + tf.keras.layers.Dense(512, activation='relu'), + tf.keras.layers.Dropout(0.2), + tf.keras.layers.Dense(10, activation='softmax') +]) + +model.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + +# Train model and enable Tensorboard callback +model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test), callbacks=[tensorboard_callback]) +``` + +## How to Configure Dataset Log Content + +When using Tensorboard, you can record and configure different datasets and log content. +Here are some common configuration methods: + +### Configure Training and Validation Dataset Logs + +While training the model, you can use TensorFlow's `tf.summary` API to record logs +for the training and validation datasets. Here is a sample code snippet: + +```python +# Import necessary libraries +import tensorflow as tf + +# Create log directories +train_log_dir = 'logs/gradient_tape/train' +val_log_dir = 'logs/gradient_tape/val' +train_summary_writer = tf.summary.create_file_writer(train_log_dir) +val_summary_writer = tf.summary.create_file_writer(val_log_dir) + +# Train model and record logs +for epoch in range(EPOCHS): + for (x_train, y_train) in train_dataset: + # Training step + train_step(x_train, y_train) + with train_summary_writer.as_default(): + tf.summary.scalar('loss', train_loss.result(), step=epoch) + tf.summary.scalar('accuracy', train_accuracy.result(), step=epoch) + + for (x_val, y_val) in val_dataset: + # Validation step + val_step(x_val, y_val) + with val_summary_writer.as_default(): + tf.summary.scalar('loss', val_loss.result(), step=epoch) + tf.summary.scalar('accuracy', val_accuracy.result(), step=epoch) +``` + +### Configure Custom Logs + +In addition to logs for training and validation datasets, you can also record other +custom log content such as learning rate and gradient distribution. Here is a sample code snippet: + +```python +# Record custom logs +with train_summary_writer.as_default(): + tf.summary.scalar('learning_rate', learning_rate, step=epoch) + tf.summary.histogram('gradients', gradients, step=epoch) +``` + +## Tensorboard Management + +In AI Lab, Tensorboards created through various methods are uniformly +displayed on the job analysis page, making it convenient for users to view and manage. + + + +Users can view information such as the link, status, and creation time of Tensorboard +on the job analysis page and directly access the visualized results of Tensorboard through the link. diff --git a/docs/en/docs/baize/developer/jobs/tensorflow.md b/docs/en/docs/baize/developer/jobs/tensorflow.md new file mode 100644 index 0000000..c3cf2b4 --- /dev/null +++ b/docs/en/docs/baize/developer/jobs/tensorflow.md @@ -0,0 +1,165 @@ +# Tensorflow Jobs + +Tensorflow, along with Pytorch, is a highly active open-source deep learning framework +that provides a flexible environment for training and deployment. + +AI Lab provides support and adaptation for the Tensorflow framework. +You can quickly create Tensorflow jobs and conduct model training through graphical operations. + +## Job Configuration + +- The job types support both `Tensorflow Single` and `Tensorflow Distributed` modes. +- The runtime image already supports the Tensorflow framework by default, + so no additional installation is required. + +## Job Runtime Environment + +Here, we use the `baize-notebook` base image and the `associated environment` as the basic runtime environment for jobs. + +> For information on how to create an environment, refer to [Environment List](../dataset/environments.md). + +## Creating a Job + +### Example TFJob Single + + + +1. Log in to the AI Lab platform and click **Job Center** in the left navigation bar + to enter the **Jobs** page. +2. Click the **Create** button in the upper right corner to enter the job creation page. +3. Select the job type as `Tensorflow Single` and click **Next** . +4. Fill in the job name and description, then click **OK** . + +#### Pre-warming the Code Repository + +Use **AI Lab** -> **Dataset List** to create a dataset and pull the code from a remote GitHub repository into the dataset. +This way, when creating a job, you can directly select the dataset and mount the code into the job. + +Demo code repository address: [https://github.com/d-run/training-sample-code/](https://github.com/d-run/training-sample-code/) + +#### Parameters + +- Launch command: Use `bash` +- Command parameters: Use `python /code/tensorflow/tf-single.py` + +```python +""" + pip install tensorflow numpy +""" + +import tensorflow as tf +import numpy as np + +# Create some random data +x = np.random.rand(100, 1) +y = 2 * x + 1 + np.random.rand(100, 1) * 0.1 + +# Create a simple model +model = tf.keras.Sequential([ + tf.keras.layers.Dense(1, input_shape=(1,)) +]) + +# Compile the model +model.compile(optimizer='adam', loss='mse') + +# Train the model, setting epochs to 10 +history = model.fit(x, y, epochs=10, verbose=1) + +# Print the final loss +print('Final loss: {' + str(history.history['loss'][-1]) +'}') + +# Use the model to make predictions +test_x = np.array([[0.5]]) +prediction = model.predict(test_x) +print(f'Prediction for x=0.5: {prediction[0][0]}') +``` + +#### Results + +After the job is successfully submitted, you can enter the job details to see the resource usage. From the upper right corner, navigate to **Workload Details** to view log outputs during the training process. + +### TFJob Distributed Job + +1. Log in to **AI Lab** and click **Job Center** in the left navigation bar to enter the **Jobs** page. +2. Click the **Create** button in the upper right corner to enter the job creation page. +3. Select the job type as `Tensorflow Distributed` and click **Next**. +4. Fill in the job name and description, then click **OK**. + +#### Example Job Introduction + + + +This job includes three roles: `Chief`, `Worker`, and `Parameter Server (PS)`. + +- Chief: Responsible for coordinating the training process and saving model checkpoints. +- Worker: Executes the actual model training. +- PS: Used in asynchronous training to store and update model parameters. + +Different resources are allocated to different roles. `Chief` and `Worker` use GPUs, +while `PS` uses CPUs and larger memory. + +#### Parameters + +- Launch command: Use `bash` +- Command parameters: Use `python /code/tensorflow/tensorflow-distributed.py` + +```python +import os +import json +import tensorflow as tf + +class SimpleModel(tf.keras.Model): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = tf.keras.layers.Dense(1, input_shape=(10,)) + + def call(self, x): + return self.fc(x) + +def train(): + # Print environment information + print(f"TensorFlow version: {tf.__version__}") + print(f"GPU available: {tf.test.is_gpu_available()}") + if tf.test.is_gpu_available(): + print(f"GPU device count: {len(tf.config.list_physical_devices('GPU'))}") + + # Retrieve distributed training information + tf_config = json.loads(os.environ.get('TF_CONFIG') or '{}') + job_type = tf_config.get('job', {}).get('type') + job_id = tf_config.get('job', {}).get('index') + + print(f"Job type: {job_type}, Job ID: {job_id}") + + # Set up distributed strategy + strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy() + + with strategy.scope(): + model = SimpleModel() + loss_fn = tf.keras.losses.MeanSquaredError() + optimizer = tf.keras.optimizers.SGD(learning_rate=0.001) + + # Generate some random data + data = tf.random.normal((100, 10)) + labels = tf.random.normal((100, 1)) + + @tf.function + def train_step(inputs, labels): + with tf.GradientTape() as tape: + predictions = model(inputs) + loss = loss_fn(labels, predictions) + gradients = tape.gradient(loss, model.trainable_variables) + optimizer.apply_gradients(zip(gradients, model.trainable_variables)) + return loss + + for epoch in range(10): + loss = train_step(data, labels) + if job_type == 'chief': + print(f'Epoch {epoch}, Loss: {loss.numpy():.4f}') + +if __name__ == '__main__': + train() +``` + +#### Results + +Similarly, you can enter the job details to view the resource usage and log outputs of each Pod. diff --git a/docs/en/docs/baize/developer/jobs/view.md b/docs/en/docs/baize/developer/jobs/view.md new file mode 100644 index 0000000..cf8937c --- /dev/null +++ b/docs/en/docs/baize/developer/jobs/view.md @@ -0,0 +1,212 @@ +--- +hide: + - toc +--- + +# View Job Workloads + +Once a job is created, it will be displayed in the job list. + +1. In the job list, click the **┇** on the right side of a job and select **Job Workload Details** . + + ![Click Menu Item](../../images/view-wl01.png) + +2. A pop-up window will appear asking you to choose which Pod to view. Click **Enter** . + + ![Pop-up Enter](../../images/view-wl02.png) + +3. You will be redirected to the container management interface, where you can view the container’s working status, labels and annotations, and any events that have occurred. + + ![View Details](../../images/view-wl03.png) + +4. You can also view detailed logs of the current Pod for the recent period. + By default, 100 lines of logs are displayed. To view more detailed logs or to download logs, click the blue **Insight** text at the top. + + ![Logs](../../images/view-wl04.png) + +5. Additionally, you can use the **...** in the upper right corner to view the current Pod's YAML, and to upload or download files. + Below is an example of a Pod's YAML. + +```yaml +kind: Pod +apiVersion: v1 +metadata: + name: neko-tensorboard-job-test-202404181843-skxivllb-worker-0 + namespace: default + uid: ddedb6ff-c278-47eb-ae1e-0de9b7c62f8c + resourceVersion: '41092552' + creationTimestamp: '2024-04-18T10:43:36Z' + labels: + training.kubeflow.org/job-name: neko-tensorboard-job-test-202404181843-skxivllb + training.kubeflow.org/operator-name: pytorchjob-controller + training.kubeflow.org/replica-index: '0' + training.kubeflow.org/replica-type: worker + annotations: + cni.projectcalico.org/containerID: 0cfbb9af257d5e69027c603c6cb2d3890a17c4ae1a145748d5aef73a10d7fbe1 + cni.projectcalico.org/podIP: '' + cni.projectcalico.org/podIPs: '' + hami.io/bind-phase: success + hami.io/bind-time: '1713437016' + hami.io/vgpu-devices-allocated: GPU-29d5fa0d-935b-2966-aff8-483a174d61d1,NVIDIA,1024,20:; + hami.io/vgpu-devices-to-allocate: ; + hami.io/vgpu-node: worker-a800-1 + hami.io/vgpu-time: '1713437016' + k8s.v1.cni.cncf.io/network-status: |- + [{ + "name": "kube-system/calico", + "ips": [ + "10.233.97.184" + ], + "default": true, + "dns": {} + }] + k8s.v1.cni.cncf.io/networks-status: |- + [{ + "name": "kube-system/calico", + "ips": [ + "10.233.97.184" + ], + "default": true, + "dns": {} + }] + ownerReferences: + - apiVersion: kubeflow.org/v1 + kind: PyTorchJob + name: neko-tensorboard-job-test-202404181843-skxivllb + uid: e5a8b05d-1f03-4717-8e1c-4ec928014b7b + controller: true + blockOwnerDeletion: true +spec: + volumes: + - name: 0-dataset-pytorch-examples + persistentVolumeClaim: + claimName: pytorch-examples + - name: kube-api-access-wh9rh + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + defaultMode: 420 + containers: + - name: pytorch + image: m.daocloud.io/docker.io/pytorch/pytorch + command: + - bash + args: + - '-c' + - >- + ls -la /root && which pip && pip install pytorch_lightning tensorboard + && python /root/Git/pytorch/examples/mnist/main.py + ports: + - name: pytorchjob-port + containerPort: 23456 + protocol: TCP + env: + - name: PYTHONUNBUFFERED + value: '1' + - name: PET_NNODES + value: '1' + resources: + limits: + cpu: '4' + memory: 8Gi + nvidia.com/gpucores: '20' + nvidia.com/gpumem: '1024' + nvidia.com/vgpu: '1' + requests: + cpu: '4' + memory: 8Gi + nvidia.com/gpucores: '20' + nvidia.com/gpumem: '1024' + nvidia.com/vgpu: '1' + volumeMounts: + - name: 0-dataset-pytorch-examples + mountPath: /root/Git/pytorch/examples + - name: kube-api-access-wh9rh + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + restartPolicy: Never + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + nodeName: worker-a800-1 + securityContext: {} + affinity: {} + schedulerName: hami-scheduler + tolerations: + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + priorityClassName: baize-high-priority + priority: 100000 + enableServiceLinks: true + preemptionPolicy: PreemptLowerPriority +status: + phase: Succeeded + conditions: + - type: Initialized + status: 'True' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:43:36Z' + reason: PodCompleted + - type: Ready + status: 'False' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:46:34Z' + reason: PodCompleted + - type: ContainersReady + status: 'False' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:46:34Z' + reason: PodCompleted + - type: PodScheduled + status: 'True' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:43:36Z' + hostIP: 10.20.100.211 + podIP: 10.233.97.184 + podIPs: + - ip: 10.233.97.184 + startTime: '2024-04-18T10:43:36Z' + containerStatuses: + - name: pytorch + state: + terminated: + exitCode: 0 + reason: Completed + startedAt: '2024-04-18T10:43:39Z' + finishedAt: '2024-04-18T10:46:34Z' + containerID: >- + containerd://09010214bcf3315e81d38fba50de3943c9d2b48f50a6cc2e83f8ef0e5c6eeec1 + lastState: {} + ready: false + restartCount: 0 + image: m.daocloud.io/docker.io/pytorch/pytorch:latest + imageID: >- + m.daocloud.io/docker.io/pytorch/pytorch@sha256:11691e035a3651d25a87116b4f6adc113a27a29d8f5a6a583f8569e0ee5ff897 + containerID: >- + containerd://09010214bcf3315e81d38fba50de3943c9d2b48f50a6cc2e83f8ef0e5c6eeec1 + started: false + qosClass: Guaranteed +``` diff --git a/docs/en/docs/baize/developer/notebooks/baizectl.md b/docs/en/docs/baize/developer/notebooks/baizectl.md new file mode 100644 index 0000000..f1cf03e --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/baizectl.md @@ -0,0 +1,682 @@ +--- +MTPE: windsonsea +Date: 2024-08-05 +--- + +# baizectl CLI Usage Guide + +`baizectl` is a command line tool specifically designed for model developers and data scientists within +the AI Lab module. It provides a series of commands to help users manage +distributed training jobs, check job statuses, manage datasets, and more. It also supports connecting +to Kubernetes worker clusters and AI platform workspaces, aiding users in efficiently using and managing +Kubernetes platform resources. + +## Installation + +Currently, `baizectl` is integrated within AI Lab. Once you create a Notebook, you can directly use `baizectl` within it. + +--- + +## Getting Started + +### Basic Information + +The basic format of the `baizectl` command is as follows: + +```bash +jovyan@19d0197587cc:/$ baizectl +AI platform management tool + +Usage: + baizectl [command] + +Available Commands: + completion Generate the autocompletion script for the specified shell + data Management datasets + help Help about any command + job Manage jobs + login Login to the platform + version Show cli version + +Flags: + --cluster string Cluster name to operate + -h, --help help for baizectl + --mode string Connection mode: auto, api, notebook (default "auto") + -n, --namespace string Namespace to use for the operation. If not set, the default Namespace will be used. + -s, --server string access base url + --skip-tls-verify Skip TLS certificate verification + --token string access token + -w, --workspace int32 Workspace ID to use for the operation + +Use "baizectl [command] --help" for more information about a command. +``` + +The above provides basic information about `baizectl`. Users can view the help information using +`baizectl --help`, or view the help information for specific commands using `baizectl [command] --help`. + +### View Versions + +`baizectl` supports viewing version information using the `version` command. + +```bash +(base) jovyan@den-0:~$ baizectl version +baizectl version: v0.5.0, commit sha: ac0837c4 +``` + +### Command Format + +The basic format of the `baizectl` command is as follows: + +```bash +baizectl [command] [flags] +``` + +Here, `[command]` refers to the specific operation command, such as `data` and `job`, and +`[flags]` are optional parameters used to specify detailed information about the operation. + +### Common Options + +- `--cluster string`: Specify the name of the cluster to operate on. +- `-h, --help`: Display help information. +- `--mode string`: Connection mode, optional values are `auto`, `api`, `notebook` (default value is `auto`). +- `-n, --namespace string`: Specify the namespace for the operation. If not set, + the default namespace will be used. +- `-s, --server string`: Base URL +- `--skip-tls-verify`: Skip TLS certificate verification. +- `--token string`: Access token +- `-w, --workspace int32`: Specify the workspace ID for the operation. + +--- + +## Features + +### Job Management + +`baizectl` provides a series of commands to manage distributed training jobs, +including viewing job lists, submitting jobs, viewing logs, restarting jobs, deleting jobs, and more. + +```bash +jovyan@19d0197587cc:/$ baizectl job +Manage jobs + +Usage: + baizectl job [command] + +Available Commands: + delete Delete a job + logs Show logs of a job + ls List jobs + restart restart a job + submit Submit a job + +Flags: + -h, --help help for job + -o, --output string Output format. One of: table, json, yaml (default "table") + --page int Page number (default 1) + --page-size int Page size (default -1) + --search string Search query + --sort string Sort order + --truncate int Truncate output to the given length, 0 means no truncation (default 50) + +Use "baizectl job [command] --help" for more information about a command. +``` + +#### Submit Training Jobs + +`baizectl` supports submitting a job using the `submit` command. +You can view detailed information by using `baizectl job submit --help`. + +```bash +(base) jovyan@den-0:~$ baizectl job submit --help +Submit a job + +Usage: + baizectl job submit [flags] -- command ... + +Aliases: + submit, create + +Examples: +# Submit a job to run the command "torchrun python train.py" +baizectl job submit -- torchrun python train.py +# Submit a job with 2 workers(each pod use 4 gpus) to run the command "torchrun python train.py" and use the image "pytorch/pytorch:1.8.1-cuda11.1-cudnn8-runtime" +baizectl job submit --image pytorch/pytorch:1.8.1-cuda11.1-cudnn8-runtime --workers 2 --resources nvidia.com/gpu=4 -- torchrun python train.py +# Submit a tensorflow job to run the command "python train.py" +baizectl job submit --tensorflow -- python train.py + + +Flags: + --annotations stringArray The annotations of the job, the format is key=value + --auto-load-env It only takes effect when executed in Notebook, the environment variables of the current environment will be automatically read and set to the environment variables of the Job, the specific environment variables to be read can be specified using the BAIZE_MAPPING_ENVS environment variable, the default is PATH,CONDA_*,*PYTHON*,NCCL_*, if set to false, the environment variables of the current environment will not be read. (default true) + --commands stringArray The default command of the job + -d, --datasets stringArray The dataset bind to the job, the format is datasetName:mountPath, e.g. mnist:/data/mnist + -e, --envs stringArray The environment variables of the job, the format is key=value + -x, --from-notebook string Define whether to read the configuration of the current Notebook and directly create tasks, including images, resources, and dataset. + auto: Automatically determine the mode according to the current environment. If the current environment is a Notebook, it will be set to notebook mode. + false: Do not read the configuration of the current Notebook. + true: Read the configuration of the current Notebook. (default "auto") + -h, --help help for submit + --image string The image of the job, it must be specified if fromNotebook is false. + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --labels stringArray The labels of the job, the format is key=value + --max-retries int32 number of retries before marking this job failed + --max-run-duration int Specifies the duration in seconds relative to the startTime that the job may be active before the system tries to terminate it + --name string The name of the job, if empty, the name will be generated automatically. + --paddle PaddlePaddle Job, has higher priority than --job-type + --priority string The priority of the job, current support baize-medium-priority, baize-low-priority, baize-high-priority + --pvcs stringArray The pvcs bind to the job, the format is pvcName:mountPath, e.g. mnist:/data/mnist + --pytorch Pytorch Job, has higher priority than --job-type + --queue string The queue to used + --requests-resources stringArray Similar to resources, but sets the resources of requests + --resources stringArray The resources of the job, it is a string in the format of cpu=1,memory=1Gi,nvidia.com/gpu=1, it will be set to the limits and requests of the container. + --restart-policy string The job restart policy (default "on-failure") + --runtime-envs baizectl data ls --runtime-env The runtime environment to use for the job, you can use baizectl data ls --runtime-env to get the runtime environment + --shm-size int32 The shared memory size of the job, default is 0, which means no shared memory, if set to more than 0, the job will use the shared memory, the unit is MiB + --tensorboard-log-dir string The tensorboard log directory, if set, the job will automatically start tensorboard, else not. The format is /path/to/log, you can use relative path in notebook. + --tensorflow Tensorflow Job, has higher priority than --job-type + --workers int The workers of the job, default is 1, which means single worker, if set to more than 1, the job will be distributed. (default 1) + --working-dir string The working directory of job container, if in notebook mode, the default is the directory of the current file +``` + +!!! note + + Explanation of command parameters for submitting jobs: + + - --name: Job name. If empty, it will be auto-generated. + - --image: Image name. This must be specified. + - --priority: Job priority, supporting high=`baize-high-priority`, medium=`baize-medium-priority`, + low=`baize-low-priority`. + - --resources: Job resources, formatted as `cpu=1 memory=1Gi,nvidia.com/gpu=1`. + - --workers: Number of job worker nodes. The default is 1. When set to greater than 1, + the job will run in a distributed manner. + - --queue: Job queue. Queue resources need to be created in advance. + - --working-dir: Working directory. In Notebook mode, the current file directory will be used by default. + - --datasets: Dataset, formatted as `datasetName:mountPath`, for example `mnist:/data/mnist`. + - --shm-size: Shared memory size. This can be enabled for distributed training jobs, + indicating the use of shared memory, with units in MiB. + - --labels: Job labels, formatted as `key=value`. + - --max-retries: Maximum retry count. The number of times to retry the job upon failure. + The job will restart upon failure. Default is unlimited. + - --max-run-duration: Maximum run duration. The job will be terminated by the system + if it exceeds the specified run time. Default is unlimited. + - --restart-policy: Restart policy, supporting `on-failure`, `never`, `always`. The default is `on-failure`. + - --from-notebook: Whether to read configurations from the Notebook. + Supports `auto`, `true`, `false`, with the default being `auto`. + +##### Example of a PyTorch Single-Node Job + +Example of submitting a training job. Users can modify parameters based on their actual needs. +Below is an example of creating a PyTorch job: + +```bash +baizectl job submit --name demojob-v2 -t PYTORCH \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --resources cpu=1,memory=1Gi \ + --workers 1 \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +##### PyTorch 分布式任务示例 + +提交训练任务示例,用户可以根据实际需求修改参数,以下为创建一个 PyTorch 任务的示例: + +##### Example of a Distributed PyTorch Job + +Example of submitting a training job. +You can modify parameters based on their actual needs. +Below is an example of creating a distributed PyTorch job: + +```bash +baizectl job submit --name demojob-v2 -t PYTORCH \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --resources cpu=1,memory=1Gi \ + --workers 2 \ # Multiple job replicas will automatically create a distributed job. + --shm-size 1024 \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +##### Example of a TensorFlow Job + +Use the `-t` parameter to specify the job type. Below is an example of creating a TensorFlow job: + +```bash +baizectl job submit --name demojob-v2 -t TENSORFLOW \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --from-notebook auto \ + --workers 1 \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +You can also use the `--job-type` or `--tensorflow` parameter to specify the job type. + +##### Example of a Paddle Job + +```bash +baizectl job submit --name demojob-v2 -t PADDLE \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +#### View Job List + +`baizectl job` supports viewing the job list using the `ls` command. By default, +it displays `pytorch` jobs, but users can specify the job type using the `-t` parameter. + +```bash +(base) jovyan@den-0:~$ baizectl job ls # View pytorch jobs by default + NAME TYPE PHASE DURATION COMMAND + demong PYTORCH SUCCEEDED 1m2s sleep 60 + demo-sleep PYTORCH RUNNING 1h25m28s sleep 7200 +(base) jovyan@den-0:~$ baizectl job ls demo-sleep # View a specific job + NAME TYPE PHASE DURATION COMMAND + demo-sleep PYTORCH RUNNING 1h25m28s sleep 7200 +(base) jovyan@den-0:~$ baizectl job ls -t TENSORFLOW # View tensorflow jobs + NAME TYPE PHASE DURATION COMMAND + demotfjob TENSORFLOW CREATED 0s sleep 1000 +``` + +The job list uses `table` as the default display format. If you want to view more information, +you can use the `json` or `yaml` format, which can be specified using the `-o` parameter. + +```bash +(base) jovyan@den-0:~$ baizectl job ls -t TENSORFLOW -o yaml +- baseConfig: + args: + - sleep + - "1000" + image: release.daocloud.io/baize/baize-notebook:v0.5.0 + labels: + app: den + podConfig: + affinity: {} + kubeEnvs: + - name: CONDA_EXE + value: /opt/conda/bin/conda + - name: CONDA_PREFIX + value: /opt/conda + - name: CONDA_PROMPT_MODIFIER + value: '(base) ' + - name: CONDA_SHLVL + value: "1" + - name: CONDA_DIR + value: /opt/conda + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_DEFAULT_ENV + value: base + - name: PATH + value: /opt/conda/bin:/opt/conda/condabin:/command:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + priorityClass: baize-high-priority + queue: default + creationTimestamp: "2024-06-16T07:47:27Z" + jobSpec: + runPolicy: + suspend: true + tfReplicaSpecs: + Worker: + replicas: 1 + restartPolicy: OnFailure + template: + metadata: + creationTimestamp: null + spec: + affinity: {} + containers: + - args: + - sleep + - "1000" + env: + - name: CONDA_EXE + value: /opt/conda/bin/conda + - name: CONDA_PREFIX + value: /opt/conda + - name: CONDA_PROMPT_MODIFIER + value: '(base) ' + - name: CONDA_SHLVL + value: "1" + - name: CONDA_DIR + value: /opt/conda + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_DEFAULT_ENV + value: base + - name: PATH + value: /opt/conda/bin:/opt/conda/condabin:/command:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + image: release.daocloud.io/baize/baize-notebook:v0.5.0 + name: tensorflow + resources: + limits: + memory: 1Gi + requests: + cpu: "1" + memory: 2Gi + workingDir: /home/jovyan + priorityClassName: baize-high-priority + name: demotfjob + namespace: ns-chuanjia-ndx + phase: CREATED + roleConfig: + TF_WORKER: + replicas: 1 + resources: + limits: + memory: 1Gi + requests: + cpu: "1" + memory: 2Gi + totalResources: + limits: + memory: "1073741824" + requests: + cpu: "1" + memory: "2147483648" + trainingConfig: + restartPolicy: RESTART_POLICY_ON_FAILURE + trainingMode: SINGLE + type: TENSORFLOW +``` + +#### View Job Logs + +`baizectl job` supports viewing job logs using the `logs` command. +You can view detailed information by using `baizectl job logs --help`. + +```bash +(base) jovyan@den-0:~$ baizectl job logs --help +Show logs of a job + +Usage: + baizectl job logs [pod-name] [flags] + +Aliases: + logs, log + +Flags: + -f, --follow Specify if the logs should be streamed. + -h, --help help for logs + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --paddle PaddlePaddle Job, has higher priority than --job-type + --pytorch Pytorch Job, has higher priority than --job-type + --tail int Lines of recent log file to display. + --tensorflow Tensorflow Job, has higher priority than --job-type + --timestamps Show timestamps +``` + +!!! note + + - The `--follow` parameter allows for real-time log viewing. + - The `--tail` parameter specifies the number of log lines to view, with a default of 50 lines. + - The `--timestamps` parameter displays timestamps. + +Example of viewing job logs: + +```bash +(base) jovyan@den-0:~$ baizectl job log -t TENSORFLOW tf-sample-job-v2-202406161632-evgrbrhn -f +2024-06-16 08:33:06.083766: I tensorflow/core/util/port.cc:110] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`. +2024-06-16 08:33:06.086189: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used. +2024-06-16 08:33:06.132416: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used. +2024-06-16 08:33:06.132903: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations. +To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags. +2024-06-16 08:33:07.223046: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT +Model: "sequential" +_________________________________________________________________ + Layer (type) Output Shape Param # +================================================================= + Conv1 (Conv2D) (None, 13, 13, 8) 80 + + flatten (Flatten) (None, 1352) 0 + + Softmax (Dense) (None, 10) 13530 + +================================================================= +Total params: 13610 (53.16 KB) +Trainable params: 13610 (53.16 KB) +Non-trainable params: 0 (0.00 Byte) +... +``` + +#### Delete Jobs + +`baizectl job` supports deleting jobs using the `delete` command and also supports +deleting multiple jobs simultaneously. + +```bash +(base) jovyan@den-0:~$ baizectl job delete --help +Delete a job + +Usage: + baizectl job delete [flags] + +Aliases: + delete, del, remove, rm + +Flags: + -h, --help help for delete + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --paddle PaddlePaddle Job, has higher priority than --job-type + --pytorch Pytorch Job, has higher priority than --job-type + --tensorflow Tensorflow Job, has higher priority than --job-type +``` + +Here is an example to delete jobs: + +```bash +(base) jovyan@den-0:~$ baizectl job ls + NAME TYPE PHASE DURATION COMMAND + demong PYTORCH SUCCEEDED 1m2s sleep 60 + demo-sleep PYTORCH RUNNING 1h20m51s sleep 7200 + demojob PYTORCH FAILED 16m46s sleep 1000 + demojob-v2 PYTORCH RUNNING 3m13s sleep 1000 + demojob-v3 PYTORCH CREATED 0s sleep 1000 +(base) jovyan@den-0:~$ baizectl job delete demojob # delete a job +Delete job demojob in ns-chuanjia-ndx successfully +(base) jovyan@den-0:~$ baizectl job delete demojob-v2 demojob-v3 # delete several jobs +Delete job demojob-v2 in ns-chuanjia-ndx successfully +Delete job demojob-v3 in ns-chuanjia-ndx successfully +``` + +#### Restart Jobs + +`baizectl job` supports restarting jobs using the `restart` command. +You can view detailed information by using `baizectl job restart --help`. + +```bash +(base) jovyan@den-0:~$ baizectl job restart --help +restart a job + +Usage: + baizectl job restart [flags] job + +Aliases: + restart, rerun + +Flags: + -h, --help help for restart + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --paddle PaddlePaddle Job, has higher priority than --job-type + --pytorch Pytorch Job, has higher priority than --job-type + --tensorflow Tensorflow Job, has higher priority than --job-type +``` + +### Dataset Management + +`baizectl` supports managing datasets. Currently, it supports viewing the dataset list, +making it convenient to quickly bind datasets during job training. + +```bash +(base) jovyan@den-0:~$ baizectl data +Management datasets + +Usage: + baizectl data [flags] + baizectl data [command] + +Aliases: + data, dataset, datasets, envs, runtime-envs + +Available Commands: + ls List datasets + +Flags: + -h, --help help for data + -o, --output string Output format. One of: table, json, yaml (default "table") + --page int Page number (default 1) + --page-size int Page size (default -1) + --search string Search query + --sort string Sort order + --truncate int Truncate output to the given length, 0 means no truncation (default 50) + +Use "baizectl data [command] --help" for more information about a command. +``` + +#### View Datasets + +`baizectl data` supports viewing the datasets using the `ls` command. +By default, it displays in `table` format, but users can specify the output format using the `-o` parameter. + +```bash +(base) jovyan@den-0:~$ baizectl data ls + NAME TYPE URI PHASE + fashion-mnist GIT https://gitee.com/samzong_lu/fashion-mnist.git READY + sample-code GIT https://gitee.com/samzong_lu/training-sample-code.... READY + training-output PVC pvc://training-output READY +``` + +When submitting a training job, you can specify the dataset using the `-d` or `--datasets` parameter, for example: + +```bash +baizectl job submit --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --datasets sample-code:/home/jovyan/code \ + -- sleep 1000 +``` + +To mount multiple datasets simultaneously, you can use the following format: + +```bash +baizectl job submit --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --datasets sample-code:/home/jovyan/code fashion-mnist:/home/jovyan/data \ + -- sleep 1000 +``` + +#### View Dependencies (Environment) + +The environment `runtime-env` is a unique environment management capability of Suanova. +By decoupling the dependencies required for model development, training tasks, and inference, +it offers a more flexible way to manage dependencies without the need to repeatedly +build complex Docker images. You simply need to select the appropriate environment. + +Additionally, `runtime-env` supports hot updates and dynamic upgrades, allowing you +to update environment dependencies without rebuilding the image. + +`baizectl data` supports viewing the environment list using the `runtime-env` command. +By default, it displays in `table` format, but users can specify the output format using the `-o` parameter. + +```bash +(base) jovyan@den-0:~$ baizectl data ls --runtime-env + NAME TYPE URI PHASE + fashion-mnist GIT https://gitee.com/samzong_lu/fashion-mnist.git READY + sample-code GIT https://gitee.com/samzong_lu/training-sample-code.... READY + training-output PVC pvc://training-output READY + tensorflow-sample CONDA conda://python?version=3.12.3 PROCESSING +``` + +When submitting a training job, you can specify the environment using the `--runtime-env` parameter: + +```bash +baizectl job submit --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --runtime-env tensorflow-sample \ + -- sleep 1000 +``` + +--- + +## Advanced Usage + +`baizectl` supports more advanced usage, such as generating auto-completion scripts, +using specific clusters and namespaces, and using specific workspaces. + +### Generating Auto-Completion Scripts + +```bash +baizectl completion bash > /etc/bash_completion.d/baizectl +``` + +The above command generates an auto-completion script for `bash` and saves it to the +`/etc/bash_completion.d/baizectl` directory. You can load the auto-completion script +by using `source /etc/bash_completion.d/baizectl`. + +### Using Specific Clusters and Namespaces + +```bash +baizectl job ls --cluster my-cluster --namespace my-namespace +``` + +This command will list all jobs in the `my-namespace` namespace within the `my-cluster` cluster. + +### Using Specific Workspaces + +```bash +baizectl job ls --workspace 123 +``` + +## Frequently Asked Questions + +- **Question**: Why can't I connect to the server? + + **Solution**: Check if the `--server` parameter is set correctly and ensure that the network connection + is stable. If the server uses a self-signed certificate, you can use `--skip-tls-verify` to skip + TLS certificate verification. + +- **Question**: How can I resolve insufficient permissions issues? + + **Solution**: Ensure that you are using the correct `--token` parameter to log in and + check if the current user has the necessary permissions for the operation. + +- **Question**: Why can't I list the datasets? + + **Solution**: Check if the namespace and workspace are set correctly and ensure that + the current user has permission to access these resources. + +--- + +## Conclusion + +With this guide, you can quickly get started with `baizectl` commands and efficiently manage AI platform +resources in practical applications. If you have any questions or issues, it is recommended to +use `baizectl [command] --help` to check more detailed information. diff --git a/docs/en/docs/baize/developer/notebooks/baizess.md b/docs/en/docs/baize/developer/notebooks/baizess.md new file mode 100644 index 0000000..5f67727 --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/baizess.md @@ -0,0 +1,51 @@ +# baizess Source Switch Tool Usage Guide + +`baizess` is a built-in, out-of-the-box source switch tool within the Notebook of AI Lab module. It provides a streamlined command-line interface to facilitate the management of package sources for various programming environments. With baizess, users can easily switch sources for commonly used package managers, ensuring seamless access to the latest libraries and dependencies. This tool enhances the efficiency of developers and data scientists by simplifying the process of managing package sources. + +## Installation + +Currently, `baizess` is integrated within AI Lab. Once you create a Notebook, you can directly use `baizess` within it. + +## Getting Started + +### Basic Information + +The basic information of the `baizess` command is as follows: + +```bash +jovyan@19d0197587cc:/$ baizess +source switch tool + +Usage: + baizess [command] [package-manager] + +Available Commands: + set Switch the source of specified package manager to current fastest source + reset Reset the source of specified package manager to default source + +Available Package-managers: + apt (require root privilege) + conda + pip +``` + +### Command Format + +The basic format of the `baizess` command is as follows: + +```bash +baizess [command] [package-manager] +``` + +Here,`[command]` refers to the specific operation command, and `[package-manager]` is used to specify the corresponding package manager for the operation. + +#### Command + +- `set`:Backup the source, perform speed test, and switch the specified package manager's source to the fastest domestic source based on speed test result. +- `reset`:Reset the specified package manager to default source. + +#### Currently supported package-manager + +- `apt` (Source switch and reset require `root` privilege) +- `conda` (original source will be backed up in `/etc/apt/backup/`) +- `pip` (updated source will be written to `~/.condarc`) diff --git a/docs/en/docs/baize/developer/notebooks/create.md b/docs/en/docs/baize/developer/notebooks/create.md new file mode 100644 index 0000000..9044bc3 --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/create.md @@ -0,0 +1,37 @@ +--- +MTPE: windsonsea +date: 2024-06-11 +hide: + - toc +--- + +# Create Notebook + +Notebook provides an online web interactive programming environment, making it convenient for developers to quickly conduct data science and machine learning experiments. + +Upon entering the developer console, developers can create and manage Notebooks in different clusters and namespaces. + +1. Click **Notebooks** in the left navigation bar to enter the Notebook list. Click the **Create** button on the right. + + ![click button](../../images/notebook01.png) + +2. The system will pre-fill basic configuration data, including the cluster, namespace, + queue, priority, resources, and job arguments. Adjust these arguments and click **OK**. + + ![fill forms](../../images/notebook02.png) + +3. The newly created Notebook will initially be in the **Pending** state, and will change to **Running** + after a moment, with the latest one appearing at the top of the list by default. + + ![created](../../images/notebook01.png) + +4. Click the **┇** on the right side to perform more actions: update arguments, start/stop, clone Notebook, view workload details, and delete. + +!!! note + + If you choose pure CPU resources and find that all GPUs on the node are mounted, + you can try adding the following container environment variable to resolve this issue: + + ```config + NVIDIA_VISIBLE_DEVICES="" + ``` diff --git a/docs/en/docs/baize/developer/notebooks/delete.md b/docs/en/docs/baize/developer/notebooks/delete.md new file mode 100644 index 0000000..aba5e69 --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/delete.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# Delete Notebook + +If you find a Notebook to be redundant, expired, or no longer needed for any other reason, you can delete it from the Notebook list. + +1. Click the **┇** on the right side of the Notebook in the Notebook list, then choose **Delete** from the dropdown menu. + + + +2. In the pop-up window, confirm the Notebook you want to delete, enter the Notebook name, and then click **Delete**. + + + +3. A confirmation message will appear indicating successful deletion, and the Notebook will disappear from the list. + + + +!!! caution + + Once a Notebook is deleted, it cannot be recovered, so please proceed with caution. diff --git a/docs/en/docs/baize/developer/notebooks/notebook-auto-close.md b/docs/en/docs/baize/developer/notebooks/notebook-auto-close.md new file mode 100644 index 0000000..ff0b94a --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/notebook-auto-close.md @@ -0,0 +1,69 @@ +--- +MTPE: windsonsea +Date: 2024-09-05 +--- + +# Automatic Shutdown of Idle Notebooks + +To optimize resource usage, the smart computing system automatically shuts down idle notebooks +after a period of inactivity. This helps free up resources when a notebook is not in use. + +- **Advantages**: This feature significantly reduces resource waste from long periods of inactivity, + enhancing overall efficiency. +- **Disadvantages**: Without proper backup strategies in place, this may lead to potential data loss. + +!!! note + + This feature is enabled by default at the cluster level, with a default timeout of 30 minutes. + +## Change Configurations + +Currently, configuration changes must be made manually, but more convenient options will be available in the future. + +To modify the deployment parameters of `baize-agent` in your worker cluster, update the Helm application. + +### Modify on UI + +1. In the clusters page, locate your worker cluster, go to its details, + select __Helm Apps__, and find `baize-agent` under the `baize-system` namespace, Click __Update__ on the upper right corner. + + ![baize-agent](../../images/notebook-idle.png) + +2. Adjust YAML as shown below: + + ![baize-agent](../../images/notebook-idle02.png) + + ```yaml + ... + notebook-controller: + culling_enabled: false + cull_idle_time: 120 + idleness_check_period: 1 + ... + ``` + +3. After confirming the changes, click __Next__ and __OK__ . + +### Modify on CLI + +In the console, use the `helm upgrade` command to change the configuration: + +```bash +# Set version number +export VERSION=0.8.0 + +# Update Helm Chart +helm upgrade --install baize-agent baize/baize-agent \ + --namespace baize-system \ + --create-namespace \ + --set global.imageRegistry=release.daocloud.io \ + --set notebook-controller.culling_enabled=true \ # Enable automatic shutdown (default: true) + --set notebook-controller.cull_idle_time=120 \ # Set idle timeout to 120 minutes (default: 30 minutes) + --set notebook-controller.idleness_check_period=1 \ # Set check interval to 1 minute (default: 1 minute) + --version=$VERSION +``` + +!!! note + + To prevent data loss after an automatic shutdown, upgrade to v0.8.0 or higher + and enable the auto-save feature in your notebook configuration. diff --git a/docs/en/docs/baize/developer/notebooks/notebook-with-envs.md b/docs/en/docs/baize/developer/notebooks/notebook-with-envs.md new file mode 100644 index 0000000..1b495a4 --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/notebook-with-envs.md @@ -0,0 +1,136 @@ +--- +MTPE: windsonsea +date: 2024-09-05 +--- + +# Use Environments in Notebooks + +Environment management is one of the key features of AI Lab. By associating an environment +in a **Notebook** , you can quickly switch between different environments, making it easier for them to develop and debug. + +## Select an Environment When Creating a Notebook + +When creating a **Notebook**, you can select one or more environments. +If there isn’t a suitable environment, you can create a new one in **Environments** . + +![Attach-Envs](../../images/notebook04.png) + +> For instructions on how to create an environment, refer to [Environments](../dataset/environments.md). + +## Use Environments in Notebooks + +!!! note + + In the Notebook, both `conda` and `mamba` are provided as environment management tools. + You can choose the appropriate tool based on their needs. + +In AI Lab, you can use the `conda` environment management tool. +You can view the list of current environments in the Notebook by using the command `!conda env list`. + +```bash +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ conda env list +# conda environments: +# +dkj-python312-pure /opt/baize-runtime-env/dkj-python312-pure/conda/envs/dkj-python312-pure +python-3.10 /opt/baize-runtime-env/python-3.10/conda/envs/python-3.10 +torch-smaple /opt/baize-runtime-env/torch-smaple/conda/envs/torch-smaple +base * /opt/conda # Currently activated environment +baize-base /opt/conda/envs/baize-base +``` + +This command lists all `conda` environments and adds an asterisk (*) +before the currently activated environment. + +## Manage Kernel Environment in JupyterLab + +In JupyterLab, the environments associated with the Notebook are automatically bounded +to the Kernel list, allowing you to quickly switch environments through the Kernel. + +![Switch-Envs](../../images/notebook05.png) + +With this method, you can simultaneously write and debug algorithms in a single Notebook. + +## Switch Environments in a Terminal + +> The Notebook for AI Lab now also supports VSCode. + +If you prefer managing and switching environments in the Terminal, you can follow these steps: + +Upon first starting and using the Notebook, you need to execute `conda init`, +and then run `conda activate ` to switch to the proper environment. + +```bash +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ conda init bash # Initialize bash environment, only needed for the first use +no change /opt/conda/condabin/conda + change /opt/conda/bin/conda + change /opt/conda/bin/conda-env + change /opt/conda/bin/activate + change /opt/conda/bin/deactivate + change /opt/conda/etc/profile.d/conda.sh + change /opt/conda/etc/fish/conf.d/conda.fish + change /opt/conda/shell/condabin/Conda.psm1 + change /opt/conda/shell/condabin/conda-hook.ps1 + change /opt/conda/lib/python3.11/site-packages/xontrib/conda.xsh + change /opt/conda/etc/profile.d/conda.csh + change /home/jovyan/.bashrc + action taken. +Added mamba to /home/jovyan/.bashrc + +==> For changes to take effect, close and re-open your current shell. <== + +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ source ~/.bashrc # Reload bash environment +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ conda activate python-3.10 # Switch to python-3.10 environment +(python-3.10) jovyan@chuanjia-jupyter-0:~/yolov8$ conda env list + + mamba version : 1.5.1 +# conda environments: +# +dkj-python312-pure /opt/baize-runtime-env/dkj-python312-pure/conda/envs/dkj-python312-pure +python-3.10 * /opt/baize-runtime-env/python-3.10/conda/envs/python-3.10 # Currently activated environment +torch-smaple /opt/baize-runtime-env/torch-smaple/conda/envs/torch-smaple +base /opt/conda +baize-base /opt/conda/envs/baize-base +``` + +> If you prefer to use `mamba`, you will need to use `mamba init` and `mamba activate `. + +## View Packages in Environment + +One important feature of different environment management is the ability +to use different packages by quickly switching environments within a Notebook. + +You can use the command below to view all packages in the current environment using `conda`. + +```bash +(python-3.10) jovyan@chuanjia-jupyter-0:~/yolov8$ conda list +# packages in environment at /opt/baize-runtime-env/python-3.10/conda/envs/python-3.10: +# +# Name Version Build Channel +_libgcc_mutex 0.1 main defaults +_openmp_mutex 5.1 1_gnu defaults +... # Output truncated +idna 3.7 py310h06a4308_0 defaults +ipykernel 6.28.0 py310h06a4308_0 defaults +ipython 8.20.0 py310h06a4308_0 defaults +ipython_genutils 0.2.0 pyhd3eb1b0_1 defaults +jedi 0.18.1 py310h06a4308_1 defaults +jinja2 3.1.4 py310h06a4308_0 defaults +jsonschema 4.19.2 py310h06a4308_0 defaults +jsonschema-specifications 2023.7.1 py310h06a4308_0 defaults +jupyter_client 7.4.9 py310h06a4308_0 defaults +jupyter_core 5.5.0 py310h06a4308_0 defaults +jupyter_events 0.8.0 py310h06a4308_0 defaults +jupyter_server 2.10.0 py310h06a4308_0 defaults +jupyter_server_terminals 0.4.4 py310h06a4308_1 defaults +jupyterlab_pygments 0.2.2 py310h06a4308_0 defaults +... # Output truncated +xz 5.4.6 h5eee18b_1 defaults +yaml 0.2.5 h7b6447c_0 defaults +zeromq 4.3.5 h6a678d5_0 defaults +zlib 1.2.13 h5eee18b_1 defaults +``` + +## Update Packages in Environment + +Currently, you can update the packages in the environment through the +**Environment Management** UI in AI Lab. diff --git a/docs/en/docs/baize/developer/notebooks/notebook-with-ssh.md b/docs/en/docs/baize/developer/notebooks/notebook-with-ssh.md new file mode 100644 index 0000000..4a1766e --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/notebook-with-ssh.md @@ -0,0 +1,156 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +--- + +# Notebook SSH Guide + +The AI Lab provided by Notebook supports local access via SSH; + +With simple configuration, you can use SSH to access the Jupyter Notebook. +Whether you are using Windows, Mac, or Linux operating systems, you can follow the steps below. + +## Configure SSH Credentials + +### Generate SSH Key Pair + +First, you need to generate an SSH public and private key pair on your computer. This key pair will be used for the authentication process to ensure secure access. + +=== "Mac/Linux" + + 1. Open the terminal. + 2. Enter the command: + + ```bash + ssh-keygen -t rsa -b 4096 + ``` + + 3. When prompted with “Enter a file in which to save the key,” you can press Enter to use the default path or specify a new path. + 4. Next, you will be prompted to enter a passphrase (optional), which adds an extra layer of security. If you choose to enter a passphrase, remember it as you will need it each time you use the key. + +=== "Windows" + + 1. Install Git Bash (if you haven't already). + 2. Open Git Bash. + 3. Enter the command: + + ```bash + ssh-keygen -t rsa -b 4096 + ``` + + 4. Follow the same steps as Mac/Linux. + +### Add SSH Public Key to Personal Center (Optional) + +1. Open the generated public key file, usually located at `~/.ssh/id_rsa.pub` (if you did not change the default path). +2. Copy the public key content. +3. Log in to the system's personal center. +4. Look for the SSH public key configuration area and paste the copied public key into the designated location. +5. Save the changes. + +## Enable SSH in Notebook + +1. Log in to the Jupyter Notebook web interface. +2. Find the Notebook for which you want to enable SSH. +3. In the Notebook's settings or details page, find the option **Enable SSH** and enable it. +4. Record or copy the displayed SSH access command. This command will be used in subsequent steps for SSH connection. + +## SSH in Different Environments + +### Example + +Assume the SSH command you obtained is as follows: + +```bash +ssh username@mockhost -p 2222 +``` + +Replace `username` with your username, `mockhost` with the actual hostname, and `2222` with the actual port number. + +### Windows + +It is recommended to use PuTTY or Git Bash for SSH connection. + +=== "PuTTY" + + 1. Open PuTTY. + 2. In the **Host Name (or IP address)** field, enter `mockhost` (the actual hostname). + 3. Enter the port number `2222` (the actual port number). + 4. Click **Open** to start the connection. + 5. On the first connection, you may be prompted to verify the server's identity. Click **Yes** . + +=== "Git Bash" + + 1. Open Git Bash. + 2. Enter the ssh command to access your machine: + + ```bash + ssh username@mockhost -p 2222 + ``` + + 3. Press Enter. + +### Mac/Linux + +1. Open the terminal. +2. Enter the ssh command to access your machine + + ```bash + ssh username@mockhost -p 2222 + ``` + +3. If prompted to accept the host's identity, type `yes`. + +## Remote Development with IDE + +In addition to using command line tools for SSH connection, you can also utilize modern IDEs such as Visual Studio Code (VSCode) and PyCharm's SSH remote connection feature to develop locally while utilizing remote server resources. + +=== "Using SSH in VSCode" + + VSCode supports SSH remote connection through the **Remote - SSH** extension, allowing you to edit files on the remote server directly in the local VSCode environment and run commands. + + Steps: + + 1. Ensure you have installed VSCode and the **Remote - SSH** extension. + 2. Open VSCode and click the remote resource manager icon at the bottom of the left activity bar. + 3. Select **Remote-SSH: Connect to Host...** and then click **+ Add New SSH Host...** + 4. Enter the SSH connection command, for example: + + ```bash + ssh username@mockhost -p 2222 + ``` + + 5. Press Enter. Replace `username`, `mockhost`, and `2222` with your actual username, hostname, and port number. + 6. Select a configuration file to save this SSH host, usually the default is fine. + + After completing, your SSH host will be added to the SSH target list. Click your host to connect. + If it's your first connection, you may be prompted to verify the host's fingerprint. After accepting, you will be asked to enter the passphrase (if the SSH key has a passphrase). + Once connected successfully, you can edit remote files in VSCode and utilize remote resources just as if you were developing locally. + +=== "Using SSH in PyCharm" + + PyCharm Professional Edition supports connecting to remote servers via SSH and directly developing in the local PyCharm. + + Steps: + + 1. Open PyCharm and open or create a project. + 2. Select **File** -> **Settings** (on Mac, it's **PyCharm** -> **Preferences**). + 3. In the settings window, navigate to **Project: YourProjectName** -> **Python Interpreter**. + 4. Click the gear icon in the upper right corner and select **Add...** + - In the pop-up window, select **SSH Interpreter**. + - Enter the remote host information: hostname (`mockhost`), port number (`2222`), username (`username`). + Replace these placeholders with your actual information. + - Click **Next**. PyCharm will attempt to connect to the remote server. If the connection is successful, you will be asked to enter the passphrase or select the private key file. + + 5. Once configured, click **Finish**. Now, your PyCharm will use the Python interpreter on the remote server. + +## Security Restrictions + +Within the same Workspace, any user can log in to a Notebook with SSH enabled using their own SSH credentials. +This means that as long as users have configured their SSH public key in the personal center and the Notebook has enabled SSH, they can use SSH for a secure connection. + +Note that permissions for different users may vary depending on the Workspace configuration. Ensure you understand and comply with your organization's security and access policies. + +--- + +By following the above steps, you should be able to successfully configure and use SSH to access the Jupyter Notebook. If you encounter any issues, refer to the system help documentation or contact the system administrator. diff --git a/docs/en/docs/baize/developer/notebooks/start-pause.md b/docs/en/docs/baize/developer/notebooks/start-pause.md new file mode 100644 index 0000000..b7151ab --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/start-pause.md @@ -0,0 +1,20 @@ +--- +hide: + - toc +--- + +# Start and Stop Notebook + +After a Notebook is successfully created, it typically has several states: + +- Pending +- Running +- Stopped + +If a Notebook is in the **Stopped** state, click the **┇** on the right side in the list, then choose **Start** from the dropdown menu. + + + +This Notebook will move into the running queue, and its status will change to **Pending**. If everything is normal, its status will change to **Running** after a moment. + +If you have finished using the Notebook, you can choose **Stop** from the menu to change its status to **Stopped**. diff --git a/docs/en/docs/baize/developer/notebooks/view.md b/docs/en/docs/baize/developer/notebooks/view.md new file mode 100644 index 0000000..2303fcb --- /dev/null +++ b/docs/en/docs/baize/developer/notebooks/view.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# View Notebook Workload + +If you want to view the workload of a specific Notebook, you can follow these steps: + +1. Click the **┇** on the right side of the Notebook in the Notebook list, then choose **Workload Details** from the dropdown menu. + + + +2. You will be directed to the StatefulSet list, where you can view: + + - The running status, IP address, resource requests, and usage of the Pod containers + - Container configuration information + - Access methods: ClusterIP, NodePort + - Scheduling strategies: node and workload affinity, anti-affinity + - Labels and annotations: key-value pairs of labels and annotations for the workload and Pods + - Autoscaling: support for HPA, CronHPA, and VPA + - Event list: warnings, notifications, and other messages + + + +3. In the StatefulSet list, click the **┇** on the right side to perform more actions specific to the Pods. + + diff --git a/docs/en/docs/baize/developer/quick-start.md b/docs/en/docs/baize/developer/quick-start.md new file mode 100644 index 0000000..86bc21f --- /dev/null +++ b/docs/en/docs/baize/developer/quick-start.md @@ -0,0 +1,62 @@ +--- +hide: + - toc +--- + +# Quick Start + +This document provides a simple guide for users to use the AI Lab platform for +the entire development and training process of datasets, Notebooks, and job training. + +1. Click **Data Management** -> **Datasets** in the navigation bar, + then click **Create**. Create three datasets as follows: + + - Code: [https://github.com/d-run/drun-samples](https://github.com/d-run/drun-samples/tree/main/tensorflow/tf-fashion-mnist-sample) + - For faster access in China, use Gitee: [https://gitee.com/samzong_lu/training-sample-code.git](https://gitee.com/samzong_lu/training-sample-code.git) + - Data: [https://github.com/zalandoresearch/fashion-mnist](https://github.com/zalandoresearch/fashion-mnist) + - For faster access in China, use Gitee: [https://gitee.com/samzong_lu/fashion-mnist.git](https://gitee.com/samzong_lu/fashion-mnist.git) + - Empty PVC: Create an empty PVC to output the trained model and logs after training. + + !!! note + + Currently, only `StorageClass` with `ReadWriteMany` mode is supported. Please use NFS or the recommended [JuiceFS](https://juicefs.com/zh-cn/). + + + + + + + +2. Prepare the development environment by clicking **Notebooks** in the navigation bar, + then click **Create**. Associate the three datasets created in the previous step and + fill in the mount paths as shown in the image below: + + + +3. Wait for the Notebook to be created successfully, click the access link in + the list to enter the Notebook. Execute the following command in the Notebook terminal to start the job training. + + ```shell + python /home/jovyan/code/tensorflow/tf-fashion-mnist-sample/train.py + ``` + + + +4. Click **Job Center** -> **Jobs** in the navigation bar, create a `Tensorflow Single` job. + Refer to the image below for job configuration and enable the **Job Analysis (Tensorboard)** feature. + Click **Create** and wait for the status to complete. + + - Image address: `release.daocloud.io/baize/jupyter-tensorflow-full:v1.8.0-baize` + - Command: `python` + - Arguments: `/home/jovyan/code/tensorflow/tf-fashion-mnist-sample/train.py` + + !!! note + + For large datasets or models, it is recommended to enable GPU configuration in the resource configuration step. + + + +5. In the job created in the previous step, you can click the specific job analysis to + view the job status and optimize the job training. + + diff --git a/docs/en/docs/baize/images/agent-helm.png b/docs/en/docs/baize/images/agent-helm.png new file mode 100644 index 0000000..7a98add Binary files /dev/null and b/docs/en/docs/baize/images/agent-helm.png differ diff --git a/docs/en/docs/baize/images/bind01.png b/docs/en/docs/baize/images/bind01.png new file mode 100644 index 0000000..e36807a Binary files /dev/null and b/docs/en/docs/baize/images/bind01.png differ diff --git a/docs/en/docs/baize/images/bind02.png b/docs/en/docs/baize/images/bind02.png new file mode 100644 index 0000000..eea10f9 Binary files /dev/null and b/docs/en/docs/baize/images/bind02.png differ diff --git a/docs/en/docs/baize/images/bind03.png b/docs/en/docs/baize/images/bind03.png new file mode 100644 index 0000000..3f0fbfd Binary files /dev/null and b/docs/en/docs/baize/images/bind03.png differ diff --git a/docs/en/docs/baize/images/bind04.png b/docs/en/docs/baize/images/bind04.png new file mode 100644 index 0000000..17b47e9 Binary files /dev/null and b/docs/en/docs/baize/images/bind04.png differ diff --git a/docs/en/docs/baize/images/change-ws.png b/docs/en/docs/baize/images/change-ws.png new file mode 100644 index 0000000..cd6430a Binary files /dev/null and b/docs/en/docs/baize/images/change-ws.png differ diff --git a/docs/en/docs/baize/images/cluster.png b/docs/en/docs/baize/images/cluster.png new file mode 100644 index 0000000..8a86a73 Binary files /dev/null and b/docs/en/docs/baize/images/cluster.png differ diff --git a/docs/en/docs/baize/images/conda01.png b/docs/en/docs/baize/images/conda01.png new file mode 100644 index 0000000..c32d768 Binary files /dev/null and b/docs/en/docs/baize/images/conda01.png differ diff --git a/docs/en/docs/baize/images/conda02.png b/docs/en/docs/baize/images/conda02.png new file mode 100644 index 0000000..b840730 Binary files /dev/null and b/docs/en/docs/baize/images/conda02.png differ diff --git a/docs/en/docs/baize/images/conda03.png b/docs/en/docs/baize/images/conda03.png new file mode 100644 index 0000000..7357355 Binary files /dev/null and b/docs/en/docs/baize/images/conda03.png differ diff --git a/docs/en/docs/baize/images/dataset01.png b/docs/en/docs/baize/images/dataset01.png new file mode 100644 index 0000000..8bb75fe Binary files /dev/null and b/docs/en/docs/baize/images/dataset01.png differ diff --git a/docs/en/docs/baize/images/dataset02.png b/docs/en/docs/baize/images/dataset02.png new file mode 100644 index 0000000..81ddd67 Binary files /dev/null and b/docs/en/docs/baize/images/dataset02.png differ diff --git a/docs/en/docs/baize/images/dataset03.png b/docs/en/docs/baize/images/dataset03.png new file mode 100644 index 0000000..785587c Binary files /dev/null and b/docs/en/docs/baize/images/dataset03.png differ diff --git a/docs/en/docs/baize/images/dataset04.png b/docs/en/docs/baize/images/dataset04.png new file mode 100644 index 0000000..269323d Binary files /dev/null and b/docs/en/docs/baize/images/dataset04.png differ diff --git a/docs/en/docs/baize/images/dataset05.png b/docs/en/docs/baize/images/dataset05.png new file mode 100644 index 0000000..e2fb6a1 Binary files /dev/null and b/docs/en/docs/baize/images/dataset05.png differ diff --git a/docs/en/docs/baize/images/dataset06.png b/docs/en/docs/baize/images/dataset06.png new file mode 100644 index 0000000..9cd8904 Binary files /dev/null and b/docs/en/docs/baize/images/dataset06.png differ diff --git a/docs/en/docs/baize/images/dataset07.png b/docs/en/docs/baize/images/dataset07.png new file mode 100644 index 0000000..dc6b862 Binary files /dev/null and b/docs/en/docs/baize/images/dataset07.png differ diff --git a/docs/en/docs/baize/images/delete02.png b/docs/en/docs/baize/images/delete02.png new file mode 100644 index 0000000..d2d397d Binary files /dev/null and b/docs/en/docs/baize/images/delete02.png differ diff --git a/docs/en/docs/baize/images/ds-delete01.png b/docs/en/docs/baize/images/ds-delete01.png new file mode 100644 index 0000000..7a52e75 Binary files /dev/null and b/docs/en/docs/baize/images/ds-delete01.png differ diff --git a/docs/en/docs/baize/images/ds-delete02.png b/docs/en/docs/baize/images/ds-delete02.png new file mode 100644 index 0000000..4bef572 Binary files /dev/null and b/docs/en/docs/baize/images/ds-delete02.png differ diff --git a/docs/en/docs/baize/images/ds-delete03.png b/docs/en/docs/baize/images/ds-delete03.png new file mode 100644 index 0000000..8dfcf02 Binary files /dev/null and b/docs/en/docs/baize/images/ds-delete03.png differ diff --git a/docs/en/docs/baize/images/inference-interface.png b/docs/en/docs/baize/images/inference-interface.png new file mode 100644 index 0000000..a989517 Binary files /dev/null and b/docs/en/docs/baize/images/inference-interface.png differ diff --git a/docs/en/docs/baize/images/job01.png b/docs/en/docs/baize/images/job01.png new file mode 100644 index 0000000..d3e5dec Binary files /dev/null and b/docs/en/docs/baize/images/job01.png differ diff --git a/docs/en/docs/baize/images/job02.png b/docs/en/docs/baize/images/job02.png new file mode 100644 index 0000000..c6bf3a1 Binary files /dev/null and b/docs/en/docs/baize/images/job02.png differ diff --git a/docs/en/docs/baize/images/job03.png b/docs/en/docs/baize/images/job03.png new file mode 100644 index 0000000..e78e9ca Binary files /dev/null and b/docs/en/docs/baize/images/job03.png differ diff --git a/docs/en/docs/baize/images/job04.png b/docs/en/docs/baize/images/job04.png new file mode 100644 index 0000000..7e83937 Binary files /dev/null and b/docs/en/docs/baize/images/job04.png differ diff --git a/docs/en/docs/baize/images/notebook-idle.png b/docs/en/docs/baize/images/notebook-idle.png new file mode 100644 index 0000000..9f483e8 Binary files /dev/null and b/docs/en/docs/baize/images/notebook-idle.png differ diff --git a/docs/en/docs/baize/images/notebook-idle02.png b/docs/en/docs/baize/images/notebook-idle02.png new file mode 100644 index 0000000..748e697 Binary files /dev/null and b/docs/en/docs/baize/images/notebook-idle02.png differ diff --git a/docs/en/docs/baize/images/notebook-images.png b/docs/en/docs/baize/images/notebook-images.png new file mode 100644 index 0000000..12bb1ac Binary files /dev/null and b/docs/en/docs/baize/images/notebook-images.png differ diff --git a/docs/en/docs/baize/images/notebook01.png b/docs/en/docs/baize/images/notebook01.png new file mode 100644 index 0000000..284b1d6 Binary files /dev/null and b/docs/en/docs/baize/images/notebook01.png differ diff --git a/docs/en/docs/baize/images/notebook02.png b/docs/en/docs/baize/images/notebook02.png new file mode 100644 index 0000000..0748948 Binary files /dev/null and b/docs/en/docs/baize/images/notebook02.png differ diff --git a/docs/en/docs/baize/images/notebook03.png b/docs/en/docs/baize/images/notebook03.png new file mode 100644 index 0000000..11579db Binary files /dev/null and b/docs/en/docs/baize/images/notebook03.png differ diff --git a/docs/en/docs/baize/images/notebook04.png b/docs/en/docs/baize/images/notebook04.png new file mode 100644 index 0000000..984e6a0 Binary files /dev/null and b/docs/en/docs/baize/images/notebook04.png differ diff --git a/docs/en/docs/baize/images/oam-overview.png b/docs/en/docs/baize/images/oam-overview.png new file mode 100644 index 0000000..ade3fef Binary files /dev/null and b/docs/en/docs/baize/images/oam-overview.png differ diff --git a/docs/en/docs/baize/images/q-delete01.png b/docs/en/docs/baize/images/q-delete01.png new file mode 100644 index 0000000..e5a03fc Binary files /dev/null and b/docs/en/docs/baize/images/q-delete01.png differ diff --git a/docs/en/docs/baize/images/queue01.png b/docs/en/docs/baize/images/queue01.png new file mode 100644 index 0000000..8b2a38c Binary files /dev/null and b/docs/en/docs/baize/images/queue01.png differ diff --git a/docs/en/docs/baize/images/queue02.png b/docs/en/docs/baize/images/queue02.png new file mode 100644 index 0000000..4c80300 Binary files /dev/null and b/docs/en/docs/baize/images/queue02.png differ diff --git a/docs/en/docs/baize/images/queue03.png b/docs/en/docs/baize/images/queue03.png new file mode 100644 index 0000000..40f0b24 Binary files /dev/null and b/docs/en/docs/baize/images/queue03.png differ diff --git a/docs/en/docs/baize/images/resource.png b/docs/en/docs/baize/images/resource.png new file mode 100644 index 0000000..67bcd8d Binary files /dev/null and b/docs/en/docs/baize/images/resource.png differ diff --git a/docs/en/docs/baize/images/triton-infer-0.png b/docs/en/docs/baize/images/triton-infer-0.png new file mode 100644 index 0000000..df0aae1 Binary files /dev/null and b/docs/en/docs/baize/images/triton-infer-0.png differ diff --git a/docs/en/docs/baize/images/triton-infer-1.png b/docs/en/docs/baize/images/triton-infer-1.png new file mode 100644 index 0000000..188d061 Binary files /dev/null and b/docs/en/docs/baize/images/triton-infer-1.png differ diff --git a/docs/en/docs/baize/images/triton-infer-2.png b/docs/en/docs/baize/images/triton-infer-2.png new file mode 100644 index 0000000..e46b611 Binary files /dev/null and b/docs/en/docs/baize/images/triton-infer-2.png differ diff --git a/docs/en/docs/baize/images/triton-infer-3.png b/docs/en/docs/baize/images/triton-infer-3.png new file mode 100644 index 0000000..bea80f9 Binary files /dev/null and b/docs/en/docs/baize/images/triton-infer-3.png differ diff --git a/docs/en/docs/baize/images/update-baize.png b/docs/en/docs/baize/images/update-baize.png new file mode 100644 index 0000000..73b43f5 Binary files /dev/null and b/docs/en/docs/baize/images/update-baize.png differ diff --git a/docs/en/docs/baize/images/view-wl01.png b/docs/en/docs/baize/images/view-wl01.png new file mode 100644 index 0000000..fd7467f Binary files /dev/null and b/docs/en/docs/baize/images/view-wl01.png differ diff --git a/docs/en/docs/baize/images/view-wl02.png b/docs/en/docs/baize/images/view-wl02.png new file mode 100644 index 0000000..60536d3 Binary files /dev/null and b/docs/en/docs/baize/images/view-wl02.png differ diff --git a/docs/en/docs/baize/images/view-wl03.png b/docs/en/docs/baize/images/view-wl03.png new file mode 100644 index 0000000..a9f5ebf Binary files /dev/null and b/docs/en/docs/baize/images/view-wl03.png differ diff --git a/docs/en/docs/baize/images/view-wl04.png b/docs/en/docs/baize/images/view-wl04.png new file mode 100644 index 0000000..4a95a93 Binary files /dev/null and b/docs/en/docs/baize/images/view-wl04.png differ diff --git a/docs/en/docs/baize/images/workspace.png b/docs/en/docs/baize/images/workspace.png new file mode 100644 index 0000000..1fec80d Binary files /dev/null and b/docs/en/docs/baize/images/workspace.png differ diff --git a/docs/en/docs/baize/oam/index.md b/docs/en/docs/baize/oam/index.md new file mode 100644 index 0000000..3d1846b --- /dev/null +++ b/docs/en/docs/baize/oam/index.md @@ -0,0 +1,19 @@ +--- +MTPE: windsonsea +date: 2024-05-21 +hide: + - toc +--- + +# Operator + +Operator is the daily management of IT resources by IT operations personnel, handling workspace tasks. + +![Operator Overview](../images/oam-overview.png) + +Here, you can visually understand the current usage status of resources such as clusters, nodes, CPUs, GPUs, and vGPUs. + +## Glossary + +- GPU Allocated: Statistics on the GPU allocation status of all unfinished tasks in the current cluster, calculating the ratio between requested GPUs (Request) and total resources (Total). +- GPU Utilization: Statistics on the actual resource utilization of all running tasks in the current cluster, calculating the ratio between the GPUs actually used (Usage) and the total resources (Total). diff --git a/docs/en/docs/baize/oam/queue/create.md b/docs/en/docs/baize/oam/queue/create.md new file mode 100644 index 0000000..a1d1a05 --- /dev/null +++ b/docs/en/docs/baize/oam/queue/create.md @@ -0,0 +1,22 @@ +--- +MTPE: windsonsea +date: 2024-05-21 +hide: + - toc +--- + +# Create Queue + +In the Operator mode, queues can be used to schedule and optimize batch job workloads, effectively managing multiple tasks running on a cluster and optimizing resource utilization through a queue system. + +1. Click **Queue Management** in the left navigation bar, then click the **Create** button on the right. + + ![click button](../../images/queue01.png) + +2. The system will pre-fill basic setup data, including the cluster to deploy to, workspace, and queuing policy. Click **OK** after adjusting these parameters. + + ![fill in](../../images/queue02.png) + +3. A confirmation message will appear upon creation, returning you to the queue management list. Click the **┇** on the right side of the list to perform additional operations such as update or delete. + + ![more actions](../../images/queue03.png) diff --git a/docs/en/docs/baize/oam/queue/delete.md b/docs/en/docs/baize/oam/queue/delete.md new file mode 100644 index 0000000..14a6537 --- /dev/null +++ b/docs/en/docs/baize/oam/queue/delete.md @@ -0,0 +1,24 @@ +--- +MTPE: windsonsea +date: 2024-05-21 +hide: + - toc +--- + +# Delete Queue + +In the Operator mode, if you find a queue to be redundant, expired, or no longer needed for any other reason, you can delete it from the queue list. + +1. Click the **┇** on the right side of the queue in the queue list, then choose **Delete** from the dropdown menu. + + ![delete](../../images/q-delete01.png) + +2. In the pop-up window, confirm the queue you want to delete, enter the queue name, and then click **Delete**. + + ![confirm](../../images/delete02.png) + +3. A confirmation message will appear indicating successful deletion, and the queue will disappear from the list. + +!!! caution + + Once a queue is deleted, it cannot be recovered, so please proceed with caution. diff --git a/docs/en/docs/baize/oam/resource.md b/docs/en/docs/baize/oam/resource.md new file mode 100644 index 0000000..daf54cb --- /dev/null +++ b/docs/en/docs/baize/oam/resource.md @@ -0,0 +1,14 @@ +--- +MTPE: windsonsea +date: 2024-05-21 +hide: + - toc +--- + +# GPU Management + +Automatically consolidate GPU resource information across the entire platform, providing detailed GPU device information display, and allowing you to view workload statistics and task execution information for various GPUs. + +After entering **Operator**, click **Resource Management** -> **GPU Management** in the left navigation bar to view GPU and task information. + +![GPU management](../images/resource.png) diff --git a/docs/en/docs/baize/quickstart/developer/.gitkeep b/docs/en/docs/baize/quickstart/developer/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/en/docs/baize/quickstart/oam/.gitkeep b/docs/en/docs/baize/quickstart/oam/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/en/docs/ghippo/images/14.png b/docs/en/docs/ghippo/images/14.png new file mode 100644 index 0000000..9aa7d08 Binary files /dev/null and b/docs/en/docs/ghippo/images/14.png differ diff --git a/docs/en/docs/ghippo/images/access.png b/docs/en/docs/ghippo/images/access.png new file mode 100644 index 0000000..9da2789 Binary files /dev/null and b/docs/en/docs/ghippo/images/access.png differ diff --git a/docs/en/docs/ghippo/images/addcluster01.png b/docs/en/docs/ghippo/images/addcluster01.png new file mode 100644 index 0000000..8adb495 Binary files /dev/null and b/docs/en/docs/ghippo/images/addcluster01.png differ diff --git a/docs/en/docs/ghippo/images/addcluster02.png b/docs/en/docs/ghippo/images/addcluster02.png new file mode 100644 index 0000000..022c6c9 Binary files /dev/null and b/docs/en/docs/ghippo/images/addcluster02.png differ diff --git a/docs/en/docs/ghippo/images/agent.png b/docs/en/docs/ghippo/images/agent.png new file mode 100644 index 0000000..f2c5101 Binary files /dev/null and b/docs/en/docs/ghippo/images/agent.png differ diff --git a/docs/en/docs/ghippo/images/clusterlist01.png b/docs/en/docs/ghippo/images/clusterlist01.png new file mode 100644 index 0000000..4add7ef Binary files /dev/null and b/docs/en/docs/ghippo/images/clusterlist01.png differ diff --git a/docs/en/docs/ghippo/images/gmagpiereport.png b/docs/en/docs/ghippo/images/gmagpiereport.png new file mode 100644 index 0000000..19bf5b5 Binary files /dev/null and b/docs/en/docs/ghippo/images/gmagpiereport.png differ diff --git a/docs/en/docs/ghippo/images/gproduct03.png b/docs/en/docs/ghippo/images/gproduct03.png new file mode 100644 index 0000000..9c5019c Binary files /dev/null and b/docs/en/docs/ghippo/images/gproduct03.png differ diff --git a/docs/en/docs/ghippo/images/ldap00.png b/docs/en/docs/ghippo/images/ldap00.png new file mode 100644 index 0000000..21f94b7 Binary files /dev/null and b/docs/en/docs/ghippo/images/ldap00.png differ diff --git a/docs/en/docs/ghippo/images/ldap01.png b/docs/en/docs/ghippo/images/ldap01.png new file mode 100644 index 0000000..74e37a9 Binary files /dev/null and b/docs/en/docs/ghippo/images/ldap01.png differ diff --git a/docs/en/docs/ghippo/images/login02.png b/docs/en/docs/ghippo/images/login02.png new file mode 100644 index 0000000..0509b1a Binary files /dev/null and b/docs/en/docs/ghippo/images/login02.png differ diff --git a/docs/en/docs/ghippo/images/logindesign.png b/docs/en/docs/ghippo/images/logindesign.png new file mode 100644 index 0000000..4fe84d2 Binary files /dev/null and b/docs/en/docs/ghippo/images/logindesign.png differ diff --git a/docs/en/docs/ghippo/images/menu1.png b/docs/en/docs/ghippo/images/menu1.png new file mode 100644 index 0000000..ec4813f Binary files /dev/null and b/docs/en/docs/ghippo/images/menu1.png differ diff --git a/docs/en/docs/ghippo/images/menu2.png b/docs/en/docs/ghippo/images/menu2.png new file mode 100644 index 0000000..2bae9ed Binary files /dev/null and b/docs/en/docs/ghippo/images/menu2.png differ diff --git a/docs/en/docs/ghippo/images/menu3.png b/docs/en/docs/ghippo/images/menu3.png new file mode 100644 index 0000000..8d9090b Binary files /dev/null and b/docs/en/docs/ghippo/images/menu3.png differ diff --git a/docs/en/docs/ghippo/images/menu4.png b/docs/en/docs/ghippo/images/menu4.png new file mode 100644 index 0000000..b7a8489 Binary files /dev/null and b/docs/en/docs/ghippo/images/menu4.png differ diff --git a/docs/en/docs/ghippo/images/mybusiness.png b/docs/en/docs/ghippo/images/mybusiness.png new file mode 100644 index 0000000..8317dd5 Binary files /dev/null and b/docs/en/docs/ghippo/images/mybusiness.png differ diff --git a/docs/en/docs/ghippo/images/nav01.png b/docs/en/docs/ghippo/images/nav01.png new file mode 100644 index 0000000..64d5446 Binary files /dev/null and b/docs/en/docs/ghippo/images/nav01.png differ diff --git a/docs/en/docs/ghippo/images/nav02.png b/docs/en/docs/ghippo/images/nav02.png new file mode 100644 index 0000000..3ed6bcc Binary files /dev/null and b/docs/en/docs/ghippo/images/nav02.png differ diff --git a/docs/en/docs/ghippo/images/note.svg b/docs/en/docs/ghippo/images/note.svg new file mode 100644 index 0000000..5e473ae --- /dev/null +++ b/docs/en/docs/ghippo/images/note.svg @@ -0,0 +1,18 @@ + + + + Icon/16/Prompt备份@0.5x + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/docs/ghippo/images/oauth2.png b/docs/en/docs/ghippo/images/oauth2.png new file mode 100644 index 0000000..5014a5b Binary files /dev/null and b/docs/en/docs/ghippo/images/oauth2.png differ diff --git a/docs/en/docs/ghippo/images/oidc-button.png b/docs/en/docs/ghippo/images/oidc-button.png new file mode 100644 index 0000000..ed70422 Binary files /dev/null and b/docs/en/docs/ghippo/images/oidc-button.png differ diff --git a/docs/en/docs/ghippo/images/oidc01.png b/docs/en/docs/ghippo/images/oidc01.png new file mode 100644 index 0000000..f1b73f3 Binary files /dev/null and b/docs/en/docs/ghippo/images/oidc01.png differ diff --git a/docs/en/docs/ghippo/images/password01en.png b/docs/en/docs/ghippo/images/password01en.png new file mode 100644 index 0000000..88172a2 Binary files /dev/null and b/docs/en/docs/ghippo/images/password01en.png differ diff --git a/docs/en/docs/ghippo/images/password02en.png b/docs/en/docs/ghippo/images/password02en.png new file mode 100644 index 0000000..5984daa Binary files /dev/null and b/docs/en/docs/ghippo/images/password02en.png differ diff --git a/docs/en/docs/ghippo/images/password03en.png b/docs/en/docs/ghippo/images/password03en.png new file mode 100644 index 0000000..ad24586 Binary files /dev/null and b/docs/en/docs/ghippo/images/password03en.png differ diff --git a/docs/en/docs/ghippo/images/password04.png b/docs/en/docs/ghippo/images/password04.png new file mode 100644 index 0000000..293579d Binary files /dev/null and b/docs/en/docs/ghippo/images/password04.png differ diff --git a/docs/en/docs/ghippo/images/password04en.png b/docs/en/docs/ghippo/images/password04en.png new file mode 100644 index 0000000..c8d30ca Binary files /dev/null and b/docs/en/docs/ghippo/images/password04en.png differ diff --git a/docs/en/docs/ghippo/images/platform02.png b/docs/en/docs/ghippo/images/platform02.png new file mode 100644 index 0000000..d8b3392 Binary files /dev/null and b/docs/en/docs/ghippo/images/platform02.png differ diff --git a/docs/en/docs/ghippo/images/platform03.png b/docs/en/docs/ghippo/images/platform03.png new file mode 100644 index 0000000..73d189e Binary files /dev/null and b/docs/en/docs/ghippo/images/platform03.png differ diff --git a/docs/en/docs/ghippo/images/report01.png b/docs/en/docs/ghippo/images/report01.png new file mode 100644 index 0000000..c38ee37 Binary files /dev/null and b/docs/en/docs/ghippo/images/report01.png differ diff --git a/docs/en/docs/ghippo/images/security-policy.png b/docs/en/docs/ghippo/images/security-policy.png new file mode 100644 index 0000000..17378ba Binary files /dev/null and b/docs/en/docs/ghippo/images/security-policy.png differ diff --git a/docs/en/docs/ghippo/images/selfapplication.png b/docs/en/docs/ghippo/images/selfapplication.png new file mode 100644 index 0000000..64129f8 Binary files /dev/null and b/docs/en/docs/ghippo/images/selfapplication.png differ diff --git a/docs/en/docs/ghippo/images/sso1.png b/docs/en/docs/ghippo/images/sso1.png new file mode 100644 index 0000000..17f1dc2 Binary files /dev/null and b/docs/en/docs/ghippo/images/sso1.png differ diff --git a/docs/en/docs/ghippo/images/sso2.png b/docs/en/docs/ghippo/images/sso2.png new file mode 100644 index 0000000..f732bc3 Binary files /dev/null and b/docs/en/docs/ghippo/images/sso2.png differ diff --git a/docs/en/docs/ghippo/images/sso3.png b/docs/en/docs/ghippo/images/sso3.png new file mode 100644 index 0000000..d42376f Binary files /dev/null and b/docs/en/docs/ghippo/images/sso3.png differ diff --git a/docs/en/docs/ghippo/images/system-message1.png b/docs/en/docs/ghippo/images/system-message1.png new file mode 100644 index 0000000..72cd0a5 Binary files /dev/null and b/docs/en/docs/ghippo/images/system-message1.png differ diff --git a/docs/en/docs/ghippo/images/system-message2.png b/docs/en/docs/ghippo/images/system-message2.png new file mode 100644 index 0000000..124a000 Binary files /dev/null and b/docs/en/docs/ghippo/images/system-message2.png differ diff --git a/docs/en/docs/ghippo/images/system-message3.png b/docs/en/docs/ghippo/images/system-message3.png new file mode 100644 index 0000000..e8a42ae Binary files /dev/null and b/docs/en/docs/ghippo/images/system-message3.png differ diff --git a/docs/en/docs/ghippo/images/ws01.png b/docs/en/docs/ghippo/images/ws01.png new file mode 100644 index 0000000..dabf343 Binary files /dev/null and b/docs/en/docs/ghippo/images/ws01.png differ diff --git a/docs/en/docs/ghippo/images/ws02.png b/docs/en/docs/ghippo/images/ws02.png new file mode 100644 index 0000000..35b4d46 Binary files /dev/null and b/docs/en/docs/ghippo/images/ws02.png differ diff --git a/docs/en/docs/ghippo/images/ws03.png b/docs/en/docs/ghippo/images/ws03.png new file mode 100644 index 0000000..3e8b1e0 Binary files /dev/null and b/docs/en/docs/ghippo/images/ws03.png differ diff --git a/docs/en/docs/ghippo/images/wsbind1.png b/docs/en/docs/ghippo/images/wsbind1.png new file mode 100644 index 0000000..f3699f2 Binary files /dev/null and b/docs/en/docs/ghippo/images/wsbind1.png differ diff --git a/docs/en/docs/ghippo/images/wsbind2.png b/docs/en/docs/ghippo/images/wsbind2.png new file mode 100644 index 0000000..23e411a Binary files /dev/null and b/docs/en/docs/ghippo/images/wsbind2.png differ diff --git a/docs/en/docs/ghippo/images/wsbind3.png b/docs/en/docs/ghippo/images/wsbind3.png new file mode 100644 index 0000000..d52bbd4 Binary files /dev/null and b/docs/en/docs/ghippo/images/wsbind3.png differ diff --git a/docs/en/docs/ghippo/images/wsbind4.png b/docs/en/docs/ghippo/images/wsbind4.png new file mode 100644 index 0000000..319f60e Binary files /dev/null and b/docs/en/docs/ghippo/images/wsbind4.png differ diff --git a/docs/en/docs/ghippo/images/wsbind5.png b/docs/en/docs/ghippo/images/wsbind5.png new file mode 100644 index 0000000..4b6367b Binary files /dev/null and b/docs/en/docs/ghippo/images/wsbind5.png differ diff --git a/docs/en/docs/ghippo/install/gm-gateway.md b/docs/en/docs/ghippo/install/gm-gateway.md new file mode 100644 index 0000000..d7d1a24 --- /dev/null +++ b/docs/en/docs/ghippo/install/gm-gateway.md @@ -0,0 +1,172 @@ +# Use Guomi Gateway to proxy AI platform + +Follow the steps below to configure the Guomi Gateway for AI platform. + +## Software Introduction + +**[Tengine](https://github.com/alibaba/tengine):** Tengine is a web server project initiated by +taobao.com. Based on Nginx, it adds many advanced features and features for the needs of high-traffic websites. + +**[Tongsuo](https://github.com/Tongsuo-Project/Tongsuo):** Formerly known as BabaSSL, +Tongsuo is an open-source cryptographic library that offers a range of modern cryptographic algorithms +and secure communication protocols. It is designed to support a variety of use cases, including +storage, network security, key management, and privacy computing. By providing foundational +cryptographic capabilities, Tongsuo ensures the privacy, integrity, and authenticity of data +during transmission, storage, and usage. It also enhances security throughout the data lifecycle, +offering robust privacy protection and security features. + +## Preparation + +A Linux host with Docker installed and internet access. + +## Compile and install Tengine & Tongsuo + +!!! note + + This configuration is for reference only. + +```Dockerfile +FROM docker.m.daocloud.io/debian:11.3 + +# Version +ENV TENGINE_VERSION="2.3.4" \ + TONGSUO_VERSION="8.3.2" + +# Install required system packages and dependencies +RUN apt update && \ + apt -y install \ + wget \ + gcc \ + make \ + libpcre3 \ + libpcre3-dev \ + zlib1g-dev \ + perl \ + && apt clean + +# Build tengine +RUN mkdir -p /tmp/pkg/cache/ && cd /tmp/pkg/cache/ \ + && wget https://github.com/alibaba/tengine/archive/refs/tags/${TENGINE_VERSION}.tar.gz -O tengine-${TENGINE_VERSION}.tar.gz \ + && tar zxvf tengine-${TENGINE_VERSION}.tar.gz \ + && wget https://github.com/Tongsuo-Project/Tongsuo/archive/refs/tags/${TONGSUO_VERSION}.tar.gz -O Tongsuo-${TONGSUO_VERSION}.tar.gz \ + && tar zxvf Tongsuo-${TONGSUO_VERSION}.tar.gz \ + && cd tengine-${TENGINE_VERSION} \ + && ./configure \ + --add-module=modules/ngx_openssl_ntls \ + --with-openssl=/tmp/pkg/cache/Tongsuo-${TONGSUO_VERSION} \ + --with-openssl-opt="--strict-warnings enable-ntls" \ + --with-http_ssl_module --with-stream \ + --with-stream_ssl_module --with-stream_sni \ + && make \ + && make install \ + && ln -s /usr/local/nginx/sbin/nginx /usr/sbin/ \ + && rm -rf /tmp/pkg/cache + +EXPOSE 80 443 +STOPSIGNAL SIGTERM +CMD ["nginx", "-g", "daemon off;"] +``` + +```shell +docker build -t tengine:0.0.1 . +``` + +## Generate SM2 and RSA TLS Certificates + +Here's how to generate SM2 and RSA TLS certificates and configure the Guomi gateway. + +### SM2 TLS Certificate + +!!! note + + This certificate is only for testing purposes. + +You can refer to the [Tongsuo official documentation](https://www.yuque.com/tsdoc/ts) to use [OpenSSL to generate SM2 certificates](https://www.yuque.com/tsdoc/ts/pb5vqr), +or visit [Guomi SSL Laboratory to apply for SM2 certificates](https://www.gmssl.cn/gmssl/index.jsp?go=CA). + +In the end, we will get the following files: + +```shell +-rw-r--r-- 1 root root 749 Dec 8 02:59 sm2.*.enc.crt.pem +-rw-r--r-- 1 root root 258 Dec 8 02:59 sm2.*.enc.key.pem +-rw-r--r-- 1 root root 749 Dec 8 02:59 sm2.*.sig.crt.pem +-rw-r--r-- 1 root root 258 Dec 8 02:59 sm2.*.sig.key.pem +``` + +### RSA TLS Certificate + +```shell +-rw-r--r-- 1 root root 216 Dec 8 03:21 rsa.*.crt.pem +-rw-r--r-- 1 root root 4096 Dec 8 02:59 rsa.*.key.pem +``` + +## Configure SM2 and RSA TLS Certificates for the Guomi Gateway + +The Guomi gateway used in this article supports SM2 and RSA TLS certificates. The advantage of dual certificates is that when the browser does not support SM2 TLS certificates, it automatically switches to RSA TLS certificates. + +For more detailed configurations, please refer to the [Tongsuo official documentation](https://www.yuque.com/tsdoc/ts). + +We enter the Tengine container: + +```shell +# Go to the nginx configuration file directory +cd /usr/local/nginx/conf + +# Create the cert folder to store TLS certificates +mkdir cert + +# Copy the SM2 and RSA TLS certificates to the `/usr/local/nginx/conf/cert` directory +cp sm2.*.enc.crt.pem sm2.*.enc.key.pem sm2.*.sig.crt.pem sm2.*.sig.key.pem /usr/local/nginx/conf/cert +cp rsa.*.crt.pem rsa.*.key.pem /usr/local/nginx/conf/cert + +# Edit the nginx.conf configuration +vim nginx.conf +... +server { + listen 443 ssl; + proxy_http_version 1.1; + # Enable Guomi function to support SM2 TLS certificates + enable_ntls on; + + # RSA certificate + # If your browser does not support Guomi certificates, you can enable this option, and Tengine will automatically recognize the user's browser and use RSA certificates for fallback + ssl_certificate /usr/local/nginx/conf/cert/rsa.*.crt.pem; + ssl_certificate_key /usr/local/nginx/conf/cert/rsa.*.key.pem; + + # Configure two pairs of SM2 certificates for encryption and signature + # SM2 signature certificate + ssl_sign_certificate /usr/local/nginx/conf/cert/sm2.*.sig.crt.pem; + ssl_sign_certificate_key /usr/local/nginx/conf/cert/sm2.*.sig.key.pem; + # SM2 encryption certificate + ssl_enc_certificate /usr/local/nginx/conf/cert/sm2.*.enc.crt.pem; + ssl_enc_certificate_key /usr/local/nginx/conf/cert/sm2.*.enc.key.pem; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # You need to modify the address here to the address of the Istio ingress gateway + # For example, proxy_pass https://istio-ingressgateway.istio-system.svc.cluster.local + # Or proxy_pass https://demo-dev.daocloud.io + proxy_pass https://istio-ingressgateway.istio-system.svc.cluster.local; + } +} +``` + +## Reload the Configuration of the Guomi Gateway + +```shell +nginx -s reload +``` + +## Next Steps + +After successfully deploying the Guomi gateway, [customize the AI platform reverse proxy server address](reverse-proxy.md). + +## Verification + +You can deploy a web browser that supports Guomi certificates. +For example, [Samarium Browser](https://github.com/guanzhi/SamariumBrowser), +and then access the UI interface through Tengine to verify if the Guomi certificate is effective. diff --git a/docs/en/docs/ghippo/install/login.md b/docs/en/docs/ghippo/install/login.md new file mode 100644 index 0000000..bb54107 --- /dev/null +++ b/docs/en/docs/ghippo/install/login.md @@ -0,0 +1,36 @@ +--- +hide: + - toc +--- + +# Login + +Before a user uses a new system, there is no data in the system, and the system cannot identify the new user. In order to identify the user identity and bind user data, the user needs an account that can uniquely identify the user identity. + +AI platform assigns an account with certain permissions to the user through the way the administrator creates a new user in __User and Access Control__ . All behaviors generated by this user will be associated with their own account. + +The user logs in through the account/password, and the system verifies whether the identity is legal. If the verification is legal, the user logs in successfully. + +!!! note + + If the user does not perform any operation within 24 hours after logging in, the login status will be automatically logged out. If the logged-in user is always active, the logged-in state will persist. + +The simple process of user login is shown in the figure below. + +```mermaid +graph TB + +user[Input username] --> pass[Input password] --> judge([Click Login and verify username and password]) +judge -.Correct.->success[Success] +judge -.Incorrect.->fail[Fail] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class user,pass cluster; +class judge plain +class success,fail k8s +``` + +The user login screen is as shown in the figure below. For the specific login screen, please refer to the actual product. diff --git a/docs/en/docs/ghippo/install/reverse-proxy.md b/docs/en/docs/ghippo/install/reverse-proxy.md new file mode 100644 index 0000000..1f0555c --- /dev/null +++ b/docs/en/docs/ghippo/install/reverse-proxy.md @@ -0,0 +1,80 @@ +# Customize AI platform Reverse Proxy Server Address + +The specific setup steps are as follows: + +1. Check if the global management Helm repository exists. + + ```shell + helm repo list | grep ghippo + ``` + + If the result is empty or shows the following error, proceed to the next step; + otherwise, skip the next step. + + ```none + Error: no repositories to show + ``` + +2. Add and update the global management Helm repository. + + ```shell + helm repo add ghippo http://{harbor url}/chartrepo/{project} + helm repo update ghippo + ``` + +3. Set environment variables for easier use in the following steps. + + ```shell + # Your reverse proxy address, for example `export Suanova_PROXY="https://demo-alpha.daocloud.io"` + export Suanova_PROXY="https://domain:port" + + # Helm --set parameter backup file + export GHIPPO_VALUES_BAK="ghippo-values-bak.yaml" + + # Get the current version of ghippo + export GHIPPO_HELM_VERSION=$(helm get notes ghippo -n ghippo-system | grep "Chart Version" | awk -F ': ' '{ print $2 }') + ``` + +4. Backup the --set parameters. + + ```shell + helm get values ghippo -n ghippo-system -o yaml > ${GHIPPO_VALUES_BAK} + ``` + +5. Add your reverse proxy address. + + !!! note + + - If possible, you can use the __yq__ command: + + ```shell + yq -i ".global.reverseProxy = \"${Suanova_PROXY}\"" ${GHIPPO_VALUES_BAK} + ``` + + - Or you can use the __vim__ command to edit and save: + + ```shell + vim ${GHIPPO_VALUES_BAK} + + USER-SUPPLIED VALUES: + ... + global: + ... + reverseProxy: ${Suanova_PROXY} # Only need to modify this line + ``` + +6. Run `helm upgrade` to apply the configuration. + + ```shell + helm upgrade ghippo ghippo/ghippo \ + -n ghippo-system \ + -f ${GHIPPO_VALUES_BAK} \ + --version ${GHIPPO_HELM_VERSION} + ``` + +7. Use __kubectl__ to restart the global management Pod to apply the configuration. + + ```shell + kubectl rollout restart deploy/ghippo-apiserver -n ghippo-system + kubectl rollout restart statefulset/ghippo-keycloakx -n ghippo-system + ``` diff --git a/docs/en/docs/ghippo/install/user-isolation.md b/docs/en/docs/ghippo/install/user-isolation.md new file mode 100644 index 0000000..a2320cc --- /dev/null +++ b/docs/en/docs/ghippo/install/user-isolation.md @@ -0,0 +1,79 @@ +# Customize AI platform Reverse Proxy Server Address + +The specific setup steps are as follows: + +1. Check if the global management Helm repository exists. + + ```shell + helm repo list | grep ghippo + ``` + + If the result is empty or shows the following error, proceed to the next step; + otherwise, skip the next step. + + ```none + Error: no repositories to show + ``` + +2. Add and update the global management Helm repository. + + ```shell + helm repo add ghippo http://{harbor url}/chartrepo/{project} + helm repo update ghippo + ``` + +3. Set environment variables for easier use in the following steps. + + ```shell + # Your reverse proxy address, for example `export Suanova_PROXY="https://demo-alpha.daocloud.io"` + export Suanova_PROXY="https://domain:port" + + # Helm --set parameter backup file + export GHIPPO_VALUES_BAK="ghippo-values-bak.yaml" + + # Get the current version of ghippo + export GHIPPO_HELM_VERSION=$(helm get notes ghippo -n ghippo-system | grep "Chart Version" | awk -F ': ' '{ print $2 }') + ``` + +4. Backup the --set parameters. + + ```shell + helm get values ghippo -n ghippo-system -o yaml > ${GHIPPO_VALUES_BAK} + ``` + +5. Add your reverse proxy address. + + !!! note + + - If possible, you can use the __yq__ command: + + ```shell + yq -i ".apiserver.userIsolationMode = \"Folder\"" ${GHIPPO_VALUES_BAK} + ``` + + - Or you can use the __vim__ command to edit and save: + + ```shell + vim ${GHIPPO_VALUES_BAK} + + USER-SUPPLIED VALUES: + ... + # Just add the following two lines + apiserver: + userIsolationMode: Folder + ``` + +6. Run `helm upgrade` to apply the configuration. + + ```shell + helm upgrade ghippo ghippo/ghippo \ + -n ghippo-system \ + -f ${GHIPPO_VALUES_BAK} \ + --version ${GHIPPO_HELM_VERSION} + ``` + +7. Use __kubectl__ to restart the global management Pod to apply the configuration. + + ```shell + kubectl rollout restart deploy/ghippo-apiserver -n ghippo-system + ``` diff --git a/docs/en/docs/ghippo/permissions/amamba.md b/docs/en/docs/ghippo/permissions/amamba.md new file mode 100644 index 0000000..5aaf5cc --- /dev/null +++ b/docs/en/docs/ghippo/permissions/amamba.md @@ -0,0 +1,72 @@ +--- +hide: + - toc +--- + +# Workbench Permissions + +[Workbench](../../amamba/intro/index.md) supports three user roles: + +- Workspace Admin +- Workspace Editor +- Workspace Viewer + +Each role has different permissions, which are described below. + + + +| Menu Objects | Actions | Workspace Admin | Workspace Editor | Workspace Viewer | +| -------- | ----------- | -------------- | ---------------- | ---------------- | +| Apps | View App List | ✓ | ✓ | ✓ | +| | View details (jump to container management) | ✓ | ✓ | ✓ | +| | View application logs (jump to observables) | ✓ | ✓ | ✓ | +| | View application monitoring (jump to observables) | ✓ | ✓ | ✓ | +| | View RabbitMQ Details - Basic Information | ✓ | ✓ | ✓ | +| | View service mesh (jump to service mesh) | ✓ | ✓ | ✓ | +| | View microservice engine (jump to microservice engine) | ✓ | ✓ | ✓ | +| | Create App | ✓ | ✓ | ✗ | +| | Edit YAML | ✓ | ✓ | ✗ | +| | Update replica count | ✓ | ✓ | ✗ | +| | Update container image | ✓ | ✓ | ✗ | +| | Edit Pipeline | ✓ | ✓ | ✗ | +| | App Grouping | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Namespace | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✗ | ✗ | +| | Edit Tab | ✓ | ✗ | ✗ | +| | Edit Resource Quota | ✓ | ✗ | ✗ | +| | delete | ✓ | ✗ | ✗ | +| Pipeline | View Pipeline | ✓ | ✓ | ✓ | +| | View running records | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | run | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| | Copy | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | cancel run | ✓ | ✓ | ✗ | +| Credentials | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Continuous Deployment | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | sync | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✓ | +| Code repository | View | ✓ | ✓ | ✗ | +| | import | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Grayscale release | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | Post | ✓ | ✓ | ✗ | +| | Continue posting | ✓ | ✓ | ✗ | +| | End of publication | ✓ | ✓ | ✗ | +| | Update | ✓ | ✓ | ✗ | +| | rollback | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | + +!!! note + + For a complete introduction to role and access management, please refer to [Role and Access Management](../user-guide/access-control/role.md). \ No newline at end of file diff --git a/docs/en/docs/ghippo/permissions/baize.md b/docs/en/docs/ghippo/permissions/baize.md new file mode 100644 index 0000000..8074cf8 --- /dev/null +++ b/docs/en/docs/ghippo/permissions/baize.md @@ -0,0 +1,67 @@ +--- +MTPE: windsonsea +Date: 2024-07-24 +hide: + - toc +--- + +# AI Lab Permissions + +[AI Lab](../../baize/intro/index.md) supports four user roles: + +- Admin / Baize Owner: Has full permissions (create, read, update, delete) for all features in the `Developer` and `Operator`. +- Workspace Admin: Has full permissions (create, read, update, delete) for all features in the authorized workspace's `Developer`. +- Workspace Editor: Has update and read permissions for all features in the authorized workspace's `Developer`. +- Workspace Viewer: Has read permissions for all features in the authorized workspace's `Developer`. + +Each role has different permissions, as detailed below. + + + +| Menu Object | Operation | Admin / Baize Owner | Workspace Admin | Workspace Editor | Workspace Viewer | +|---------------|-------------|-----------------------|-------------------|--------------------|--------------------| +| **Developer** | | | | | | +| Overview | View Overview | ✓ | ✓ | ✓ | ✓ | +| Notebooks | View Notebooks | ✓ | ✓ | ✓ | ✓ | +| | View Notebooks Details | ✓ | ✓ | ✓ | ✗ | +| | Create Notebooks | ✓ | ✓ | ✗ | ✗ | +| | Update Notebooks | ✓ | ✓ | ✓ | ✗ | +| | Clone Notebooks | ✓ | ✓ | ✗ | ✗ | +| | Stop Notebooks | ✓ | ✓ | ✓ | ✗ | +| | Start Notebooks | ✓ | ✓ | ✓ | ✗ | +| | Delete Notebooks | ✓ | ✓ | ✗ | ✗ | +| Jobs | View Jobs | ✓ | ✓ | ✓ | ✓ | +| | View Job Details | ✓ | ✓ | ✓ | ✓ | +| | Create Job | ✓ | ✓ | ✗ | ✗ | +| | Clone Job | ✓ | ✓ | ✗ | ✗ | +| | View Job Load Details | ✓ | ✓ | ✓ | ✗ | +| | Delete Job | ✓ | ✓ | ✗ | ✗ | +| Job Analysis | View Job Analysis | ✓ | ✓ | ✓ | ✓ | +| | View Job Analysis Details | ✓ | ✓ | ✓ | ✓ | +| | Delete Job Analysis | ✓ | ✓ | ✗ | ✗ | +| Datasets | View Datasets | ✓ | ✓ | ✓ | ✗ | +| | Create Dataset | ✓ | ✓ | ✗ | ✗ | +| | Resync Dataset | ✓ | ✓ | ✓ | ✗ | +| | Update Credentials | ✓ | ✓ | ✓ | ✗ | +| | Delete Dataset | ✓ | ✓ | ✗ | ✗ | +| Runtime Env | View Runtime Env | ✓ | ✓ | ✓ | ✓ | +| | Create Runtime Env | ✓ | ✓ | ✗ | ✗ | +| | Update Runtime Env | ✓ | ✓ | ✓ | ✗ | +| | Delete Runtime Env | ✓ | ✓ | ✗ | ✗ | +| Inference Services | View Inference Services | ✓ | ✓ | ✓ | ✓ | +| | View Inference Services Details | ✓ | ✓ | ✓ | ✓ | +| | Create Inference Service | ✓ | ✓ | ✗ | ✗ | +| | Update Inference Service | ✓ | ✓ | ✓ | ✗ | +| | Stop Inference Service | ✓ | ✓ | ✓ | ✗ | +| | Start Inference Service | ✓ | ✓ | ✓ | ✗ | +| | Delete Inference Service | ✓ | ✓ | ✗ | ✗ | +| **Operator** | | | | | | +| Overview | View Overview | ✓ | ✗ | ✗ | ✗ | +| GPU Management | View GPU Management | ✓ | ✗ | ✗ | ✗ | +| Queue Management | View Queue Management | ✓ | ✗ | ✗ | ✗ | +| | View Queue Details | ✓ | ✗ | ✗ | ✗ | +| | Create Queue | ✓ | ✗ | ✗ | ✗ | +| | Update Queue | ✓ | ✗ | ✗ | ✗ | +| | Delete Queue | ✓ | ✗ | ✗ | ✗ | diff --git a/docs/en/docs/ghippo/permissions/kpanda.md b/docs/en/docs/ghippo/permissions/kpanda.md new file mode 100644 index 0000000..37ad70a --- /dev/null +++ b/docs/en/docs/ghippo/permissions/kpanda.md @@ -0,0 +1,366 @@ +--- +hide: + - toc +--- + +# Container Management Permissions + +The container management module uses the following roles: + +- Admin / Kpanda Owner +- [Cluster Admin](../../kpanda/user-guide/permissions/permission-brief.md#cluster-admin) +- [NS Admin](../../kpanda/user-guide/permissions/permission-brief.md#ns-admin) +- [NS Editor](../../kpanda/user-guide/permissions/permission-brief.md#ns-editor) +- [NS Viewer](../../kpanda/user-guide/permissions/permission-brief.md#ns-viewer) + +!!! note + + - For more information about permissions, please refer to the [Container Management Permission System Description](../../kpanda/user-guide/permissions/permission-brief.md). + - For creating, managing, and deleting roles, please refer to [Role and Permission Management](../user-guide/access-control/role.md). + - The permissions of __Cluster Admin__ , __NS Admin__ , __NS Editor__ , __NS Viewer__ only take effect within the current cluster or namespace. + +The permissions granted to each role are as follows: + + + +| Primary Function | Secondary Function | Permission | Cluster Admin | Ns Admin | Ns Editor | NS Viewer | +| ------------ | -------------------- | ------------ | ------------- | -------- | --------- | --------- | +| Cluster | Cluster List | View Cluster List | ✔ | ✔ | ✔ | ✔ | +| | | Access Cluster | ✘ | ✘ | ✘ | ✘ | +| | | Create Cluster | ✘ | ✘ | ✘ | ✘ | +| | Cluster Operations | Enter Console | ✔ | ✔ (only in the list) | ✔ | ✘ | +| | | View Monitoring | ✔ | ✘ | ✘ | ✘ | +| | | Edit Basic Configuration | ✔ | ✘ | ✘ | ✘ | +| | | Download kubeconfig | ✔ | ✔ (with ns permission) | ✔ (with ns permission) | ✔ (with ns permission) | +| | | Disconnect Cluster | ✘ | ✘ | ✘ | ✘ | +| | | View Logs | ✔ | ✘ | ✘ | ✘ | +| | | Retry | ✘ | ✘ | ✘ | ✘ | +| | | Uninstall Cluster | ✘ | ✘ | ✘ | ✘ | +| | Cluster Overview | View Cluster Overview | ✔ | ✘ | ✘ | ✘ | +| | Node Management | Access Node | ✘ | ✘ | ✘ | ✘ | +| | | View Node List | ✔ | ✘ | ✘ | ✘ | +| | | View Node Details | ✔ | ✘ | ✘ | ✘ | +| | | View YAML | ✔ | ✘ | ✘ | ✘ | +| | | Pause Scheduling | ✔ | ✘ | ✘ | ✘ | +| | | Modify Labels | ✔ | ✘ | ✘ | ✘ | +| | | Modify Annotations | ✔ | ✘ | ✘ | ✘ | +| | | Modify Taints | ✔ | ✘ | ✘ | ✘ | +| | | Remove Node | ✘ | ✘ | ✘ | ✘ | +| | Deployment | View List | ✔ | ✔ | ✔ | ✔ | +| | | View/Manage Details | ✔ | ✔ | ✔ | ✔ (view only) | +| | | Create by YAML | ✔ | ✔ | ✔ | ✘ | +| | | Create by image | ✔ | ✔ | ✔ | ✘ | +| Select an instance in ws bound to ns | Select image | ✔ | ✔ | ✔ | ✘ | +| | | View IP Pool | ✔ | ✔ | ✔ | ✘ | +| | | Edit Network Interface | ✔ | ✔ | ✔ | ✘ | +| | | Enter Console | ✔ | ✔ | ✔ | ✘ | +| | | View Monitoring | ✔ | ✔ | ✔ | ✔ | +| | | View Logs | ✔ | ✔ | ✔ | ✔ | +| | | Load Balancer Scaling | ✔ | ✔ | ✔ | ✘ | +| | | Edit YAML | ✔ | ✔ | ✔ | ✘ | +| | | Update | ✔ | ✔ | ✔ | ✘ | +| | | Status - Pause Upgrade | ✔ | ✔ | ✔ | ✘ | +| | | Status - Stop | ✔ | ✔ | ✔ | ✘ | +| | | Status - Restart | ✔ | ✔ | ✔ | ✘ | +| | | Delete | ✔ | ✔ | ✔ | ✘ | +| | StatefulSet | View List | ✔ | ✔ | ✔ | ✔ | +| | | View/Manage Details | ✔ | ✔ | ✔ | ✔ (view only) | +| | | Create by YAML | ✔ | ✔ | ✔ | ✘ | +| | | Create by image | ✔ | ✔ | ✔ | ✘ | +| | Select an instance in ws bound to ns | Select image | ✔ | ✔ | ✔ | ✘ | +| | | Enter Console | ✔ | ✔ | ✔ | ✘ | +| | | View Monitoring | ✔ | ✔ | ✔ | ✔ | +| | | View Logs | ✔ | ✔ | ✔ | ✔ | +| | | Load Balancer Scaling | ✔ | ✔ | ✔ | ✘ | +| | | Edit YAML | ✔ | ✔ | ✔ | ✘ | +| | | Update | ✔ | ✔ | ✔ | ✘ | +| | | Status - Stop | ✔ | ✔ | ✔ | ✘ | +| | | Status - Restart | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | 守护进程 | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create by image | ✓ | ✓ | ✓ | ✗ | +| | Select an instance in ws bound to ns | Select image | ✓ | ✓ | ✓ | ✗ | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | Status - restart | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Job | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create by image | ✓ | ✓ | ✓ | ✗ | +| | | Instance list | ✓ | ✓ | ✓ | ✓ | +| | Select an instance in ws bound to ns | Select image | ✓ | ✓ | ✓ | ✗ | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | View YAML | ✓ | ✓ | ✓ | ✓ | +| | | Restart | ✓ | ✓ | ✓ | ✗ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | CronJob | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create by image | ✓ | ✓ | ✓ | ✗ | +| | Select an instance in ws bound to ns | Select image | ✓ | ✓ | ✓ | ✗ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Stop | ✓ | ✓ | ✓ | ✗ | +| | | View jobs | ✓ | ✓ | ✓ | ✓ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Pod | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | View YAML | ✓ | ✓ | ✓ | ✓ | +| | | Upload file | ✓ | ✓ | ✓ | ✗ | +| | | Download file | ✓ | ✓ | ✓ | ✗ | +| | | View containers | ✓ | ✓ | ✓ | ✓ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | ReplicaSet | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | View YAML | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Helm app | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | View YAML | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Helm chart | View list | ✓ | ✓ | ✓ | ✓ | +| | | View details | ✓ | ✓ | ✓ | ✓ | +| | | Install chart | ✓ | ✓ (Fine for ns level) | ✗ | ✗ | +| | | Download chart | ✓ | ✓ | ✓ (Consistent with viewing interface) | ✓ | +| | Helm repo | View list | ✓ | ✓ | ✓ | ✓ | +| | | Create repo | ✓ | ✗ | ✗ | ✗ | +| | | Update repo | ✓ | ✗ | ✗ | ✗ | +| | | Clone repo | ✓ | ✗ | ✗ | ✗ | +| | | Refresh repo | ✓ | ✗ | ✗ | ✗ | +| | | Modify label | ✓ | ✗ | ✗ | ✗ | +| | | Modify annotation | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | Service | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Ingress | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Network policy | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✗ | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Network config | Config | ✓ | ✓ | ✓ | ✗ | +| | CRD | View list | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✗ | ✗ | ✗ | +| | | Create by YAML | ✓ | ✗ | ✗ | ✗ | +| | | Edit YAML | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | PVC | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create | ✓ | ✓ | ✓ | ✗ | +| | | Select sc | ✓ | ✓ | ✓ | ✗ | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Clone | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | PV | View list | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✗ | ✗ | ✗ | +| | | Create by YAML | ✓ | ✗ | ✗ | ✗ | +| | | Create | ✓ | ✗ | ✗ | ✗ | +| | | Edit YAML | ✓ | ✗ | ✗ | ✗ | +| | | Update | ✓ | ✗ | ✗ | ✗ | +| | | Clone | ✓ | ✗ | ✗ | ✗ | +| | | Modify label | ✓ | ✗ | ✗ | ✗ | +| | | Modify annotation | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | SC | View list | ✓ | ✗ | ✗ | ✗ | +| | | Create by YAML | ✓ | ✗ | ✗ | ✗ | +| | | Create | ✓ | ✗ | ✗ | ✗ | +| | | View YAML | ✓ | ✗ | ✗ | ✗ | +| | | Update | ✓ | ✗ | ✗ | ✗ | +| | | Authorize NS | ✓ | ✗ | ✗ | ✗ | +| | | Deauthorize | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | ConfigMap | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create | ✓ | ✓ | ✓ | ✗ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | Export ConfigMap | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Secret | View list | ✓ | ✓ | ✓ | ✗ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✗ | +| | | Create by YAML | ✓ | ✓ | ✓ | ✗ | +| | | Create | ✓ | ✓ | ✓ | ✗ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | Export secret | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Namespace | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Create by YAML | ✓ | ✗ | ✗ | ✗ | +| | | Create | ✓ | ✗ | ✗ | ✗ | +| | | View YAML | ✓ | ✓ | ✓ | ✗ | +| | | Modify label | ✓ | ✓ | ✗ | ✗ | +| | | Unbind WS | ✗ | ✗ | ✗ | ✗ | +| | | Bind WS | ✗ | ✗ | ✗ | ✗ | +| | | Quotas | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | Cluster operation | View list | ✓ | ✗ | ✗ | ✗ | +| | | View YAML | ✓ | ✗ | ✗ | ✗ | +| | | View logs | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | Helm operation | Set preserved entries | ✓ | ✗ | ✗ | ✗ | +| | | View YAML | ✓ | ✓ | ✗ | ✗ | +| | | View logs | ✓ | ✓ | ✗ | ✗ | +| | | Delete | ✓ | ✓ | ✗ | ✗ | +| | Cluster upgrade | View details | ✓ | ✗ | ✗ | ✗ | +| | | Upgrade | ✗ | ✗ | ✗ | ✗ | +| | Cluster settings | Addon config | ✓ | ✗ | ✗ | ✗ | +| | | Advanced config | ✓ | ✗ | ✗ | ✗ | +| Namespace | | View list | ✓ | ✓ | ✓ | ✓ | +| | | Create | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ | +| | | View YAML | ✓ | ✓ | ✓ | ✗ | +| | | Modify label | ✓ | ✓ | ✗ | ✗ | +| | | Bind WS | ✓ | ✗ | ✗ | ✗ | +| | | Quotas | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| Workload | Deployment | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | Workload scaling | ✓ | ✓ | ✓ | ✗ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | Status - Pause Upgrade | ✓ | ✓ | ✓ | ✗ | +| | | Status - Stop | ✓ | ✓ | ✓ | ✗ | +| | | Status - restart | ✓ | ✓ | ✓ | ✗ | +| | | Revert | ✓ | ✓ | ✓ | ✗ | +| | | Modify label and annotation | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | StatefulSet | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | Workload scaling | ✓ | ✓ | ✓ | ✗ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | Status - Stop | ✓ | ✓ | ✓ | ✗ | +| | | Status - restart | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | DaemonSet | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | Edit YAML | ✓ | ✓ | ✓ | ✗ | +| | | Update | ✓ | ✓ | ✓ | ✗ | +| | | Status - restart | ✓ | ✓ | ✓ | ✗ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Job | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | View YAML | ✓ | ✓ | ✓ | ✗ | +| | | Restart | ✓ | ✓ | ✓ | ✗ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | CronJob | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| | Pod | View list | ✓ | ✓ | ✓ | ✓ | +| | | View/Manage details | ✓ | ✓ | ✓ | ✓ (Only view) | +| | | Go to console | ✓ | ✓ | ✓ | ✗ | +| | | Check monitor | ✓ | ✓ | ✓ | ✓ | +| | | View logs | ✓ | ✓ | ✓ | ✓ | +| | | View YAML | ✓ | ✓ | ✓ | ✓ | +| | | Upload file | ✓ | ✓ | ✓ | ✗ | +| | | Download file | ✓ | ✓ | ✓ | ✗ | +| | | View containers | ✓ | ✓ | ✓ | ✓ | +| | | View event | ✓ | ✓ | ✓ | ✓ | +| | | Delete | ✓ | ✓ | ✓ | ✗ | +| Backup and Restore | App backup | View list | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✗ | ✗ | ✗ | +| | | Create backup schedule | ✓ | ✗ | ✗ | ✗ | +| | | View YAML | ✓ | ✗ | ✗ | ✗ | +| | | Update Schedule | ✓ | ✗ | ✗ | ✗ | +| | | Pause | ✓ | ✗ | ✗ | ✗ | +| | | Run now | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | Resume backup | View list | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✗ | ✗ | ✗ | +| | | Resume backup | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | Backup point | View list | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | Object storage | View list | ✓ | ✗ | ✗ | ✗ | +| | etcd backup | View backup policies | ✓ | ✗ | ✗ | ✗ | +| | | Create backup policies | ✓ | ✗ | ✗ | ✗ | +| | | View logs | ✓ | ✗ | ✗ | ✗ | +| | | View YAML | ✓ | ✗ | ✗ | ✗ | +| | | Update backup policy | ✓ | ✗ | ✗ | ✗ | +| | | Stop/Start | ✓ | ✗ | ✗ | ✗ | +| | | Run now | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✗ | ✗ | ✗ | +| | | Delete backup records | ✓ | ✗ | ✗ | ✗ | +| | | View backup points | ✓ | ✗ | ✗ | ✗ | +| Cluster inspection | Cluster inspection | View list | ✓ | ✗ | ✗ | ✗ | +| | | View/Manage details | ✓ | ✗ | ✗ | ✗ | +| | | Cluster inspection | ✓ | ✗ | ✗ | ✗ | +| | | Settings | ✓ | ✗ | ✗ | ✗ | +| Permissions | Permissions | View list | ✓ | ✗ | ✗ | ✗ | +| | | Grant to cluster admin | ✓ | ✗ | ✗ | ✗ | +| | | Delete | ✓ | ✗ | ✗ | ✗ | +| | NS permissions | View list | ✓ | ✓ | ✗ | ✗ | +| | | Grant to ns admin | ✓ | ✓ | ✗ | ✗ | +| | | Grant to ns editor | ✓ | ✓ | ✗ | ✗ | +| | | Grant to ns viewer | ✓ | ✓ | ✗ | ✗ | +| | | Edit permissions | ✓ | ✓ | ✗ | ✗ | +| | | Delete | ✓ | ✓ | ✗ | ✗ | +| Security | Compliance scanning | View scanning report | ✓ | ✗ | ✗ | ✗ | +| | | View scanning report details | ✓ | ✗ | ✗ | ✗ | +| | | Download scanning report | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning report | ✓ | ✗ | ✗ | ✗ | +| | | View scanning policies | ✓ | ✗ | ✗ | ✗ | +| | | Create scanning policy | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning policy | ✓ | ✗ | ✗ | ✗ | +| | | View scanning config list | ✓ | ✗ | ✗ | ✗ | +| | | View scanning config details | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning config | ✓ | ✗ | ✗ | ✗ | +| | Scan permission | View scanning reports | ✓ | ✗ | ✗ | ✗ | +| | | View scanning report details | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning report | ✓ | ✗ | ✗ | ✗ | +| | | View scanning policies | ✓ | ✗ | ✗ | ✗ | +| | | Create scanning policy | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning policy | ✓ | ✗ | ✗ | ✗ | +| | Scan vulnerability | View scanning reports | ✓ | ✗ | ✗ | ✗ | +| | | View scanning report detail | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning report | ✓ | ✗ | ✗ | ✗ | +| | | View scanning policies | ✓ | ✗ | ✗ | ✗ | +| | | Create scanning policy | ✓ | ✗ | ✗ | ✗ | +| | | Delete scanning policy | ✓ | ✗ | ✗ | ✗ | diff --git a/docs/en/docs/ghippo/permissions/mcamel.md b/docs/en/docs/ghippo/permissions/mcamel.md new file mode 100644 index 0000000..4f97398 --- /dev/null +++ b/docs/en/docs/ghippo/permissions/mcamel.md @@ -0,0 +1,88 @@ +# Middleware Permissions + +[Middleware](../../middleware/index.md) includes selected middleware: +MySQL, Redis, MongoDB, PostgreSQL, Elasticsearch, Kafka, RabbitMQ, RocketMQ, MinIO. +Middleware supports three user roles: + +- Workspace Admin +- Workspace Editor +- Workspace Viewer + +Each role has different permissions, which are described below. + + + +## Middleware Permissions + +| Middleware Modules | Menu Objects | Actions | Workspace Admin | Workspace Editor | Workspace Viewer | +| ------- | ----------------- | ------- | --------------- | ---------------- | --------------- | +| MySQL | MySQL Instance List | View List | ✓ | ✓ | ✓ | +| | | instance name search | ✓ | ✓ | ✓ | +| | | Create instance | ✓ | ✓ | ✗ | +| | | Update Instance Configuration | ✓ | ✓ | ✗ | +| | | delete instance | ✓ | ✗ | ✗ | +| | MySQL Instance Details | Instance Overview | ✓ | ✓ | ✓ | +| | | Instance Monitoring | ✓ | ✓ | ✓ | +| | | View Instance Configuration Parameters | ✓ | ✓ | ✓ | +| | | Modify instance configuration parameters | ✓ | ✓ | ✗ | +| | | View Instance Access Password | ✓ | ✓ | ✗ | +| | | View instance backup list | ✓ | ✓ | ✓ | +| | | instance creation backup | ✓ | ✓ | ✗ | +| | | Instance modification automatic backup task | ✓ | ✓ | ✗ | +| | | Create new instance with backup | ✓ | ✓ | ✗ | +| | Backup configuration management | Backup configuration list | ✓ | ✗ | ✗ | +| | | Create Backup Configuration | ✓ | ✗ | ✗ | +| | | Modify backup configuration | ✓ | ✗ | ✗ | +| | | delete backup configuration | ✓ | ✗ | ✗ | +| RabbitMQ | RabbitMQ Instance List | View List | ✓ | ✓ | ✓ | +| | | instance name search | ✓ | ✓ | ✓ | +| | | Create instance | ✓ | ✓ | ✗ | +| | | Update Instance Configuration | ✓ | ✓ | ✗ | +| | | delete instance | ✓ | ✗ | ✗ | +| | RabbitMQ Instance Details | Instance Overview | ✓ | ✓ | ✓ | +| | | Instance Monitoring | ✓ | ✓ | ✓ | +| | | View Instance Configuration Parameters | ✓ | ✓ | ✓ | +| | | Modify instance configuration parameters | ✓ | ✓ | ✗ | +| | | View Instance Access Password | ✓ | ✓ | ✗ | +| Elasticsearch | Elasticsearch Instance List | View List | ✓ | ✓ | ✓ | +| | | instance name search | ✓ | ✓ | ✓ | +| | | Create instance | ✓ | ✓ | ✗ | +| | | Update Instance Configuration | ✓ | ✓ | ✗ | +| | | delete instance | ✓ | ✗ | ✗ | +| | Elasticsearch Instance Details | Instance Overview | ✓ | ✓ | ✓ | +| | | Instance Monitoring | ✓ | ✓ | ✓ | +| | | View Instance Configuration Parameters | ✓ | ✓ | ✓ | +| | | Modify instance configuration parameters | ✓ | ✓ | ✗ | +| | | View Instance Access Password | ✓ | ✓ | ✗ | +| Redis | Redis Instance List | View List | ✓ | ✓ | ✓ | +| | | instance name search | ✓ | ✓ | ✓ | +| | | Create instance | ✓ | ✓ | ✗ | +| | | Update Instance Configuration | ✓ | ✓ | ✗ | +| | | delete instance | ✓ | ✗ | ✗ | +| | Redis Instance Details | Instance Overview | ✓ | ✓ | ✓ | +| | | Instance Monitoring | ✓ | ✓ | ✓ | +| | | View Instance Configuration Parameters | ✓ | ✓ | ✓ | +| | | Modify instance configuration parameters | ✓ | ✓ | ✗ | +| | | View Instance Access Password | ✓ | ✓ | ✗ | +| Kafka | Kafka instance list | View list | ✓ | ✓ | ✓ | +| | | instance name search | ✓ | ✓ | ✓ | +| | | Create instance | ✓ | ✓ | ✗ | +| | | Update Instance Configuration | ✓ | ✓ | ✗ | +| | | delete instance | ✓ | ✗ | ✗ | +| | Kafka Instance Details | Instance Overview | ✓ | ✓ | ✓ | +| | | Instance Monitoring | ✓ | ✓ | ✓ | +| | | View Instance Configuration Parameters | ✓ | ✓ | ✓ | +| | | Modify instance configuration parameters | ✓ | ✓ | ✗ | +| | | View Instance Access Password | ✓ | ✓ | ✗ | +| MinIO | MinIO Instance List | View List | ✓ | ✓ | ✓ | +| | | instance name search | ✓ | ✓ | ✓ | +| | | Create instance | ✓ | ✓ | ✗ | +| | | Update Instance Configuration | ✓ | ✓ | ✗ | +| | | delete instance | ✓ | ✗ | ✗ | +| | MinIO Instance Details | Instance Overview | ✓ | ✓ | ✓ | +| | | Instance Monitoring | ✓ | ✓ | ✓ | +| | | View Instance Configuration Parameters | ✓ | ✓ | ✓ | +| | | Modify instance configuration parameters | ✓ | ✓ | ✗ | +| | | View Instance Access Password | ✓ | ✓ | ✗ | \ No newline at end of file diff --git a/docs/en/docs/ghippo/permissions/mspider.md b/docs/en/docs/ghippo/permissions/mspider.md new file mode 100644 index 0000000..7dc6c8a --- /dev/null +++ b/docs/en/docs/ghippo/permissions/mspider.md @@ -0,0 +1,96 @@ +--- +hide: + - toc +--- + +# Service Mesh Permissions + +[Service Mesh](../../mspider/intro/index.md) supports several user roles: + +- Admin +- Workspace Admin +- Workspace Editor +- Workspace Viewer + + + +The specific permissions for each role are shown in the following table. + +| Menu Object | Action | Admin | Workspace Admin | Workspace Editor | Workspace Viewer | +| ----------- | ------ | ----- | --------------- | ---------------- | ---------------- | +| Service Mesh List | [Create Mesh](../../mspider/user-guide/service-mesh/README.md) | ✓ | ✗ | ✗ | ✗ | +| | Edit Mesh | ✓ | ✓ | ✗ | ✗ | +| | [Delete Mesh](../../mspider/user-guide/service-mesh/delete.md) | ✓ | ✗ | ✗ | ✗ | +| | [View Mesh](../../mspider/user-guide/service-mesh/README.md) | ✓ | ✓ | ✓ | ✓ | +| Mesh Overview | View | ✓ | ✓ | ✓ | ✓ | +| Service List | View | ✓ | ✓ | ✓ | ✓ | +| | Create VM | ✓ | ✓ | ✓ | ✗ | +| | Delete VM | ✓ | ✓ | ✓ | ✗ | +| Service Entry | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Virtual Service | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Destination Rule | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Gateway Rule | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Peer Authentication | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Request Authentication | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Authorization Policy | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Namespace Sidecar Management | Enable Injection | ✓ | ✓ | ✓ | ✗ | +| | Disable Injection | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| | Sidecar Service Discovery Scope | ✓ | ✓ | ✓ | ✗ | +| Workload Sidecar Management | Enable Injection | ✓ | ✓ | ✓ | ✗ | +| | Disable Injection | ✓ | ✓ | ✓ | ✗ | +| | Configure Sidecar Resources | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Global Sidecar Injection | Enable Injection | ✓ | ✓ | ✗ | ✗ | +| | Disable Injection | ✓ | ✓ | ✗ | ✗ | +| | Configure Sidecar Resources | ✓ | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Cluster Management (for Hosted Mesh only) | Join Cluster | ✓ | ✓ | ✗ | ✗ | +| | Leave Cluster | ✓ | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Mesh Gateway Management | Create | ✓ | ✓ | ✗ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Istio Resource Management | Create | ✓ | ✓ | ✗ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| TLS Certificate Management | Create | ✓ | ✓ | ✓ | ✗ | +| | Edit | ✓ | ✓ | ✓ | ✗ | +| | Delete | ✓ | ✓ | ✓ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Multicloud Network Interconnection | Enable | ✓ | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✗ | ✗ | +| | Edit | ✓ | ✓ | ✗ | ✗ | +| | Delete | ✓ | ✓ | ✗ | ✗ | +| | Disable | ✓ | ✓ | ✗ | ✗ | +| System Upgrade | Istio Upgrade | ✓ | ✓ | ✗ | ✗ | +| | Sidecar Upgrade | ✓ | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | ✓ | +| Workspace Management | Bind | ✓ | ✗ | ✗ | ✗ | +| | Unbind | ✓ | ✗ | ✗ | ✗ | +| | View | ✓ | ✗ | ✗ | ✗ | diff --git a/docs/en/docs/ghippo/permissions/skoala.md b/docs/en/docs/ghippo/permissions/skoala.md new file mode 100644 index 0000000..5ab1b97 --- /dev/null +++ b/docs/en/docs/ghippo/permissions/skoala.md @@ -0,0 +1,125 @@ +# Microservice Engine Permissions + +[Microservice engine](../../skoala/intro/index.md) includes two parts: microservice management center and microservice gateway. The microservice engine supports three user roles: + +- Workspace Admin +- Workspace Editor +- Workspace Viewer + +Each role has different permissions, which are described below. + + + +## Microservice Governance Permissions + +| Menu Objects | Actions | Workspace Admin | Workspace Editor | Workspace Viewer | +| ------------ | ------- | --------------- | ---------------- | ---------------- | +| Hosted Registry List | View List | ✓ | ✓ | ✓ | +| Hosted Registry | View Basic Information | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | restart | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✗ | ✗ | +| | On/Off | ✓ | ✓ | ✗ | +| Microservice Namespace | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Microservice List | View | ✓ | ✓ | ✓ | +| | filter namespace | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | Governance | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Service Governance Rules-Sentinel | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Service Governance Rules-Mesh | Governance | ✓ | ✓ | ✗ | +| Instance List | View | ✓ | ✓ | ✓ | +| | On/Off | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| Service Governance Policy-Sentinel | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Service Governance Policy-Mesh | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | Create with YAML | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | YAML Editing | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Microservice Configuration List | View | ✓ | ✓ | ✓ | +| | filter namespace | ✓ | ✓ | ✓ | +| | Batch delete | ✓ | ✓ | ✗ | +| | Export/Import | ✓ | ✓ | ✗ | +| | Create | ✓ | ✓ | ✗ | +| | Clone | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | History query | ✓ | ✓ | ✓ | +| | rollback | ✓ | ✓ | ✗ | +| | listen query | ✓ | ✓ | ✓ | +| Business Monitor | View | ✓ | ✓ | ✓ | +| Resource Monitor | View | ✓ | ✓ | ✓ | +| Request Log | View | ✓ | ✓ | ✓ | +| Instance Log | View | ✓ | ✓ | ✓ | +| Plugin Center | View | ✓ | ✓ | ✓ | +| | Open | ✓ | ✓ | ✗ | +| | Close | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | View Details | ✓ | ✓ | ✓ | +| access registry list | view | ✓ | ✓ | ✓ | +| | Access | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | Remove | ✓ | ✗ | ✗ | +| Microservices | View List | ✓ | ✓ | ✓ | +| | View Details | ✓ | ✓ | ✓ | +| | Governance | ✓ | ✓ | ✗ | +| Service Governance Policy-Mesh | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | Create with YAML | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | YAML Editing | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | + +## Microservice Gateway Permissions + +| Objects | Actions | Workspace Admin | Workspace Editor | Workspace Viewer | +| ------- | ---- | --------------- | ---------------- | ---------------- | +| Gateway List | View | ✓ | ✓ | ✓ | +| Gateway instance | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✗ | ✗ | +| Diagnostic Mode | View | ✓ | ✓ | ✓ | +| | debug | ✓ | ✓ | ✗ | +| Service List | View | ✓ | ✓ | ✓ | +| | Add | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Service Details | View | ✓ | ✓ | ✓ | +| Service Source Management | View | ✓ | ✓ | ✓ | +| | Add | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| API List | View | ✓ | ✓ | ✓ | +| | Create | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✗ | +| Request Log | View | ✓ | ✓ | ✓ | +| Instance Log | View | ✓ | ✓ | ✓ | +| Plugin Center | View | ✓ | ✓ | ✓ | +| | enable | ✓ | ✓ | ✗ | +| | disabled | ✓ | ✓ | ✗ | +| Plugin Configuration | View | ✓ | ✓ | ✓ | +| | enable | ✓ | ✓ | ✗ | +| Domain List | View | ✓ | ✓ | ✓ | +| | Add | ✓ | ✓ | ✗ | +| | edit | ✓ | ✓ | ✗ | +| | delete | ✓ | ✓ | ✓ | +| Monitor Alert | View | ✓ | ✓ | ✓ | + +!!! note + + For a complete introduction to role and access management, please refer to [Role and Access Management](../user-guide/access-control/role.md). \ No newline at end of file diff --git a/docs/en/docs/ghippo/user-guide/access-control/custom-role.md b/docs/en/docs/ghippo/user-guide/access-control/custom-role.md new file mode 100644 index 0000000..43e90e9 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/custom-role.md @@ -0,0 +1,61 @@ +# Custom Roles + +AI platform supports the creation of three scopes of custom roles: + +- The permissions of **Platform Role** take effect on all relevant resources of the platform +- The permissions of **workspace role** take effect on the resources under the workspace where the user is located +- The permissions of **folder role** take effect on the folder where the user is located and the subfolders and workspace resources under it + +## Create a platform role + +A platform role refers to a role that can manipulate features related to a certain module of AI platform (such as container management, microservice engine, Multicloud Management, service mesh, Container registry, Workbench, and global management). + +1. From the left navigation bar, click __Global Management__ -> __Access Control__ -> __Roles__ , and click __Create Custom Role__ . + + ![button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom01.png) + +1. Enter the name and description, select __Platform Role__ , check the role permissions and click __OK__ . + + ![fill](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom02.png) + +1. Return to the role list, search for the custom role you just created, and click __┇__ on the right to perform operations such as copying, editing, and deleting. + + ![other](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom03.png) + +1. After the platform role is successfully created, you can go to [User](user.md)/[group](group.md) to add users and groups for this role. + +## Create a workspace role + +A workspace role refers to a role that can manipulate features related to a module (such as container management, microservice engine, Multicloud Management, service mesh, container registry, Workbench, and global management) according to the workspace. + +1. From the left navigation bar, click __Global Management__ -> __Access Control__ -> __Roles__ , and click __Create Custom Role__ . + + ![button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom01.png) + +1. Enter the name and description, select __Workspace role__ , check the role permissions and click __OK__ . + + ![workspace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom04.png) + +1. Return to the role list, search for the custom role you just created, and click __┇__ on the right to perform operations such as copying, editing, and deleting. + + ![other](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom05.png) + +1. After the workspace role is successfully created, you can go to [Workspace](../workspace/workspace.md) to authorize and set which workspaces this role can manage. + +## Create Folder Role + +The folder role refers to the ability to manipulate the relevant features of a module of AI platform (such as container management, microservice engine, Multicloud Management, service mesh, container registry, Workbench and global management) according to folders and subfolders. Role. + +1. From the left navigation bar, click __Global Management__ -> __Access Control__ -> __Roles__ , and click __Create Custom Role__ . + + ![button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom01.png) + +1. Enter the name and description, select __Folder Role__ , check the role permissions and click __OK__ . + + ![folder](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom06.png) + +1. Return to the role list, search for the custom role you just created, and click __┇__ on the right to perform operations such as copying, editing, and deleting. + + ![other](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/custom07.png) + +1. After the folder role is successfully created, you can go to [Folder](../workspace/folders.md) to authorize and set which folders this role can manage. diff --git a/docs/en/docs/ghippo/user-guide/access-control/docking.md b/docs/en/docs/ghippo/user-guide/access-control/docking.md new file mode 100644 index 0000000..15a6fd9 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/docking.md @@ -0,0 +1,28 @@ +# Docking Portal + +When two or more platforms need to integrate or embed with each other, +user system integration is usually required. During the process of user system integration, +the __Docking Portal__ mainly provides SSO (Single Sign-On) capability. +If you want to integrate AI platform as a user source into a client platform, +you can achieve it by docking a product through __Docking Portal__ . + +## Docking a product + +Prerequisite: Administrator privileges for the platform or IAM Owner privileges +for access control. + +1. Log in with an admin, navigate to __Access Control__ , select __Docking Portal__ , + enter the Docking Portal list, and click __Create SSO Profile__ in the upper right corner. + + ![Create SSO Profile button](../../images/sso1.png) + +2. On the __Create SSO Profile__ page, fill in the Client ID. + + ![Create SSO Profile](../../images/sso2.png) + +3. After successfully creating the SSO access, in the Docking Portal list, + click the just created Client ID to enter the details, + copy the Client ID, Secret Key, and Single Sign-On URL information, + and fill them in the client platform to complete the user system integration. + + ![Docking Portal Details](../../images/sso3.png) diff --git a/docs/en/docs/ghippo/user-guide/access-control/global.md b/docs/en/docs/ghippo/user-guide/access-control/global.md new file mode 100644 index 0000000..ff72d0a --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/global.md @@ -0,0 +1,45 @@ +# System Roles + +## Use cases + +AI platform provides predefined system roles to help users simplify the process of role permission usage. + +!!! note + + AI platform provides three types of system roles: platform role, workspace role, and folder role. + + - Platform role: has proper permissions for all related resources on the platform. Please go to user/group page for authorization. + - Workspace role: has proper permissions for a specific workspace. Please go to the specific workspace page for authorization. + - Folder role: has proper permissions for a specific folder, subfolder, and resources under its workspace. Please go to the specific folder page for authorization. + +## Platform Roles + +Five system roles are predefined in Access Control: Admin, IAM Owner, Audit Owner, Kpanda Owner, and Workspace and Folder Owner. These five roles are created by the system and cannot be modified by users. The proper permissions of each role are as follows: + +| Role Name | Role Type | Module | Role Permissions | +| --- | --- | --- | --- | +| Admin | System role | All | Platform administrator, manages all platform resources, represents the highest authority of the platform. | +| IAM Owner | System role | Access Control | Administrator of Access Control, has all permissions under this service, such as managing users/groups and authorization. | +| Audit Owner | System role | Audit Log | Administrator of Audit Log, has all permissions under this service, such as setting audit log policies and exporting audit logs. | +| Kpanda Owner | System role | Container Management | Administrator of Container Management, has all permissions under this service, such as creating/accessing clusters, deploying applications, granting cluster/namespace-related permissions to users/groups. | +| Workspace and Folder Owner | System role | Workspace and Folder | Administrator of Workspace and Folder, has all permissions under this service, such as creating folders/workspaces, authorizing folder/workspace-related permissions to users/groups, using features such as Workbench and microservice engine under the workspace. | + +## Workspace Roles + +Three system roles are predefined in Access Control: Workspace Admin, Workspace Editor, and Workspace Viewer. These three roles are created by the system and cannot be modified by users. The proper permissions of each role are as follows: + +| Role Name | Role Type | Module | Role Permissions | +| --- | --- | --- | --- | +| Workspace Admin | System role | Workspace | Administrator of a workspace, with management permission of the workspace. | +| Workspace Editor | System role | Workspace | Editor of a workspace, with editing permission of the workspace. | +| Workspace Viewer | System role | Workspace | Viewer of a workspace, with readonly permission of the workspace. | + +## Folder Roles + +Three system roles are predefined in Access Control: Folder Admin, Folder Editor, and Folder Viewer. These three roles are created by the system and cannot be modified by users. The proper permissions of each role are as follows: + +| Role Name | Role Type | Module | Role Permissions | +| --- | --- | --- | --- | +| Folder Admin | System role | Workspace | Administrator of a folder and its subfolders/workspaces, with management permission. | +| Folder Editor | System role | Workspace | Editor of a folder and its subfolders/workspaces, with editing permission. | +| Folder Viewer | System role | Workspace | Viewer of a folder and its subfolders/workspaces, with readonly permission. | diff --git a/docs/en/docs/ghippo/user-guide/access-control/group.md b/docs/en/docs/ghippo/user-guide/access-control/group.md new file mode 100644 index 0000000..4320063 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/group.md @@ -0,0 +1,75 @@ +# Group + +A group is a collection of users. By joining a group, a user can inherit the role permissions of the group. Authorize users in batches through groups to better manage users and their permissions. + +## Use cases + +When a user's permission changes, it only needs to be moved to the corresponding group without affecting other users. + +When the permissions of a group change, you only need to modify the role permissions of the group to apply to all users in the group. + +## Create group + +Prerequisite: Admin or IAM Owner. + +1. Enters __Access Control__ , selects __Groups__ , enters the list of groups, and clicks __Create a group__ on the upper right. + + ![group button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group00.png) + +2. Fill in the group information on the __Create group__ page. + + ![fill](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group01.png) + +3. Click __OK__ , the group is created successfully, and you will return to the group list page. The first line in the list is the newly created group. + +## Add permissions to a group + +Prerequisite: The group already exists. + +1. Enters __Access Control__ , selects __Groups__ , enters the list of groups, and clicks __┇__ -> __Add permissions__ . + + ![add permissions](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group02.png) + +2. On the __Add permissions__ page, check the required role permissions (multiple choices are allowed). + + ![button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group03.png) + +3. Click __OK__ to add permissions to the group. Automatically return to the group list, click a group to view the permissions granted to the group. + + ![view](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group04.png) + +## Add users to a group + +1. Enters __Access Control__ , selects __Groups__ to display the group list, and on the right side of a group, click __┇__ -> __Add Members__ . + + ![members](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group05.png) + +2. On the __Add Group Members__ page, click the user to be added (multiple choices are allowed). If there is no user available, click __Create a new user__ , first go to create a user, and then return to this page and click the refresh icon to display the newly created user. + + ![new user](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/group06.png) + +3. Click __OK__ to finish adding users to the group. + +!!! note + + Users in the group will inherit the permissions of the group; users who join the group can be viewed in the group details. + +## Delete group + +Note: Deleting a group will not delete the users in the group, but the users in the group will no longer be able to inherit the permissions of the group + +1. The administrator enters __Access Control__ , selects __group__ to enter the group list, and on the right side of a group, click __┇__ -> __Delete__ . + + ![delete](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/deletegroup01.png) + +2. Click __Delete__ to delete the group. + + ![confirm](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/deletegroup02.png) + +3. Return to the group list, and the screen will prompt that the deletion is successful. + + ![success](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/deletegroup03.png) + +!!! note + + Deleting a group will not delete the users in the group, but the users in the group will no longer be able to inherit the permissions from the group. diff --git a/docs/en/docs/ghippo/user-guide/access-control/iam.md b/docs/en/docs/ghippo/user-guide/access-control/iam.md new file mode 100644 index 0000000..63de633 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/iam.md @@ -0,0 +1,42 @@ +# What is IAM + +IAM (Identity and Access Management) is an important module of global management. You can create, manage and destroy users (groups) through the access control module, and use system roles and custom roles to control other users Access to the AI platform. + +## Benefits + +- Simple and smooth + + Structures and roles within an enterprise can be complex, with the management of projects, work groups, and mandates constantly changing. Access control uses a clear and tidy page to open up the authorization relationship between users, groups, and roles, and realize the authorization of users (groups) with the shortest link. + +- Appropriate role + + Access control pre-defines an administrator role for each sub-module, without user maintenance, you can directly authorize the predefined system roles of the platform to users to realize the modular management of the platform. For fine-grained permissions, please refer to [Permission Management](role.md). + +- Enterprise-grade access control + + When you want your company's employees to use the company's internal authentication system to log in to the AI platform without creating corresponding users on the AI platform, you can use the identity provider feature of access control to establish a trust relationship between your company and Suanova, Through joint authentication, employees can directly log in to the AI platform with the existing account of the enterprise, realizing single sign-on. + +## Usage Process + +Here is a typical process to perform access control. + +```mermaid +graph TD + login[Login] --> user[Create User] + user --> auth[Authorize User] + auth --> group[Create Group] + group --> role[Create Custom Role] + role --> id[Create Identity Provider] + + classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; + classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; + classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + class login,user,auth,group,role,id cluster; + +click login "https://docs.daocloud.io/en/ghippo/install/login.html" +click user "https://docs.daocloud.io/en/ghippo/user-guide/access-control/user.html" +click auth "https://docs.daocloud.io/en/ghippo/user-guide/access-control/role.html" +click group "https://docs.daocloud.io/en/ghippo/user-guide/access-control/group.html" +click role "https://docs.daocloud.io/en/ghippo/user-guide/access-control/custom-role.html" +click id "https://docs.daocloud.io/en/ghippo/user-guide/access-control/idprovider.html" +``` diff --git a/docs/en/docs/ghippo/user-guide/access-control/idprovider.md b/docs/en/docs/ghippo/user-guide/access-control/idprovider.md new file mode 100644 index 0000000..bd942d1 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/idprovider.md @@ -0,0 +1,35 @@ +# Identity provider + +Global management supports single sign-on based on LDPA and OIDC protocols. If your enterprise or organization has its own account system and you want to manage members in the organization to use AI platform resources, you can use the identity provider feature provided by global management. Instead of having to create username/passwords for every organization member in your AI platform. You can grant permissions to use AI platform resources to these external user identities. + +## Basic concept + +- Identity Provider (IdP for short) + + Responsible for collecting and storing user identity information, usernames, and passwords, and responsible for authenticating users when they log in. In the identity authentication process between an enterprise and AI platform, the identity provider refers to the identity provider of the enterprise itself. + +- Service Provider (SP) + + The service provider establishes a trust relationship with the identity provider IdP, and uses the user information provided by the IDP to provide users with specific services. In the process of enterprise authentication with AI platform, the service provider refers to AI platform. + +- LDAP + + LDAP refers to Lightweight Directory Access Protocol (Lightweight Directory Access Protocol), which is often used for single sign-on, that is, users can log in with one account password in multiple services. Global management supports LDAP for identity authentication, so the enterprise IdP that establishes identity authentication with AI platform through the LDAP protocol must support the LDAP protocol. For a detailed description of LDAP, please refer to: [Welcome to LDAP](ldap.md). + +- OIDC + + OIDC, short for OpenID Connect, is an identity authentication standard protocol based on the OAuth 2.0 protocol. Global management supports the OIDC protocol for identity authentication, so the enterprise IdP that establishes identity authentication with AI platform through the OIDC protocol must support the OIDC protocol. For a detailed description of OIDC, please refer to: [Welcome to OpenID Connect](https://openid.net/connect/). + +- OAuth 2.0 + + OAuth 2.0 is the abbreviation of Open Authorization 2.0. It is an open authorization protocol. The authorization framework supports third-party applications to obtain access permissions in their own name. + +## Features + +- Administrators do not need to recreate AI platform users + + Before using the identity provider for identity authentication, the administrator needs to create an account for the user in the enterprise management system and AI platform respectively; after using the identity provider for identity authentication, the enterprise administrator only needs to create an account for the user in the enterprise management system, Users can access both systems at the same time, reducing personnel management costs. + +- Users do not need to remember two sets of platform accounts + + Before using the identity provider for identity authentication, users need to log in with the accounts of the two systems to access the enterprise management system and AI platform; after using the identity provider for identity authentication, users can log in to the enterprise management system to access the two systems. diff --git a/docs/en/docs/ghippo/user-guide/access-control/ldap.md b/docs/en/docs/ghippo/user-guide/access-control/ldap.md new file mode 100644 index 0000000..ddba8fe --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/ldap.md @@ -0,0 +1,77 @@ +--- +hide: + - toc +--- + +# LDAP + +The full name of LDAP is Lightweight Directory Access Protocol, which is an open and neutral +industry-standard application protocol that provides access control and maintains directories +for distributed information through the IP protocol. + +If your enterprise or organization has its own account system, and your enterprise user management +system supports the LDAP protocol, you can use the identity provider feature based on the LDAP protocol +provided by the Global Management instead of creating usernames/passwords for each member in AI platform. +You can grant permissions to use AI platform resources to these external user identities. + +In Global Management, the operation steps are as follows: + +1. Log in to AI platform as a user with __admin__ role. Click __Global Management__ -> __Access Control__ + in the lower left corner of the left navigation bar. + + ![access control](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/ws01.png) + +1. Click __Identity Provider__ on the left nav bar, click __Create an Identity Provider__ button. + + ![id provider](../../images/ldap00.png) + +1. In the __LDAP__ tab, fill in the following fields and click __Save__ to establish a trust relationship + with the identity provider and a user mapping relationship. + + ![ldap](../../images/ldap01.png) + + | Field | Description | + | ----- | ----------- | + | Vendor | Supports LDAP (Lightweight Directory Access Protocol) and AD (Active Directory) | + | Identity Provider Name (UI display name) | Used to distinguish different identity providers | + | Connection URL | The address and port number of the LDAP service, e.g., ldap://10.6.165.2:30061 | + | Bind DN | The DN of the LDAP administrator, which Keycloak will use to access the LDAP server | cn=admin,dc=daocloud,dc=com | + | Bind credentials | The password of the LDAP administrator. This field can retrieve its value from a vault using the ${vault.ID} format. | + | Users DN | The full DN of the LDAP tree where your users are located. This DN is the parent of the LDAP users. For example, if the DN of a typical user is similar to “uid='john',ou=users,dc=example,dc=com”, it can be “ou=users,dc=example,dc=com”. | dc=daocloud,dc=io | + | User Object Classes | All values of the LDAP objectClass attribute for users in LDAP, separated by commas. For example: “inetOrgPerson,organizationalPerson”. New Keycloak users will be written to LDAP with all of these object classes, and existing LDAP user records will be found if they contain all of these object classes.| + | Enable StartTLS | Encrypts the connection between AI platform and LDAP when enabled | + | Default Permission | Users/groups have no permissions by default after synchronization | + | Full name mapping | Corresponding First name and Last Name | + | User Name Mapping | The unique username for the user | + | Mailbox Mapping | User email | + + **Advanced Config** + + | Field | Description | + | ----- | ----------- | + | Enable or not | Enabled by default. When disabled, this LDAP configuration will not take effect. | + | Periodic full sync | Disabled by default. When enabled, a sync period can be configured, such as syncing once every hour. | + | Edit mode | Read-only mode will not modify the source data in LDAP. Write mode will sync data back to LDAP after user information is edited on the platform. | + | Read timeout | Adjusting this value can effectively avoid interface timeouts when the amount of LDAP data is large. | + | User LDAP filter | An additional LDAP filter used to filter the search for users. Leave it empty if no additional filter is needed. Ensure it starts with “(” and ends with “)”. | + | Username LDAP attribute | The name of the LDAP attribute maps to the Keycloak username. For many LDAP server vendors, it can be “uid”. For Active Directory, it can be “sAMAccountName” or “cn”. This attribute should be filled in for all LDAP user records you want to import into Keycloak. | + | RDN LDAP attribute | The name of the LDAP attribute that serves as the RDN (top-level attribute) of the typical user DN. It is usually the same as the Username LDAP attribute, but this is not required. For example, for Active Directory, when the username attribute might be “sAMAccountName”, “cn” is often used as the RDN attribute. | + | UUID LDAP attribute | The name of the LDAP attribute used as the unique object identifier (UUID) for objects in LDAP. For many LDAP server vendors, it is “entryUUID”. However, some may differ. For example, for Active Directory, it should be “objectGUID”. If your LDAP server does not support the UUID concept, you can use any other attribute that should be unique among LDAP users in the tree, such as “uid” or “entryDN”. | + +1. On the __Sync Groups__ tab, fill in the following fields to configure the mapping relationship of + groups, and click __Save__ again. + + | Field | Description | Example | + | ----- | ----------- | ------- | + | base DN | location of the group in the LDAP tree | ou=groups,dc=example,dc=org | + | Usergroup Object Filter | Object classes for usergroups, separated by commas if more classes are required. In a typical LDAP deployment, usually "groupOfNames", the system has been filled in automatically, if you need to change it, just edit it. * means all. | * | + | group name | cn | Unchangeable | + +!!! note + + 1. After you have established a trust relationship between the enterprise user management system + and AI platform through the LDAP protocol, you can synchronize the users or groups in the enterprise + user management system to AI platform at one time through auto/manual synchronization. + 1. After synchronization, the administrator can authorize groups/groups in batches, and users + can log in to AI platform through the account/password in the enterprise user management system. + 1. See the [LDAP Operations Demo Video](../../../videos/ghippo.md#integration-with-ldap-users-and-user-groups) for a hands-on tutorial. diff --git a/docs/en/docs/ghippo/user-guide/access-control/oauth2.0.md b/docs/en/docs/ghippo/user-guide/access-control/oauth2.0.md new file mode 100644 index 0000000..c91de96 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/oauth2.0.md @@ -0,0 +1,44 @@ +--- +MTPE: windsonsea +date: 2024-02-18 +--- + +# OAuth 2.0 - WeCom + +If all members in your enterprise or organization are managed in WeCom, you can use the +identity provider feature based on the OAuth 2.0 protocol provided by Global Management, +without the need to create a username/password for each organization member in AI platform. +You can grant these external user identities permission to use AI platform resources. + +## Steps + +1. Log in to AI platform with a user who has the **admin** role. Click + **Global Management** -> **Access Control** at the bottom of the left navigation bar. + + ![Users and Access Control](../../images/access.png) + +2. Select **Identity Providers** on the left navigation bar, and click the **OAuth 2.0** tab. + Fill in the form fields and establish a trust relationship with WeCom, then click **Save**. + + ![Oauth2.0](../../images/oauth2.png) + +## Corresponding fields in WeCom + +!!! note + + Before integration, you need to create a custom application in the WeCom management console. Refer to + [How to create a custom application link](https://open.work.weixin.qq.com/help2/pc/16892?person_id=1&searchData=) + + | Field | Description | + | ----------- | ---------------| + | Corp ID | ID of WeCom | + | Agent ID | ID of the custom application | + | ClientSecret | Secret of the custom application | + +WeCom ID: + +![Oauth2.0](../../images/mybusiness.png) + +Agent ID and ClientSecret: + +![agent](../../images/selfapplication.png) diff --git a/docs/en/docs/ghippo/user-guide/access-control/oidc.md b/docs/en/docs/ghippo/user-guide/access-control/oidc.md new file mode 100644 index 0000000..7211c50 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/oidc.md @@ -0,0 +1,65 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-08-12 +--- + +# Create and Manage OIDC + +OIDC (OpenID Connect) is an identity layer based on OAuth 2.0 and an identity authentication standard protocol based on the OAuth2 protocol. + +If your enterprise or organization already has its own account system, and your enterprise user +management system supports the OIDC protocol, you can use the OIDC protocol-based identity provider +feature provided by the Global Management instead of creating usernames/passwords for each member in AI platform. +You can grant permissions to use AI platform resources to these external user identities. + +The specific operation steps are as follows. + +1. Log in to AI platform as a user with __admin__ role. Click __Global Management__ -> __Access Control__ at the bottom of the left navigation bar. + + ![access control](../../images/ws01.png) + +2. On the left nav bar select __Identity Provider__ , click __OIDC__ -> __Create an Identity Provider__ + + ![click create](../../images/oidc-button.png) + +3. After completing the form fields and establishing a trust relationship with the identity provider, click __Save__ . + + ![oidc](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/oidc02.png) + + | Fields | Descriptions | + | ------ | ------------ | + | Provider Name | displayed on the login page and is the entry point for the identity provider | + | Authentication Method | Client authentication method. If the JWT is signed with a private key, select __JWT signed with private key__ from the dropdown. For details, refer to [Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication). | + | Client ID | Client ID | + | Client Secret | Client Secret | + | Client URL | One-click access to login URL, Token URL, user information URL and logout URL through the identity provider's well-known interface | + | Auto-associate | After it is turned on, when the identity provider username/email is duplicated with the AI platform username/email, the two will be automatically associated | + +!!! note + + 1. After the user completes the first login to AI platform through the enterprise user management system, + the user information will be synchronized to __Access Control__ -> __User List__ of AI platform. + 1. Users who log in for the first time will not be given any default permissions and need to be authorized + by an administrator (the administrator can be a platform administrator, submodule administrator + or resource administrator). + 1. For practical tutorials, please refer to [OIDC Operation Video Tutorials](../../../videos/ghippo.md#oidc), + or refer to [Azure OpenID Connect (OIDC) Access Process](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc). + +## User identity authentication interaction process + +The interactive process of user authentication is as follows: + +![oidc](../../images/oidc01.png) + +1. Use a browser to initiate a single sign-on request for AI platform. +1. According to the information carried in the login link, AI platform searches for the proper configuration information + in __Global Management__ -> __Access Control__ -> __Identity Provider__ , constructs an OIDC + authorization Request, and sends it to the browser. +1. After the browser receives the request, it forwards the OIDC authorization Request to the enterprise IdP. +1. Enter the username and password on the login page of the enterprise IdP. The enterprise IdP verifies + the provided identity information, constructs an ID token carrying user information, and sends an + OIDC authorization response to the browser. +1. After the browser responds, it forwards the OIDC authorization Response to AI platform. +1. AI platform takes the ID Token from the OIDC Authorization Response, maps it to a specific user list + according to the configured identity conversion rules, and issues the Token. +1. Complete single sign-on to access AI platform. diff --git a/docs/en/docs/ghippo/user-guide/access-control/role.md b/docs/en/docs/ghippo/user-guide/access-control/role.md new file mode 100644 index 0000000..64e186f --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/role.md @@ -0,0 +1,125 @@ +# Role and Permission Management + +A role corresponds to a set of permissions that determine the actions that can be +performed on resources. Granting a user a role means granting all the permissions included in that role. + +AI platform platform provides three levels of roles, which effectively solve your permission-related issues: + +- [Platform Roles](#platform-roles) +- [Workspace Roles](#workspace-roles) +- [Folder Roles](#folder-roles) + +## Platform Roles + +Platform roles are coarse-grained permissions that grant corresponding permissions to +all relevant resources on the platform. By assigning platform roles, users can have +permissions to create, delete, modify, and view all clusters and workspaces, but not +specifically to a particular cluster or workspace. AI platform provides 5 pre-defined +platform roles that users can directly use: + +- Admin +- Kpanda Owner +- Workspace and Folder Owner +- IAM Owner +- Audit Owner + +![5 pre-defined platform roles](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole01.png) + +Additionally, AI platform supports the creation of custom platform roles with customized content +as needed. For example, creating a platform role that includes all functional permissions in +the Workbench. Since the Workbench depends on workspaces, the platform will automatically +select the "view" permission for workspaces by default. Please do not manually deselect it. +If User A is granted this Workbench role, they will automatically have all functional permissions +related to the Workbench in all workspaces. + +![Permission list](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole02.png) + +### Platform Role Authorization Methods + +There are three ways to authorize platform roles: + +- In the __Global Management__ -> __Access Control__ -> __Users__ section, find the user + in the user list, click __...__ , select __Authorization__ , and grant platform role permissions to the user. + + ![Click Authorization](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole03.png) + +- In the __Global Management__ -> __Access Control__ -> __Groups__ section, create a group in the group list, + add the user to the group, and grant authorization to the group + (the specific operation is: find the group in the group list, click __...__ , select __Add Permissions__ , and grant platform roles to the group). + + ![Add permissions](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole04.png) + +- In the __Global Management__ -> __Access Control__ -> __Roles__ section, find the corresponding platform role + in the role list, click the role name to access details, click the __Related Members__ button, select the user or group, and click __OK__ . + + ![Related Members Button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole05.png) + +## Workspace Roles + +Workspace roles are fine-grained roles that grant users management permissions, view permissions, +or Workbench-related permissions for a specific workspace. Users with these roles can only manage +the assigned workspace and cannot access other workspaces. AI platform provides 3 pre-defined workspace +roles that users can directly use: + +- Workspace Admin +- Workspace Editor +- Workspace Viewer + +![3 pre-defined workspace roles](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole06.png) + +Moreover, AI platform supports the creation of custom workspace roles with customized content as needed. +For example, creating a workspace role that includes all functional permissions in the Workbench. +Since the Workbench depends on workspaces, the platform will automatically select the "view" permission +for workspaces by default. Please do not manually deselect it. If User A is granted this role in +Workspace 01, they will have all functional permissions related to the Workbench in Workspace 01. + +!!! note + + Unlike platform roles, workspace roles need to be used within the workspace. Once authorized, + users will only have the functional permissions of that role within the assigned workspace. + +### Workspace Role Authorization Methods + +In the __Global Management__ -> __Workspace and Folder__ list, find the workspace, +click __Authorization__ , and grant workspace role permissions to the user. + +![Authorization Button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole07.png) + +![Fill and Select](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole08.png) + +## Folder Roles + +Folder roles have permissions granularity between platform roles and workspace roles. +They grant users management permissions and view permissions for a specific folder and its sub-folders, +as well as all workspaces within that folder. Folder roles are commonly used in departmental scenarios +in enterprises. For example, User B is a leader of a first-level department and usually has management +permissions over the first-level department, all second-level departments under it, and projects within +those departments. In this scenario, User B is granted admin permissions for the first-level folder, +which also grants corresponding permissions for the second-level folders and workspaces below them. +AI platform provides 3 pre-defined folder roles that users can directly use: + +- Folder Admin +- Folder Editor +- Folder Viewer + +![3 pre-defined folder roles](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole09.png) + +Additionally, AI platform supports the creation of custom folder roles with customized content as needed. +For example, creating a folder role that includes all functional permissions in the Workbench. +If User A is granted this role in Folder 01, they will have all functional permissions related +to the Workbench in all workspaces within Folder 01. + +!!! note + + The functionality of modules depends on workspaces, and folders provide further grouping mechanisms + with permission inheritance capabilities. Therefore, folder permissions not only include the folder + itself but also its sub-folders and workspaces. + +### Folder Role Authorization Methods + +In the __Global Management__ -> __Workspace and Folder__ list, find the folder, +click __Authorization__ , and grant folder role permissions to the user. + +![Authorization Button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole10.png) + +![Fill and Select](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/newrole11.png) diff --git a/docs/en/docs/ghippo/user-guide/access-control/user.md b/docs/en/docs/ghippo/user-guide/access-control/user.md new file mode 100644 index 0000000..00db927 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/user.md @@ -0,0 +1,110 @@ +# User + +A user refers to a user created by the platform administrator Admin or the access control administrator IAM Owner on the __Global Management__ -> __Access Control__ -> __Users__ page, or a user connected through LDAP / OIDC . +The username represents the account, and the user logs in to the Suanova Enterprise platform through the username and password. + +Having a user account is a prerequisite for users to access the platform. The newly created user does not have any permissions by default. For example, you need to assign corresponding role permissions to users, such as granting administrator permissions to submodules in __User List__ or __User Details__ . +The sub-module administrator has the highest authority of the sub-module, and can create, manage, and delete all resources of the module. +If a user needs to be granted permission for a specific resource, such as the permission to use a certain resource, please see [Resource Authorization Description](#authorize-for-user). + +This page introduces operations such as creating, authorizing, disabling, enabling, and deleting users. + +## Create user + +Prerequisite: You have the platform administrator Admin permission or the access control administrator IAM Admin permission. + +1. The administrator enters __Access Control__ , selects __Users__ , enters the user list, and clicks __Create User__ on the upper right. + + ![create user](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/createuser01.png) + +2. Fill in the username and login password on the __Create User__ page. If you need to create + multiple users at one time, you can click __Create User__ to create in batches, and you can + create up to 5 users at a time. Determine whether to set the user to reset the password + when logging in for the first time according to your actual situation. + + ![create user](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/createuser02.png) + +3. Click __OK__ , the user is successfully created and returns to the user list page. + +!!! note + + The username and password set here will be used to log in to the platform. + +## Authorize for User + +Prerequisite: The user already exists. + +1. The administrator enters __Access Control__ , selects __Users__ , enters the user list, and clicks __┇__ -> __Authorization__ . + + ![Menu](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/authorize01.png) + +2. On the __Authorization__ page, check the required role permissions (multiple choices are allowed). + + ![Interface](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/authorize02.png) + +3. Click __OK__ to complete the authorization for the user. + +!!! note + + In the user list, click a user to enter the user details page. + +## Add user to group + +1. The administrator enters __Access Control__ , selects __Users__ , enters the user list, and clicks __┇__ -> __Add to Group__ . + + ![Add group menu](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/joingroup01.png) + +2. On the __Add to Group__ page, check the groups to be joined (multiple choices are allowed). If there is no optional group, click __Create a new group__ to create a group, and then return to this page and click the __Refresh__ button to display the newly created group. + + ![Add group interface](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/joingroup02.png) + +3. Click __OK__ to add the user to the group. + +!!! note + + The user will inherit the permissions of the group, and you can view the groups that the user has joined in __User Details__ . + +## Enable/Disable user + +Once a user is deactivated, that user will no longer be able to access the Platform. Unlike deleting a user, a disabled user can be enabled again as needed. It is recommended to disable the user before deleting it to ensure that no critical service is using the key created by the user. + +1. The administrator enters __Access Control__ , selects __Users__ , enters the user list, and clicks a username to enter user details. + + ![User details](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/createuser03.png) + +2. Click __Edit__ on the upper right, turn off the status button, and make the button gray and inactive. + + ![Edit](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/enableuser01.png) + +3. Click __OK__ to finish disabling the user. + +## Forgot password + +Premise: User mailboxes need to be set. There are two ways to set user mailboxes. + +- On the user details page, the administrator clicks __Edit__ , enters the user's email address in the pop-up box, and clicks __OK__ to complete the email setting. + + ![Edit](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/enableuser02.png) + +- Users can also enter the __Personal Center__ and set the email address on the __Security Settings__ page. + + ![User center](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/mailbox.png) + +If the user forgets the password when logging in, please refer to [Reset Password](../password.md). + +## Delete users + +!!! warning + + After deleting a user, the user will no longer be able to access platform resources in any way, please delete carefully. + Before deleting a user, make sure your key programs no longer use keys created by that user. + If you are unsure, it is recommended to disable the user before deleting. + If you delete a user and then create a new user with the same name, the new user is considered a new, separate identity that does not inherit the deleted user's roles. + +1. The administrator enters __Access Control__ , selects __Users__ , enters the user list, and clicks __┇__ -> __Delete__ . + + ![Delete user](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/deleteuser01.png) + +2. Click __Delete__ to finish deleting the user. + + ![Confirm deletion](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/deleteuser02.png) diff --git a/docs/en/docs/ghippo/user-guide/access-control/webhook.md b/docs/en/docs/ghippo/user-guide/access-control/webhook.md new file mode 100644 index 0000000..becdb06 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/access-control/webhook.md @@ -0,0 +1,86 @@ +# Webhook Message Notification + +With AI platform integrated into the client's system, you can create Webhooks to send message notifications when users are created, updated, deleted, logged in, or logged out. + +Webhook is a mechanism for implementing real-time event notifications. It allows an application to push data or events to another application without the need for polling or continuous querying. By configuring Webhooks, you can specify that the target application receives and processes notifications when a certain event occurs. + +The working principle of Webhook is as follows: + +1. The source application (AI platform) performs a specific operation or event. +2. The source application packages the relevant data and information into an HTTP request and sends it to the URL specified by the target application (e.g., enterprise WeChat group robot). +3. The target application receives the request and processes it based on the data and information provided. + +By using Webhooks, you can achieve the following functionalities: + +- Real-time notification: Notify other applications in a timely manner when a specific event occurs. +- Automation: The target application can automatically trigger predefined operations based on the received Webhook requests, eliminating the need for manual intervention. +- Data synchronization: Use Webhooks to pass data from one application to another, enabling synchronized updates. + +Common use cases include: + +- Version control systems (e.g., GitHub, GitLab): Automatically trigger build and deployment operations when code repositories change. +- E-commerce platforms: Send update notifications to logistics systems when order statuses change. +- Chatbot platforms: Push messages to target servers via Webhooks for processing when user messages are received. + +## Configuration Steps + +The steps to configure Webhooks in AI platform are as follows: + +1. On the left nav, click __Global Management__ -> __Access Control__ -> __Docking Portal__ , create a client ID. + + ![oem in](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/oem/images/webh01.png) + +2. Click a client ID to enter the details page, then click the __Create Webhook__ button. + + ![button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/oem/images/webh02.png) + +3. Fill in the field information in the popup window and click __OK__ . + + - Object: Currently only supports the __User__ object. + - Action: Send Webhook messages when users are created/updated/deleted/logged in or out. + - URL: The address to receive the messages. + - Method: Choose the appropriate method as required, e.g., for enterprise WeChat, POST is recommended. + - Advanced Configuration: You can write the message body in JSON format. For enterprise WeChat groups, refer to the [Group Robot configuration guide](https://developer.work.weixin.qq.com/document/path/91770). + + ![fill](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/oem/images/webh03.png) + +4. A screen prompt indicates that the Webhook was created successfully. + + ![success](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/oem/images/webh04.png) + +5. Now try creating a user. + + ![create](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/oem/images/webh05.png) + +6. User creation succeeds, and you can see that an enterprise WeChat group received a message. + + ![message](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/oem/images/webh06.png) + +## Advanced Configuration Example + +**Default Message Body** + +AI platform predefines some variables that you can use in the message body based on your needs. + +```json +{ + "id": "{{$$.ID$$}}", + "email": "{{$$.Email$$}}", + "username": "{{$$.Name$$}}", + "last_name": "{{$$.LastName$$}}", + "first_name": "{{$$.FirstName$$}}", + "created_at": "{{$$.CreatedAt$$}}", + "enabled": "{{$$.Enabled$$}}" +} +``` + +**Message Body for WeCom Group Robot** + +```json +{ + "msgtype": "text", + "text": { + "content": "{{$$.Name$$}} hello world" + } +} +``` diff --git a/docs/en/docs/ghippo/user-guide/audit/audit-log.md b/docs/en/docs/ghippo/user-guide/audit/audit-log.md new file mode 100644 index 0000000..6bb7c5b --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/audit-log.md @@ -0,0 +1,81 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-08-26 +--- + +# Audit log + +Audit logs help you monitor and record the activities of each user, and provide features for +collecting, storing and querying security-related records arranged in chronological order. With the +audit log service, you can continuously monitor and retain user behaviors in the Global Management +module, including but not limited to user creation, user login/logout, user authorization, and user +operations related to Kubernetes. + +## Features + +The audit log feature has the following characteristics: + +- Out of the box: When installing and using the platform, the audit log feature will be enabled + by default, automatically recording various user-related actions, such as creating users, authorization, + and login/logout. By default, 365 days of user behavior can be viewed within the platform. + +- Security analysis: The audit log will record user operations in detail and provide an export function. + Through these events, you can judge whether the account is at risk. + +- Real-time recording: Quickly collect operation events, and trace back in the audit log list after user operations, so that suspicious behavior can be found at any time. + +- Convenient and reliable: The audit log supports manual cleaning and automatic cleaning, and the cleaning policy can be configured according to your storage size. + +## View Audit Logs + +1. Log in to AI platform with a user account that has the __admin__ or __Audit Owner__ role. + + ![Log in to AI platform](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/lang00.png) + +2. At the bottom of the left navigation bar, click __Global Management__ -> __Audit Logs__ . + + ![Audit Logs](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit01.png) + +## User operations + +On the __User operations__ tab, you can search for user operation events by time range, or by using fuzzy or exact search. + +Click the __┇__ icon on the right side of an event to view its details. + +![User audit logs](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit02.png) + +The event details are shown in the following figure. + +![User event details](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit03.png) + +Click the __Export__ in the upper right corner to export the user operation logs within the selected time range in CSV or Excel format. + +![Export](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit04.png) + +## System operations + +On the __System operations__ tab, you can search for system operation events by time range, or by using fuzzy or exact search. + +Similarly, click the __┇__ icon on the right side of an event to view its details. + +![System event details](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit05.png) + +Click the __Export__ in the upper right corner to export the system operation logs within the selected time range in CSV or Excel format. + +![Export](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit06.png) + +## Settings + +On the __Settings__ tab, you can clean up audit logs for user operations and system operations. + +![Clean up](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/audit07.png) + +You can manually clean up the logs, but it is recommended to export and save them before cleaning. You can also set the maximum retention time for the logs to automatically clean them up. + +!!! note + + The audit logs related to Kubernetes in the auditing module are provided by the Insight module. + To reduce the storage pressure of the audit logs, Global Management by default does not collect Kubernetes-related logs. + If you need to record them, please refer to [Enabling K8s Audit Logs](./open-k8s-audit.md). + Once enabled, the cleanup function is consistent with the Global Management cleanup function, + but they do not affect each other. diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/amamba.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/amamba.md new file mode 100644 index 0000000..614b997 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/amamba.md @@ -0,0 +1,51 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Workbench Audit Items + +| Events | Resource Type | Notes | +| --- | --- | --- | +| Create-Application | Application | | +| Update-Application | Application | Edit YAML, create snapshots, rollback | +| Delete-Application | Application | | +| Create-OAMApplication | OAMApplication | | +| Update-OAMApplication | OAMApplication | Edit YAML | +| Add-OAMApplicationComponent | OAMApplicationComponent | Add component | +| Update-OAMApplicationComponentTrait | OAMApplicationComponentTrait | Update OAM features for application component | +| Delete-OAMApplication | OAMApplication | | +| Create-HelmApplication | HelmApplication | | +| Create-OLMApplication | OLMApplication | | +| Update-OLMApplication | OLMApplication | | +| Delete-OLMApplication | OLMApplication | | +| Create-Namespace | Namespace | | +| Update-NamespaceQuota | NamespaceQuota | | +| Delete-Namespace | Namespace | | +| Create-Pipeline | Pipeline | | +| Update-Pipeline | Pipeline | Includes all update operations (edit Jenkinsfile, edit configuration, edit graphical) | +| Run-Pipeline | Pipeline | Run immediately | +| ReRun-Pipeline | Pipeline | Re-run operation | +| Abort-Pipeline | Pipeline | Terminate operation + termination of approval step | +| Approval-Pipeline | Pipeline | Approve pipeline | +| Delete-Pipeline | Pipeline | | +| Create-PipelineCredential | PipelineCredential | | +| Delete-PipelineCredential | PipelineCredential | | +| Create-GrayscaleTask | GrayscaleTask | Whether to distinguish between blue-green or canary | +| Update-GrayscaleTask | GrayscaleTask | Update release task, update version, edit YAML, update number of instances | +| Upgrade-GrayscaleTask | GrayscaleTask | | +| Abort-GrayscaleTask | GrayscaleTask | | +| Undo-GrayscaleTask | GrayscaleTask | | +| Delete-GrayscaleTask | GrayscaleTask | | +| Create-GitOpsApplication | GitOpsApplication | | +| Update-GitOpsApplication | GitOpsApplication | | +| Sync-GitOpsApplication | GitOpsApplication | | +| Delete-GitOpsApplication | GitOpsApplication | | +| Import-GitOpsRepository | GitOpsRepository | | +| Delete-GitOpsRepository | GitOpsRepository | | +| Integrated-Toolchain | Toolchain | | +| Delete-Toolchain | Toolchain | | +| Bind-ToolchainProject | ToolchainProject | Jira and GitLab support SonarQube from an administrator's perspective as well | +| Unbind-ToolchainProject | ToolchainProject | Jira and GitLab support SonarQube from an administrator's perspective as well | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/ghippo.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/ghippo.md new file mode 100644 index 0000000..e4e02fe --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/ghippo.md @@ -0,0 +1,62 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Audit Items of Global Management + +| Events | Resource Type | Notes | +| --- | --- | --- | +| UpdateEmail-Account | Account | | +| UpdatePassword-Account | Account | | +| CreateAccessKeys-Account | Account | | +| UpdateAccessKeys-Account | Account | | +| DeleteAccessKeys-Account | Account | | +| Create-User | User | | +| Delete-User | User | | +| Update-User | User | | +| UpdateRoles-User | User | | +| UpdatePassword-User | User | | +| CreateAccessKeys-User | User | | +| UpdateAccessKeys-User | User | | +| DeleteAccessKeys-User | User | | +| Create-Group | Group | | +| Delete-Group | Group | | +| Update-Group | Group | | +| AddUserTo-Group | Group | | +| RemoveUserFrom-Group | Group | | +| UpdateRoles-Group | Group | | +| UpdateRoles-User | User | | +| Create-LADP | LADP | | +| Update-LADP | LADP | | +| Delete-LADP | LADP | Unable to audit through API server for OIDC | +| Login-User | User | | +| Logout-User | User | | +| UpdatePassword-SecurityPolicy | SecurityPolicy | | +| UpdateSessionTimeout-SecurityPolicy | SecurityPolicy | | +| UpdateAccountLockout-SecurityPolicy | SecurityPolicy | | +| UpdateLogout-SecurityPolicy | SecurityPolicy | | +| MailServer-SecurityPolicy | SecurityPolicy | | +| CustomAppearance-SecurityPolicy | SecurityPolicy | | +| OfficialAuthz-SecurityPolicy | SecurityPolicy | | +| Create-Workspace | Workspace | | +| Delete-Workspace | Workspace | | +| BindResourceTo-Workspace | Workspace | | +| UnBindResource-Workspace | Workspace | | +| BindShared-Workspace | Workspace | | +| SetQuota-Workspace | Workspace | | +| Authorize-Workspace | Workspace | | +| DeAuthorize-Workspace | Workspace | | +| UpdateDeAuthorize-Workspace | Workspace | | +| Update-Workspace | Workspace | | +| Create-Folder | Folder | | +| Delete-Folder | Folder | | +| UpdateAuthorize-Folder | Folder | | +| Update-Folder | Folder | | +| Authorize-Folder | Folder | | +| DeAuthorize-Folder | Folder | | +| AutoCleanup-Audit | Audit | | +| ManualCleanup-Audit | Audit | | +| Export-Audit | Audit | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/insight.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/insight.md new file mode 100644 index 0000000..2bea63e --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/insight.md @@ -0,0 +1,52 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Insight Audit Items + +| Events | Resource Type | Notes | +| --- | --- | --- | +| Create-ProbeJob | ProbeJob | | +| Update-ProbeJob | ProbeJob | | +| Delete-ProbeJob | ProbeJob | | +| Create-AlertPolicy | AlertPolicy | | +| Update-AlertPolicy | AlertPolicy | | +| Delete-AlertPolicy | AlertPolicy | | +| Import-AlertPolicy | AlertPolicy | | +| Create-AlertRule | AlertRule | | +| Update-AlertRule | AlertRule | | +| Delete-AlertRule | AlertRule | | +| Create-RuleTemplate | RuleTemplate | | +| Update-RuleTemplate | RuleTemplate | | +| Delete-RuleTemplate | RuleTemplate | | +| Create-email | email | | +| Update-email | email | | +| Delete-Receiver | Receiver | | +| Create-dingtalk | dingtalk | | +| Update-dingtalk | dingtalk | | +| Delete-Receiver | Receiver | | +| Create-wecom | wecom | | +| Update-wecom | wecom | | +| Delete-Receiver | Receiver | | +| Create-webhook | webhook | | +| Update-webhook | webhook | | +| Delete-Receiver | Receiver | | +| Create-sms | sms | | +| Update-sms | sms | | +| Delete-Receiver | Receiver | | +| Create-aliyun(tencent,custom) | aliyun, tencent, custom | | +| Update-aliyun(tencent,custom) | aliyun, tencent, custom | | +| Delete-SMSserver | SMSserver | | +| Create-MessageTemplate | MessageTemplate | | +| Update-MessageTemplate | MessageTemplate | | +| Delete-MessageTemplate | MessageTemplate | | +| Create-AlertSilence | AlertSilence | | +| Update-AlertSilence | AlertSilence | | +| Delete-AlertSilence | AlertSilence | | +| Create-AlertInhibition | AlertInhibition | | +| Update-AlertInhibition | AlertInhibition | | +| Delete-AlertInhibition | AlertInhibition | | +| Update-SystemSettings | SystemSettings | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kairship.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kairship.md new file mode 100644 index 0000000..e6c41c5 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kairship.md @@ -0,0 +1,48 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Audit Items of MultiCloud Management + +| Events | Resource Type | Notes | +| --- | --- | --- | +| Create-Instance | Instance | | +| Delete-Instance | Instance | | +| Integrate-Cluster | Cluster | | +| Remove-Cluster | Cluster | | +| Create-Deployment | Deployment | | +| Update-Deployment | Deployment | | +| Delete-Deployment | Deployment | | +| Create-Job | Job | | +| Update-Job | Job | | +| Delete-Job | Job | | +| Create-CronJob | CronJob | | +| Update-CronJob | CronJob | | +| Delete-CronJob | CronJob | | +| Create-CRD | CRD | | +| Update-CRD | CRD | | +| Delete-CRD | CRD | | +| Create-Multicloud Services | Multicloud Services | | +| Update-Multicloud Services | Multicloud Services | | +| Delete-Multicloud Services | Multicloud Services | | +| Create-Multicloud Ingress | Multicloud Ingress | | +| Update-Multicloud Ingress | Multicloud Ingress | | +| Delete-Multicloud Ingress | Multicloud Ingress | | +| Create-Multicloud Namespace | Multicloud Namespace | | +| Update-Multicloud Namespace | Multicloud Namespace | | +| Delete-Multicloud Namespace | Multicloud Namespace | | +| Create-Multicloud ConfigMaps | Multicloud ConfigMaps | | +| Update-Multicloud ConfigMaps | Multicloud ConfigMaps | | +| Delete-Multicloud ConfigMaps | Multicloud ConfigMaps | | +| Create-Multicloud Secret | Multicloud Secret | | +| Update-Multicloud Secret | Multicloud Secret | | +| Delete-Multicloud Secret | Multicloud Secret | | +| Create-Propagation Policies | Propagation Policies | | +| Update-Propagation Policies | Propagation Policies | | +| Delete-Propagation Policies | Propagation Policies | | +| Create-Override Policies | Override Policies | | +| Update-Override Policies | Override Policies | | +| Delete-Override Policies | Override Policies | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kangaroo.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kangaroo.md new file mode 100644 index 0000000..1637d74 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kangaroo.md @@ -0,0 +1,26 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Audit Items of Container Registry + +| Events | Resource Type | Notes | +| --- | --- | --- | +| Delete-Image | Image | | +| Delete-Artifacts | Artifacts | | +| Create-ReclaimRule | ReclaimRule | Only one record per interface | +| Delete-ReclaimRule | ReclaimRule | +| Scheduled-ReclaimRule | ReclaimRule | +| Manual-ReclaimRule | ReclaimRule | Record separately | +| Create-IntegratedRegistryinWorkspace | IntegratedRegistryinWorkspace | | +| Delete-IntegratedRegistryinWorkspace | IntegratedRegistryinWorkspace | | +| Update-IntegratedRegistryinWorkspace | IntegratedRegistryinWorkspace | | +| Create-IntegratedRegistrybyAdmin | IntegratedRegistrybyAdmin | | +| Delete-IntegratedRegistrybyAdmin | IntegratedRegistrybyAdmin | | +| Update-IntegratedRegistrybyAdmin | IntegratedRegistrybyAdmin | | +| Create-Harbor | Harbor | | +| Delete-Harbor | Harbor | | +| Update-Harbor | Harbor | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kpanda.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kpanda.md new file mode 100644 index 0000000..64f23d6 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/kpanda.md @@ -0,0 +1,50 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Audit Items of Container Management + +| Events | Resource Types | +| ------ | ------------- | +| Create-Cluster | Cluster | +| Delete-Cluster | Cluster | +| Integrate-Cluster | Cluster | +| Remove-Cluster | Cluster | +| Upgrade-Cluster | Cluster | +| Integrate-Node | Node | +| Remove-Node | Node | +| Update-NodeGPUMode | NodeGPUMode | +| Create-HelmRepo | HelmRepo | +| Create-HelmApp | HelmApp | +| Delete-HelmApp | HelmApp | +| Create-Deployment | Deployment | +| Delete-Deployment | Deployment | +| Create-DaemonSet | DaemonSet | +| Delete-DaemonSet | DaemonSet | +| Create-StatefulSet | StatefulSet | +| Delete-StatefulSet | StatefulSet | +| Create-Job | Job | +| Delete-Job | Job | +| Create-CronJob | CronJob | +| Delete-CronJob | CronJob | +| Delete-Pod | Pod | +| Create-Service | Service | +| Delete-Service | Service | +| Create-Ingress | Ingress | +| Delete-Ingress | Ingress | +| Create-StorageClass | StorageClass | +| Delete-StorageClass | StorageClass | +| Create-PersistentVolume | PersistentVolume | +| Delete-PersistentVolume | PersistentVolume | +| Create-PersistentVolumeClaim | PersistentVolumeClaim | +| Delete-PersistentVolumeClaim | PersistentVolumeClaim | +| Delete-ReplicaSet | ReplicaSet | +| BindResourceTo-Workspace | Workspace | +| UnBindResource-Workspace | Workspace | +| BindResourceTo-Workspace | Workspace | +| UnBindResource-Workspace | Workspace | +| Create-CloudShell | CloudShell | +| Delete-CloudShell | CloudShell | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/mcamel.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/mcamel.md new file mode 100644 index 0000000..b57ec27 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/mcamel.md @@ -0,0 +1,34 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Middleware Audit Items + +| Events | Resource Type | Notes | +| --- | --- | --- | +| create-ElasticsearchInstance | ElasticsearchInstance | | +| create-KafkaInstance | KafkaInstance | | +| create-MinIOInstance | MinIOInstance | | +| create-PostgreSQLInstance | PostgreSQLInstance | | +| create-RabbitMQInstance | RabbitMQInstance | | +| create-MySQLInstance | MySQLInstance | | +| create-RedisInstance | RedisInstance | | +| delete-ElasticsearchInstance | ElasticsearchInstance | | +| delete-KafkaInstance | KafkaInstance | | +| delete-MinIOInstance | MinIOInstance | | +| delete-PostgreSQLInstance | PostgreSQLInstance | | +| delete-RabbitMQInstance | RabbitMQInstance | | +| delete-MySQLInstance | MySQLInstance | | +| delete-RedisInstance | RedisInstance | | +| update-MySQLBackup | MySQLBackup | | +| update-RedisBackup | RedisBackup | | +| update-ElasticsearchInstance | ElasticsearchInstance | | +| update-KafkaInstance | KafkaInstance | | +| update-MinIOInstance | MinIOInstance | | +| update-MySQLInstance | MySQLInstance | | +| update-PostgreSQLInstance | PostgreSQLInstance | | +| update-RabbitMQInstance | RabbitMQInstance | | +| update-RedisInstance | RedisInstance | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/mspider.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/mspider.md new file mode 100644 index 0000000..b8cfa4a --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/mspider.md @@ -0,0 +1,25 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Service Mesh Audit Items + +| Events | Resource Type | Notes | +| --- | --- | --- | +| create-MeshInstance | MeshInstance | | +| delete-MeshInstance | MeshInstance | | +| Add-Cluster | cluster | | +| Remove-Cluster | cluster | | +| InjectSidecarTo-Namespace | Namespace | | +| ForbiddenInjectSidecarTo-Namespace | Namespace | | +| InjectSidecarTo-Workload | workload | | +| ForbiddenInjectSidecarTo-Workload | workload | | +| create-MeshGateway | MeshGateway | | +| delete-MeshGateway | MeshGateway | | +| Enable-Multicloud | Multicloud | | +| Close-Multicloud | Multicloud | | +| EnableInterconnection | MulticloudGroup | | +| DisableInterconnection | MulticloudGroup | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/skoala.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/skoala.md new file mode 100644 index 0000000..45c57c5 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/skoala.md @@ -0,0 +1,125 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Microservice Audit Items + +| Events | Resource Type | Notes | +| --- | --- | --- | +| Create-Gateway | Gateway | | +| Update-Gateway | Gateway | | +| ListClusterGateway-Gateway | Gateway | | +| Delete-Gateway | Gateway | | +| UpdateAPIStatus-GatewayAPI | GatewayAPI | | +| DebugGatewayAPI-GatewayAPI | GatewayAPI | | +| CreateGatewayAPI-GatewayAPI | GatewayAPI | | +| ImportAPICheck-GatewayAPI | GatewayAPI | | +| ImportAPI-GatewayAPI | GatewayAPI | | +| UpdateGatewayAPIAdvancedPolicy-GatewayAPI | GatewayAPI | | +| UpdateGatewayAPI-GatewayAPI | GatewayAPI | | +| BatchOperationAPI-GatewayAPI | GatewayAPI | | +| DeleteAPI-GatewayAPI | GatewayAPI | | +| CreateService-GatewayService | GatewayService | | +| UpdateServicePolicy-GatewayService | GatewayService | | +| UpdateService-GatewayService | GatewayService | | +| DeleteService-GatewayService | GatewayService | | +| CreateLane-Lane | Lane | | +| CreateLaneDrainageRule-Lane | Lane | | +| ActionLane-Lane | Lane | | +| UpdateLaneDrainageRuleStatus-Lane | Lane | | +| UpdateLaneDrainageRule-Lane | Lane | | +| DeleteLane-Lane | Lane | | +| DeleteLaneDrainageRule-Lane | Lane | | +| AddLaneService-Lane | Lane | | +| DeleteLaneService-Lane | Lane | | +| CreateServiceIstioPlugin-Mesh | Mesh | | +| CreateTimeout-Mesh | Mesh | | +| CreateFault-Mesh | Mesh | | +| CreateOutlierDetection-Mesh | Mesh | | +| CreateConnectionPool-Mesh | Mesh | | +| CreateRetry-Mesh | Mesh | | +| CreateRewrite-Mesh | Mesh | | +| SortServiceIstioPlugin-Mesh | Mesh | | +| UpdateServiceIstioPlugin-Mesh | Mesh | | +| UpdateTimeout-Mesh | Mesh | | +| UpdateLb-Mesh | Mesh | | +| UpdateFault-Mesh | Mesh | | +| UpdateOutlierDetection-Mesh | Mesh | | +| UpdateConnectionPool-Mesh | Mesh | | +| UpdateRetry-Mesh | Mesh | | +| UpdateRewrite-Mesh | Mesh | | +| ExportService-Mesh | Mesh | | +| DeleteServiceIstioPlugin-Mesh | Mesh | | +| DeleteTimeout-Mesh | Mesh | | +| DeleteFault-Mesh | Mesh | | +| DeleteOutlierDetection-Mesh | Mesh | | +| DeleteConnectionPool-Mesh | Mesh | | +| DeleteRetry-Mesh | Mesh | | +| DeleteRewrite-Mesh | Mesh | | +| CreateServiceIstioPluginRLSRules-Mesh | Mesh | | +| UpdateServiceIstioPluginRLSRules-Mesh | Mesh | | +| DeleteServiceIstioPluginRLSRules-Mesh | Mesh | | +| RemoveService-Mesh | Mesh | | +| QueryServiceInstance-Nacos | Nacos | | +| CreateConfig-Nacos | Nacos | | +| CreateServiceAPI-Nacos | Nacos | | +| CreateNamespace-Nacos | Nacos | | +| Create-Nacos | Nacos | | +| UpdateService-Nacos | Nacos | | +| UpdateConfig-Nacos | Nacos | | +| UpdateServiceAPI-Nacos | Nacos | | +| UpdateServiceInstance-Nacos | Nacos | | +| UpdateNamespace-Nacos | Nacos | | +| Update-Nacos | Nacos | | +| RollbackConfig-Nacos | Nacos | | +| DeleteConfig-Nacos | Nacos | | +| DeleteBetaConfig-Nacos | Nacos | | +| DeleteNamespace-Nacos | Nacos | | +| Delete-Nacos | Nacos | | +| GetServiceInsight-Nacos | Nacos | | +| GetServiceInstanceInsight-Nacos | Nacos | | +| UpdateUserPassword-Nacos | Nacos | | +| Update-Plugin | Plugin | | +| CreateServiceAPI-Registry | Registry | | +| Create-Registry | Registry | | +| UpdateServiceAPI-Registry | Registry | | +| UpdateInstance-Registry | Registry | | +| Update-Registry | Registry | | +| GetServiceInsight-Registry | Registry | | +| GetInstanceInsight-Registry | Registry | | +| Ping-Registry | Registry | | +| Delete-Registry | Registry | | +| CreateOrUpdateTokenServer-Sentinel | Sentinel | | +| CreateFlowRule-Sentinel | Sentinel | | +| CreateParamFlowRule-Sentinel | Sentinel | | +| CreateDegradeRule-Sentinel | Sentinel | | +| CreateAuthorityRule-Sentinel | Sentinel | | +| CreateSystemRule-Sentinel | Sentinel | | +| UpdateFlowRule-Sentinel | Sentinel | | +| UpdateParamFlowRule-Sentinel | Sentinel | | +| UpdateDegradeRule-Sentinel | Sentinel | | +| UpdateAuthorityRule-Sentinel | Sentinel | | +| UpdateSystemRule-Sentinel | Sentinel | | +| DeleteClusterFlow-Sentinel | Sentinel | | +| DeleteFlowRule-Sentinel | Sentinel | | +| DeleteParamFlowRule-Sentinel | Sentinel | | +| DeleteDegradeRule-Sentinel | Sentinel | | +| DeleteAuthorityRule-Sentinel | Sentinel | | +| DeleteSystemRule-Sentinel | Sentinel | | +| DeleteInsGovern-Sentinel | Sentinel | | +| CreatePlugin-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| UpdatePluginStatus-SkoalaPlugin | SkoalaPlugin | | +| UpdatePlugin-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| DeletePlugin-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| CreatePluginTemplate-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| CreatePlugin-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| UpdatePluginTemplate-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| UpdatePlugin-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| DeletePluginTemplate-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| DeletePlugin-SkoalaPluginTemplate | SkoalaPluginTemplate | | +| CreateVirtualhost-Virtualhost | Virtualhost | | +| UpdateVirtualhost-Virtualhost | Virtualhost | | +| 删除域名:DeleteVirtualhost-Virtualhost | Virtualhost | | diff --git a/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/virtnest.md b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/virtnest.md new file mode 100644 index 0000000..5f9f166 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/gproduct-audit/virtnest.md @@ -0,0 +1,24 @@ +--- +MTPE: windsonsea +date: 2024-05-22 +hide: + - toc +--- + +# Audit Items of Virtual Machine + +| Events | Resource Type | Notes | +| --- | --- | --- | +| Restart-VMs | VM | | +| ConvertToTemplate-VMs | VM | | +| Edit-VMs | VM | | +| Update-VMs | VM | | +| Restore-VMs | VM | | +| Power on-VMs | VM | | +| LiveMigrate-VMs | VM | | +| Delete-VMs | VM | | +| Delete-VM Template | VM Template | | +| Create-VMs | VM | | +| CreateSnapshot-VMs | VM | | +| Power off-VMs | VM | | +| Clone-VMs | VM | | diff --git a/docs/en/docs/ghippo/user-guide/audit/open-audit.md b/docs/en/docs/ghippo/user-guide/audit/open-audit.md new file mode 100644 index 0000000..769e8da --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/open-audit.md @@ -0,0 +1,196 @@ +# Enable/Disable collection of audit logs + +- Kubernetes Audit Logs: Kubernetes itself generates audit logs. When this feature is enabled, audit log files for + Kubernetes will be created in the specified directory. +- Collecting Kubernetes Audit Logs: The log files mentioned above are collected using the Insight Agent. The + prerequisite for collecting Kubernetes audit logs are that the cluster has enabled Kubernetes audit logs, the + export of audit logs has been allowed, and the collection of audit logs has been opened. + +## AI platform Installation Status + +- For AI Community installations, the Kubernetes audit log switch was not operated during the management cluster + installation process. +- For AI platform Enterprise installations, the Kubernetes audit log switch is enabled by default. + - To set it to default off, you can modify the installer's __clusterConfig.yaml__ file + (set __logPath__ to empty ""). +- The collection of Kubernetes audit logs switch is disabled by default for the management cluster. + - Default settings do not support configuration. + +## Management Cluster Collection of Kubernetes Audit Logs Switch + +### AI platform Enterprise Installation Environment + +#### Confirm Enabling Kubernetes Audit Logs + +Run the following command to check if audit logs are generated under the __/var/log/kubernetes/audit__ directory. +If they exist, it means that Kubernetes audit logs are successfully enabled. + +```shell +ls /var/log/kubernetes/audit +``` + +If they are not enabled, please refer to the [documentation on enabling/disabling Kubernetes audit logs](open-k8s-audit.md). + +#### Enable Collection of Kubernetes Audit Logs Process + +1. Add ChartMuseum to the helm repo. + + ```shell + helm repo add chartmuseum http://10.5.14.30:8081 + ``` + + Modify the IP address in this command to the IP address of the Spark node. + + !!! note + + If using a self-built Harbor repository, please modify the chart repo URL in the first step to the + insight-agent chart URL of the self-built repository. + +2. Save the current Insight Agent helm values. + + ```shell + helm get values insight-agent -n insight-system -o yaml > insight-agent-values-bak.yaml + ``` + +3. Get the current version number ${insight_version_code}. + + ```shell + insight_version_code=`helm list -n insight-system |grep insight-agent | awk {'print $10'}` + ``` + +4. Update the helm value configuration. + + ```shell + helm upgrade --install --create-namespace --version ${insight_version_code} --cleanup-on-fail insight-agent chartmuseum/insight-agent -n insight-system -f insight-agent-values-bak.yaml --set global.exporters.auditLog.kubeAudit.enabled=true + ``` + +5. Restart all fluentBit pods under the insight-system namespace. + + ```shell + fluent_pod=`kubectl get pod -n insight-system | grep insight-agent-fluent-bit | awk {'print $1'} | xargs` + kubectl delete pod ${fluent_pod} -n insight-system + ``` + +#### Disable Collection of Kubernetes Audit Logs + +The remaining steps are the same as enabling the collection of Kubernetes audit logs, with only a modification +in the previous section's step 4: updating the helm value configuration. + +```shell +helm upgrade --install --create-namespace --version ${insight_version_code} --cleanup-on-fail insight-agent chartmuseum/insight-agent -n insight-system -f insight-agent-values-bak.yaml --set global.exporters.auditLog.kubeAudit.enabled=false +``` + +### AI Community Online Installation Environment + +!!! note + + If installing AI Community in a Kind cluster, perform the following steps inside the Kind container. + +#### Confirm Enabling Kubernetes Audit Logs + +Run the following command to check if audit logs are generated under the __/var/log/kubernetes/audit__ directory. +If they exist, it means that Kubernetes audit logs are successfully enabled. + +```shell +ls /var/log/kubernetes/audit +``` + +If they are not enabled, please refer to the [documentation on enabling/disabling Kubernetes audit logs](open-k8s-audit.md). + +#### Enable Collection of Kubernetes Audit Logs Process + +1. Save the current values. + + ```shell + helm get values insight-agent -n insight-system -o yaml > insight-agent-values-bak.yaml + ``` + +2. Get the current version number ${insight_version_code} and update the configuration. + + ```shell + insight_version_code=`helm list -n insight-system |grep insight-agent | awk {'print $10'}` + ``` + +3. Update the helm value configuration. + + ```shell + helm upgrade --install --create-namespace --version ${insight_version_code} --cleanup-on-fail insight-agent insight-release/insight-agent -n insight-system -f insight-agent-values-bak.yaml --set global.exporters.auditLog.kubeAudit.enabled=true + ``` + + If the upgrade fails due to an unsupported version, check if the helm repo used in the command has that version. + If not, retry after you updated the helm repo. + + ```shell + helm repo update insight-release + ``` + +4. Restart all fluentBit pods under the insight-system namespace. + + ```shell + fluent_pod=`kubectl get pod -n insight-system | grep insight-agent-fluent-bit | awk {'print $1'} | xargs` + kubectl delete pod ${fluent_pod} -n insight-system + ``` + +#### Disable Collection of Kubernetes Audit Logs + +The remaining steps are the same as enabling the collection of Kubernetes audit logs, with only a modification +in the previous section's step 3: updating the helm value configuration. + +```shell +helm upgrade --install --create-namespace --version ${insight_version_code} --cleanup-on-fail insight-agent insight-release/insight-agent -n insight-system -f insight-agent-values-bak.yaml --set global.exporters.auditLog.kubeAudit.enabled=false +``` + +## Change Worker Cluster + +Each worker cluster is independent and can be turned on as needed. + +### Steps to Enable Audit Log Collection When Creating a Cluster + +By default, the collection of K8s audit logs is turned off. If you need to enable it, you can follow these steps: + +![Default Off](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker01.png) + +![Enable Audit Logs](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker02.png) + +Set the switch to the enabled state to enable the collection of K8s audit logs. + +When creating a worker cluster via AI platform, ensure that the K8s audit log option for the cluster is set to 'true' so +that the created worker cluster will have audit logs enabled. + +![Audit Logs Enabled](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker03.png) + +After the cluster creation is successful, the K8s audit logs for that worker cluster will be collected. + +### Steps to Enable/Disable After Accessing or Creating the Cluster + +#### Confirm Enabling K8s Audit Logs + +Run the following command to check if audit logs are generated under the __/var/log/kubernetes/audit__ directory. +If they exist, it means that K8s audit logs are successfully enabled. + +```shell +ls /var/log/kubernetes/audit +``` + +If they are not enabled, please refer to the [documentation on enabling/disabling K8s audit logs](open-k8s-audit.md). + +#### Enable Collection of K8s Audit Logs + +The collection of K8s audit logs is disabled by default. To enable it, follow these steps: + +1. Select the cluster that has been accessed and needs to enable the collection of K8s audit logs. + + ![Select Cluster](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker04.png) + +2. Go to the Helm application management page and update the insight-agent configuration (if insight-agent is not installed, + you can [install it](../../../insight/quickstart/install/install-agent.md)). + + ![Go to Helm Applications](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker05.png) + +3. Enable/Disable the collection of K8s audit logs switch. + + ![Enable/Disable Switch](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker06.png) + +4. After enabling/disabling the switch, the fluent-bit pod needs to be restarted for the changes to take effect. + + ![Restart Pods](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/worker07.png) diff --git a/docs/en/docs/ghippo/user-guide/audit/open-k8s-audit.md b/docs/en/docs/ghippo/user-guide/audit/open-k8s-audit.md new file mode 100644 index 0000000..5cb6753 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/open-k8s-audit.md @@ -0,0 +1,199 @@ +--- +MTPE: WANG0608GitHub +Done: 2024-08-05 +--- + +# Generate K8s Audit Logs + +By default, the Kubernetes cluster does not generate audit log information. +Through the following configuration, you can enable the audit log feature of Kubernetes. + +!!! note + + In a public cloud environment, it may not be possible to control the output and output path of Kubernetes audit logs. + +1. Prepare the Policy file for the audit log +2. Configure the API server, and enable audit logs +3. Reboot and verify + +## Prepare audit log Policy file + +??? note "Click to view Policy YAML for audit log" + + ```yaml title="policy.yaml" + apiVersion: audit.k8s.io/v1 + kind: Policy + rules: + # The following requests were manually identified as high-volume and low-risk, + # so drop them. + - level: None + users: ["system:kube-proxy"] + verbs: ["watch"] + resources: + - group: "" # core + resources: ["endpoints", "services", "services/status"] + - level: None + # Ingress controller reads `configmaps/ingress-uid` through the unsecured port. + # TODO(#46983): Change this to the ingress controller service account. + users: ["system:unsecured"] + namespaces: ["kube-system"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["configmaps"] + - level: None + users: ["kubelet"] # legacy kubelet identity + verbs: ["get"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + userGroups: ["system:nodes"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + users: + - system:kube-controller-manager + - system:kube-scheduler + - system:serviceaccount:kube-system:endpoint-controller + verbs: ["get", "update"] + namespaces: ["kube-system"] + resources: + - group: "" # core + resources: ["endpoints"] + - level: None + users: ["system:apiserver"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["namespaces", "namespaces/status", "namespaces/finalize"] + # Don't log HPA fetching metrics. + - level: None + users: + - system:kube-controller-manager + verbs: ["get", "list"] + resources: + - group: "metrics.k8s.io" + # Don't log these read-only URLs. + - level: None + nonResourceURLs: + - /healthz* + - /version + - /swagger* + # Don't log events requests. + - level: None + resources: + - group: "" # core + resources: ["events"] + # Secrets, ConfigMaps, TokenRequest and TokenReviews can contain sensitive & binary data, + # so only log at the Metadata level. + - level: Metadata + resources: + - group: "" # core + resources: ["secrets", "configmaps", "serviceaccounts/token"] + - group: authentication.k8s.io + resources: ["tokenreviews"] + omitStages: + - "RequestReceived" + # Get responses can be large; skip them. + - level: Request + verbs: ["get", "list", "watch"] + resources: + - group: "" # core + - group: "admissionregistration.k8s.io" + - group: "apiextensions.k8s.io" + - group: "apiregistration.k8s.io" + - group: "apps" + - group: "authentication.k8s.io" + - group: "authorization.k8s.io" + - group: "autoscaling" + - group: "batch" + - group: "certificates.k8s.io" + - group: "extensions" + - group: "metrics.k8s.io" + - group: "networking.k8s.io" + - group: "policy" + - group: "rbac.authorization.k8s.io" + - group: "settings.k8s.io" + - group: "storage.k8s.io" + omitStages: + - "RequestReceived" + # Default level for known APIs + - level: RequestResponse + resources: + - group: "" # core + - group: "admissionregistration.k8s.io" + - group: "apiextensions.k8s.io" + - group: "apiregistration.k8s.io" + - group: "apps" + - group: "authentication.k8s.io" + - group: "authorization.k8s.io" + - group: "autoscaling" + - group: "batch" + - group: "certificates.k8s.io" + - group: "extensions" + - group: "metrics.k8s.io" + - group: "networking.k8s.io" + - group: "policy" + - group: "rbac.authorization.k8s.io" + - group: "settings.k8s.io" + - group: "storage.k8s.io" + omitStages: + - "RequestReceived" + # Default level for all other requests. + - level: Metadata + omitStages: + - "RequestReceived" + ``` + +Put the above audit log file in __/etc/kubernetes/audit-policy/__ folder, and name it __apiserver-audit-policy.yaml__ . + +## Configure the API server + +Open the configuration file kube-apiserver.yaml of the API server, usually in the __/etc/kubernetes/manifests/__ folder, and add the following configuration information: + +Please back up kube-apiserver.yaml before this step. The backup file cannot be placed in the __/etc/kubernetes/manifests/__ , and it is recommended to put it in the __/etc/kubernetes/tmp__ . + +1. Add the command under __spec.containers.command__ : + + ```yaml + --audit-log-maxage=30 + --audit-log-maxbackup=10 + --audit-log-maxsize=100 + --audit-log-path=/var/log/audit/kube-apiserver-audit.log + --audit-policy-file=/etc/kubernetes/audit-policy/apiserver-audit-policy.yaml + ``` + +2. Add the command under __spec.containers.volumeMounts__ : + + ```yaml + - mountPath: /var/log/audit + name: audit-logs + - mountPath: /etc/kubernetes/audit-policy + name: audit-policy + ``` + +3. Add the command under __spec.volumes__ : + + ```yaml + - hostPath: + path: /var/log/kubernetes/audit + type: "" + name: audit-logs + - hostPath: + path: /etc/kubernetes/audit-policy + type: "" + name: audit-policy + ``` + +## Test and verify + +After a while, the API server will automatically restart, and run the following command to check whether there is an audit log generated in the __/var/log/kubernetes/audit__ directory. If so, it means that the K8s audit log is successfully enabled. + +```shell +ls /var/log/kubernetes/audit +``` + +If you want to close it, just remove the relevant commands in __spec.containers.command__ . diff --git a/docs/en/docs/ghippo/user-guide/audit/source-ip.md b/docs/en/docs/ghippo/user-guide/audit/source-ip.md new file mode 100644 index 0000000..a3c8e93 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/audit/source-ip.md @@ -0,0 +1,58 @@ +--- +MPTE: WANG0608GitHub +Date: 2024-08-13 +--- + +# Get Source IP in Audit Logs + +The source IP in audit logs plays a critical role in system and network management. +It helps track activities, maintain security, resolve issues, and ensure system +compliance. However, getting the source IP can result in some performance overhead, +so that audit logs are not always enabled in AI platform. +The default enablement of source IP in audit logs and the methods to enable it vary +depending on the installation mode. The following sections will explain the default +enablement and the steps to enable source IP in audit logs based on the installation mode. + +!!! note + + Enabling audit logs will modify the replica count of the istio-ingressgateway, resulting in a certain performance overhead. + Enabling audit logs requires disabling LoadBalance of kube-proxy and Topology Aware Routing, which can have a certain impact on cluster performance. + After enabling audit logs, it is essential to ensure that the istio-ingressgateway exists on the proper node to the access IP. If the istio-ingressgateway drifts due to node health issues or other issues, it needs to be manually rescheduled back to that node. Otherwise, it will affect the normal operation of AI platform. + +## Determine the Installation Mode + +```bash +kubectl get pod -n metallb-system +``` + +Run the above command in the cluster. If the result is as follows, +it means that the cluster is not in the MetalLB installation mode: + +```console +No resources found in metallbs-system namespace. +``` + +## NodePort Installation Mode + +In this mode, the source IP in audit logs is disabled by default. +The steps to enable it are as follows: + +1. Set the minimum replica count of the __istio-ingressgateway__ HPA to be equal to the number of control plane nodes + + ```bash + count=$(kubectl get nodes --selector=node-role.kubernetes.io/control-plane | wc -l) + count=$((count-1)) + + kubectl patch hpa istio-ingressgateway -n istio-system -p '{"spec":{"minReplicas":'$count'}}' + ``` + +2. Modify the __externalTrafficPolicy__ and __internalTrafficPolicy__ value of the __istio-ingressgateway__ service to "Local" + + ```bash + kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local","internalTrafficPolicy":"Local"}}' + ``` + +## MetalLB Installation Mode + +In this mode, the source IP in audit logs is gotten by default after the installation. +For more information, refer to [MetalLB Source IP](../../../network/modules/metallb/source_ip.md). diff --git a/docs/en/docs/ghippo/user-guide/password.md b/docs/en/docs/ghippo/user-guide/password.md new file mode 100644 index 0000000..6144751 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/password.md @@ -0,0 +1,65 @@ +--- +MTPE: ModetaNiu +Date: 2023-07-09 +--- + +# Reset Password + +If you forget your password, you can reset it by following the instructions on this page. + +## Steps to Reset Password + +When an administrator initially creates a user, it sets a username and password for him. +After the user logs in, fill in the email address and change the password in __Personal Center__ . +If the user has not set an email address, he can only contact the administrator to reset the password. + +1. If you forget your password, you can click __Forgot your password?__ on the login interface. + + ![Login Interface](../images/password01en.png) + +1. Enter your login email and click __Submit__ . + + ![Forgot your password](../images/password02en.png) + +1. Find the password reset email in the mailbox, and click the link in your email. The link is effective for 5 minutes. + + ![Click the link](../images/password03en.png) + +1. Install applications that support 2FA dynamic password generation (such as Google Authenticator) on mobile phone + or other devices. Set up a dynamic password to activate your account, and click __Submit__ . + + ![Config dynamic password](../images/password04en.png) + +1. Set a new password and click __Submit__ . The requirements for setting a new password are consistent with + the password rules when creating an account. + + ![Update password](../images/password04.png) + +1. The password is successfully reset, and you enter the home page directly. + +## Reset password process + +The flow of the password reset process is as follows. + +```mermaid +graph TB + +pass[Forgot password] --> usern[Enter username] +--> button[Click button to send a mail] --> judge1[Check your username is correct or not] + + judge1 -.Correct.-> judge2[Check if you have bounded a mail] + judge1 -.Wrong.-> tip1[Error of incorrect username] + + judge2 -.A mail has been bounded.-> send[Send a reset mail] + judge2 -.No any mail bounded.-> tip2[No any mail bounded
Contact admin to reset password] + +send --> click[Click the mail link] --> config[Config dynamic password] --> reset[Reset password] +--> success[Successfully reset] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class pass,usern,button,tip1,send,tip2,send,click,config,reset,success plain; +class judge1,judge2 k8s +``` diff --git a/docs/en/docs/ghippo/user-guide/personal-center/accesstoken.md b/docs/en/docs/ghippo/user-guide/personal-center/accesstoken.md new file mode 100644 index 0000000..a7c6a1b --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/personal-center/accesstoken.md @@ -0,0 +1,58 @@ +--- +MTPE: windsonsea +date: 2024-01-11 +--- + +# Access key + +The access key can be used to access the openAPI and continuous delivery. Users can obtain the key and access the API by referring to the following steps in the personal center. + +## Get key + +Log in to AI platform, find __Personal Center__ in the drop-down menu in the upper right corner, and you can manage the access key of the account on the __Access Keys__ page. + +![key list](../../images/platform02.png) + +![created a key](../../images/platform03.png) + +!!! info + + Access key is displayed only once. If you forget your access key, + you will need to create a new key. + +## Use the key to access API + +When accessing AI platform openAPI, add the header `Authorization:Bearer ${token}` to the request to identify the visitor, where `${token}` is the key obtained in the previous step. For the specific API, see [OpenAPI Documentation](https://docs.daocloud.io/openapi/). + +**Request Example** + +```bash +curl -X GET -H 'Authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRKVjlBTHRBLXZ4MmtQUC1TQnVGS0dCSWc1cnBfdkxiQVVqM2U3RVByWnMiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjE0MTU5NjksImlhdCI6MTY2MDgxMTE2OSwiaXNzIjoiZ2hpcHBvLmlvIiwic3ViIjoiZjdjOGIxZjUtMTc2MS00NjYwLTg2MWQtOWI3MmI0MzJmNGViIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJncm91cHMiOltdfQ.RsUcrAYkQQ7C6BxMOrdD3qbBRUt0VVxynIGeq4wyIgye6R8Ma4cjxG5CbU1WyiHKpvIKJDJbeFQHro2euQyVde3ygA672ozkwLTnx3Tu-_mB1BubvWCBsDdUjIhCQfT39rk6EQozMjb-1X1sbLwzkfzKMls-oxkjagI_RFrYlTVPwT3Oaw-qOyulRSw7Dxd7jb0vINPq84vmlQIsI3UuTZSNO5BCgHpubcWwBss-Aon_DmYA-Et_-QtmPBA3k8E2hzDSzc7eqK0I68P25r9rwQ3DeKwD1dbRyndqWORRnz8TLEXSiCFXdZT2oiMrcJtO188Ph4eLGut1-4PzKhwgrQ' https://demo-dev.daocloud.io/apis/ghippo.io/v1alpha1/users?page=1&pageSize=10 -k +``` + +**Request result** + +```json +{ + "items": [ + { + "id": "a7cfd010-ebbe-4601-987f-d098d9ef766e", + "name": "a", + "email": "", + "description": "", + "firstname": "", + "lastname": "", + "source": "locale", + "enabled": true, + "createdAt": "1660632794800", + "updatedAt": "0", + "lastLoginAt": "" + } + ], + "pagination": { + "page": 1, + "pageSize": 10, + "total": 1 + } +} +``` diff --git a/docs/en/docs/ghippo/user-guide/personal-center/language.md b/docs/en/docs/ghippo/user-guide/personal-center/language.md new file mode 100644 index 0000000..e4ac00c --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/personal-center/language.md @@ -0,0 +1,31 @@ +--- +hide: + - toc +--- + +# language settings + +This section explains how to set the interface language. Currently supports Chinese, English two languages. + +Language setting is the portal for the platform to provide multilingual services. The platform is displayed in Chinese by default. Users can switch the platform language by selecting English or automatically detecting the browser language preference according to their needs. +Each user's multilingual service is independent of each other, and switching will not affect other users. + +The platform provides three ways to switch languages: Chinese, English-English, and automatically detect your browser language preference. + +The operation steps are as follows. + +1. Log in to the AI platform with your username/password. Click __Global Management__ at the bottom of the left navigation bar. + + + +2. Click the username in the upper right corner and select __Personal Center__ . + + + +3. Click the __Language Settings__ tab. + + + +4. Toggle the language option. + + \ No newline at end of file diff --git a/docs/en/docs/ghippo/user-guide/personal-center/security-setting.md b/docs/en/docs/ghippo/user-guide/personal-center/security-setting.md new file mode 100644 index 0000000..2ba9b40 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/personal-center/security-setting.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# Security Settings + +Function description: It is used to fill in the email address and modify the login password. + +- Email: After the administrator configures the email server address, the user can click the Forget Password button on the login page to fill in the email address there to retrieve the password. +- Password: The password used to log in to the platform, it is recommended to change the password regularly. + +The specific operation steps are as follows: + +1. Click the username in the upper right corner and select __Personal Center__ . + + ![Personal Center](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/lang01.png) + +2. Click the __Security Settings__ tab. Fill in your email address or change the login password. + + ![Security Settings](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/security01.png) diff --git a/docs/en/docs/ghippo/user-guide/personal-center/ssh-key.md b/docs/en/docs/ghippo/user-guide/personal-center/ssh-key.md new file mode 100644 index 0000000..f79fe21 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/personal-center/ssh-key.md @@ -0,0 +1,106 @@ +# Configuring SSH Public Key + +This article explains how to configure SSH public key. + +## Step 1. View Existing SSH Keys + +Before generating a new SSH key, please check if you need to use an existing SSH key stored in the root directory of the local user. +For Linux and Mac, use the following command to view existing public keys. Windows users can use the +following command in WSL (requires Windows 10 or above) or Git Bash to view the generated public keys. + +- **ED25519 Algorithm:** + + ```bash + cat ~/.ssh/id_ed25519.pub + ``` + +- **RSA Algorithm:** + + ```bash + cat ~/.ssh/id_rsa.pub + ``` + +If a long string starting with ssh-ed25519 or ssh-rsa is returned, it means that a local public key already exists. +You can skip [Step 2 Generate SSH Key](#step-2-generate-ssh-key) and proceed directly to [Step 3](#step-3-copy-the-public-key). + +## Step 2. Generate SSH Key + +If [Step 1](#step-1-view-existing-ssh-keys) does not return the specified content string, it means that +there is no available SSH key locally and a new SSH key needs to be generated. Please follow these steps: + +1. Access the terminal (Windows users please use [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) or [Git Bash](https://gitforwindows.org/)), and run `ssh-keygen -t`. + +2. Enter the key algorithm type and an optional comment. + + The comment will appear in the .pub file and can generally use the email address as the comment content. + + - To generate a key pair based on the `ED25519` algorithm, use the following command: + + ```bash + ssh-keygen -t ed25519 -C "" + ``` + + - To generate a key pair based on the `RSA` algorithm, use the following command: + + ```bash + ssh-keygen -t rsa -C "" + ``` + +3. Press Enter to choose the SSH key generation path. + + Taking the ED25519 algorithm as an example, the default path is as follows: + + ```console + Generating public/private ed25519 key pair. + Enter file in which to save the key (/home/user/.ssh/id_ed25519): + ``` + + The default key generation path is `/home/user/.ssh/id_ed25519`, and the corresponding public key is `/home/user/.ssh/id_ed25519.pub`. + +4. Set a passphrase for the key. + + ```console + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + ``` + + The passphrase is empty by default, and you can choose to use a passphrase to protect the private key file. + If you do not want to enter a passphrase every time you access the repository using the SSH protocol, + you can enter an empty passphrase when creating the key. + +5. Press Enter to complete the key pair creation. + +## Step 3. Copy the Public Key + +In addition to manually copying the generated public key information printed on the command line, you can use the following commands to copy the public key to the clipboard, depending on the operating system. + +- Windows (in [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) or [Git Bash](https://gitforwindows.org/)): + + ```bash + cat ~/.ssh/id_ed25519.pub | clip + ``` + +- Mac: + + ```bash + tr -d '\n'< ~/.ssh/id_ed25519.pub | pbcopy + ``` + +- GNU/Linux (requires xclip): + + ```bash + xclip -sel clip < ~/.ssh/id_ed25519.pub + ``` + +## Step 4. Set the Public Key on AI platform Platform + +1. Log in to the AI platform UI page and select **Profile** -> **SSH Public Key** in the upper right corner of the page. + +2. Add the generated SSH public key information. + + 1. SSH public key content. + + 2. Public key title: Supports customizing the public key name for management differentiation. + + 3. Expiration: Set the expiration period for the public key. After it expires, + the public key will be automatically invalidated and cannot be used. If not set, it will be permanently valid. diff --git a/docs/en/docs/ghippo/user-guide/platform-setting/about.md b/docs/en/docs/ghippo/user-guide/platform-setting/about.md new file mode 100644 index 0000000..c9d2f98 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/platform-setting/about.md @@ -0,0 +1,26 @@ +--- +hide: + - toc +--- + +# About + +The __About__ page primarily showcases the latest versions of each module, highlights the open source software used, and expresses gratitude to the technical team via an animated video. + +Steps to view are as follows: + +1. Log in to AI platform as a user with __Admin__ role. Click __Global Management__ at the bottom of the left navigation bar. + + ![about](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/about01.png) + +2. Click __Settings__ , select __About__ , and check the product version, open source software statement, and development teams. + + ![product](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/about02.png) + + **License Statement** + + ![license](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/about03.png) + + **Technical Team** + + ![team](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/about04.png) diff --git a/docs/en/docs/ghippo/user-guide/platform-setting/appearance.md b/docs/en/docs/ghippo/user-guide/platform-setting/appearance.md new file mode 100644 index 0000000..b42b7a4 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/platform-setting/appearance.md @@ -0,0 +1,108 @@ +--- +hide: + - toc +--- + +# Customize Appearance + +In AI platform, you have the option to customize the appearance of the login page, top navigation bar, bottom copyright and ICP registration to enhance your product recognition. + +## Customizing Login Page and Top Navigation Bar + +1. To get started, log in to AI platform as a user with the __admin__ role and navigate to __Global Management__ -> __Settings__ found at the bottom of the left navigation bar. + + ![settings](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/appear01.png) + +2. Select __Appearance__ . On the __Custom your login page__ tab, modify the icon and text of the login page as needed, then click __Save__ . + + ![login](../../images/logindesign.png) + +3. Log out and refresh the login page to see the configured effect. + + ![nav](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/appear03.png) + +4. On the __Advanced customization__ tab, you can modify login page, navigation bar, copyright, and ICP registration with css. + + ![advanced](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/appear05.png) + +!!! note + + If you wish to restore the default settings, simply click __Revert__ . This action will discard all customized settings. + +## Advanced Customization + +Advanced customization allows you to modify the color, font spacing, and font size of the entire container platform using CSS styles. Please note that familiarity with CSS syntax is required. + +To reset any advanced customizations, delete the contents of the black input box or click the __Revert__ button. + +**Sample CSS for Login Page Customization:** + +```css +.test { + width: 12px; +} + +#kc-login { + /* color: red!important; */ +} +``` + +**CSS sample for page customization after login:** + +```css +.dao-icon.dao-iconfont.icon-service-global.dao-nav__head-icon { + color: red!important; +} +.ghippo-header-logo { + background-color: green!important; +} +.ghippo-header { + background-color: rgb(128, 115, 0)!important; +} +.ghippo-header-nav-main { + background-color: rgb(0, 19, 128)!important; +} +.ghippo-header-sub-nav-main .dao-popper-inner { + background-color: rgb(231, 82, 13) !important; +} +``` + +**CSS sample for custom footer (including copyright, filing, and other information at the bottom)** + +```css + + + +``` diff --git a/docs/en/docs/ghippo/user-guide/platform-setting/mail-server.md b/docs/en/docs/ghippo/user-guide/platform-setting/mail-server.md new file mode 100644 index 0000000..23eec99 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/platform-setting/mail-server.md @@ -0,0 +1,46 @@ +--- +hide: + - toc +--- + +# Mail Server + +AI platform will send an e-mail to the user to verify the e-mail address if the user forgets the password to ensure that the user is acting in person. +In order for AI platform to be able to send email, you need to provide your mail server address first. + +The specific operation steps are as follows: + +1. Log in to AI platform as a user with __admin__ role. Click __Global Management__ at the bottom of the left navigation bar. + + + +1. Click __Settings__ , select __Mail Server Settings__ . + + + + Complete the following fields to configure the mail server: + + | Field | Description | Example | + | ----- | ----------- | ------------ | + | SMTP server address | SMTP server address that can provide mail service | smtp.163.com | + | SMTP server port | Port for sending mail | 25 | + | Username | Name of the SMTP user | test@163.com | + | Password | Password for the SMTP account | 123456 | + | Sender's email address | Sender's email address | test@163.com | + | Use SSL secure connection | SSL can be used to encrypt emails, thereby improving the security of information transmitted via emails, usually need to configure a certificate for the mail server | Disable | + +1. After the configuration is complete, click __Save__ , and click __Test Mail Server__ . + + + +1. A message indicating that the mail has been successfully sent appears in the upper right corner of the screen, indicating that the mail server has been successfully set up. + + + +## Common problem + +Q: What is the reason why the user still cannot retrieve the password after the mail server is set up? + +Answer: The user may not have an email address or set a wrong email address; at this time, users with the admin role can find the user by username in __Global Management__ -> __Access Control__ , and set it as The user sets a new login password. + +If the mail server is not connected, please check whether the mail server address, username and password are correct. \ No newline at end of file diff --git a/docs/en/docs/ghippo/user-guide/platform-setting/security.md b/docs/en/docs/ghippo/user-guide/platform-setting/security.md new file mode 100644 index 0000000..4788553 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/platform-setting/security.md @@ -0,0 +1,22 @@ +# Security Policy + +AI platform offers robust security measures, including password policies and access control for the graphical interface. + +## Password Policy + +- New passwords must differ from the most recent historical password. +- Users are required to change their passwords upon expiration. +- Passwords must not match the username. +- Passwords cannot be the same as the user's email address. +- Customizable password rules. +- Customizable minimum password length. + +## Access Control Policy + +- **Session Timeout Policy**: Users will be automatically logged out after a period of inactivity lasting x hours. +- **Account Lockout Policy**: Accounts will be locked after multiple failed login attempts within a specified time frame. +- **Login/Logout Policy**: Users will be logged out when closing the browser. + +To configure the password and access control policies, navigate to global management, then click **Settings** -> **Security Policy** in the left navigation bar. + +![Security Policy](../../images/security-policy.png) diff --git a/docs/en/docs/ghippo/user-guide/report-billing/billing.md b/docs/en/docs/ghippo/user-guide/report-billing/billing.md new file mode 100644 index 0000000..81dfd41 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/report-billing/billing.md @@ -0,0 +1,57 @@ +--- +MTPE: windsonsea +Date: 2024-07-29 +hide: + - toc +--- + +# Accounting & Billing + +Accounting and billing further process the usage data of resources based on reports. +You can manually set the unit price and currency unit for CPU, memory, GPU and storage. +After setting, the system will automatically calculate the expenses of clusters, nodes, pods, +namespaces, and workspaces over a period. You can adjust the period freely and export +billing reports in Excel or Csv format after filtering by week, month, quarter, or year. + +## Billing Rules and Effective Time + +- Billing Rules: Default billing is based on the maximum value of request and usage. +- Effective Time: Effective the next day, the fees incurred on that day are calculated + based on the unit price and quantity obtained at midnight the next day. + +## Features + +- Support customizing the billing unit for CPU, memory, storage and GPU, as well as the currency unit. +- Support custom querying of billing data within a year, automatically calculating the + billing situation for the selected time period. +- Support exporting billing reports in CSV and Excel formats. +- Support enabling/disabling individual billing reports. After enabling/disabling, the platform will + start/stop collecting data within 20 minutes, and past collected data will still be displayed normally. +- Support selective display of billing data for CPU, total memory, storage, GPU and total. + +## Report Dimensions + +Currently, the following reports are supported: + +- Cluster Billing Report: Displays the CPU billing, memory billing, storage billing, GPU billing and overall + billing situation for all clusters within a certain period, as well as the number of nodes in + that cluster. By clicking the number of nodes, you can quickly enter the node billing report and view the billing situation of nodes in that cluster during that time period. +- Node Billing Report: Displays the CPU billing, memory billing, storage billing, GPU billing and overall billing situation for all nodes within a certain period, as well as the IP, type, and belonging cluster of nodes. +- Pod Report: Displays the CPU billing, memory billing, storage billing, GPU billing and overall billing situation for all pods within a certain period, as well as the namespace, cluster, and workspace to which the pod belongs. +- Workspace Billing Report: Displays the CPU billing, memory billing, storage billing, GPU billing and overall + billing situation for all workspaces within a certain period, as well as the number of namespaces + and pods. By clicking the number of namespaces, you can quickly enter the namespace billing report + and view the billing situation of namespaces in that workspace during that time period; the same + method can be used to view the billing situation of pods in that workspace during that time period. +- Namespace Billing Report: Displays the CPU billing, memory billing, storage billing, GPU billing and overall + billing situation for all namespaces within a certain period, as well as the number of pods, + the belonging cluster, and workspace. By clicking the number of pods, you can quickly enter + the pod billing report and view the billing situation of pods in that namespace during that time period. + +## Operating Steps + +1. Log in to AI platform as a user with the __admin__ role. Click __Global Management__ -> __Operations Management__ at the bottom of the left navigation bar. + + ![Report Management](../../images/gmagpiereport.png) + +2. After entering the **Operations Management** , switch to different menus to view billing reports for clusters, nodes, and pods. diff --git a/docs/en/docs/ghippo/user-guide/report-billing/index.md b/docs/en/docs/ghippo/user-guide/report-billing/index.md new file mode 100644 index 0000000..e46abad --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/report-billing/index.md @@ -0,0 +1,37 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-18 +hide: + - toc +--- + +# Operation Management + +Operation Management provides a visual representation of the total usage and utilization rates of CPU, +memory, storage and GPU across various dimensions such as cluster, node, namespace, pod, and workspace +within a specified time range on the platform. It also automatically calculates platform consumption +information based on usage, usage time, and unit price. By default, the module enables all report statistics, +but platform administrators can manually enable or disable individual reports. After enabling or disabling, +the platform will start or stop collecting report data within a maximum of 20 minutes. Previously collected +data will still be displayed normally. Operation Management data can be retained on the platform for up to +365 days. Statistical data exceeding this retention period will be automatically deleted. You can also download +reports in CSV or Excel format for further statistics and analysis. + +Operation Management is available only for the Standard Edition and above. It is not supported in the Community Edition. + +You need to [install or upgrade the Operations Management module](./gmagpie-offline-install.md) first, and then you can experience report management and billing metering. + +## Report Management + +Report Management provides data statistics for cluster, node, pods, workspace, and namespace across +five dimensions: CPU Utilization, Memory Utilization, Storage Utilization, GPU Computing Power Utilization, +and GPU Memory Utilization. It also integrates with the audit and alert modules to support the statistical +management of audit and alert data, supporting a total of seven types of reports. + +## Accounting & Billing + +Accounting & Billing provides billing statistics for clusters, nodes, pods, namespaces, and workspaces +on the platform. It calculates the consumption for each resource during the statistical period based on +the usage of CPU, memory, storage and GPU, as well as user-configured prices and currency units. Depending +on the selected time span, such as monthly, quarterly, or annually, it can quickly calculate the actual +consumption for that period. diff --git a/docs/en/docs/ghippo/user-guide/report-billing/report.md b/docs/en/docs/ghippo/user-guide/report-billing/report.md new file mode 100644 index 0000000..e2be37e --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/report-billing/report.md @@ -0,0 +1,43 @@ +--- +MTPE: windsonsea +Date: 2024-04-23 +hide: + - toc +--- + +# Report Management + +Report management visually displays statistical data across clusters, nodes, pods, workspaces, namespaces, audits, and alarms. This data provides a reliable foundation for platform billing and utilization optimization. + +## Features + +- Supports custom queries for statistical data within a year +- Allows exporting reports in CSV and Excel formats +- Supports enabling/disabling individual reports; once toggled, the platform will start/stop data collection within 20 minutes, but previously collected data will still be displayed. +- Displays maximum, minimum, and average values for CPU utilization, memory utilization, storage utilization, and GPU memory utilization + +## Report Dimensions + +Currently, the following reports are supported: + +- **Cluster Report**: Displays the maximum, minimum, and average values of CPU utilization, memory utilization, storage utilization, and GPU memory utilization for all clusters during a specific time period, as well as the number of nodes under the cluster. + You can quickly access the node report by clicking on the node count and view the utilization of nodes under the cluster during that period. +- **Node Report**: Displays the maximum, minimum, and average values of CPU utilization, memory utilization, storage utilization, and GPU memory utilization for all nodes during a specific time period, along with the node's IP, type, and affiliated cluster. +- **Pod Report**: Shows the maximum, minimum, and average values of CPU utilization, memory utilization, storage utilization, and GPU memory utilization for all pods during a specific time period, as well as the pod's namespace, affiliated cluster, and workspace. +- **Workspace Report**: Displays the maximum, minimum, and average values of CPU utilization, memory utilization, storage utilization, and GPU memory utilization for all workspaces during a specific time period, along with the number of namespaces and pods. + You can quickly access the namespace report by clicking on the namespace count and view the utilization of namespaces under the workspace during that period; similarly, you can view the utilization of pods under the workspace. +- **Namespace Report**: Displays the maximum, minimum, and average values of CPU utilization, memory utilization, storage utilization, and GPU memory utilization for all namespaces during a specific time period, as well as the number of pods, affiliated clusters, and workspaces. + You can quickly access the pod report by clicking on the pod count and view the utilization of pods within the namespace during that period. +- **Audit Report**: Divided into user actions and resource operations. The user action report mainly counts the number of operations by a single user during a period, including successful and failed attempts; + The resource operation report mainly counts the number of operations on a type of resource by all users. +- **Alarm Report**: Displays the number of alarms for all nodes during a specific period, including the occurrences of fatal, severe, and warning alarms. + +## Steps + +1. Log in to AI platform as a user with the __Admin__ role. Click __Global Management__ -> __Operations Management__ at the bottom of the left sidebar. + + ![Report Management](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/images/gmagpiereport.png) + +2. After entering Operations Management, switch between different menus to view reports on clusters, nodes, and pods. + + ![Report](../../images/report01.png) diff --git a/docs/en/docs/ghippo/user-guide/workspace/folder-permission.md b/docs/en/docs/ghippo/user-guide/workspace/folder-permission.md new file mode 100644 index 0000000..882e8fc --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/folder-permission.md @@ -0,0 +1,39 @@ +# Description of folder permissions + +Folders have permission mapping capabilities, which can map the permissions of users/groups in this folder to subfolders, workspaces and resources under it. + +If the user/group is Folder Admin role in this folder, it is still Folder Admin role when mapped to a subfolder, and Workspace Admin is mapped to the workspace under it; +If a Namespace is bound in __Workspace and Folder__ -> __Resource Group__ , the user/group is also a Namespace Admin after mapping. + +!!! note + + The permission mapping capability of folders will not be applied to shared resources, because sharing is to share the use permissions of the cluster to multiple workspaces, rather than assigning management permissions to workspaces, so permission inheritance and role mapping will not be implemented. + +## Use cases + +Folders have hierarchical capabilities, so when folders are mapped to departments/suppliers/projects in the enterprise, + +- If a user/group has administrative authority (Admin) in the first-level department, the second-level, third-level, and fourth-level departments or projects under it also have administrative authority; +- If a user/group has access rights (Editor) in the first-level department, the second-, third-, and fourth-level departments or projects under it also have access rights; +- If a user/group has read-only permission (Viewer) in the first-level department, the second-level, third-level, and fourth-level departments or projects under it also have read-only permission. + +| Objects | Actions | Folder Admin | Folder Editor | Folder Viewer | +| --------------------------- | -------- | ------------ | ------------- | ------------- | +| on the folder itself | view | ✓ | ✓ | ✓ | +| | Authorization | ✓ | ✗ | ✗ | +| | Modify Alias ​​| ✓ | ✗ | ✗ | +| To Subfolder | Create | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | +| | Authorization | ✓ | ✗ | ✗ | +| | Modify Alias ​​| ✓ | ✗ | ✗ | +| workspace under it | create | ✓ | ✗ | ✗ | +| | View | ✓ | ✓ | ✓ | +| | Authorization | ✓ | ✗ | ✗ | +| | Modify Alias ​​| ✓ | ✗ | ✗ | +| Workspace under it - Resource Group | View | ✓ | ✓ | ✓ | +| | resource binding | ✓ | ✗ | ✗ | +| | unbind | ✓ | ✗ | ✗ | +| Workspaces under it - Shared Resources | View | ✓ | ✓ | ✓ | +| | New share | ✓ | ✗ | ✗ | +| | Unshare | ✓ | ✗ | ✗ | +| | Resource Quota | ✓ | ✗ | ✗ | \ No newline at end of file diff --git a/docs/en/docs/ghippo/user-guide/workspace/folders.md b/docs/en/docs/ghippo/user-guide/workspace/folders.md new file mode 100644 index 0000000..bbcbc0e --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/folders.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# Create/Delete Folders + +Folders have the capability to map permissions, allowing users/user groups to have their permissions in the folder mapped to its sub-folders, workspaces, and resources. + +Follow the steps below to create a folder: + +1. Log in to AI platform with a user account having the admin/folder admin role. + Click __Global Management__ -> __Workspace and Folder__ at the bottom of the left navigation bar. + + ![Global Management](../images/ws01.png) + +2. Click the __Create Folder__ button in the top right corner. + + ![Create Folder](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/user-guide/images/ws02.png) + +3. Fill in the folder name, parent folder, and other information, then click __OK__ to complete creating the folder. + + ![Confirm](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/fd03.png) + +!!! tip + + After successful creation, the folder name will be displayed in the left tree structure, represented by different icons for workspaces and folders. + + ![Workspaces and Folders](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/fd04.png) + +!!! note + + To edit or delete a specific folder, select it and Click __┇__ on the right side. + + - If there are resources bound to the resource group or shared resources within the folder, the folder cannot be deleted. All resources need to be unbound before deleting. + + - If there are registry resources accessed by the microservice engine module within the folder, the folder cannot be deleted. All access to the registry needs to be removed before deleting the folder. diff --git a/docs/en/docs/ghippo/user-guide/workspace/quota.md b/docs/en/docs/ghippo/user-guide/workspace/quota.md new file mode 100644 index 0000000..90c3281 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/quota.md @@ -0,0 +1,119 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-02 +--- + +# Resource Quota + +Shared resources do not necessarily mean that the shared users can use the shared resources without +any restrictions. Admin, Kpanda Owner, and Workspace Admin can limit the maximum usage quota of a user +through the __Resource Quota__ feature in shared resources. If no restrictions are set, it means the +usage is unlimited. + +- CPU Request (Core) +- CPU Limit (Core) +- Memory Request (MB) +- Memory Limit (MB) +- Total Storage Request (GB) +- Persistent Volume Claims (PVC) +- GPU Type, Spec, Quantity (including but not limited to Nvidia, Ascend, ILLUVATAR, and other GPUs) + +A resource (cluster) can be shared among multiple workspaces, and a workspace can use resources from +multiple shared clusters simultaneously. + +## Resource Groups and Shared Resources + +Cluster resources in both shared resources and resource groups are derived from [Container Management](../../../kpanda/intro/index.md). However, different effects will occur when binding a cluster to a workspace or sharing it with a workspace. + +1. Binding Resources + + Users/User groups in the workspace will have full management and usage permissions for the cluster. + Workspace Admin will be mapped as Cluster Admin. + Workspace Admin can access the [Container Management module](../../../kpanda/user-guide/permissions/permission-brief.md) + to manage the cluster. + + ![Resource Group](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota01.png) + + !!! note + + As of now, there are no Cluster Editor and Cluster Viewer roles in the Container Management module. + Therefore, Workspace Editor and Workspace Viewer cannot be mapped. + +2. Adding Shared Resources + + Users/User groups in the workspace will have usage permissions for the cluster resources, which can be + + used when [creating namespaces](../../../amamba/user-guide/namespace/namespace.md). + + ![Shared Resources](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota02.png) + + Unlike resource groups, when sharing a cluster with a workspace, the roles of the users in the workspace + will not be mapped to the resources. Therefore, Workspace Admin will not be mapped as Cluster Admin. + +This section demonstrates three scenarios related to resource quotas. + +## Create Namespaces + +Creating a namespace involves resource quotas. + +1. Add a shared cluster to workspace __ws01__ . + + ![Add Shared Cluster](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota03.png) + +2. Select workspace __ws01__ and the shared cluster in Workbench, and create a namespace __ns01__ . + + ![Create Namespace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota04.png) + + - If no resource quotas are set in the shared cluster, there is no need to set resource quotas when creating + the namespace. + - If resource quotas are set in the shared cluster (e.g., CPU Request = 100 cores), the CPU request for the + namespace must be less than or equal to 100 cores (__CPU Request ≤ 100 core__) for successful creation. + +## Bind Namespace to Workspace + +Prerequisite: Workspace ws01 has added a shared cluster, and the operator has the Workspace Admin + Kpanda Owner +or Admin role. + +The two methods of binding have the same effect. + +- Bind the created namespace ns01 to ws01 in Container Management. + + ![Bind to Workspace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota05.png) + + - If no resource quotas are set in the shared cluster, the namespace ns01 can be successfully bound regardless + of whether resource quotas are set. + - If resource quotas are set in the shared cluster (e.g., CPU Request = 100 cores), the namespace ns01 + must meet the requirement of CPU requests less than or equal to 100 cores (__CPU Request ≤ 100 core__) + for successful binding. + +- Bind the namespace ns01 to ws01 in Global Management. + + ![Bind to Workspace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota06.png) + + - If no resource quotas are set in the shared cluster, the namespace ns01 can be successfully bound + regardless of whether resource quotas are set. + - If resource quotas are set in the shared cluster (e.g., CPU Request = 100 cores), the namespace ns01 + must meet the requirement of CPU requests less than or equal to 100 cores (__CPU Request ≤ 100 core__) + for successful binding. + +## Unbind Namespace from Workspace + +The two methods of unbinding have the same effect. + +- Unbind the namespace ns01 from workspace ws01 in Container Management. + + ![Bind to Workspace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota07.png) + + - If no resource quotas are set in the shared cluster, unbinding the namespace ns01 will not affect the + resource quotas, regardless of whether resource quotas were set for the namespace. + - If resource quotas (__CPU Request = 100 cores__) are set in the shared cluster and the namespace ns01 + has its own resource quotas, unbinding will release the corresponding resource quota. + +- Unbind the namespace ns01 from workspace ws01 in Global Management. + + ![Bind to Workspace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/quota08.png) + + - If no resource quotas are set in the shared cluster, unbinding the namespace ns01 will not affect the + resource quotas, regardless of whether resource quotas were set for the namespace. + - If resource quotas (__CPU Request = 100 cores__) are set in the shared cluster and the namespace ns01 + has its own resource quotas, unbinding will release the corresponding resource quota. diff --git a/docs/en/docs/ghippo/user-guide/workspace/res-gp-and-shared-res.md b/docs/en/docs/ghippo/user-guide/workspace/res-gp-and-shared-res.md new file mode 100644 index 0000000..2fc9052 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/res-gp-and-shared-res.md @@ -0,0 +1,28 @@ +# Differences between Resource Groups and Shared Resources + +Both resource groups and shared resources support cluster binding, but they have significant differences in usage. + +## Differences in Usage Scenarios + +- Cluster Binding for Resource Groups: Resource groups are usually used for batch authorization. After binding a resource group to a cluster, + the workspace administrator will be mapped as a cluster administrator and able to manage and use cluster resources. +- Cluster Binding for Shared Resources: Shared resources are usually used for resource quotas. A typical scenario is that the platform administrator assigns a cluster to a first-level supplier, who then assigns the cluster to a second-level supplier and sets resource quotas for the second-level supplier. + +![diff](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/res-gp01.png) + +Note: In this scenario, the platform administrator needs to impose resource restrictions on secondary suppliers. +Currently, it is not supported to limit the cluster quota of secondary suppliers by the primary supplier. + +## Differences in Cluster Quota Usage + +- Cluster Binding for Resource Groups: The workspace administrator is mapped as the administrator of the cluster and is equivalent to being granted the Cluster Admin role in Container Management-Permission Management. They can have unrestricted access to cluster resources, manage important content such as management nodes, and cannot be subject to resource quotas. +- Cluster Binding for Shared Resources: The workspace administrator can only use the quota in the cluster to create namespaces in the Workbench and does not have cluster management permissions. If the workspace is restricted by a quota, the workspace administrator can only create and use namespaces within the quota range. + +## Differences in Resource Types + +- Resource Groups: Can bind to clusters, cluster-namespaces, multiclouds, multicloud namespaces, meshs, and mesh-namespaces. +- Shared Resources: Can only bind to clusters. + +## Similarities between Resource Groups and Shared Resources + +After binding to a cluster, both resource groups and shared resources can go to the Workbench to create namespaces, which will be automatically bound to the workspace. diff --git a/docs/en/docs/ghippo/user-guide/workspace/workspace.md b/docs/en/docs/ghippo/user-guide/workspace/workspace.md new file mode 100644 index 0000000..4b8b01a --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/workspace.md @@ -0,0 +1,42 @@ +--- +hide: + - toc +--- + +# Creating/Deleting Workspaces + +A workspace is a resource category that represents a hierarchical relationship of resources. +A workspace can contain resources such as clusters, namespaces, and registries. Typically, +each workspace corresponds to a project and different resources can be allocated, and +different users and user groups can be assigned to each workspace. + +Follow the steps below to create a workspace: + +1. Log in to AI platform with a user account having the admin/folder admin role. + Click __Global Management__ -> __Workspace and Folder__ at the bottom of the left navigation bar. + + ![Global Management](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/ws01.png) + +3. Click the __Create Workspace__ button in the top right corner. + + ![Create Workspace](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/ws02.png) + +4. Fill in the workspace name, folder assignment, and other information, then click __OK__ to complete creating the workspace. + + ![Confirm](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/ws03.png) + +!!! tip + + After successful creation, the workspace name will be displayed in the left tree structure, represented by different icons for folders and workspaces. + + ![Folders and Workspaces](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/ws04.png) + +!!! note + + To edit or delete a specific workspace or folder, select it and click __...__ on the right side. + + - If resource groups and shared resources have resources under the workspace, the workspace cannot be deleted. All resources need to be unbound before deletion of the workspace. + + - If Microservices Engine has Integrated Registry under the workspace, the workspace cannot be deleted. Integrated Registry needs to be removed before deletion of the workspace. + + - If Container Registry has Registry Space or Integrated Registry under the workspace, the workspace cannot be deleted. Registry Space needs to be removed, and Integrated Registry needs to be deleted before deletion of the workspace. diff --git a/docs/en/docs/ghippo/user-guide/workspace/ws-folder.md b/docs/en/docs/ghippo/user-guide/workspace/ws-folder.md new file mode 100644 index 0000000..fe14939 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/ws-folder.md @@ -0,0 +1,65 @@ +--- +hide: + - toc +--- + +# Workspace and Folder + +Workspace and Folder is a feature that provides resource isolation and grouping, addressing issues +related to unified authorization, resource grouping, and resource quotas. + +Workspace and Folder involves two concepts: workspaces and folders. + +## Workspaces + +Workspaces allow the management of resources through __Authorization__ , __Resource Group__ , and __Shared Resource__ , +enabling users (and user groups) to share resources within the workspace. + +![Workspaces](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/ghippo/images/wsfd01.png) + +- Resources + + Resources are at the lowest level of the hierarchy in the resource management module. They include clusters, namespaces, pipelines, gateways, and more. All these resources can only have workspaces as their parent level. Workspaces act as containers for grouping resources. + +- Workspace + + A workspace usually refers to a project or environment, and the resources in each workspace are logically isolated from those in other workspaces. + You can grant users (groups of users) different access rights to the same set of resources through authorization in the workspace. + + Workspaces are at the first level, counting from the bottom of the hierarchy, and contain resources. + All resources except shared resources have one and only one parent. All workspaces also have one and only one parent folder. + + Resources are grouped by workspace, and there are two grouping modes in workspace, namely __Resource Group__ and __Shared Resource__ . + +- Resource group + + A resource can only be added to one resource group, and resource groups correspond to workspaces one by one. + After a resource is added to a resource group, Workspace Admin will obtain the management authority of the resource, which is equivalent to the owner of the resource. + +- Share resource + + For shared resources, multiple workspaces can share one or more resources. + Resource owners can choose to share their own resources with the workspace. Generally, when sharing, the resource owner will limit the amount of resources that can be used by the shared workspace. + After resources are shared, Workspace Admin only has resource usage rights under the resource limit, and cannot manage resources or adjust the amount of resources that can be used by the workspace. + + At the same time, shared resources also have certain requirements for the resources themselves. Only Cluster (cluster) resources can be shared. + Cluster Admin can share Cluster resources to different workspaces, and limit the use of workspaces on this Cluster. + + Workspace Admin can create multiple Namespaces within the resource quota, but the sum of the resource quotas of the Namespaces cannot exceed the resource quota of the Cluster in the workspace. + For Kubernetes resources, the only resource type that can be shared currently is Cluster. + +## Folder + +Folders can be used to build enterprise business hierarchy relationships. + +- Folders are a further grouping mechanism based on workspaces and have a hierarchical structure. + A folder can contain workspaces, other folders, or a combination of both, forming a tree-like organizational relationship. + +- Folders allow you to map your business hierarchy and group workspaces by department. + Folders are not directly linked to resources, but indirectly achieve resource grouping through workspaces. + +- A folder has one and only one parent folder, and the root folder is the highest level of the hierarchy. + The root folder has no parent, and folders and workspaces are attached to the root folder. + +In addition, users (groups) in folders can inherit permissions from their parents through a hierarchical structure. +The permissions of the user in the hierarchical structure come from the combination of the permissions of the current level and the permissions inherited from its parents. The permissions are additive and there is no mutual exclusion. diff --git a/docs/en/docs/ghippo/user-guide/workspace/ws-permission.md b/docs/en/docs/ghippo/user-guide/workspace/ws-permission.md new file mode 100644 index 0000000..1bc938e --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/ws-permission.md @@ -0,0 +1,54 @@ +# Description of workspace permissions + +The workspace has permission mapping and resource isolation capabilities, and can map the permissions of users/groups in the workspace to the resources under it. +If the user/group has the Workspace Admin role in the workspace and the resource Namespace is bound to the workspace-resource group, the user/group will become Namespace Admin after mapping. + +!!! note + + The permission mapping capability of the workspace will not be applied to shared resources, because sharing is to share the cluster usage permissions to multiple workspaces, rather than assigning management permissions to the workspaces, so permission inheritance and role mapping will not be implemented. + +## Use cases + +Resource isolation is achieved by binding resources to different workspaces. Therefore, resources can be flexibly allocated to each workspace (tenant) with the help of permission mapping, resource isolation, and resource sharing capabilities. + +Generally applicable to the following two use cases: + +- Cluster one-to-one + + | Ordinary Cluster | Department/Tenant (Workspace) | Purpose | + | -------- | ---------------- | -------- | + | Cluster 01 | A | Administration and Usage | + | Cluster 02 | B | Administration and Usage | + +- Cluster one-to-many + + | Cluster | Department/Tenant (Workspace) | Resource Quota | + | ------- | ---------------- | ---------- | + | Cluster 01 | A | 100 core CPU | + | | B | 50-core CPU | + +## Permission description + +| Action Objects | Operations | Workspace Admin | Workspace Editor | Workspace Viewer | +| :------- | :---------------- | :-------------- | :-------------- | :--------------- | +| itself | view | ✓ | ✓ | ✓ | +| - | Authorization | ✓ | ✗ | ✗ | +| - | Modify Alias | ✓ | ✓ | ✗ | +| Resource Group | View | ✓ | ✓ | ✓ | +| - | resource binding | ✓ | ✗ | ✗ | +| - | unbind | ✓ | ✗ | ✗ | +| Shared Resources | View | ✓ | ✓ | ✓ | +| - | Add Share | ✓ | ✗ | ✗ | +| - | Unshare | ✓ | ✗ | ✗ | +| - | Resource Quota | ✓ | ✗ | ✗ | +| - | Using Shared Resources [^1] | ✓ | ✗ | ✗ | + +[^1]: + Authorized users can go to modules such as workbench, microservice engine, middleware, multicloud orchestration, and service mesh to use resources in the workspace. + For the operation scope of the roles of Workspace Admin, Workspace Editor, and Workspace Viewer in each module, please refer to the permission description: + + - [Workbench Permissions](../../permissions/amamba.md) + - [Service Mesh Permissions](../../permissions/mspider.md) + - [Middleware permissions](../../permissions/mcamel.md) + - [Microservice Engine Permissions](../../permissions/skoala.md) + - [Container Management Permissions](../../../kpanda/user-guide/permissions/permission-brief.md) \ No newline at end of file diff --git a/docs/en/docs/ghippo/user-guide/workspace/wsbind-permission.md b/docs/en/docs/ghippo/user-guide/workspace/wsbind-permission.md new file mode 100644 index 0000000..9b28ad7 --- /dev/null +++ b/docs/en/docs/ghippo/user-guide/workspace/wsbind-permission.md @@ -0,0 +1,41 @@ +--- +MTPE: WANG0608GitHub +date: 2024-07-16 +--- + +# Resource Binding Permission Instructions + +If a user John ("John" represents any user who is required to bind resources) has +the [Workspace Admin role](../access-control/role.md#workspace-role-authorization-methods) assigned or has been granted proper permissions through a [custom role](../access-control/custom-role.md), +which includes the [Workspace's "Resource Binding" Permissions](./ws-permission.md#description-of-workspace-permissions), and wants to bind a specific cluster or namespace to the workspace. + +To bind cluster/namespace resources to a workspace, not only the [workspace's "Resource Binding" permissions](./ws-permission.md#description-of-workspace-permissions) are required, +but also the permissions of [Cluster Admin](../../../kpanda/user-guide/permissions/permission-brief.md#cluster-admin). + +## Granting Authorization to John + +1. Using the [Platform Admin Role](../access-control/role.md#workspace-role-authorization-methods), + grant John the role of Workspace Admin on the **Workspace** -> **Authorization** page. + + ![Resource Binding](../../images/wsbind1.png) + +1. Then, on the **Container Management** -> **Permissions** page, authorize John as a Cluster Admin by **Add Permission**. + + ![Cluster Permissions1](../../images/wsbind2.png) + + ![Cluster Permissions2](../../images/wsbind3.png) + +## Binding to Workspace + +Using John's account to log in to AI platform, on the **Container Management** -> **Clusters** page, + John can bind the specified cluster to his own workspace by using the **Bind Workspace** button. + +!!! note + + John can only bind clusters or namespaces to a specific workspace in the [Container Management module](../../../kpanda/intro/index.md), and cannot perform this operation in the Global Management module. + +![cluster banding](../../images/wsbind4.png) + +To bind a namespace to a workspace, you must have at least Workspace Admin and Cluster Admin permissions. + +![cluster banding](../../images/wsbind5.png) \ No newline at end of file diff --git a/docs/en/docs/images/DaoCloud.png b/docs/en/docs/images/DaoCloud.png new file mode 100644 index 0000000..7c129ba Binary files /dev/null and b/docs/en/docs/images/DaoCloud.png differ diff --git a/docs/en/docs/images/DaoCloud.svg b/docs/en/docs/images/DaoCloud.svg new file mode 100644 index 0000000..ba3bf85 --- /dev/null +++ b/docs/en/docs/images/DaoCloud.svg @@ -0,0 +1,21 @@ + + + + +Icon / Brand 20*20 / Suanova + + + + + + + + + + + + diff --git a/docs/en/docs/images/favicon.ico b/docs/en/docs/images/favicon.ico new file mode 100644 index 0000000..5642350 Binary files /dev/null and b/docs/en/docs/images/favicon.ico differ diff --git a/docs/en/docs/images/regis01.png b/docs/en/docs/images/regis01.png new file mode 100644 index 0000000..6e188a8 Binary files /dev/null and b/docs/en/docs/images/regis01.png differ diff --git a/docs/en/docs/images/regis02.png b/docs/en/docs/images/regis02.png new file mode 100644 index 0000000..b9cb180 Binary files /dev/null and b/docs/en/docs/images/regis02.png differ diff --git a/docs/en/docs/images/regis05.png b/docs/en/docs/images/regis05.png new file mode 100644 index 0000000..f6bb14f Binary files /dev/null and b/docs/en/docs/images/regis05.png differ diff --git a/docs/en/docs/images/suanova.png b/docs/en/docs/images/suanova.png new file mode 100644 index 0000000..cbe6548 Binary files /dev/null and b/docs/en/docs/images/suanova.png differ diff --git a/docs/en/docs/index.md b/docs/en/docs/index.md new file mode 100644 index 0000000..f1fbe60 --- /dev/null +++ b/docs/en/docs/index.md @@ -0,0 +1,27 @@ +# User Registration + +New users need to register to use the AI platform for the first time. + +## Prerequisites + +1. The AI platform is installed. +2. Email registration feature is enabled. +3. A valid email address is available. + +## Email Registration Steps + +1. Open the homepage of the AI platform and click **Register**. + + ![home](./images/regis01.PNG) + +2. Enter your username, password, and email, then click **Register**. + + ![to register](./images/regis02.PNG) + +3. The system will prompt that an email has been sent to your inbox. + +4. Log into your email account, find the email, and click the link. + +5. Congratulations, you have successfully logged in the AI platform, and you can now begin your AI journey. + + ![verify](./images/regis05.PNG) diff --git a/docs/en/docs/insight/image/big-log01.png b/docs/en/docs/insight/image/big-log01.png new file mode 100644 index 0000000..b178b19 Binary files /dev/null and b/docs/en/docs/insight/image/big-log01.png differ diff --git a/docs/en/docs/insight/image/big-log02.png b/docs/en/docs/insight/image/big-log02.png new file mode 100644 index 0000000..a28c76a Binary files /dev/null and b/docs/en/docs/insight/image/big-log02.png differ diff --git a/docs/en/docs/insight/image/big-log03.png b/docs/en/docs/insight/image/big-log03.png new file mode 100644 index 0000000..f6616d8 Binary files /dev/null and b/docs/en/docs/insight/image/big-log03.png differ diff --git a/docs/en/docs/insight/image/big-log04.png b/docs/en/docs/insight/image/big-log04.png new file mode 100644 index 0000000..bac3d72 Binary files /dev/null and b/docs/en/docs/insight/image/big-log04.png differ diff --git a/docs/en/docs/insight/image/cluster.png b/docs/en/docs/insight/image/cluster.png new file mode 100644 index 0000000..565754c Binary files /dev/null and b/docs/en/docs/insight/image/cluster.png differ diff --git a/docs/en/docs/insight/image/inhibition-01.png b/docs/en/docs/insight/image/inhibition-01.png new file mode 100644 index 0000000..53f0ba8 Binary files /dev/null and b/docs/en/docs/insight/image/inhibition-01.png differ diff --git a/docs/en/docs/insight/image/inhibition.png b/docs/en/docs/insight/image/inhibition.png new file mode 100644 index 0000000..ab8626b Binary files /dev/null and b/docs/en/docs/insight/image/inhibition.png differ diff --git a/docs/en/docs/insight/image/insight-ns-toleration.png b/docs/en/docs/insight/image/insight-ns-toleration.png new file mode 100644 index 0000000..b2eaa81 Binary files /dev/null and b/docs/en/docs/insight/image/insight-ns-toleration.png differ diff --git a/docs/en/docs/insight/image/node.png b/docs/en/docs/insight/image/node.png new file mode 100644 index 0000000..bcc3449 Binary files /dev/null and b/docs/en/docs/insight/image/node.png differ diff --git a/docs/en/docs/insight/image/notify-01.png b/docs/en/docs/insight/image/notify-01.png new file mode 100644 index 0000000..0dd5183 Binary files /dev/null and b/docs/en/docs/insight/image/notify-01.png differ diff --git a/docs/en/docs/insight/image/notify-02.png b/docs/en/docs/insight/image/notify-02.png new file mode 100644 index 0000000..e84ce39 Binary files /dev/null and b/docs/en/docs/insight/image/notify-02.png differ diff --git a/docs/en/docs/insight/image/overview.png b/docs/en/docs/insight/image/overview.png new file mode 100644 index 0000000..859a2cc Binary files /dev/null and b/docs/en/docs/insight/image/overview.png differ diff --git a/docs/en/docs/insight/image/servicemap.png b/docs/en/docs/insight/image/servicemap.png new file mode 100644 index 0000000..8c6d448 Binary files /dev/null and b/docs/en/docs/insight/image/servicemap.png differ diff --git a/docs/en/docs/insight/image/trace00.png b/docs/en/docs/insight/image/trace00.png new file mode 100644 index 0000000..f54b62e Binary files /dev/null and b/docs/en/docs/insight/image/trace00.png differ diff --git a/docs/en/docs/insight/image/tracelog.png b/docs/en/docs/insight/image/tracelog.png new file mode 100644 index 0000000..bb4c1fb Binary files /dev/null and b/docs/en/docs/insight/image/tracelog.png differ diff --git a/docs/en/docs/insight/image/workload-1.png b/docs/en/docs/insight/image/workload-1.png new file mode 100644 index 0000000..699f4b9 Binary files /dev/null and b/docs/en/docs/insight/image/workload-1.png differ diff --git a/docs/en/docs/insight/image/workload.png b/docs/en/docs/insight/image/workload.png new file mode 100644 index 0000000..cc052da Binary files /dev/null and b/docs/en/docs/insight/image/workload.png differ diff --git a/docs/en/docs/insight/image/workload00.png b/docs/en/docs/insight/image/workload00.png new file mode 100644 index 0000000..909ad43 Binary files /dev/null and b/docs/en/docs/insight/image/workload00.png differ diff --git a/docs/en/docs/insight/quickstart/agent-status.md b/docs/en/docs/insight/quickstart/agent-status.md new file mode 100644 index 0000000..1f8e3a3 --- /dev/null +++ b/docs/en/docs/insight/quickstart/agent-status.md @@ -0,0 +1,42 @@ +# Insight-agent component status + +Insight is a multicluster observation product in AI platform. In order to realize the unified collection of multicluster observation data, users need to install the Helm application __insight-agent__ +(Installed in insight-system namespace by default). See [How to install __insight-agent__ ](install/install-agent.md). + +## Status description + +In __Insight__ -> __Data Collection__ section, you can view the status of __insight-agent__ installed in each cluster. + +- __not installed__ : __insight-agent__ is not installed under the insight-system namespace in this cluster +- __Running__ : __insight-agent__ is successfully installed in the cluster, and all deployed components are running +- __Exception__ : If insight-agent is in this state, it means that the helm deployment failed or the deployed components are not running + +Can be checked by: + +1. Run the following command, if the status is __deployed__ , go to the next step. + If it is __failed__ , since it will affect the upgrade of the application, + it is recommended to reinstall after uninstalling __Container Management__ -> __Helm Apps__ : + + ```bash + helm list -n insight-system + ``` + +2. run the following command or check the status of the components deployed in the cluster in + __Insight__ -> __Data Collection__ . If there is a pod that is not in the __Running__ state, please restart the abnormal pod. + + ```bash + kubectl get pods -n insight-system + ``` + +## Supplementary instructions + +1. The resource consumption of the metric collection component Prometheus in __insight-agent__ is directly proportional + to the number of pods running in the cluster. Adjust Prometheus resources according to the cluster size, + please refer to [Prometheus Resource Planning](./res-plan/prometheus-res.md). + +2. Since the storage capacity of the metric storage component vmstorage in the global service cluster + is directly proportional to the sum of the number of pods in each cluster. + + - Please contact the platform administrator to adjust the disk capacity of vmstorage according to the cluster size, + see [vmstorage disk capacity planning](./res-plan/vms-res-plan.md). + - Adjust vmstorage disk according to multicluster size, see [vmstorge disk expansion](./res-plan/modify-vms-disk.md). diff --git a/docs/en/docs/insight/quickstart/install/big-log-and-trace.md b/docs/en/docs/insight/quickstart/install/big-log-and-trace.md new file mode 100644 index 0000000..980755b --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/big-log-and-trace.md @@ -0,0 +1,285 @@ +--- +MTPE: ModetaNiu +DATE: 2024-09-14 +--- + +# Enable Big Log and Big Trace Modes + +The Insight Module supports switching log to **Big Log** mode and trace to **Big Trace** mode, in order to +enhance data writing capabilities in large-scale environments. +This page introduces following methods for enabling these modes: + +- Enable or upgrade to Big Log and Big Trace modes [through the installer](#enabling-via-installer) (controlled by the same parameter value in `manifest.yaml`) +- Manually enable Big Log and Big Trace modes [through Helm commands](#enabling-via-helm-commands) + +## Logs + +This section explains the differences between the normal log mode and the Big Log mode. + +### Log Mode + +Components: Fluentbit + Elasticsearch + +This mode is referred to as the ES mode, and the data flow diagram is shown below: + +![Log Mode](../../image/big-log01.png) + +### Big Log Mode + +Components: Fluentbit + **Kafka** + **Vector** + Elasticsearch + +This mode is referred to as the Kafka mode, and the data flow diagram is shown below: + +![Big Log Mode](../../image/big-log02.png) + +## Traces + +This section explains the differences between the normal trace mode and the Big Trace mode. + +### Trace Mode + +Components: Agent opentelemetry-collector + Global opentelemetry-collector + Jaeger-collector + Elasticsearch + +This mode is referred to as the OTlp mode, and the data flow diagram is shown below: + +![Trace Mode](../../image/big-log03.png) + +### Big Trace Mode + +Components: Agent opentelemetry-collector + Kafka + Global opentelemetry-collector + Jaeger-collector + Elasticsearch + +This mode is referred to as the Kafka mode, and the data flow diagram is shown below: + +![Big Trace Mode](../../image/big-log04.png) + +## Enabling via Installer + +When deploying/upgrading AI platform using the installer, the `manifest.yaml` file includes the `infrastructures.kafka` field. +To enable observable Big Log and Big Trace modes, Kafka must be activated: + +```yaml title="manifest.yaml" +apiVersion: manifest.daocloud.io/v1alpha1 +kind: SuanovaManifest +... +infrastructures: + ... + kafka: + enable: true # Default is false + cpuLimit: 1 + memLimit: 2Gi + pvcSize: 15Gi +``` + +### Enable + +When using a `manifest.yaml` that enables `kafka` during installation, Kafka middleware will be installed by default, +and Big Log and Big Trace modes will be enabled automatically. The installation command is: + +```bash +./dce5-installer cluster-create -c clusterConfig.yaml -m manifest.yaml +``` + +### Upgrade + +The upgrade also involves modifying the `kafka` field. However, note that since the old environment was installed +with `kafka: false`, Kafka is not present in the environment. Therefore, you need to specify the upgrade +for `middleware` to install Kafka middleware simultaneously. The upgrade command is: + +```bash +./dce5-installer cluster-create -c clusterConfig.yaml -m manifest.yaml -u gproduct,middleware +``` + +!!! note + + After the upgrade is complete, you need to manually restart the following components: + + - insight-agent-fluent-bit + - insight-agent-opentelemetry-collector + - insight-opentelemetry-collector + +## Enabling via Helm Commands + +Prerequisites: Ensure that there is a **usable Kafka** and that the address is accessible. + +Use the following commands to retrieve the values of the old versions of Insight and insight-agent (it's recommended to back them up): + +```bash +helm get values insight -n insight-system -o yaml > insight.yaml +helm get values insight-agent -n insight-system -o yaml > insight-agent.yaml +``` + +### Enabling Big Log + +There are several ways to enable or upgrade to Big Log mode: + +=== "Use `--set` in the `helm upgrade` command" + + First, run the following Insight upgrade command, ensuring the Kafka brokers address is correct: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --set global.kafka.brokers="10.6.216.111:30592" \ + --set global.kafka.enabled=true \ + --set vector.enabled=true \ + --version 0.30.1 + ``` + + Then, run the following insight-agent upgrade command, ensuring the Kafka brokers address is correct: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --set global.exporters.logging.kafka.brokers="10.6.216.111:30592" \ + --set global.exporters.logging.output=kafka \ + --version 0.30.1 + ``` + +=== "Modify YAML and run helm upgrade" + + Follow these steps to modify the YAML and then run the `helm upgrade` command: + + 1. Modify `insight.yaml` + + ```yaml title="insight.yaml" + global: + ... + kafka: + brokers: 10.6.216.111:30592 + enabled: true + ... + vector: + enabled: true + ``` + + 1. Upgrade the Insight component: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version 0.30.1 + ``` + + 1. Modify `insight-agent.yaml` + + ```yaml title="insight-agent.yaml" + global: + ... + exporters: + ... + logging: + ... + kafka: + brokers: 10.6.216.111:30592 + output: kafka + ``` + + 1. Upgrade the insight-agent: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version 0.30.1 + ``` + +=== "Upgrade via Container Management UI" + + In the Container Management module, find the cluster, select **Helm Apps** from the left navigation bar, + and find and update the insight-agent. + + In **Logging Settings**, select **kafka** for **output** and fill in the correct **brokers** address. + + Note that after the upgrade is complete, you need to manually restart the **insight-agent-fluent-bit** component. + +### Enabling Big Trace + +There are several ways to enable or upgrade to Big Trace mode: + +=== "Using --set in the `helm upgrade` command" + + First, run the following Insight upgrade command, ensuring the Kafka brokers address is correct: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --set global.kafka.brokers="10.6.216.111:30592" \ + --set global.kafka.enabled=true \ + --set global.tracing.kafkaReceiver.enabled=true \ + --version 0.30.1 + ``` + + Then, run the following insight-agent upgrade command, ensuring the Kafka brokers address is correct: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --set global.exporters.trace.kafka.brokers="10.6.216.111:30592" \ + --set global.exporters.trace.output=kafka \ + --version 0.30.1 + ``` + +=== "Modify YAML and run helm upgrade" + + Follow these steps to modify the YAML and then run the `helm upgrade` command: + + 1. Modify `insight.yaml` + + ```yaml title="insight.yaml" + global: + ... + kafka: + brokers: 10.6.216.111:30592 + enabled: true + ... + tracing: + ... + kafkaReceiver: + enabled: true + ``` + + 1. Upgrade the Insight component: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version 0.30.1 + ``` + + 1. Modify `insight-agent.yaml` + + ```yaml title="insight-agent.yaml" + global: + ... + exporters: + ... + trace: + ... + kafka: + brokers: 10.6.216.111:30592 + output: kafka + ``` + + 1. Upgrade the insight-agent: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version 0.30.1 + ``` + +=== "Upgrade via Container Management UI" + + In the Container Management module, find the cluster, select **Helm Apps** from the left navigation bar, + and find and update the insight-agent. + + In **Trace Settings**, select **kafka** for **output** and fill in the correct **brokers** address. + + Note that after the upgrade is complete, you need to manually **restart the insight-agent-opentelemetry-collector** and **insight-opentelemetry-collector** components. \ No newline at end of file diff --git a/docs/en/docs/insight/quickstart/install/component-scheduling.md b/docs/en/docs/insight/quickstart/install/component-scheduling.md new file mode 100644 index 0000000..48d4bb0 --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/component-scheduling.md @@ -0,0 +1,332 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-10-08 +--- + +# Custom Insight Component Scheduling Policy + +When deploying Insight to a Kubernetes environment, proper resource management and optimization are crucial. +Insight includes several core components such as Prometheus, OpenTelemetry, FluentBit, Vector, and Elasticsearch. +These components, during their operation, may negatively impact the performance of other pods within the cluster +due to resource consumption issues. To effectively manage resources and optimize cluster operations, +node affinity becomes an important option. + +This page is about how to add [taints](#configure-dedicated-nodes-for-insight-using-taints) +and [node affinity](#use-node-labels-and-node-affinity-to-manage-component-scheduling) to ensure that each component +runs on the appropriate nodes, avoiding resource competition or contention, thereby guranttee the stability and efficiency +of the entire Kubernetes cluster. + +## Configure dedicated nodes for Insight using taints + +Since the Insight Agent includes DaemonSet components, the configuration method described in this section +is to have all components except the Insight DaemonSet run on dedicated nodes. + +This is achieved by adding taints to the dedicated nodes and using tolerations to match them. More details can be +found in the [Kubernetes official documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/). + +You can refer to the following commands to add and remove taints on nodes: + +```bash +# Add taint +kubectl taint nodes worker1 node.daocloud.io=insight-only:NoSchedule + +# Remove taint +kubectl taint nodes worker1 node.daocloud.io:NoSchedule- +``` + +There are two ways to schedule Insight components to dedicated nodes: + +### 1. Add tolerations for each component + +Configure the tolerations for the `insight-server` and `insight-agent` Charts respectively: + +=== "insight-server Chart" + + ```yaml + server: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + ui: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + runbook: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + # mysql: + victoria-metrics-k8s-stack: + victoria-metrics-operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmcluster: + spec: + vmstorage: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmselect: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vminsert: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmalert: + spec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + alertmanager: + spec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + jaeger: + collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + query: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + opentelemetry-collector-aggregator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + opentelemetry-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + grafana-operator: + operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + grafana: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + kibana: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + elastic-alert: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + vector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + ``` + +=== "insight-agent Chart" + + ```yaml + kube-prometheus-stack: + prometheus: + prometheusSpec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + prometheus-node-exporter: + tolerations: + - effect: NoSchedule + operator: Exists + prometheusOperator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + kube-state-metrics: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + tailing-sidecar-operator: + operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-kubernetes-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + prometheus-blackbox-exporter: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + etcd-exporter: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + ``` + +### 2. Configure at the namespace level + +Allow pods in the `insight-system` namespace to tolerate the `node.daocloud.io=insight-only` taint. + +1. Adjust the `apiserver` configuration file `/etc/kubernetes/manifests/kube-apiserver.yaml` to include + `PodTolerationRestriction,PodNodeSelector`. See the following picture: + + ![insight-ns-toleration](../../image/insight-ns-toleration.png) + +2. Add an annotation to the `insight-system` namespace: + + ```yaml + apiVersion: v1 + kind: Namespace + metadata: + name: insight-system + annotations: + scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Equal", "effect": "NoSchedule", "key": "node.daocloud.io", "value": "insight-only"}]' + ``` + +Restart the components under the insight-system namespace to allow normal scheduling of pods under the insight-system. + +## Use node labels and node affinity to manage component scheduling + +!!! info + + Node affinity is conceptually similar to `nodeSelector`, allowing you to constrain + which nodes a pod can be scheduled on based on **labels** on the nodes. + There are two types of node affinity: + + 1. requiredDuringSchedulingIgnoredDuringExecution: The scheduler will only schedule the pod + if the rules are met. This feature is similar to nodeSelector but has more expressive syntax. + 2. preferredDuringSchedulingIgnoredDuringExecution: The scheduler will try to find nodes that + meet the rules. If no matching nodes are found, the scheduler will still schedule the Pod. + + For more details, please refer to the [Kubernetes official documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity). + +To meet different user needs for scheduling Insight components, Insight provides fine-grained labels for +different components' scheduling policies. Below is a description of the labels and their associated components: + +| Label Key | Label Value | Description | +| --- | ------- | ------------ | +| `node.daocloud.io/insight-any` | Any value, recommended to use `true` | Represents that all Insight components prefer nodes with this label | +| `node.daocloud.io/insight-prometheus` | Any value, recommended to use `true` | Specifically for Prometheus components | +| `node.daocloud.io/insight-vmstorage` | Any value, recommended to use `true` | Specifically for VictoriaMetrics vmstorage components | +| `node.daocloud.io/insight-vector` | Any value, recommended to use `true` | Specifically for Vector components | +| `node.daocloud.io/insight-otel-col` | Any value, recommended to use `true` | Specifically for OpenTelemetry components | + +You can refer to the following commands to add and remove labels on nodes: + +```bash +# Add label to node8, prioritizing scheduling insight-prometheus to node8 +kubectl label nodes node8 node.daocloud.io/insight-prometheus=true + +# Remove the node.daocloud.io/insight-prometheus label from node8 +kubectl label nodes node8 node.daocloud.io/insight-prometheus- +``` + +Below is the default affinity preference for the insight-prometheus component during deployment: + +```yaml +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: DoesNotExist + weight: 1 + - preference: + matchExpressions: + - key: node.daocloud.io/insight-prometheus # (1)! + operator: Exists + weight: 2 + - preference: + matchExpressions: + - key: node.daocloud.io/insight-any + operator: Exists + weight: 3 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - insight-agent-kube-prometh-prometheus +``` + +1. Prioritize scheduling insight-prometheus to nodes with the node.daocloud.io/insight-prometheus label diff --git a/docs/en/docs/insight/quickstart/install/gethosturl.md b/docs/en/docs/insight/quickstart/install/gethosturl.md new file mode 100644 index 0000000..61058f6 --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/gethosturl.md @@ -0,0 +1,188 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-24 +--- + +# Get Data Storage Address of Global Service Cluster + +Insight is a product for unified observation of multiple clusters. To achieve unified storage and +querying of observation data from multiple clusters, sub-clusters need to report the collected observation data to the +[global service cluster](../../../kpanda/user-guide/clusters/cluster-role.md#global-service-cluster) +for unified storage. This document provides the required address of the storage component when +installing the collection component insight-agent. + +## Install insight-agent in Global Service Cluster + +If installing insight-agent in the global service cluster, it is recommended to access the cluster via domain name: + +```shell +export vminsert_host="vminsert-insight-victoria-metrics-k8s-stack.insight-system.svc.cluster.local" # (1)! +export es_host="insight-es-master.insight-system.svc.cluster.local" # (2)! +export otel_col_host="insight-opentelemetry-collector.insight-system.svc.cluster.local" # (3)! +``` + +## Install insight-agent in Other Clusters + +### Get Address via Interface Provided by Insight Server + +1. The [management cluster](../../../kpanda/user-guide/clusters/cluster-role.md#management-clusters) + uses the default LoadBalancer mode for exposure. + + Log in to the console of the global service cluster and run the following command: + + + ```bash + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' + ``` + + !!! note + + Please replace the `${INSIGHT_SERVER_IP}` parameter in the command. + + You will get the following response: + + ```json + { + "values": { + "global": { + "exporters": { + "logging": { + "host": "10.6.182.32" + }, + "metric": { + "host": "10.6.182.32" + }, + "auditLog": { + "host": "10.6.182.32" + }, + "trace": { + "host": "10.6.182.32" + } + } + }, + "opentelemetry-operator": { + "enabled": true + }, + "opentelemetry-collector": { + "enabled": true + } + } + } + ``` + + - `global.exporters.logging.host` is the log service address, no need to set the proper service port, + the default value will be used. + - `global.exporters.metric.host` is the metrics service address. + - `global.exporters.trace.host` is the trace service address. + - `global.exporters.auditLog.host` is the audit log service address (same service as trace but different port). + +1. Management cluster disables LoadBalancer + + When calling the interface, you need to additionally pass an externally accessible node IP from the cluster, + which will be used to construct the complete access address of the proper service. + + ```bash + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' --data '{"extra": {"EXPORTER_EXTERNAL_IP": "10.5.14.51"}}' + ``` + + You will get the following response: + + ```json + { + "values": { + "global": { + "exporters": { + "logging": { + "scheme": "https", + "host": "10.5.14.51", + "port": 32007, + "user": "elastic", + "password": "j8V1oVoM1184HvQ1F3C8Pom2" + }, + "metric": { + "host": "10.5.14.51", + "port": 30683 + }, + "auditLog": { + "host": "10.5.14.51", + "port": 30884 + }, + "trace": { + "host": "10.5.14.51", + "port": 30274 + } + } + }, + "opentelemetry-operator": { + "enabled": true + }, + "opentelemetry-collector": { + "enabled": true + } + } + } + ``` + + - `global.exporters.logging.host` is the log service address. + - `global.exporters.logging.port` is the NodePort exposed by the log service. + - `global.exporters.metric.host` is the metrics service address. + - `global.exporters.metric.port` is the NodePort exposed by the metrics service. + - `global.exporters.trace.host` is the trace service address. + - `global.exporters.trace.port` is the NodePort exposed by the trace service. + - `global.exporters.auditLog.host` is the audit log service address (same service as trace but different port). + - `global.exporters.auditLog.port` is the NodePort exposed by the audit log service. + +### Connect via LoadBalancer + +1. If `LoadBalancer` is enabled in the cluster and a `VIP` is set for Insight, you can manually execute + the following command to obtain the address information for `vminsert` and `opentelemetry-collector`: + + ```shell + $ kubectl get service -n insight-system | grep lb + lb-insight-opentelemetry-collector LoadBalancer 10.233.23.12 4317:31286/TCP,8006:31351/TCP 24d + lb-vminsert-insight-victoria-metrics-k8s-stack LoadBalancer 10.233.63.67 8480:31629/TCP 24d + ``` + + - `lb-vminsert-insight-victoria-metrics-k8s-stack` is the address for the metrics service. + - `lb-insight-opentelemetry-collector` is the address for the tracing service. + +2. Execute the following command to obtain the address information for `elasticsearch`: + + ```shell + $ kubectl get service -n mcamel-system | grep es + mcamel-common-es-cluster-masters-es-http NodePort 10.233.16.120 9200:30465/TCP 47d + ``` + + `mcamel-common-es-cluster-masters-es-http` is the address for the logging service. + +### Connect via NodePort + +The LoadBalancer feature is disabled in the global service cluster. + +In this case, the LoadBalancer resources mentioned above will not be created by default. The relevant service names are: + +- vminsert-insight-victoria-metrics-k8s-stack (metrics service) +- common-es (logging service) +- insight-opentelemetry-collector (tracing service) + +After obtaining the corresponding port information for the services in the above two scenarios, make the following settings: + +```shell +--set global.exporters.logging.host= # (1)! +--set global.exporters.logging.port= # (2)! +--set global.exporters.metric.host= # (3)! +--set global.exporters.metric.port= # (4)! +--set global.exporters.trace.host= # (5)! +--set global.exporters.trace.port= # (6)! +--set global.exporters.auditLog.host= # (7)! +``` + +1. NodeIP of the externally accessible management cluster +2. NodePort of the logging service port 9200 +3. NodeIP of the externally accessible management cluster +4. NodePort of the metrics service port 8480 +5. NodeIP of the externally accessible management cluster +6. NodePort of the tracing service port 4317 +7. NodeIP of the externally accessible management cluster diff --git a/docs/en/docs/insight/quickstart/install/index.md b/docs/en/docs/insight/quickstart/install/index.md new file mode 100644 index 0000000..dfdb7df --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/index.md @@ -0,0 +1,49 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-19 +--- + +# Start Observing + +AI platform platform enables the management and creation of multicloud and multiple clusters. +Building upon this capability, Insight serves as a unified observability solution for +multiple clusters. It collects observability data from multiple clusters by deploying the insight-agent +plugin and allows querying of metrics, logs, and trace data through the AI platform Insight. + + __insight-agent__ is a tool that facilitates the collection of observability data from multiple clusters. +Once installed, it automatically collects metrics, logs, and trace data without any modifications. + +Clusters created through __Container Management__ come pre-installed with insight-agent. Hence, +this guide specifically provides instructions on enabling observability for integrated clusters. + +- [Install insight-agent online](install-agent.md) + +As a unified observability platform for multiple clusters, Insight's resource consumption of certain components +is closely related to the data of cluster creation and the number of integrated clusters. +When installing insight-agent, it is necessary to adjust the resources of the corresponding components based on the cluster size. + +1. Adjust the CPU and memory resources of the __Prometheus__ collection component in insight-agent + according to the size of the cluster created or integrated. Please refer to + [Prometheus resource planning](../res-plan/prometheus-res.md). + +2. As the metric data from multiple clusters is stored centrally, AI platform platform administrators + need to adjust the disk space of __vmstorage__ based on the cluster size. + Please refer to [vmstorage disk capacity planning](../res-plan/vms-res-plan.md). + +- For instructions on adjusting the disk space of vmstorage, please refer to + [Expanding vmstorage disk](../res-plan/modify-vms-disk.md). + +Since AI platform supports the management of multicloud and multiple clusters, +insight-agent has undergone partial verification. However, there are known conflicts +with monitoring components when installing insight-agent in Suanova 4.0 clusters and +Openshift 4.x clusters. If you encounter similar issues, please refer to the following documents: + +- [Install insight-agent in Suanova 4.0.x](../other/install-agentindce.md) +- [Install insight-agent in Openshift 4.x](../other/install-agent-on-ocp.md) + +Currently, the insight-agent collection component has undergone functional testing +for popular versions of Kubernetes. Please refer to: + +- [Kubernetes cluster compatibility testing](../../compati-test/k8s-compatibility.md) +- [Openshift 4.x cluster compatibility testing](../../compati-test/ocp-compatibility.md) +- [Rancher cluster compatibility testing](../../compati-test/rancher-compatibility.md) diff --git a/docs/en/docs/insight/quickstart/install/install-agent.md b/docs/en/docs/insight/quickstart/install/install-agent.md new file mode 100644 index 0000000..3d72c38 --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/install-agent.md @@ -0,0 +1,44 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# Install insight-agent + +insight-agent is a plugin for collecting insight data, supporting unified observation of metrics, links, and log data. This article describes how to install insight-agent in an online environment for the accessed cluster. + +## Prerequisites + +Please confirm that your cluster has successfully connected to the __container management__ platform. You can refer to [Integrate Clusters](../../../kpanda/user-guide/clusters/integrate-cluster.md) for details. + +## Steps + +1. Enter __Container Management__ from the left navigation bar, and enter __Clusters__ . Find the cluster where you want to install insight-agent. + + ![Find Cluster](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/insight-agent01.png) + +1. Choose __Install now__ to jump, or click the cluster and click __Helm Applications__ -> __Helm Templates__ in the left navigation bar, search for __insight-agent__ in the search box, and click it for details. + + ![Search insight-agent](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/insight-agent02.png) + +1. Select the appropriate version and click __Install__ . + + ![Install](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/insight-agent03.png) + +1. Fill in the name, select the namespace and version, and fill in the addresses of logging, metric, audit, and trace reporting data in the yaml file. The system has filled in the address of the component for data reporting by default, please check it before clicking __OK__ to install. + + If you need to modify the data reporting address, please refer to [Get Data Reporting Address](./gethosturl.md). + + ![Sheet Fill1](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/insight-agent04-1.png) + + ![Sheet Fill2](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/insight-agent04-2.png) + +1. The system will automatically return to __Helm Apps__ . When the application status changes from __Unknown__ to __Deployed__ , it means that insight-agent is installed successfully. + + ![Finish Page](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/insight-agent05.png) + + !!! note + + - Click __┇__ on the far right, and you can perform more operations such as __Update__ , __View YAML__ and __Delete__ in the pop-up menu. + - For a practical installation demo, watch [Video demo of installing insight-agent](../../../videos/insight.md#install-insight-agent) diff --git a/docs/en/docs/insight/quickstart/install/knownissues.md b/docs/en/docs/insight/quickstart/install/knownissues.md new file mode 100644 index 0000000..fb7096a --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/knownissues.md @@ -0,0 +1,83 @@ +--- +MTPE: windsonsea +date: 2024-02-26 +--- + +# Known Issues + +This page lists some issues related to the installation and uninstallation of Insight Agent and their workarounds. + +## v0.23.0 + +### Insight Agent + +#### Uninstallation Failure of Insight Agent + +When you run the following command to uninstall Insight Agent, + +```sh +helm uninstall insight agent +``` + +The `tls secret` used by `otel-operator` is failed to uninstall. + +Due to the logic of "reusing tls secret" in the following code of `otel-operator`, +it checks whether `MutationConfiguration` exists and reuses the CA cert bound in +MutationConfiguration. However, since `helm uninstall` has uninstalled `MutationConfiguration`, +it results in a null value. + +Therefore, please manually delete the corresponding `secret` using one of the following methods: + +- **Delete via command line**: Log in to the console of the target cluster and run the following command: + + ```sh + kubectl -n insight-system delete secret insight-agent-opentelemetry-operator-controller-manager-service-cert + ``` + +- **Delete via UI**: Log in to AI platform container management, select the target cluster, select **Secret** + from the left menu, input `insight-agent-opentelemetry-operator-controller-manager-service-cert`, + then select `Delete`. + +### Insight Agent + +#### Log Collection Endpoint Not Updated When Upgrading Insight Agent + +When updating the log configuration of the insight-agent from Elasticsearch to Kafka or from Kafka +to Elasticsearch, the changes do not take effect and the agent continues to use the previous configuration. + +**Solution** : + +Manually restart Fluent Bit in the cluster. + +## v0.21.0 + +### Insight Agent + +#### PodMonitor Collects Multiple Sets of JVM Metrics + +1. In this version, there is a defect in **PodMonitor/insight-kubernetes-pod**: it will incorrectly + create Jobs to collect metrics for all containers in Pods that are marked with + `insight.opentelemetry.io/metric-scrape=true`, instead of only the containers corresponding + to `insight.opentelemetry.io/metric-port`. + +2. After PodMonitor is declared, **PrometheusOperator** will pre-configure some service discovery configurations. + Considering the compatibility of CRDs, it is abandoned to configure the collection tasks through **annotations**. + +3. Use the additional scrape config mechanism provided by Prometheus to configure the service discovery rules + in a secret and introduce them into Prometheus. + +Therefore: + +1. Delete the current **PodMonitor** for **insight-kubernetes-pod** +2. Use a new rule + +In the new rule, **action: keepequal** is used to compare the consistency between **source_labels** +and **target_label** to determine whether to create collection tasks for the ports of a container. +Note that this feature is only available in Prometheus v2.41.0 (2022-12-20) and higher. + +```diff ++ - source_labels: [__meta_kubernetes_pod_annotation_insight_opentelemetry_io_metric_port] ++ separator: ; ++ target_label: __meta_kubernetes_pod_container_port_number ++ action: keepequal +``` diff --git a/docs/en/docs/insight/quickstart/install/upgrade-note.md b/docs/en/docs/insight/quickstart/install/upgrade-note.md new file mode 100644 index 0000000..109010a --- /dev/null +++ b/docs/en/docs/insight/quickstart/install/upgrade-note.md @@ -0,0 +1,166 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-24 +--- + +# Upgrade Notes + +This page provides some considerations for upgrading insight-server and insight-agent. + +## insight-agent + +### Upgrade from v0.28.x (or lower) to v0.29.x + +Due to the upgrade of the Opentelemetry community operator chart version in v0.29.0, the supported values for `featureGates` in the values file have changed. Therefore, before upgrading, you need to set the value of `featureGates` to empty, as follows: + +```diff +- --set opentelemetry-operator.manager.featureGates="+operator.autoinstrumentation.go,+operator.autoinstrumentation.multi-instrumentation,+operator.autoinstrumentation.nginx" \ ++ --set opentelemetry-operator.manager.featureGates="" +``` + +## insight-server + +### Upgrade from v0.26.x (or lower) to v0.27.x or higher + +In v0.27.x, the switch for the vector component has been separated. If the existing environment has vector enabled, you need to specify `--set vector.enabled=true` when upgrading the insight-server. + +### Upgrade from v0.19.x (or lower) to 0.20.x + +Before upgrading __Insight__ , you need to manually delete the __jaeger-collector__ and +__jaeger-query__ deployments by running the following command: + +```bash +kubectl -n insight-system delete deployment insight-jaeger-collector +kubectl -n insight-system delete deployment insight-jaeger-query +``` + +### Upgrade from v0.17.x (or lower) to v0.18.x + +In v0.18.x, there have been updates to the Jaeger-related deployment files, +so you need to manually run the following commands before upgrading insight-server: + +```bash +kubectl -n insight-system delete deployment insight-jaeger-collector +kubectl -n insight-system delete deployment insight-jaeger-query +``` + +There have been changes to metric names in v0.18.x, so after upgrading insight-server, +insight-agent should also be upgraded. + +In addition, the parameters for enabling the tracing module and adjusting the ElasticSearch connection +have been modified. Refer to the following parameters: + +```diff ++ --set global.tracing.enable=true \ +- --set jaeger.collector.enabled=true \ +- --set jaeger.query.enabled=true \ ++ --set global.elasticsearch.scheme=${your-external-elasticsearch-scheme} \ ++ --set global.elasticsearch.host=${your-external-elasticsearch-host} \ ++ --set global.elasticsearch.port=${your-external-elasticsearch-port} \ ++ --set global.elasticsearch.user=${your-external-elasticsearch-username} \ ++ --set global.elasticsearch.password=${your-external-elasticsearch-password} \ +- --set jaeger.storage.elasticsearch.scheme=${your-external-elasticsearch-scheme} \ +- --set jaeger.storage.elasticsearch.host=${your-external-elasticsearch-host} \ +- --set jaeger.storage.elasticsearch.port=${your-external-elasticsearch-port} \ +- --set jaeger.storage.elasticsearch.user=${your-external-elasticsearch-username} \ +- --set jaeger.storage.elasticsearch.password=${your-external-elasticsearch-password} \ +``` + +### Upgrade from v0.15.x (or lower) to v0.16.x + +In v0.16.x, a new feature parameter `disableRouteContinueEnforce` in the `vmalertmanagers CRD` +is used. Therefore, you need to manually run the following command before upgrading insight-server: + +```shell +kubectl apply --server-side -f https://raw.githubusercontent.com/VictoriaMetrics/operator/v0.33.0/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml --force-conflicts +``` + +!!! note + + If you are performing an offline installation, after extracting the insight offline package, + please run the following command to update CRDs. + + ```shell + kubectl apply --server-side -f insight/dependency-crds --force-conflicts + ``` + +## insight-agent + +### Upgrade from v0.23.x (or lower) to v0.24.x + +In v0.24.x, CRDs have been added to the `OTEL operator chart`. However, +helm upgrade does not update CRDs, so you need to manually run the following command: + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-helm-charts/main/charts/opentelemetry-operator/crds/crd-opentelemetry.io_opampbridges.yaml +``` + +If you are performing an offline installation, you can find the above CRD yaml file after extracting the +insight-agent offline package. After extracting the insight-agent Chart, manually run the following command: + +```shell +kubectl apply -f charts/agent/crds/crd-opentelemetry.io_opampbridges.yaml +``` + +### Upgrade from v0.19.x (or lower) to v0.20.x + +In v0.20.x, Kafka log export configuration has been added, and there have been some adjustments +to the log export configuration. Before upgrading __insight-agent__ , please note the parameter changes. +The previous logging configuration has been moved to the logging.elasticsearch configuration: + +```diff +- --set global.exporters.logging.host \ +- --set global.exporters.logging.port \ ++ --set global.exporters.logging.elasticsearch.host \ ++ --set global.exporters.logging.elasticsearch.port \ +``` + +### Upgrade from v0.17.x (or lower) to v0.18.x + +Due to the updated deployment files for Jaeger In v0.18.x, it is important to +note the changes in parameters before upgrading the insight-agent. + +```diff ++ --set global.exporters.trace.enable=true \ +- --set opentelemetry-collector.enabled=true \ +- --set opentelemetry-operator.enabled=true \ +``` + +### Upgrade from v0.16.x (or lower) to v0.17.x + +In v0.17.x, the kube-prometheus-stack chart version was upgraded from 41.9.1 to 45.28.1, and +there were also some field upgrades in the CRD used, such as the __attachMetadata__ field of +servicemonitor. Therefore, the following command needs to be rund before upgrading the insight-agent: + +```bash +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --force-conflicts +``` + +If you are performing an offline installation, you can find the yaml for the above CRD in +insight-agent/dependency-crds after extracting the insight-agent offline package. + +### Upgrade from v0.11.x (or earlier) to v0.12.x + +v0.12.x upgrades kube-prometheus-stack chart from 39.6.0 to 41.9.1, including prometheus-operator to v0.60.1, prometheus-node-exporter chart to v4.3.0. +Prometheus-node-exporter uses [Kubernetes recommended label](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) after upgrading, so you need to delete __node-exporter__ daemonset. +prometheus-operator has updated the CRD, so you need to run the following command before upgrading the insight-agent: + +```shell linenums="1" +kubectl delete daemonset insight-agent-prometheus-node-exporter -n insight-system +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --force- conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml --force- conflicts +``` + +!!! note + + If you are installing offline, you can run the following command to update the CRD after decompressing the insight-agent offline package. + + ```shell + kubectl apply --server-side -f insight-agent/dependency-crds --force-conflicts + ``` diff --git a/docs/en/docs/insight/quickstart/jvm-monitor/jmx-exporter.md b/docs/en/docs/insight/quickstart/jvm-monitor/jmx-exporter.md new file mode 100644 index 0000000..935d372 --- /dev/null +++ b/docs/en/docs/insight/quickstart/jvm-monitor/jmx-exporter.md @@ -0,0 +1,136 @@ +# Use JMX Exporter to expose JVM monitoring metrics + +JMX-Exporter provides two usages: + +1. Start a standalone process. Specify parameters when the JVM starts, expose the RMI interface of JMX, JMX Exporter calls RMI to obtain the JVM runtime status data, + Convert to Prometheus metrics format, and expose ports for Prometheus to collect. +2. Start the JVM in-process. Specify parameters when the JVM starts, and run the jar package of JMX-Exporter in the form of javaagent. + Read the JVM runtime status data in the process, convert it into Prometheus metrics format, and expose the port for Prometheus to collect. + +!!! note + + Officials do not recommend the first method. On the one hand, the configuration is complicated, and on the other hand, it requires a separate process, and the monitoring of this process itself has become a new problem. + So This page focuses on the second usage and how to use JMX Exporter to expose JVM monitoring metrics in the Kubernetes environment. + +The second usage is used here, and the JMX Exporter jar package file and configuration file need to be specified when starting the JVM. +The jar package is a binary file, so it is not easy to mount it through configmap. We hardly need to modify the configuration file. +So the suggestion is to directly package the jar package and configuration file of JMX Exporter into the business container image. + +Among them, in the second way, we can choose to put the jar file of JMX Exporter in the business application mirror, +You can also choose to mount it during deployment. Here is an introduction to the two methods: + +## Method 1: Build the JMX Exporter JAR file into the business image + +The content of prometheus-jmx-config.yaml is as follows: + +```yaml title="prometheus-jmx-config.yaml" +... +ssl: false +lowercaseOutputName: false +lowercaseOutputLabelNames: false +rules: +- pattern: ".*" +``` + +!!! note + + For more configmaps, please refer to the bottom introduction or [Prometheus official documentation](https://github.com/prometheus/jmx_exporter#configuration). + +Then prepare the jar package file, you can find the latest jar package download address on the Github page of [jmx_exporter](https://github.com/prometheus/jmx_exporter) and refer to the following Dockerfile: + +```shell +FROM openjdk:11.0.15-jre +WORKDIR /app/ +COPY target/my-app.jar ./ +COPY prometheus-jmx-config.yaml ./ +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +ENV JAVA_TOOL_OPTIONS=-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml +EXPOSE 8081 8999 8080 8888 +ENTRYPOINT java $JAVA_OPTS -jar my-app.jar +``` + +Notice: + +- Start parameter format: -javaagent:=: +- Port 8088 is used here to expose the monitoring metrics of the JVM. If it conflicts with Java applications, you can change it yourself + +## Method 2: mount via init container container + +We need to make the JMX exporter into a Docker image first, the following Dockerfile is for reference only: + +```shell +FROM alpine/curl:3.14 +WORKDIR /app/ +# Copy the previously created config file to the mirror +COPY prometheus-jmx-config.yaml ./ +# Download jmx prometheus javaagent jar online +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +``` + +Build the image according to the above Dockerfile: __docker build -t my-jmx-exporter .__ + +Add the following init container to the Java application deployment Yaml: + +??? note "Click to view YAML file" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-demo-app + labels: + app: my-demo-app + spec: + selector: + matchLabels: + app: my-demo-app + template: + metadata: + labels: + app: my-demo-app + spec: + imagePullSecrets: + - name: registry-pull + initContainers: + - name: jmx-sidecar + image: my-jmx-exporter + command: ["cp", "-r", "/app/jmx_prometheus_javaagent-0.17.2.jar", "/target/jmx_prometheus_javaagent-0.17.2.jar"] ➊ + volumeMounts: + - name: sidecar + mountPath: /target + containers: + - image: my-demo-app-image + name: my-demo-app + resources: + requests: + memory: "1000Mi" + cpu: "500m" + limits: + memory: "1000Mi" + cpu: "500m" + ports: + - containerPort: 18083 + env: + - name: JAVA_TOOL_OPTIONS + value: "-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml" ➋ + volumeMounts: + - name: host-time + mountPath: /etc/localtime + readOnly: true + - name: sidecar + mountPath: /sidecar + volumes: + - name: host-time + hostPath: + path: /etc/localtime + - name: sidecar # Share the agent folder + emptyDir: {} + restartPolicy: Always + ``` + +After the above modification, the sample application my-demo-app has the ability to expose JVM metrics. +After running the service, we can access the prometheus format metrics exposed by the service through `http://lcoalhost:8088`. + +Then, you can refer to [Java Application Docking Observability with JVM Metrics](./legacy-jvm.md). diff --git a/docs/en/docs/insight/quickstart/jvm-monitor/jvm-catelogy.md b/docs/en/docs/insight/quickstart/jvm-monitor/jvm-catelogy.md new file mode 100644 index 0000000..e0d6ef1 --- /dev/null +++ b/docs/en/docs/insight/quickstart/jvm-monitor/jvm-catelogy.md @@ -0,0 +1,13 @@ +# Start monitoring Java applications + +This document mainly describes how to monitor the JVM of the customer's Java application. +It describes how Java applications that have exposed JVM metrics, and those that have not, interface with Insight. + +If your Java application does not start exposing JVM metrics, you can refer to the following documents: + +- [Expose JVM monitoring metrics with JMX Exporter](./jmx-exporter.md) +- [Expose JVM monitoring metrics using OpenTelemetry Java Agent](./otel-java-agent.md) + +If your Java application has exposed JVM metrics, you can refer to the following documents: + +- [Java application docking observability with existing JVM metrics](./legacy-jvm.md) \ No newline at end of file diff --git a/docs/en/docs/insight/quickstart/jvm-monitor/legacy-jvm.md b/docs/en/docs/insight/quickstart/jvm-monitor/legacy-jvm.md new file mode 100644 index 0000000..b03b28a --- /dev/null +++ b/docs/en/docs/insight/quickstart/jvm-monitor/legacy-jvm.md @@ -0,0 +1,94 @@ +--- +MTPE: ModetaNiu +DATE: 2024-08-14 +--- + +# Java Application with JVM Metrics to Dock Insight + +If your Java application exposes JVM monitoring metrics through other means (such as Spring Boot Actuator), +We need to allow monitoring data to be collected. You can let Insight collect existing JVM metrics by +adding Kubernetes Annotations to the workload: + +```yaml +annatation: + insight.opentelemetry.io/metric-scrape: "true" # whether to collect + insight.opentelemetry.io/metric-path: "/" # path to collect metrics + insight.opentelemetry.io/metric-port: "9464" # port for collecting metrics +``` + +YAML Example to add annotations for __my-deployment-app__ workload: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-app +spec: + selector: + matchLabels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + replicas: 1 + template: + metadata: + labels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + annotations: + insight.opentelemetry.io/metric-scrape: "true" # whether to collect + insight.opentelemetry.io/metric-path: "/" # path to collect metrics + insight.opentelemetry.io/metric-port: "9464" # port for collecting metrics +``` + +The following shows the complete YAML: + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + type: NodePort + selector: + #app: my-deployment-with-aotu-instrumentation-app + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + port: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + selector: + matchLabels: + #app: my-deployment-with-aotu-instrumentation-app + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + annotations: + insight.opentelemetry.io/metric-scrape: "true" # whether to collect + insight.opentelemetry.io/metric-path: "/actuator/prometheus" # path to collect metrics + insight.opentelemetry.io/metric-port: "8080" # port for collecting metrics + spec: + containers: + - name: myapp + image: docker.m.daocloud.io/wutang/spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + containerPort: 8080 + resources: + limits: + cpu: 500m + memory: 800Mi + requests: + cpu: 200m + memory: 400Mi +``` + +In the above example,Insight will use __:8080//actuator/prometheus__ to get Prometheus metrics exposed through *Spring Boot Actuator* . diff --git a/docs/en/docs/insight/quickstart/jvm-monitor/otel-java-agent.md b/docs/en/docs/insight/quickstart/jvm-monitor/otel-java-agent.md new file mode 100644 index 0000000..b97086d --- /dev/null +++ b/docs/en/docs/insight/quickstart/jvm-monitor/otel-java-agent.md @@ -0,0 +1,23 @@ +# Use OpenTelemetry Java Agent to expose JVM monitoring metrics + +In Opentelemetry Agent v1.20.0 and above, Opentelemetry Agent has added the JMX Metric Insight module. If your application has integrated Opentelemetry Agent to collect application traces, then you no longer need to introduce other Agents for our application Expose JMX metrics. The Opentelemetry Agent also collects and exposes metrics by instrumenting the metrics exposed by MBeans locally available in the application. + +Opentelemetry Agent also has some built-in monitoring samples for common Java Servers or frameworks, please refer to [predefined metrics](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics /semantic_conventions/runtime-environment-metrics.md#jvm-metrics). + +Using the OpenTelemetry Java Agent also needs to consider how to mount the JAR into the container. In addition to referring to the JMX Exporter above to mount the JAR file, we can also use the Operator capabilities provided by OpenTelemetry to automatically enable JVM metric exposure for our applications. : + +If your application has integrated Opentelemetry Agent to collect application traces, then you no longer need to introduce other Agents to expose JMX metrics for our application. The Opentelemetry Agent can now natively collect and expose metrics interfaces by instrumenting metrics exposed by MBeans available locally in the application. + +However, for current version, you still need to manually add the [corresponding annotations](./legacy-jvm.md) to workload before the JVM data will be collected by Insight. + +## Expose metrics for Java middleware + +Opentelemetry Agent also has some built-in middleware monitoring samples, please refer to [Predefined Metrics](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/jmx-metrics/javaagent /README.md#predefined-metrics). + +By default, no type is specified, and it needs to be specified through __-Dotel.jmx.target.system__ JVM Options, such as __-Dotel.jmx.target.system=jetty,kafka-broker__ . + +## Reference + +- [Gaining JMX Metric Insights with the OpenTelemetry Java Agent](https://opentelemetry.io/blog/2023/jmx-metric-insight/) + +- [Otel jmx metrics](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/jmx-metrics) \ No newline at end of file diff --git a/docs/en/docs/insight/quickstart/otel/golang-ebpf.md b/docs/en/docs/insight/quickstart/otel/golang-ebpf.md new file mode 100644 index 0000000..1dc5d92 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/golang-ebpf.md @@ -0,0 +1,284 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Enhance Go apps with OTel auto-instrumentation + +If you don't want to manually change the application code, you can try This page's eBPF-based automatic enhancement method. +This feature is currently in the review stage of donating to the OpenTelemetry community, and does not support Operator injection through annotations (it will be supported in the future), so you need to manually change the Deployment YAML or use a patch. + +## Prerequisites + +Make sure Insight Agent is ready. If not, see [Install insight-agent to collect data](../install/install-agent.md) and make sure the following three items are in place: + +- Enable trace feature for Insight-agent +- Whether the address and port of the trace data are filled in correctly +- Pods corresponding to deployment/opentelemetry-operator-controller-manager and deployment/insight-agent-opentelemetry-collector are ready + +## Install Instrumentation CR + +Install under the Insight-system namespace, skip this step if it has already been installed. + +Note: This CR currently only supports the injection of environment variables (including service name and trace address) required to connect to Insight, and will support the injection of Golang probes in the future. + +```bash +kubectl apply -f - <- + http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: '200' + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: 'true' + - name: OTEL_SERVICE_NAME + value: voting + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES_POD_UID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.uid + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_PROPAGATORS + value: jaeger,b3 + - name: OTEL_TRACES_SAMPLER + value: always_on + - name: OTEL_RESOURCE_ATTRIBUTES + value: >- + k8s.container.name=voting-svc,k8s.deployment.name=voting,k8s.deployment.uid=79e015e2-4643-44c0-993c-e486aebaba10,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.pod.uid=$(OTEL_RESOURCE_ATTRIBUTES_POD_UID),k8s.replicaset.name=voting-84b696c897,k8s.replicaset.uid=63f56167-6632-415d-8b01-43a3db9891ff + resources: + requests: + cpu: 100m + volumeMounts: + - name: launcherdir + mountPath: /odigos-launcher + - name: kube-api-access-gwj5v + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: emojivoto-voting-instrumentation + image: keyval/otel-go-agent:v0.6.0 + env: + - name: OTEL_TARGET_EXE + value: /usr/local/bin/emojivoto-voting-svc + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: jaeger:4317 + - name: OTEL_SERVICE_NAME + value: emojivoto-voting + resources: {} + volumeMounts: + - name: kernel-debug + mountPath: /sys/kernel/debug + - name: kube-api-access-gwj5v + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + capabilities: + add: + - SYS_PTRACE + privileged: true + runAsUser: 0 +······ +``` + +## Reference + +- [Getting Started with Go OpenTelemetry Automatic Instrumentation](https://github.com/keyval-dev/opentelemetry-go-instrumentation/blob/master/docs/getting-started/README.md) +- [Donating ebpf based instrumentation](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/4) diff --git a/docs/en/docs/insight/quickstart/otel/golang/golang.md b/docs/en/docs/insight/quickstart/otel/golang/golang.md new file mode 100644 index 0000000..9a6536f --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/golang/golang.md @@ -0,0 +1,364 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Enhance Go applications with OTel SDK + +This page contains instructions on how to set up OpenTelemetry enhancements in a Go application. + +OpenTelemetry, also known simply as OTel, is an open-source observability framework that helps generate and collect telemetry data: traces, metrics, and logs in Go apps. + +## Enhance Go apps with the OpenTelemetry SDK + +### Install related dependencies + +Dependencies related to the OpenTelemetry exporter and SDK must be installed first. If you are using another request router, please refer to [request routing](#request-routing). +After switching/going into the application source folder run the following command: + +```golang +go get go.opentelemetry.io/otel@v1.8.0 \ + go.opentelemetry.io/otel/trace@v1.8.0 \ + go.opentelemetry.io/otel/sdk@v1.8.0 \ + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin@v0.33.0 \ + go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.7.0 \ + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.4.1 +``` + +### Create an initialization feature using the OpenTelemetry SDK + +In order for an application to be able to send data, a feature is required to initialize OpenTelemetry. Add the following code snippet to the __main.go__ file: + +```golang +import ( + "context" + "os" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "go.uber.org/zap" + "google.golang.org/grpc" +) + +var tracerExp *otlptrace.Exporter + +func retryInitTracer() func() { + var shutdown func() + go func() { + for { + // otel will reconnected and re-send spans when otel col recover. so, we don't need to re-init tracer exporter. + if tracerExp == nil { + shutdown = initTracer() + } else { + break + } + time.Sleep(time.Minute * 5) + } + }() + return shutdown +} + +func initTracer() func() { + // temporarily set timeout to 10s + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + serviceName, ok := os.LookupEnv("OTEL_SERVICE_NAME") + if !ok { + serviceName = "server_name" + os.Setenv("OTEL_SERVICE_NAME", serviceName) + } + otelAgentAddr, ok := os.LookupEnv("OTEL_EXPORTER_OTLP_ENDPOINT") + if !ok { + otelAgentAddr = "http://localhost:4317" + os.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", otelAgentAddr) + } + zap.S().Infof("OTLP Trace connect to: %s with service name: %s", otelAgentAddr, serviceName) + + traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithDialOption(grpc.WithBlock())) + if err != nil { + handleErr(err, "OTLP Trace gRPC Creation") + return nil + } + + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(traceExporter), + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(resource.NewWithAttributes(semconv.SchemaURL))) + + otel.SetTracerProvider(tracerProvider) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + + tracerExp = traceExporter + return func() { + // Shutdown will flush any remaining spans and shut down the exporter. + handleErr(tracerProvider.Shutdown(ctx), "failed to shutdown TracerProvider") + } +} + +func handleErr(err error, message string) { + if err != nil { + zap.S().Errorf("%s: %v", message, err) + } +} +``` + +### Initialize tracker in main.go + +Modify the main feature to initialize the tracker in main.go. Also when your service shuts down, you should call __TracerProvider.Shutdown()__ to ensure all spans are exported. The service makes the call as a deferred feature in the main function: + +```golang +func main() { + // start otel tracing + if shutdown := retryInitTracer(); shutdown != nil { + defer shutdown() + } + ...... +} +``` + +### Add OpenTelemetry Gin middleware to the application + +Configure Gin to use the middleware by adding the following line to __main.go__ : + +```golang +import ( + .... + "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" +) + +func main() { + ...... + r := gin.Default() + r.Use(otelgin.Middleware("my-app")) + ...... +} +``` + +### Run the application + +- Local debugging and running + + > Note: This step is only used for local development and debugging. In the production environment, the Operator will automatically complete the injection of the following environment variables. + + The above steps have completed the work of initializing the SDK. Now if you need to develop and debug locally, you need to obtain the address of insight-agent-opentelemerty-collector in the insight-system namespace in advance, assuming: __insight-agent-opentelemetry-collector .insight-system.svc.cluster.local:4317__ . + + Therefore, you can add the following environment variables when you start the application locally: + + ```bash + OTEL_SERVICE_NAME=my-golang-app OTEL_EXPORTER_OTLP_ENDPOINT=http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317 go run main.go... + ``` + +- Running in a production environment + + Please refer to the introduction of __Only injecting environment variable annotations__ in [Achieving non-intrusive enhancement of applications through Operators](../operator.md) to add annotations to deployment yaml: + + ```console + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + + If you cannot use annotations, you can manually add the following environment variables to the deployment yaml: + +```yaml +······ +env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: 'http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317' + - name: OTEL_SERVICE_NAME + value: "your depolyment name" # modify it. + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES + value: 'k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)' +······ +``` + +## Request Routing + +### OpenTelemetry gin/gonic enhancements + +```golang +# Add one line to your import() stanza depending upon your request router: +middleware "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" +``` + +Then inject the OpenTelemetry middleware: + +```golang +router. Use(middleware. Middleware("my-app")) +``` + +### OpenTelemetry gorillamux enhancements + +```golang +# Add one line to your import() stanza depending upon your request router: +middleware "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" +``` + +Then inject the OpenTelemetry middleware: + +```golang +router. Use(middleware. Middleware("my-app")) +``` + +### gRPC enhancements + +Likewise, OpenTelemetry can help you auto-detect gRPC requests. To detect any gRPC server you have, add the interceptor to the server's instantiation. + +```golang +import ( + grpcotel "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +) +func main() { + [...] + + s := grpc.NewServer( + grpc.UnaryInterceptor(grpcotel.UnaryServerInterceptor()), + grpc.StreamInterceptor(grpcotel.StreamServerInterceptor()), + ) +} +``` + +It should be noted that if your program uses Grpc Client to call third-party services, you also need to add an interceptor to Grpc Client: + +```golang + [...] + + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()), + ) +``` + +### If not using request routing + +```golang +import ( + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +) +``` + +Everywhere you pass http.Handler to ServeMux you will wrap the handler function. For example, the following replacements would be made: + +```golang +- mux.Handle("/path", h) ++ mux.Handle("/path", otelhttp.NewHandler(h, "description of path")) +--- +- mux.Handle("/path", http.HandlerFunc(f)) ++ mux.Handle("/path", otelhttp.NewHandler(http.HandlerFunc(f), "description of path")) +``` + +In this way, you can ensure that each feature wrapped with othttp will automatically collect its metadata and start the corresponding trace. + +## database enhancements + +### Golang Gorm + +The OpenTelemetry community has also developed middleware for database access libraries, such as Gorm: +```golang +import ( + "github.com/uptrace/opentelemetry-go-extra/otelgorm" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{}) +if err != nil { + panic(err) +} + +otelPlugin := otelgorm.NewPlugin(otelgorm.WithDBName("mydb"), # Missing this can lead to incomplete display of database related topology + otelgorm.WithAttributes(semconv.ServerAddress("memory"))) # Missing this can lead to incomplete display of database related topology +if err := db.Use(otelPlugin); err != nil { + panic(err) +} +``` + +### Custom Span + +In many cases, the middleware provided by OpenTelemetry cannot help us record more internally called features, and we need to customize Span to record + +```golang + ······ + _, span := otel.Tracer("GetServiceDetail").Start(ctx, + "spanMetricDao.GetServiceDetail", + trace.WithSpanKind(trace.SpanKindInternal)) + defer span.End() + ······ +``` + +### Add custom properties and custom events to span + +It is also possible to set a custom attribute or tag as a span. To add custom properties and events, follow these steps: + +### Import Tracking and Property Libraries + +```golang +import ( + ... + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) +``` + +### Get the current Span from the context + +```golang +span := trace.SpanFromContext(c.Request.Context()) +``` + +### Set properties in the current Span + +```golang +span.SetAttributes(attribute. String("controller", "books")) +``` + +### Add an Event to the current Span + +Adding span events is done using __AddEvent__ on the span object. + +```golang +span.AddEvent(msg) +``` + +## Log errors and exceptions + +```golang +import "go.opentelemetry.io/otel/codes" + +// Get the current span +span := trace.SpanFromContext(ctx) + +// RecordError will automatically convert an error into a span even +span.RecordError(err) + +// Flag this span as an error +span.SetStatus(codes.Error, "internal error") +``` + +## References + +For the Demo presentation, please refer to: + +- [otel-grpc-examples](https://github.com/openinsight-proj/otel-grpc-examples/tree/no-metadata-grpcgateway-v1.11.1) +- [opentelemetry-demo/productcatalogservice](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice) +- [opentelemetry-collector-contrib/demo](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/examples/demo) diff --git a/docs/en/docs/insight/quickstart/otel/golang/meter.md b/docs/en/docs/insight/quickstart/otel/golang/meter.md new file mode 100644 index 0000000..7393d77 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/golang/meter.md @@ -0,0 +1,259 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Exposing Metrics for Applications Using OpenTelemetry SDK + +> This article is intended for users who wish to evaluate or explore the developing OTLP metrics. + +The OpenTelemetry project requires that APIs and SDKs must emit data in the OpenTelemetry Protocol (OTLP) for supported languages. + +## For Golang Applications + +Golang can expose runtime metrics through the SDK by adding the following methods to enable the metrics exporter within the application: + +### Install Required Dependencies + +Navigate to your application’s source folder and run the following command: + +```bash +go get go.opentelemetry.io/otel \ + go.opentelemetry.io/otel/attribute \ + go.opentelemetry.io/otel/exporters/prometheus \ + go.opentelemetry.io/otel/metric/global \ + go.opentelemetry.io/otel/metric/instrument \ + go.opentelemetry.io/otel/sdk/metric +``` + +### Create an Initialization Function Using OTel SDK + +```go +import ( + ..... + + "go.opentelemetry.io/otel/attribute" + otelPrometheus "go.opentelemetry.io/otel/exporters/prometheus" + "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" + "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" + selector "go.opentelemetry.io/otel/sdk/metric/selector/simple" +) + +func (s *insightServer) initMeter() *otelPrometheus.Exporter { + s.meter = global.Meter("xxx") + + config := otelPrometheus.Config{ + DefaultHistogramBoundaries: []float64{1, 2, 5, 10, 20, 50}, + Gatherer: prometheus.DefaultGatherer, + Registry: prometheus.NewRegistry(), + Registerer: prometheus.DefaultRegisterer, + } + + c := controller.New( + processor.NewFactory( + selector.NewWithHistogramDistribution( + histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries), + ), + aggregation.CumulativeTemporalitySelector(), + processor.WithMemory(true), + ), + ) + + exporter, err := otelPrometheus.New(config, c) + if err != nil { + zap.S().Panicf("failed to initialize prometheus exporter %v", err) + } + + global.SetMeterProvider(exporter.MeterProvider()) + + http.HandleFunc("/metrics", exporter.ServeHTTP) + + go func() { + _ = http.ListenAndServe(fmt.Sprintf(":%d", 8888), nil) + }() + + zap.S().Info("Prometheus server running on ", fmt.Sprintf(":%d", port)) + return exporter +} +``` + +The above method will expose a metrics endpoint for your application at: `http://localhost:8888/metrics`. + +Next, initialize it in `main.go`: + +```go +func main() { + // ... + tp := initMeter() + // ... +} +``` + +If you want to add custom metrics, you can refer to the following: + +```go +// exposeClusterMetric exposes a metric like "insight_logging_count{} 1" +func (s *insightServer) exposeLoggingMetric(lserver *log.LogService) { + s.meter = global.Meter("insight.io/basic") + + var lock sync.Mutex + logCounter, err := s.meter.AsyncFloat64().Counter("insight_log_total") + if err != nil { + zap.S().Panicf("failed to initialize instrument: %v", err) + } + + _ = s.meter.RegisterCallback([]instrument.Asynchronous{logCounter}, func(ctx context.Context) { + lock.Lock() + defer lock.Unlock() + count, err := lserver.Count(ctx) + if err == nil || count != -1 { + logCounter.Observe(ctx, float64(count)) + } + }) +} +``` + +Then, call this method in `main.go`: + +```go +// ... +s.exposeLoggingMetric(lservice) +// ... +``` + +You can check if your metrics are working correctly by visiting `http://localhost:8888/metrics`. + +## For Java Applications + +For Java applications, you can directly expose JVM-related metrics by using the OpenTelemetry agent with the following environment variable: + +```bash +OTEL_METRICS_EXPORTER=prometheus +``` + +You can then check your metrics at `http://localhost:8888/metrics`. + +Next, combine it with a Prometheus `ServiceMonitor` to complete the metrics integration. If you want to expose custom metrics, please refer to [opentelemetry-java-docs/prometheus](https://github.com/open-telemetry/opentelemetry-java-docs/blob/main/prometheus/README.md). + +The process is mainly divided into two steps: + +- Create a meter provider and specify Prometheus as the exporter. + +```java +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.example.prometheus; + +import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; +import io.opentelemetry.sdk.metrics.SdkMeterProvider; +import io.opentelemetry.sdk.metrics.export.MetricReader; + +public final class ExampleConfiguration { + + /** + * Initializes the Meter SDK and configures the Prometheus collector with all default settings. + * + * @param prometheusPort the port to open up for scraping. + * @return A MeterProvider for use in instrumentation. + */ + static MeterProvider initializeOpenTelemetry(int prometheusPort) { + MetricReader prometheusReader = PrometheusHttpServer.builder().setPort(prometheusPort).build(); + + return SdkMeterProvider.builder().registerMetricReader(prometheusReader).build(); + } +} +``` + +- Create a custom meter and start the HTTP server. + +```java +package io.opentelemetry.example.prometheus; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.MeterProvider; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Example of using the PrometheusHttpServer to convert OTel metrics to Prometheus format and expose + * these to a Prometheus instance via a HttpServer exporter. + * + *

A Gauge is used to periodically measure how many incoming messages are awaiting processing. + * The Gauge callback gets executed every collection interval. + */ +public final class PrometheusExample { + private long incomingMessageCount; + + public PrometheusExample(MeterProvider meterProvider) { + Meter meter = meterProvider.get("PrometheusExample"); + meter + .gaugeBuilder("incoming.messages") + .setDescription("No of incoming messages awaiting processing") + .setUnit("message") + .buildWithCallback(result -> result.record(incomingMessageCount, Attributes.empty())); + } + + void simulate() { + for (int i = 500; i > 0; i--) { + try { + System.out.println( + i + " Iterations to go, current incomingMessageCount is: " + incomingMessageCount); + incomingMessageCount = ThreadLocalRandom.current().nextLong(100); + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignored here + } + } + } + + public static void main(String[] args) { + int prometheusPort = 8888; + + // It is important to initialize the OpenTelemetry SDK as early as possible in your process. + MeterProvider meterProvider = ExampleConfiguration.initializeOpenTelemetry(prometheusPort); + + PrometheusExample prometheusExample = new PrometheusExample(meterProvider); + + prometheusExample.simulate(); + + System.out.println("Exiting"); + } +} +``` + +After running the Java application, you can check if your metrics are working correctly by visiting `http://localhost:8888/metrics`. + +## Insight Collecting Metrics + +Lastly, it is important to note that you have exposed metrics in your application, and now you need Insight to collect those metrics. + +The recommended way to expose metrics is via [ServiceMonitor](https://github.com/prometheus-operator/prometheus-operator/blob/501d079e3d3769b94dca6684cf155034e468829a/Documentation/design.md#servicemonitor) or PodMonitor. + +### Creating ServiceMonitor/PodMonitor + +The added ServiceMonitor/PodMonitor needs to have the label `operator.insight.io/managed-by: insight` for the Operator to recognize it: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-app + labels: + operator.insight.io/managed-by: insight +spec: + selector: + matchLabels: + app: example-app + endpoints: + - port: web + namespaceSelector: + any: true +``` diff --git a/docs/en/docs/insight/quickstart/otel/java/index.md b/docs/en/docs/insight/quickstart/otel/java/index.md new file mode 100644 index 0000000..25f95da --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/java/index.md @@ -0,0 +1,21 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Start Monitoring Java Applications + +1. For accessing and monitoring Java application links, please refer to the document [Implementing Non-Intrusive Enhancements for Applications via Operator](../operator.md), which explains how to automatically integrate links through annotations. + +2. Monitoring the JVM of Java applications: How Java applications that have already exposed JVM metrics and those that have not yet exposed JVM metrics can connect with observability Insight. + +- If your Java application has not yet started exposing JVM metrics, you can refer to the following documents: + + - [Exposing JVM Monitoring Metrics Using JMX Exporter](./jvm-monitor/jmx-exporter.md) + - [Exposing JVM Monitoring Metrics Using OpenTelemetry Java Agent](./jvm-monitor/otel-java-agent.md) + +- If your Java application has already exposed JVM metrics, you can refer to the following document: + + - [Connecting Existing JVM Metrics of Java Applications to Observability](./jvm-monitor/legacy-jvm.md) + +3. [Writing TraceId and SpanId into Java Application Logs](./mdc.md) to correlate link data with log data. diff --git a/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md b/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md new file mode 100644 index 0000000..7dd4877 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md @@ -0,0 +1,134 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Exposing JVM Monitoring Metrics Using JMX Exporter + +JMX Exporter provides two usage methods: + +1. **Standalone Process**: Specify parameters when starting the JVM to expose a JMX RMI interface. The JMX Exporter calls RMI to obtain the JVM runtime state data, converts it into Prometheus metrics format, and exposes a port for Prometheus to scrape. +2. **In-Process (JVM process)**: Specify parameters when starting the JVM to run the JMX Exporter jar file as a javaagent. This method reads the JVM runtime state data in-process, converts it into Prometheus metrics format, and exposes a port for Prometheus to scrape. + +!!! note + + The official recommendation is not to use the first method due to its complex configuration and the requirement for a separate process, which introduces additional monitoring challenges. Therefore, this article focuses on the second method, detailing how to use JMX Exporter to expose JVM monitoring metrics in a Kubernetes environment. + +In this method, you need to specify the JMX Exporter jar file and configuration file when starting the JVM. Since the jar file is a binary file that is not ideal for mounting via a configmap, and the configuration file typically does not require modifications, it is recommended to package both the JMX Exporter jar file and the configuration file directly into the business container image. + +For the second method, you can choose to include the JMX Exporter jar file in the application image or mount it during deployment. Below are explanations for both approaches: + +## Method 1: Building JMX Exporter JAR File into the Business Image + +The content of `prometheus-jmx-config.yaml` is as follows: + +```yaml title="prometheus-jmx-config.yaml" +... +ssl: false +lowercaseOutputName: false +lowercaseOutputLabelNames: false +rules: +- pattern: ".*" +``` + +!!! note + + For more configuration options, please refer to the introduction at the bottom or [Prometheus official documentation](https://github.com/prometheus/jmx_exporter#configuration). + +Next, prepare the jar file. You can find the latest jar download link on the [jmx_exporter](https://github.com/prometheus/jmx_exporter) GitHub page and refer to the following Dockerfile: + +```shell +FROM openjdk:11.0.15-jre +WORKDIR /app/ +COPY target/my-app.jar ./ +COPY prometheus-jmx-config.yaml ./ +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +ENV JAVA_TOOL_OPTIONS=-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml +EXPOSE 8081 8999 8080 8888 +ENTRYPOINT java $JAVA_OPTS -jar my-app.jar +``` + +Note: + +- The format for the startup parameter is: `-javaagent:=:` +- Here, port 8088 is used to expose JVM monitoring metrics; you may change it if it conflicts with the Java application. + +## Method 2: Mounting via Init Container + +First, we need to create a Docker image for the JMX Exporter. The following Dockerfile is for reference: + +```shell +FROM alpine/curl:3.14 +WORKDIR /app/ +# Copy the previously created config file into the image +COPY prometheus-jmx-config.yaml ./ +# Download the jmx prometheus javaagent jar online +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +``` + +Build the image using the above Dockerfile: `docker build -t my-jmx-exporter .` + +Add the following init container to the Java application deployment YAML: + +??? note "Click to expand YAML file" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-demo-app + labels: + app: my-demo-app + spec: + selector: + matchLabels: + app: my-demo-app + template: + metadata: + labels: + app: my-demo-app + spec: + imagePullSecrets: + - name: registry-pull + initContainers: + - name: jmx-sidecar + image: my-jmx-exporter + command: ["cp", "-r", "/app/jmx_prometheus_javaagent-0.17.2.jar", "/target/jmx_prometheus_javaagent-0.17.2.jar"] ➊ + volumeMounts: + - name: sidecar + mountPath: /target + containers: + - image: my-demo-app-image + name: my-demo-app + resources: + requests: + memory: "1000Mi" + cpu: "500m" + limits: + memory: "1000Mi" + cpu: "500m" + ports: + - containerPort: 18083 + env: + - name: JAVA_TOOL_OPTIONS + value: "-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml" ➋ + volumeMounts: + - name: host-time + mountPath: /etc/localtime + readOnly: true + - name: sidecar + mountPath: /sidecar + volumes: + - name: host-time + hostPath: + path: /etc/localtime + - name: sidecar # Shared agent folder + emptyDir: {} + restartPolicy: Always + ``` + +With the above modifications, the example application `my-demo-app` now has the capability to expose JVM metrics. After running the service, you can access the Prometheus formatted metrics at `http://localhost:8088`. + +Next, you can refer to [Connecting Existing JVM Metrics of Java Applications to Observability](./legacy-jvm.md). diff --git a/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md b/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md new file mode 100644 index 0000000..d52c973 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md @@ -0,0 +1,90 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Integrating Existing JVM Metrics of Java Applications with Observability + +If your Java application exposes JVM monitoring metrics through other means (such as Spring Boot Actuator), you will need to ensure that the monitoring data is collected. You can achieve this by adding annotations (Kubernetes Annotations) to your workload to allow Insight to scrape the existing JVM metrics: + +```yaml +annotations: + insight.opentelemetry.io/metric-scrape: "true" # Whether to scrape + insight.opentelemetry.io/metric-path: "/" # Path to scrape metrics + insight.opentelemetry.io/metric-port: "9464" # Port to scrape metrics +``` + +For example, to add annotations to the **my-deployment-app**: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-app +spec: + selector: + matchLabels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + replicas: 1 + template: + metadata: + labels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + annotations: + insight.opentelemetry.io/metric-scrape: "true" # Whether to scrape + insight.opentelemetry.io/metric-path: "/" # Path to scrape metrics + insight.opentelemetry.io/metric-port: "9464" # Port to scrape metrics +``` + +Here is a complete example: + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + type: NodePort + selector: + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + port: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + selector: + matchLabels: + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + annotations: + insight.opentelemetry.io/metric-scrape: "true" # Whether to scrape + insight.opentelemetry.io/metric-path: "/actuator/prometheus" # Path to scrape metrics + insight.opentelemetry.io/metric-port: "8080" # Port to scrape metrics + spec: + containers: + - name: myapp + image: docker.m.daocloud.io/wutang/spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + containerPort: 8080 + resources: + limits: + cpu: 500m + memory: 800Mi + requests: + cpu: 200m + memory: 400Mi +``` + +In the above example, Insight will scrape the Prometheus metrics exposed through **Spring Boot Actuator** via `http://:8080/actuator/prometheus`. diff --git a/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md b/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md new file mode 100644 index 0000000..df4c10d --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md @@ -0,0 +1,28 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Exposing JVM Metrics Using OpenTelemetry Java Agent + +Starting from OpenTelemetry Agent v1.20.0 and later, the OpenTelemetry Agent has introduced the JMX Metric Insight module. If your application is already integrated with the OpenTelemetry Agent for tracing, you no longer need to introduce another agent to expose JMX metrics for your application. The OpenTelemetry Agent collects and exposes metrics by detecting the locally available MBeans in the application. + +The OpenTelemetry Agent also provides built-in monitoring examples for common Java servers or frameworks. Please refer to the [Predefined Metrics](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/semantic-conventions.md). + +When using the OpenTelemetry Java Agent, you also need to consider how to mount the JAR into the container. In addition to the methods for mounting the JAR file as described with the JMX Exporter, you can leverage the capabilities provided by the OpenTelemetry Operator to automatically enable JVM metrics exposure for your application. + +If your application is already integrated with the OpenTelemetry Agent for tracing, you do not need to introduce another agent to expose JMX metrics. The OpenTelemetry Agent can now locally collect and expose metrics interfaces by detecting the locally available MBeans in the application. + +However, as of the current version, you still need to manually add the appropriate annotations to your application for the JVM data to be collected by Insight. For specific annotation content, please refer to [Integrating Existing JVM Metrics of Java Applications with Observability](./legacy-jvm.md). + +## Exposing Metrics for Java Middleware + +The OpenTelemetry Agent also includes built-in examples for monitoring middleware. Please refer to the [Predefined Metrics](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/jmx-metrics/javaagent/README.md#predefined-metrics). + +By default, no specific types are designated; you need to specify them using the `-Dotel.jmx.target.system` JVM options, for example, `-Dotel.jmx.target.system=jetty,kafka-broker`. + +## References + +- [Gaining JMX Metric Insights with the OpenTelemetry Java Agent](https://opentelemetry.io/blog/2023/jmx-metric-insight/) + +- [Otel JMX Metrics](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/jmx-metrics) diff --git a/docs/en/docs/insight/quickstart/otel/java/mdc.md b/docs/en/docs/insight/quickstart/otel/java/mdc.md new file mode 100644 index 0000000..e40cbd7 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/java/mdc.md @@ -0,0 +1,115 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Writing TraceId and SpanId into Java Application Logs + +This article explains how to automatically write TraceId and SpanId into Java application logs using OpenTelemetry. By including TraceId and SpanId in your logs, you can correlate distributed tracing data with log data, enabling more efficient fault diagnosis and performance analysis. + +## Supported Logging Libraries + +For more information, please refer to the [Logger MDC auto-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/logger-mdc-instrumentation.md). + +| Logging Framework | Supported Automatic Instrumentation Versions | Dependencies Required for Manual Instrumentation | +| ------------------ | ----------------------------------------- | ----------------------------------------------- | +| Log4j 1 | 1.2+ | None | +| Log4j 2 | 2.7+ | [opentelemetry-log4j-context-data-2.17-autoconfigure](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure) | +| Logback | 1.0+ | [opentelemetry-logback-mdc-1.0](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/logback/logback-mdc-1.0/library) | + +## Using Logback (Spring Boot Project) + +Spring Boot projects come with a built-in logging framework and use Logback as the default logging implementation. If your Java project is a Spring Boot project, you can write TraceId into logs with minimal configuration. + +Set `logging.pattern.level` in `application.properties`, adding `%mdc{trace_id}` and `%mdc{span_id}` to the logs. + +```bash +logging.pattern.level=trace_id=%mdc{trace_id} span_id=%mdc{span_id} %5p ....omited... +``` + +Here is an example of the logs: + +```console +2024-06-26 10:56:31.200 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2024-06-26 10:56:31.201 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2024-06-26 10:56:31.209 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms +2024-06-26 10:56:31.296 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=5743699405074f4e INFO 53724 --- [nio-8081-exec-1] com.example.httpserver.ot.OTServer : hello world +``` + +## Using Log4j2 + +1. Add `OpenTelemetry Log4j2` dependency in `pom.xml`: + + !!! tip + + Please replace `OPENTELEMETRY_VERSION` with the [latest version](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions). + + ```xml + + + io.opentelemetry.instrumentation + opentelemetry-log4j-context-data-2.17-autoconfigure + OPENTELEMETRY_VERSION + runtime + + + ``` + +2. Modify the `log4j2.xml` configuration, adding `%X{trace_id}` and `%X{span_id}` in the `pattern` to automatically write TraceId and SpanId into the logs: + + ```xml + + + + + + + + + + + + + + ``` + +3. If using Logback, add `OpenTelemetry Logback` dependency in `pom.xml`. + + !!! tip + + Please replace `OPENTELEMETRY_VERSION` with the [latest version](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions). + + ```xml + + + io.opentelemetry.instrumentation + opentelemetry-logback-mdc-1.0 + OPENTELEMETRY_VERSION + + + ``` + +4. Modify the `log4j2.xml` configuration, adding `%X{trace_id}` and `%X{span_id}` in the `pattern` to automatically write TraceId and SpanId into the logs: + + ```xml + + + + + %d{HH:mm:ss.SSS} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %msg%n + + + + + + + + + + + + + + + ``` diff --git a/docs/en/docs/insight/quickstart/otel/operator.md b/docs/en/docs/insight/quickstart/otel/operator.md new file mode 100644 index 0000000..5131bcf --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/operator.md @@ -0,0 +1,569 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Enhance Applications Non-Intrusively with Operators + +Currently, only Java, Node.js, Python, .NET, and Golang support non-intrusive integration through the Operator approach. + +## Prerequisites + +Please ensure that the insight-agent is ready. If not, please refer to +[Install insight-agent for data collection](../install/install-agent.md) +and make sure the following three items are ready: + +- Enable trace functionality for insight-agent +- Check if the address and port for trace data are correctly filled +- Ensure that the Pods corresponding to deployment/insight-agent-opentelemetry-operator and + deployment/insight-agent-opentelemetry-collector are ready + +## Install Instrumentation CR + +!!! tip + + Starting from Insight v0.22.0, there is no longer a need to manually install the Instrumentation CR. + +Install it in the insight-system namespace. There are some minor differences between different versions. + +=== "Insight v0.21.x" + + ```bash + K8S_CLUSTER_UID=$(kubectl get namespace kube-system -o jsonpath='{.metadata.uid}') + kubectl apply -f - < language specific env vars -> common env vars -> instrument spec configs' vars + ``` + + However, it is important to avoid manually overriding __OTEL_RESOURCE_ATTRIBUTES_NODE_NAME__ . + This variable serves as an identifier within the operator to determine if a pod has already + been injected with a probe. Manually adding this variable may prevent the probe from being + injected successfully. + +## Automatic injection Demo + +Note that the `annotation` is added under spec.annotations. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-app + labels: + app: my-app +spec: + selector: + matchLabels: + app: my-app + replicas: 1 + template: + metadata: + labels: + app: my-app + annotations: + instrumentation.opentelemetry.io/inject-java: "insight-system/insight-opentelemetry-autoinstrumentation" + spec: + containers: + - name: myapp + image: jaegertracing/vertx-create-span:operator-e2e-tests + ports: + - containerPort: 8080 + protocol: TCP +``` + +The final generated YAML is as follows: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-deployment-with-sidecar-565bd877dd-nqkk6 + generateName: my-deployment-with-sidecar-565bd877dd- + namespace: default + uid: aa89ca0d-620c-4d20-8bc1-37d67bad4ea4 + resourceVersion: '2668986' + creationTimestamp: '2022-04-08T05:58:48Z' + labels: + app: my-pod-with-sidecar + pod-template-hash: 565bd877dd + annotations: + cni.projectcalico.org/containerID: 234eae5e55ea53db2a4bc2c0384b9a1021ed3908f82a675e4a92a49a7e80dd61 + cni.projectcalico.org/podIP: 192.168.134.133/32 + cni.projectcalico.org/podIPs: 192.168.134.133/32 + instrumentation.opentelemetry.io/inject-java: "insight-system/insight-opentelemetry-autoinstrumentation" +spec: + volumes: + - name: kube-api-access-sp2mz + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + defaultMode: 420 + - name: opentelemetry-auto-instrumentation + emptyDir: {} + initContainers: + - name: opentelemetry-auto-instrumentation + image: >- + ghcr.m.daocloud.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java + command: + - cp + - /javaagent.jar + - /otel-auto-instrumentation/javaagent.jar + resources: {} + volumeMounts: + - name: opentelemetry-auto-instrumentation + mountPath: /otel-auto-instrumentation + - name: kube-api-access-sp2mz + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + containers: + - name: myapp + image: ghcr.io/pavolloffay/spring-petclinic:latest + env: + - name: OTEL_JAVAAGENT_DEBUG + value: 'true' + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: 'true' + - name: SPLUNK_PROFILER_ENABLED + value: 'false' + - name: JAVA_TOOL_OPTIONS + value: ' -javaagent:/otel-auto-instrumentation/javaagent.jar' + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://insight-agent-opentelemetry-collector.svc.cluster.local:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: '20' + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: '0.85' + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: 'true' + - name: OTEL_SERVICE_NAME + value: my-deployment-with-sidecar + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES_POD_UID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.uid + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES + value: >- + k8s.container.name=myapp,k8s.deployment.name=my-deployment-with-sidecar,k8s.deployment.uid=8de6929d-dda0-436c-bca1-604e9ca7ea4e,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.pod.uid=$(OTEL_RESOURCE_ATTRIBUTES_POD_UID),k8s.replicaset.name=my-deployment-with-sidecar-565bd877dd,k8s.replicaset.uid=190d5f6e-ba7f-4794-b2e6-390b5879a6c4 + - name: OTEL_PROPAGATORS + value: jaeger,b3 + resources: {} + volumeMounts: + - name: kube-api-access-sp2mz + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + - name: opentelemetry-auto-instrumentation + mountPath: /otel-auto-instrumentation + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + nodeName: k8s-master3 + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + schedulerName: default-scheduler + tolerations: + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + priority: 0 + enableServiceLinks: true + preemptionPolicy: PreemptLowerPriority +``` + +## Trace query + +How to query the connected services, refer to [Trace Query](../../user-guide/trace/trace.md). diff --git a/docs/en/docs/insight/quickstart/otel/otel.md b/docs/en/docs/insight/quickstart/otel/otel.md new file mode 100644 index 0000000..8739712 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/otel.md @@ -0,0 +1,35 @@ +--- +MTPE: windsonsea +Date: 2024-10-16 +--- + +# Use OTel to provide the application observability + +> Enhancement is the process of enabling application code to generate telemetry data. i.e. something that helps you monitor or measure the performance and status of your application. + +OpenTelemetry is a leading open source project providing instrumentation libraries for major programming languages ​​and popular frameworks. It is a project under the Cloud Native Computing Foundation and is supported by the vast resources of the community. +It provides a standardized data format for collected data without the need to integrate specific vendors. + +Insight supports OpenTelemetry for application instrumentation to enhance your applications. + +This guide introduces the basic concepts of telemetry enhancement using OpenTelemetry. +OpenTelemetry also has an ecosystem of libraries, plugins, integrations, and other useful tools to extend it. +You can find these resources at the [OTel Registry](https://opentelemetry.io/registry/). + +You can use any open standard library for telemetry enhancement and use Insight as an observability backend to ingest, analyze, and visualize data. + +To enhance your code, you can use the enhanced operations provided by OpenTelemetry for specific languages: + +Insight currently provides an easy way to enhance .Net NodeJS, Java, Python and Golang applications with OpenTelemetry. Please follow the guidelines below. + +## Trace Enhancement + +- Best practices for integrate trace: [Application Non-Intrusive Enhancement via Operator](./operator.md) +- Manual instrumentation with Go language as an example: [Enhance Go application with OpenTelemetry SDK](golang/golang.md) +- [Using ebpf to implement non-intrusive auto-instrumetation in Go language](./golang-ebpf.md) (experimental feature) + + \ No newline at end of file diff --git a/docs/en/docs/insight/quickstart/otel/send_tracing_to_insight.md b/docs/en/docs/insight/quickstart/otel/send_tracing_to_insight.md new file mode 100644 index 0000000..3ec7fd2 --- /dev/null +++ b/docs/en/docs/insight/quickstart/otel/send_tracing_to_insight.md @@ -0,0 +1,102 @@ +# Sending Trace Data to Insight + +This document describes how customers can send trace data to Insight on their own. It mainly includes the following two scenarios: + +1. Customer apps report traces to Insight through OTEL Agent/SDK +2. Forwarding traces to Insight through Opentelemetry Collector (OTEL COL) + +In each cluster where Insight Agent is installed, there is an __insight-agent-otel-col__ component +that is used to receive trace data from that cluster. Therefore, this component serves as the +entry point for user access and needs to obtain its address first. You can get the address of +the Opentelemetry Collector in the cluster through the AI platform interface, such as + __insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317__ : + +In addition, there are some slight differences for different reporting methods: + +## Customer apps report traces to Insight through OTEL Agent/SDK + +To successfully report trace data to Insight and display it properly, it is recommended to provide +the required metadata (Resource Attributes) for OTLP through the following environment variables. +There are two ways to achieve this: + +- Manually add them to the deployment YAML file, for example: + + ```yaml + ... + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317" + - name: "OTEL_SERVICE_NAME" + value: my-java-app-name + - name: "OTEL_K8S_NAMESPACE" + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)" + ``` + +- Use the automatic injection capability of Insight Agent to inject the metadata (Resource Attributes) + + Ensure that Insight Agent is working properly and after [installing the Instrumentation CR](./operator.md#instrumentation-cr), + you only need to add the following annotation to the Pod: + + ```console + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + + For example: + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-deployment-with-aotu-instrumentation + spec: + selector: + matchLabels: + app.kubernetes.io/name: my-deployment-with-aotu-instrumentation-kuberntes + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: my-deployment-with-aotu-instrumentation-kuberntes + annotations: + sidecar.opentelemetry.io/inject: "false" + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + +## Forwarding traces to Insight through Opentelemetry Collector + +After ensuring that the application has added the metadata mentioned above, you only need to add +an OTLP Exporter in your customer's Opentelemetry Collector to forward the trace data to +Insight Agent Opentelemetry Collector. Below is an example Opentelemetry Collector configuration file: + +```yaml +... +exporters: + otlp/insight: + endpoint: insight-opentelemetry-collector.insight-system.svc.cluster.local:4317 +service: +... +pipelines: +... +traces: + exporters: + - otlp/insight +``` + +## References + +- [Enhancing Applications Non-intrusively with the Operator](./operator.md) +- [Achieving Observability with OTel](./otel.md) diff --git a/docs/en/docs/insight/quickstart/other/install-agent-on-ocp.md b/docs/en/docs/insight/quickstart/other/install-agent-on-ocp.md new file mode 100644 index 0000000..d1bc7ff --- /dev/null +++ b/docs/en/docs/insight/quickstart/other/install-agent-on-ocp.md @@ -0,0 +1,68 @@ +# OpenShift Install Insight Agent + +Although the OpenShift system comes with a monitoring system, we will still install Insight Agent because of some rules in the data collection agreement. + +Among them, in addition to the basic installation configuration, the following parameters need to be added during helm install: + +```bash +## Parameters related to fluentbit; +--set fluent-bit.ocp.enabled=true \ +--set fluent-bit.serviceAccount.create=false \ +--set fluent-bit.securityContext.runAsUser=0 \ +--set fluent-bit.securityContext.seLinuxOptions.type=spc_t \ +--set fluent-bit.securityContext.readOnlyRootFilesystem=false \ +--set fluent-bit.securityContext.allowPrivilegeEscalation=false \ + +## Enable Prometheus(CR) for OpenShift4.x +--set compatibility.openshift.prometheus.enabled=true \ + +## Close the Prometheus instance of the higher version +--set kube-prometheus-stack.prometheus.enabled=false \ +--set kube-prometheus-stack.kubeApiServer.enabled=false \ +--set kube-prometheus-stack.kubelet.enabled=false \ +--set kube-prometheus-stack.kubeControllerManager.enabled=false \ +--set kube-prometheus-stack.coreDns.enabled=false \ +--set kube-prometheus-stack.kubeDns.enabled=false \ +--set kube-prometheus-stack.kubeEtcd.enabled=false \ +--set kube-prometheus-stack.kubeEtcd.enabled=false \ +--set kube-prometheus-stack.kubeScheduler.enabled=false \ +--set kube-prometheus-stack.kubeStateMetrics.enabled=false \ +--set kube-prometheus-stack.nodeExporter.enabled=false \ + +## Limit the namespace processed by PrometheusOperator to avoid competition with OpenShift's own PrometheusOperator +--set kube-prometheus-stack.prometheusOperator.kubeletService.namespace="insight-system" \ +--set kube-prometheus-stack.prometheusOperator.prometheusInstanceNamespaces="insight-system" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[0]="openshift-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[1]="openshift-user-workload-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[2]="openshift-customer-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[3]="openshift-route-monitor-operator" \ +``` + +### Write system monitoring data into Prometheus through OpenShift's own mechanism + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-monitoring-config + namespace: openshift-monitoring +data: + config.yaml: | + prometheusK8s: + remoteWrite: + - queueConfig: + batchSendDeadline: 60s + maxBackoff: 5s + minBackoff: 30ms + minShards: 1 + capacity: 5000 + maxSamplesPerSend: 1000 + maxShards: 100 + remoteTimeout: 30s + url: http://insight-agent-prometheus.insight-system.svc.cluster.local:9090/api/v1/write + writeRelabelConfigs: + - action: keep + regex: etcd|kubelet|node-exporter|apiserver|kube-state-metrics + sourceLabels: + - job +``` diff --git a/docs/en/docs/insight/quickstart/other/install-agentindce.md b/docs/en/docs/insight/quickstart/other/install-agentindce.md new file mode 100644 index 0000000..37da126 --- /dev/null +++ b/docs/en/docs/insight/quickstart/other/install-agentindce.md @@ -0,0 +1,70 @@ +# Install insight-agent in Suanova 4.0 + +In AI platform, previous Suanova 4.0 can be accessed as a subcluster. This guide provides potential issues and solutions when installing insight-agent in a Suanova 4.0 cluster. + +## Issue One + +Since most Suanova 4.0 clusters have installed dx-insight as the monitoring system, installing insight-agent at this time will conflict with the existing prometheus operator in the cluster, making it impossible to install smoothly. + +### Solution + +Enable the parameters of the prometheus operator, retain the prometheus operator in dx-insight, and make it compatible with the prometheus operator in insight-agent in 5.0. + +### Steps + +1. Log in to the console. +2. Enable the __--deny-namespaces__ parameter in the two prometheus operators respectively. +3. Run the following command (the following command is for reference only, the actual command needs to replace the prometheus operator name and namespace in the command). + + ```bash + kubectl edit deploy insight-agent-kube-prometh-operator -n insight-system + ``` + + ![operatoryaml](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/promerator.png) + +!!! note + - As shown in the figure above, the dx-insight component is deployed under the dx-insight tenant, and the insight-agent is deployed under the insight-system tenant. + Add __--deny-namespaces=insight-system__ in the prometheus operator in dx-insight, + Add __--deny-namespaces=dx-insight__ in the prometheus operator in insight-agent. + - Just add deny namespace, both prometheus operators can continue to scan other namespaces, and the related collection resources under kube-system or customer business namespaces are not affected. + - Please pay attention to the problem of node exporter port conflict. + +### Supplementary Explanation + +The open-source __node-exporter__ turns on hostnetwork by default and the default port is 9100. +If the monitoring system of the cluster has installed __node-exporter__ , then installing __insight-agent__ at this time will cause node-exporter port conflict and it cannot run normally. + +!!! note + Insight's __node exporter__ will enable some features to collect special indicators, so it is recommended to install. + +Currently, it does not support modifying the port in the installation command. After __helm install insight-agent__ , you need to manually modify the related ports of the insight node-exporter daemonset and svc. + +## Issue Two + +After Insight Agent is successfully deployed, fluentbit does not collect logs of Suanova 4.0. + +### Solution + +The docker storage directory of Suanova 4.0 is __/var/lib/containers__ , which is different from the path in the configuration of insigh-agent, so the logs are not collected. + +### Steps + +1. Log in to the console. +2. Modify the following parameters in the insight-agent Chart. + + ```diff + fluent-bit: + daemonSetVolumeMounts: + - name: varlog + mountPath: /var/log + - name: varlibdockercontainers + - mountPath: /var/lib/docker/containers + + mountPath: /var/lib/containers/docker/containers + readOnly: true + - name: etcmachineid + mountPath: /etc/machine-id + readOnly: true + - name: dmesg + mountPath: /var/log/dmesg + readOnly: true + ``` diff --git a/docs/en/docs/insight/quickstart/res-plan/modify-vms-disk.md b/docs/en/docs/insight/quickstart/res-plan/modify-vms-disk.md new file mode 100644 index 0000000..bc7db3e --- /dev/null +++ b/docs/en/docs/insight/quickstart/res-plan/modify-vms-disk.md @@ -0,0 +1,85 @@ +# vmstorage Disk Expansion + +This article describes the method for expanding the vmstorage disk. Please refer to the [vmstorage disk capacity planning](../res-plan/vms-res-plan.md) for the specifications of the vmstorage disk. + +## Procedure + +### Enable StorageClass expansion + +1. Log in to the AI platform platform as a global service cluster administrator. Click __Container Management__ -> __Clusters__ and go to the details of the __kpanda-global-cluster__ cluster. + +2. Select the left navigation menu __Container Storage__ -> __PVCs__ and find the PVC bound to the vmstorage. + + ![Find vmstorage](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk01.png) + +3. Click a vmstorage PVC to enter the details of the volume claim for vmstorage and confirm the StorageClass that the PVC is bound to. + + ![Modify Disk](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk02.png) + +4. Select the left navigation menu __Container Storage__ -> __Storage Class__ and find __local-path__ . Click the __┇__ on the right side of the target and select __Edit__ in the popup menu. + + ![Edit StorageClass](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk03.png) + +5. Enable __Scale Up__ and click __OK__ . + + ![Scale Up](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk04.png) + +### Modify the disk capacity of vmstorage + +1. Log in to the AI platform platform as a global service cluster administrator and go to the details of the __kpanda-global-cluster__ cluster. + +2. Select the left navigation menu __CRDs__ and find the custom resource for __vmcluster__ . + + ![vmcluster](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk05.png) + +3. Click the custom resource for vmcluster to enter the details page, switch to the __insight-system__ namespace, and select __Edit YAML__ from the right menu of __insight-victoria-metrics-k8s-stack__ . + + ![Edit YAML](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk06.png) + +4. Modify according to the legend and click __OK__ . + + ![Confirm Edit](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk07.png) + +5. Select the left navigation menu __Container Storage__ -> __PVCs__ again and find the volume claim bound to vmstorage. Confirm that the modification has taken effect. In the details page of a PVC, click the associated storage source (PV). + + ![Relate PV](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk08.png) + +6. Open the volume details page and click the __Update__ button in the upper right corner. + + ![Update](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk09.png) + +7. After modifying the __Capacity__ , click __OK__ and wait for a moment until the expansion is successful. + + ![Edit Storage](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk10.png) + +### Clone the storage volume + +If the storage volume expansion fails, you can refer to the following method to clone the storage volume. + +1. Log in to the AI platform platform as a global service cluster administrator and go to the details of the __kpanda-global-cluster__ cluster. + +2. Select the left navigation menu __Workloads__ -> __StatefulSets__ and find the statefulset for __vmstorage__ . Click the __┇__ on the right side of the target and select __Status__ -> __Stop__ -> __OK__ in the popup menu. + + ![Stop Status](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk11.png) + +3. After logging into the __master__ node of the __kpanda-global-cluster__ cluster in the command line, run the following command to copy the vm-data directory in the vmstorage container to store the metric information locally: + + ```bash + kubectl cp -n insight-system vmstorage-insight-victoria-metrics-k8s-stack-1:vm-data ./vm-data + ``` + +4. Log in to the AI platform platform and go to the details of the __kpanda-global-cluster__ cluster. Select the left navigation menu __Container Storage__ -> __PVs__ , click __Clone__ in the upper right corner, and modify the capacity of the volume. + + ![Clone](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk12.png) + + ![Edit Storage](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk13.png) + +5. Delete the previous data volume of vmstorage. + + ![Delete vmstorage](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/quickstart/images/vmdisk14.png) + +6. Wait for a moment until the volume claim is bound to the cloned data volume, then run the following command to import the exported data from step 3 into the corresponding container, and then start the previously paused __vmstorage__ . + + ```bash + kubectl cp -n insight-system ./vm-data vmstorage-insight-victoria-metrics-k8s-stack-1:vm-data + ``` diff --git a/docs/en/docs/insight/quickstart/res-plan/prometheus-res.md b/docs/en/docs/insight/quickstart/res-plan/prometheus-res.md new file mode 100644 index 0000000..22b1921 --- /dev/null +++ b/docs/en/docs/insight/quickstart/res-plan/prometheus-res.md @@ -0,0 +1,64 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-24 +--- + +# Prometheus Resource Planning + +In the actual use of Prometheus, affected by the number of cluster containers and the opening of Istio, +the CPU, memory and other resource usage of Prometheus will exceed the set resources. + +In order to ensure the normal operation of Prometheus in clusters of different sizes, +it is necessary to adjust the resources of Prometheus according to the actual size of the cluster. + +## Reference resource planning + +In the case that the mesh is not enabled, the test statistics show that the relationship +between the system Job index and pods is **Series count = 800 \* pod count** + +When the service mesh is enabled, the magnitude of the Istio-related metrics generated +by the pod after the feature is enabled is **Series count = 768 \* pod count** + +### When the service mesh is not enabled + +The following resource planning is recommended by Prometheus when **the service mesh is not enabled** : + +| Cluster size (pod count) | Metrics (service mesh is not enabled) | CPU (core) | Memory (GB) | +| ---------------- | ---------------------- | ------------------ | ------------------------ | +| 100 | 8w | Request: 0.5
Limit: 1 | Request: 2GB
Limit: 4GB | +| 200 | 16w | Request: 1
Limit: 1.5 | Request: 3GB
Limit: 6GB | +| 300 | 24w | Request: 1
Limit: 2 | Request: 3GB
Limit: 6GB | +| 400 | 32w | Request: 1
Limit: 2 | Request: 4GB
Limit: 8GB | +| 500 | 40w | Request: 1.5
Limit: 3 | Request: 5GB
Limit: 10GB | +| 800 | 64w | Request: 2
Limit: 4 | Request: 8GB
Limit: 16GB | +| 1000 | 80w | Request: 2.5
Limit: 5 | Request: 9GB
Limit: 18GB | +| 2000 | 160w | Request: 3.5
Limit: 7 | Request: 20GB
Limit: 40GB | +| 3000 | 240w | Request: 4
Limit: 8 | Request: 33GB
Limit: 66GB | + +### When the service mesh feature is enabled + +The following resource planning is recommended by Prometheus in the scenario of **starting the service mesh**: + +| Cluster size (pod count) | metric volume (service mesh enabled) | CPU (core) | Memory (GB) | +| ---------------- | -------------------- | --------------------- | ------------------------ | +| 100 | 15w | Request: 1
Limit: 2 | Request: 3GB
Limit: 6GB | +| 200 | 31w | Request: 2
Limit: 3 | Request: 5GB
Limit: 10GB | +| 300 | 46w | Request: 2
Limit: 4 | Request: 6GB
Limit: 12GB | +| 400 | 62w | Request: 2
Limit: 4 | Request: 8GB
Limit: 16GB | +| 500 | 78w | Request: 3
Limit: 6 | Request: 10GB
Limit: 20GB | +| 800 | 125w | Request: 4
Limit: 8 | Request: 15GB
Limit: 30GB | +| 1000 | 156w | Request: 5
Limit: 10 | Request: 18GB
Limit: 36GB | +| 2000 | 312w | Request: 7
Limit: 14 | Request: 40GB
Limit: 80GB | +| 3000 | 468w | Request: 8
Limit: 16 | Request: 65GB
Limit: 130GB | + +!!! note + + 1. __Pod count__ in the table refers to the pod count that is basically running stably in the cluster. + If a large number of pods are restarted, the index will increase sharply in a short period of time. + At this time, resources need to be adjusted accordingly. + 2. Prometheus stores two hours of data by default in memory, and when the + [Remote Write function](https://prometheus.io/docs/practices/remote_write/#memory-usage) is enabled in the cluster, + a certain amount of memory will be occupied, and resources surge ratio is recommended to be set to 2. + 3. The data in the table are recommended values, applicable to general situations. + If the environment has precise resource requirements, it is recommended to check the resource usage of + the corresponding Prometheus after the cluster has been running for a period of time for precise configuration. diff --git a/docs/en/docs/insight/quickstart/res-plan/vms-res-plan.md b/docs/en/docs/insight/quickstart/res-plan/vms-res-plan.md new file mode 100644 index 0000000..85364d9 --- /dev/null +++ b/docs/en/docs/insight/quickstart/res-plan/vms-res-plan.md @@ -0,0 +1,83 @@ +# vmstorage disk capacity planning + +vmstorage is responsible for storing multicluster metrics for observability. +In order to ensure the stability of vmstorage, it is necessary to adjust the disk capacity +of vmstorage according to the number of clusters and the size of the cluster. +For more information, please refer to [vmstorage retention period and disk space](https://docs.victoriametrics.com/guides/understand-your-setup-size.html?highlight=datapoint#retention-perioddisk-space). + +## Test Results + +After 14 days of disk observation of vmstorage of clusters of different sizes, +We found that the disk usage of vmstorage was positively correlated with the +amount of metrics it stored and the disk usage of individual data points. + +1. The amount of metrics stored instantaneously __increase(vm_rows{ type != "indexdb"}[30s])__ + to obtain the increased amount of metrics within 30s +2. Disk usage of a single data point: __sum(vm_data_size_bytes{type!="indexdb"}) / sum(vm_rows{type != "indexdb"})__ + +## calculation method + +**Disk usage** = Instantaneous metrics x 2 x disk usage for a single data point x 60 x 24 x storage time (days) + +**Parameter Description:** + +1. The unit of disk usage is __Byte__ . +2. __Storage duration (days) x 60 x 24__ converts time (days) into minutes to calculate disk usage. +3. The default collection time of Prometheus in Insight Agent is 30s, so twice the amount of metrics + will be generated within 1 minute. +4. The default storage duration in vmstorage is 1 month, please refer to + [Modify System Configuration](../../user-guide/system-config/modify-config.md) to modify the configuration. + +!!! warning + + This formula is a general solution, and it is recommended to reserve redundant disk + capacity on the calculation result to ensure the normal operation of vmstorage. + +## reference capacity + +The data in the table is calculated based on the default storage time of one month (30 days), +and the disk usage of a single data point (datapoint) is calculated as 0.9. +In a multicluster scenario, the number of Pods represents the sum of the number of Pods in the multicluster. + +### When the service mesh is not enabled + +| Cluster size (number of Pods) | Metrics | Disk capacity | +| ----------------- | ------ | -------- | +| 100 | 8W | 6 GiB | +| 200 | 16W | 12 GiB | +| 300 | 24w | 18 GiB | +| 400 | 32w | 24 GiB | +| 500 | 40w | 30 GiB | +| 800 | 64w | 48 GiB | +| 1000 | 80W | 60 GiB | +| 2000 | 160w | 120 GiB | +| 3000 | 240w | 180 GiB | + +### When the service mesh is enabled + +| Cluster size (number of Pods) | Metrics | Disk capacity | +| ----------------- | ------ | -------- | +| 100 | 15W | 12 GiB | +| 200 | 31w | 24 GiB | +| 300 | 46w | 36 GiB | +| 400 | 62w | 48 GiB | +| 500 | 78w | 60 GiB | +| 800 | 125w | 94 GiB | +| 1000 | 156w | 120 GiB | +| 2000 | 312w | 235 GiB | +| 3000 | 468w | 350 GiB | + +### Example + +There are two clusters in the AI platform platform, of which 500 Pods are running in the global management cluster +(service mesh is turned on), and 1000 Pods are running in the worker cluster (service mesh is not turned on), and the expected metrics are stored for 30 days. + +- The number of metrics in the global management cluster is 800x500 + 768x500 = 784000 +- Worker cluster metrics are 800x1000 = 800000 + +Then the current vmstorage disk usage should be set to (784000+80000)x2x0.9x60x24x31 =124384896000 byte = 116 GiB + +!!! note + + For the relationship between the number of metrics and the number of Pods in the cluster, + please refer to [Prometheus Resource Planning](./prometheus-res.md). diff --git a/docs/en/docs/insight/user-guide/alert-center/alert-policy.md b/docs/en/docs/insight/user-guide/alert-center/alert-policy.md new file mode 100644 index 0000000..93167f5 --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/alert-policy.md @@ -0,0 +1,83 @@ +# Alert Policies + +In addition to the built-in alert policies, AI platform allows users to create custom alert policies. Each alert policy is a collection of alert rules that can be set for clusters, nodes, and workloads. When an alert object reaches the threshold set by any of the rules in the policy, an alert is automatically triggered and a notification is sent. + +Taking the built-in alerts as an example, click the first alert policy __alertmanager.rules__ . + +![alert policy](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy01.png) + +You can see that some alert rules have been set under it. You can add more rules under this policy, or edit or delete them at any time. You can also view the historical and active alerts related to this alert policy and edit the notification configuration. + +![alertmanager.rules](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy02.png) + +## Create Alert Policies + +1. Select __Alert Center__ -> __Alert Policies__ , and click the __Create Alert Policy__ button. + + ![alert policy](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy01.png) + +2. Fill in the basic information, select one or more clusters, nodes, or workloads as the alert objects, and click __Next__ . + + ![basic information](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy03.png) + +3. The list must have at least one rule. If the list is empty, please __Add Rule__ . + + ![add rule](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy04.png) + + Create an alert rule in the pop-up window, fill in the parameters, and click __OK__ . + + ![create rule](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy05.png) + + - Template rules: Pre-defined basic metrics that can monitor CPU, memory, disk, and network. + - PromQL rules: Input a PromQL expression, please [query Prometheus expressions](https://prometheus.io/docs/prometheus/latest/querying/basics/). + - Duration: After the alert is triggered and the duration reaches the set value, the alert policy will become a triggered state. + - Alert level: Including emergency, warning, and information levels. + - Advanced settings: Custom tags and annotations. + +4. After clicking __Next__ , configure notifications. + + ![notification configuration](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy06.png) + +5. After the configuration is complete, click the __OK__ button to return to the Alert Policy list. + +!!! tip + + The newly created alert policy is in the __Not Triggered__ state. Once the threshold conditions and duration specified in the rules are met, it will change to the __Triggered__ state. + +### Create Log Rules + +After filling in the basic information, click __Add Rule__ and select __Log Rule__ as the rule type. + +Creating log rules is supported only when the resource object is selected as a node or workload. + +**Field Explanation:** + +- __Filter Condition__ : Field used to query log content, supports four filtering conditions: AND, OR, regular expression matching, and fuzzy matching. +- __Condition__ : Based on the filter condition, enter keywords or matching conditions. +- __Time Range__ : Time range for log queries. +- __Threshold Condition__ : Enter the alert threshold value in the input box. When the set threshold is reached, an alert will be triggered. Supported comparison operators are: >, ≥, =, ≤, <. +- __Alert Level__ : Select the alert level to indicate the severity of the alert. + +### Create Event Rules + +After filling in the basic information, click __Add Rule__ and select __Event Rule__ as the rule type. + +Creating event rules is supported only when the resource object is selected as a workload. + +**Field Explanation:** + +- __Event Rule__ : Only supports selecting the workload as the resource object. +- __Event Reason__ : Different event reasons for different types of workloads, where the event reasons are combined with "AND" relationship. +- __Time Range__ : Detect data generated within this time range. If the threshold condition is reached, an alert event will be triggered. +- __Threshold Condition__ : When the generated events reach the set threshold, an alert event will be triggered. +- __Trend Chart__ : By default, it queries the trend of event changes within the last 10 minutes. The value at each point represents the total number of occurrences within a certain period of time (time range) from the current time point to a previous time. + +## Other Operations + +Click __┇__ at the right side of the list, then choose __Delete__ from the pop-up menu to delete an alert policy. By clicking on the policy name, you can enter the policy details where you can add, edit, or delete the alert rules under it. + +![alert rule](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert-policy07.png) + +!!! warning + + Deleted alert strategies will be permanently removed, so please proceed with caution. diff --git a/docs/en/docs/insight/user-guide/alert-center/alert-template.md b/docs/en/docs/insight/user-guide/alert-center/alert-template.md new file mode 100644 index 0000000..a3a2e86 --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/alert-template.md @@ -0,0 +1,46 @@ +--- +MTPE: ModetaNiu +date: 2024-07-01 +--- + +# Alert Template + +The Alert template allows platform administrators to create Alert templates and rules, and +business units can directly use Alert templates to create Alert policies. This feature can +reduce the management of Alert rules by business personnel and allow for modification of +Alert thresholds based on actual environment conditions. + +## Create Alert Template + +1. In the navigation bar, select **Alert** -> **Alert Policy**, and click **Alert Template** at the top. + + ![Alert Template](../../user-guide/images/template01.png){ width=1000px} + +2. Click **Create Alert Template**, and set the name, description, and other information for the Alert template. + + ![Basic Information](../../user-guide/images/template02.png){ width=1000px} + + ![Alert Rule](../../user-guide/images/template03.png){ width=1000px} + + | Parameter | Description | + | ---- | ---- | + | Template Name | The name can only contain lowercase letters, numbers, and hyphens (-), must start and end with a lowercase letter or number, and can be up to 63 characters long. | + | Description | The description can contain any characters and can be up to 256 characters long. | + | Resource Type | Used to specify the matching type of the Alert template. | + | Alert Rule | Supports pre-defined multiple Alert rules, including template rules and PromQL rules. | + +3. Click **OK** to complete the creation and return to the Alert template list. Click the template name + to view the template details. + +## Edit Alert Template + +Click **┇** next to the target rule, then click **Edit** to enter the editing page for the suppression rule. + + ![Edit](../../user-guide/images/template04.png){ width=1000px} + +## Delete Alert Template + +Click **┇** next to the target template, then click **Delete**. Enter the name of the Alert template +in the input box to confirm deletion. + + ![Delete](../../user-guide/images/template05.png){ width=1000px} diff --git a/docs/en/docs/insight/user-guide/alert-center/index.md b/docs/en/docs/insight/user-guide/alert-center/index.md new file mode 100644 index 0000000..d2644ea --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/index.md @@ -0,0 +1,36 @@ +# Alert Center + +The Alert Center is an important feature provided by AI platform that allows users +to easily view all active and historical alerts by cluster and namespace through +a graphical interface, and search alerts based on severity level (critical, warning, info). + +![alert list](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/alert01.png) + +All alerts are triggered based on the threshold conditions set in the preset alert rules. +In AI platform, some global alert policies are built-in, but users can also create or delete +alert policies at any time, and set thresholds for the following metrics: + +- CPU usage +- Memory usage +- Disk usage +- Disk reads per second +- Disk writes per second +- Cluster disk read throughput +- Cluster disk write throughput +- Network send rate +- Network receive rate + +Users can also add labels and annotations to alert rules. Alert rules can be classified as +active or expired, and certain rules can be enabled/disabled to achieve silent alerts. + +When the threshold condition is met, users can configure how they want to be notified, +including email, DingTalk, WeCom, webhook, and SMS notifications. All notification +message templates can be customized and all messages are sent at specified intervals. + +In addition, the Alert Center also supports sending alert messages to designated users +through short message services provided by Alibaba Cloud, Tencent Cloud, and more platforms +that will be added soon, enabling multiple ways of alert notification. + +AI platform Alert Center is a powerful alert management platform that helps users +quickly detect and resolve problems in the cluster, improve business stability and availability, +and facilitate cluster inspection and troubleshooting. diff --git a/docs/en/docs/insight/user-guide/alert-center/inhibition.md b/docs/en/docs/insight/user-guide/alert-center/inhibition.md new file mode 100644 index 0000000..0fbe9f2 --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/inhibition.md @@ -0,0 +1,79 @@ +--- +MTPE: ModetaNiu +Date: 2024-07-01 +--- + +# Alert Inhibition + +Alert Inhibition is mainly a mechanism for temporarily hiding or reducing the priority of alerts that do not need +immediate attention. The purpose of this feature is to reduce unnecessary alert information that may disturb +operations personnel, allowing them to focus on more critical issues. + +Alert inhibition recognizes and ignores certain alerts by defining a set of rules to deal with specific conditions. +There are mainly the following conditions: + +- Parent-child inhibition: when a parent alert (for example, a crash on a node) is triggered, all child alerts aroused by + it (for example, a crash on a container running on that node) are inhibited. +- Similar alert inhibition: When alerts have the same characteristics (for example, the same problem on the same instance), + multiple alerts are inhibited. + +## Create Inhibition + +1. In the left navigation bar, select **Alert** -> **Noise Reduction**, and click **Inhibition** at the top. + + ![Inhibition](../../user-guide/images/inhibition01.png){ width=1000px} + +2. Click **Create Inhibition**, and set the name and rules for the inhibition. + + !!! note + + The problem of avoiding multiple similar or related alerts that may be triggered by the same issue is achieved + by defining a set of rules to identify and ignore certain alerts through [Rule Details](#view-rule-details) + and [Alert Details](#view-alert-details). + + ![Create Inhibition](../../user-guide/images/inhibition02.png){ width=1000px} + + | Parameter | Description | + | ---- | ---- | + | Name | The name can only contain lowercase letters, numbers, and hyphens (-), must start and end with a lowercase letter or number, and can be up to 63 characters long. | + | Description | The description can contain any characters and can be up to 256 characters long. | + | Cluster | The cluster where the inhibition rule applies. | + | Namespace | The namespace where the inhibition rule applies. | + | Source Alert | Matching alerts by label conditions. It compares alerts that meet all label conditions with those that meet inhibition conditions, and alerts that do not meet inhibition conditions will be sent to the user as usual.

Value range explanation:
- **Alert Level**: The level of metric or event alerts, can be set as: Critical, Major, Minor.
- **Resource Type**: The resource type specific for the alert object, can be set as: Cluster, Node, StatefulSet, Deployment, DaemonSet, Pod.
- **Labels**: Alert identification attributes, consisting of label name and label value, supports user-defined values. | + | Inhibition | Specifies the matching conditions for the target alert (the alert to be inhibited). Alerts that meet all the conditions will no longer be sent to the user. | + | Equal | Specifies the list of labels to compare to determine if the source alert and target alert match. Inhibition is triggered only when the values of the labels specified in `equal` are exactly the same in the source and target alerts. The `equal` field is optional. If the `equal` field is omitted, all labels are used for matching. | + +3. Click **OK** to complete the creation and return to Inhibition list. Click the inhibition rule name to view the rule details. + +### View Rule Details + +In the left navigation bar, select **Alert** -> **Alert Policy**, and click the policy name to view the rule details. + + ![Rule details](../../image/inhibition.png) + + !!! note + + You can add cuntom tags when adding rules. + +### View Alert Details + +In the left navigation bar, select **Alert** -> **Alerts**, and click the policy name to view details. + + ![Alert details](../../image/inhibition-01.png) + + !!! note + + Alert details show information and settings for creating inhibitions. + +## Edit Inhibition Rule + +Click **┇** next to the target rule, then click **Edit** to enter the editing page for the inhibition rule. + +![Edit Rules](../../user-guide/images/inhibition03.png){ width=1000px} + +## Delete Inhibition Rule + +Click **┇** next to the target rule, then click **Delete**. Enter the name of the inhibition rule in the input box +to confirm deletion. + +![Delete Rules](../../user-guide/images/inhibition04.png){ width=1000px} diff --git a/docs/en/docs/insight/user-guide/alert-center/message.md b/docs/en/docs/insight/user-guide/alert-center/message.md new file mode 100644 index 0000000..95da06e --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/message.md @@ -0,0 +1,88 @@ +# Notification Settings + +On the __Notification Settings__ page, you can configure how to send messages to users through email, WeCom, DingTalk, Webhook, and SMS. + +## Email Group + +1. After entering __Insight__ , click __Alert Center__ -> __Notification Settings__ in the left navigation bar. + By default, the email notification object is selected. Click __Add email group__ and add one or more email addresses. + +2. Multiple email addresses can be added. + + ![WeCom](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/notify02.png) + +3. After the configuration is complete, the notification list will automatically return. Click __┇__ on the right side + of the list to edit or delete the email group. + +## WeCom + +1. In the left navigation bar, click __Alert Center__ -> __Notification Settings__ -> __WeCom__ . Click __Add Group Robot__ and add one or more group robots. + + For the URL of the WeCom group robot, please refer to the [official document of WeCom: How to use group robots](https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html). + +2. After the configuration is complete, the notification list will automatically return. Click __┇__ on the right side + of the list, select __Send Test Information__ , and you can also edit or delete the group robot. + +## DingTalk + +1. In the left navigation bar, click __Alert Center__ -> __Notification Settings__ -> __DingTalk__ . + Click __Add Group Robot__ and add one or more group robots. + + For the URL of the DingTalk group robot, please refer to the [official document of DingTalk: Custom Robot Access](https://developers.dingtalk.com/document/robots/custom-robot-access). + +2. After the configuration is complete, the notification list will automatically return. Click __┇__ on the right + side of the list, select __Send Test Information__ , and you can also edit or delete the group robot. + +## Lark + +1. In the left navigation bar, click __Alert Center__ -> __Notification Settings__ -> __Lark__ . Click __Add Group Bot__ + and add one or more group bots. + + ![Lark](../../image/notify-01.png) + + !!! note + + When signature verification is required in Lark's group bot, you need to fill in the specific signature key + when enabling notifications. Refer to [Customizing Bot User Guide](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot). + +2. After configuration, you will be automatically redirected to the list page. Click __┇__ on the right side of the list + and select __Send Test Message__ . You can edit or delete group bots. + +## Webhook + +1. In the left navigation bar, click __Alert Center__ -> __Notification Settings__ -> __Webhook__ . + Click __New Webhook__ and add one or more Webhooks. + + For the Webhook URL and more configuration methods, please refer to the [webhook document](https://github.com/webhooksite/webhook.site). + +2. After the configuration is complete, the notification list will automatically return. Click __┇__ on the right side + of the list, select __Send Test Information__ , and you can also edit or delete the Webhook. + +## Message + +!!! note + + Alert messages are sent to the personal Message sector and notifications can be viewed by clicking 🔔 at the top. + +1. In the left navigation bar, click __Alert Center__ -> __Notification Settings__ -> __Message__,click __Create Message__ . + + You can add and notify multiple users for a message. + + ![message](../../image/notify-02.png) + +2. After configuration, you will be automatically redirected to the list page. Click __┇__ on the right side of + the list and select __Send Test Message__ . + +## SMS Group + +1. In the left navigation bar, click __Alert Center__ -> __Notification Settings__ -> __SMS__ . Click __Add SMS Group__ + and add one or more SMS groups. + +2. Enter the name, the object receiving the message, phone number, and notification server in the pop-up window. + + The notification server needs to be created in advance under __Notification Settings__ -> __Notification Server__ . + Currently, two cloud servers, Alibaba Cloud and Tencent Cloud, are supported. Please refer to your own + cloud server information for the specific configuration parameters. + +3. After the SMS group is successfully added, the notification list will automatically return. Click __┇__ on the + right side of the list to edit or delete the SMS group. diff --git a/docs/en/docs/insight/user-guide/alert-center/msg-template.md b/docs/en/docs/insight/user-guide/alert-center/msg-template.md new file mode 100644 index 0000000..c4903da --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/msg-template.md @@ -0,0 +1,49 @@ +# Message Templates + +The message template feature supports customizing the content of message templates and can notify specified objects in the form of email, WeCom, DingTalk, Webhook, and SMS. + +## Creating a Message Template + +1. In the left navigation bar, select __Alert__ -> __Message Template__ . + + Insight comes with two default built-in templates in both Chinese and English for user convenience. + + ![Click button](../images/template00.png) + +2. Fill in the template content. + + ![message template](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/template02.png) + +!!! info + + Observability comes with predefined message templates. If you need to define the content of the templates, refer to [Configure Notification Templates](../../reference/notify-helper.md). + +## Message Template Details + +Click the name of a message template to view the details of the message template in the right slider. + +![Message Template](../images/msg-detail.png) + +| Parameters | Variable | Description | +|------------|----------|-------------| +| ruleName | {{ .Labels.alertname }} | The name of the rule that triggered the alert | +| groupName | {{ .Labels.alertgroup }} | The name of the alert policy to which the alert rule belongs | +| severity | {{ .Labels.severity }} | The level of the alert that was triggered | +| cluster | {{ .Labels.cluster }} | The cluster where the resource that triggered the alert is located | +| namespace | {{ .Labels.namespace }} | The namespace where the resource that triggered the alert is located | +| node | {{ .Labels.node }} | The node where the resource that triggered the alert is located | +| targetType | {{ .Labels.target_type }} | The resource type of the alert target | +| target | {{ .Labels.target }} | The name of the object that triggered the alert | +| value | {{ .Annotations.value }} | The metric value at the time the alert notification was triggered | +| startsAt | {{ .StartsAt }} | The time when the alert started to occur | +| endsAt | {{ .EndsAt }} | The time when the alert ended | +| description | {{ .Annotations.description }} | A detailed description of the alert | +| labels | {{ for .labels }} {{ end }} | All labels of the alert use the `for` function to iterate through the labels list to get all label contents. | + +## Editing or Deleting a Message Template + +Click __┇__ on the right side of the list and select __Edit__ or __Delete__ from the pop-up menu to modify or delete the message template. + +!!! warning + + Once a template is deleted, it cannot be recovered, so please use caution when deleting templates. diff --git a/docs/en/docs/insight/user-guide/alert-center/silent.md b/docs/en/docs/insight/user-guide/alert-center/silent.md new file mode 100644 index 0000000..59141de --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/silent.md @@ -0,0 +1,30 @@ +--- +MTPE: ModetaNiu +Date: 2024-07-01 +--- + +# Alert Silence + +Alert silence is a feature that allows alerts meeting certain criteria to be temporarily disabled from +sending notifications within a specific time range. This feature helps operations personnel avoid receiving +too many noisy alerts during certain operations or events, while also allowing for more precise handling of real issues +that need to be addressed. + +On the Alert Silence page, you can see two tabs: Active Rule and Expired Rule. The former presents the rules currently in effect, +while the latter presents those that were defined in the past but have now expired (or have been deleted by the user). + +## Creating a Silent Rule + +1. In the left navigation bar, select __Alert__ -> __Noice Reduction__ -> __Alert Silence__ , and click the __Create Silence Rule__ button. + + ![click button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/silent01.png) + +2. Fill in the parameters for the silent rule, such as cluster, namespace, tags, and time, to define the scope + and effective time of the rule, and then click __OK__ . + + ![silent rule](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/silent02.png) + +3. Return to the rule list, and on the right side of the list, click __┇__ to edit or delete a silent rule. + +Through the Alert Silence feature, you can flexibly control which alerts should be ignored and when they should be effective, +thereby improving operational efficiency and reducing the possibility of false alerts. diff --git a/docs/en/docs/insight/user-guide/alert-center/sms-provider.md b/docs/en/docs/insight/user-guide/alert-center/sms-provider.md new file mode 100644 index 0000000..cc13156 --- /dev/null +++ b/docs/en/docs/insight/user-guide/alert-center/sms-provider.md @@ -0,0 +1,52 @@ +# Configure Notification Server + +Insight supports SMS notifications and currently sends alert messages using integrated Alibaba Cloud and Tencent Cloud SMS services. This article explains how to configure the SMS notification server in Insight. The variables supported in the SMS signature are the default variables in the message template. As the number of SMS characters is limited, it is recommended to choose more explicit variables. + +> For information on how to configure SMS recipients, refer to the document: [Configure SMS Notification Group](../../user-guide/alert-center/message.md). + +## Procedure + +1. Go to __Alert Center__ -> __Notification Settings__ -> __Notification Server__ . + + ![Notification Server](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/sms01.png) + +2. Click __Add Notification Server__ . + + - Configure Alibaba Cloud server. + + > To apply for Alibaba Cloud SMS service, please refer to [Alibaba Cloud SMS Service](https://help.aliyun.com/document_detail/108062.html?spm=a2c4g.57535.0.0.2cec637ffna8ye). + + Field descriptions: + + - __AccessKey ID__ : Parameter used by Alibaba Cloud to identify the user. + - __AccessKey Secret__ : Key used by Alibaba Cloud to authenticate the user. AccessKey Secret must be kept confidential. + - __SMS Signature__ : The SMS service supports creating signatures that meet the requirements according to user needs. When sending SMS, the SMS platform will add the approved SMS signature to the SMS content before sending it to the SMS recipient. + - __Template CODE__ : The SMS template is the specific content of the SMS to be sent. + - __Parameter Template__ : The SMS body template can contain variables. Users can use variables to customize the SMS content. + + Please refer to [Alibaba Cloud Variable Specification](https://help.aliyun.com/document_detail/463270.html). + + ![Notification Server](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/sms02.png) + + !!! note + + Example: The template content defined in Alibaba Cloud is: ${severity}: ${alertname} triggered at ${startat}. Refer to the configuration in the parameter template. + + - Configure Tencent Cloud server. + + > To apply for Tencent Cloud SMS service, please refer to [Tencent Cloud SMS](https://cloud.tencent.com/document/product/382/37794). + + Field descriptions: + + - __Secret ID__ : Parameter used by Tencent Cloud to identify the API caller. + - __SecretKey__ : Parameter used by Tencent Cloud to authenticate the API caller. + - __SMS Template ID__ : The SMS template ID automatically generated by Tencent Cloud system. + - __Signature Content__ : The SMS signature content, which is the full name or abbreviation of the actual website name defined in the Tencent Cloud SMS signature. + - __SdkAppId__ : SMS SdkAppId, the actual SdkAppId generated after adding the application in the Tencent Cloud SMS console. + - __Parameter Template__ : The SMS body template can contain variables. Users can use variables to customize the SMS content. Please refer to: [Tencent Cloud Variable Specification](https://cloud.tencent.com/document/product/382/39023#.E5.8F.98.E9.87.8F.E8.A7.84.E8.8C.83.3Ca-id.3D.22variable.22.3E.3C.2Fa.3E). + + ![Notification Server](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/sms03.png) + + !!! note + + Example: The template content defined in Tencent Cloud is: {1}: {2} triggered at {3}. Refer to the configuration in the parameter template. diff --git a/docs/en/docs/insight/user-guide/collection-manag/agent-status.md b/docs/en/docs/insight/user-guide/collection-manag/agent-status.md new file mode 100644 index 0000000..a213cce --- /dev/null +++ b/docs/en/docs/insight/user-guide/collection-manag/agent-status.md @@ -0,0 +1,49 @@ +# insight-agent Component Status Explanation + +In AI platform, Insight acts as a multi-cluster observability product. +To achieve unified data collection across multiple clusters, users need to install +the Helm application __insight-agent__ (installed by default in the __insight-system__ namespace). +Refer to [How to Install __insight-agent__ ](../../quickstart/install/install-agent.md). + +## Status Explanation + +In the "Observability" -> "Collection Management" section, you can view the installation status +of __insight-agent__ in each cluster. + +- __Not Installed__ : __insight-agent__ is not installed in the __insight-system__ namespace of the cluster. +- __Running__ : __insight-agent__ is successfully installed in the cluster, and all deployed components are running. +- __Error__ : If __insight-agent__ is in this state, it indicates that the helm deployment failed or + there are components deployed that are not in a running state. + +You can troubleshoot using the following steps: + +1. Run the following command. If the status is __deployed__ , proceed to the next step. + If it is __failed__ , it is recommended to uninstall and reinstall it from + __Container Management__ -> __Helm Apps__ as it may affect application upgrades: + + ```bash + helm list -n insight-system + ``` + +2. Run the following command or check the status of the deployed components in + __Insight__ -> __Data Collection__ . If there are Pods not in the __Running__ state, + restart the containers in an abnormal state. + + ```bash + kubectl get pods -n insight-system + ``` + +## Additional Notes + +1. The resource consumption of the Prometheus metric collection component in __insight-agent__ + is directly proportional to the number of Pods running in the cluster. + Please adjust the resources for Prometheus according to the cluster size. + Refer to [Prometheus Resource Planning](../../quickstart/res-plan/prometheus-res.md). + +2. The storage capacity of the vmstorage metric storage component in the global service cluster + is directly proportional to the total number of Pods in the clusters. + + - Please contact the platform administrator to adjust the disk capacity of vmstorage + based on the cluster size. Refer to [vmstorage Disk Capacity Planning](../../quickstart/res-plan/vms-res-plan.md). + - Adjust vmstorage disk based on multi-cluster scale. + Refer to [vmstorge Disk Expansion](../../quickstart/res-plan/modify-vms-disk.md). diff --git a/docs/en/docs/insight/user-guide/collection-manag/collection-manag.md b/docs/en/docs/insight/user-guide/collection-manag/collection-manag.md new file mode 100644 index 0000000..e2c0e2e --- /dev/null +++ b/docs/en/docs/insight/user-guide/collection-manag/collection-manag.md @@ -0,0 +1,31 @@ +--- +hide: + - toc +--- + +# Data Collection + + __Data Collection__ is mainly to centrally manage and display the entrance of the +cluster installation collection plug-in __insight-agent__ , which helps users quickly +view the health status of the cluster collection plug-in, and provides a quick entry +to configure collection rules. + +The specific operation steps are as follows: + +1. Click in the upper left corner and select __Insight__ -> __Data Collection__ . + + ![Data Collection](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/collectmanage01.png) + +2. You can view the status of all cluster collection plug-ins. + + ![Data Collection](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/collectmanage02.png) + +3. When the cluster is connected to __insight-agent__ and is running, click a cluster name + to enter the details。 + + ![Data Collection](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/collectmanage03.png) + +4. In the __Service Monitor__ tab, click the shortcut link to jump to __Container Management__ -> __CRD__ + to add service discovery rules. + + ![Data Collection](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/collectmanage04.png) diff --git a/docs/en/docs/insight/user-guide/collection-manag/metric-collect.md b/docs/en/docs/insight/user-guide/collection-manag/metric-collect.md new file mode 100644 index 0000000..ab504aa --- /dev/null +++ b/docs/en/docs/insight/user-guide/collection-manag/metric-collect.md @@ -0,0 +1,342 @@ +# Metrics Retrieval Methods + +Prometheus primarily uses the Pull approach to retrieve monitoring metrics from target services' exposed endpoints. Therefore, it requires configuring corresponding scraping jobs to request monitoring data and write it into the storage provided by Prometheus. Currently, Prometheus offers several configurations for these jobs: + +- Native Job Configuration: This provides native Prometheus job configuration for scraping. +- Pod Monitor: In the Kubernetes ecosystem, it allows scraping of monitoring data from Pods using Prometheus Operator. +- Service Monitor: In the Kubernetes ecosystem, it allows scraping monitoring data from Endpoints of Services using Prometheus Operator. + +!!! note + + `[ ]` indicates optional configmaps. + +## Native Job Configuration + +The corresponding configmaps are explained as follows: + +```yaml +# Name of the scraping job, also adds a label (job=job_name) to the scraped metrics +job_name: + +# Time interval between scrapes +[ scrape_interval: | default = ] + +# Timeout for scrape requests +[ scrape_timeout: | default = ] + +# URI path for the scrape request +[ metrics_path: | default = /metrics ] + +# Handling of label conflicts between scraped labels and labels added by the backend Prometheus. +# true: Retains the scraped labels and ignores conflicting labels from the backend Prometheus. +# false: Adds an "exported_" prefix to the scraped labels and includes the additional labels added by the backend Prometheus. +[ honor_labels: | default = false ] + +# Whether to use the timestamp generated by the target being scraped. +# true: Uses the timestamp from the target if available. +# false: Ignores the timestamp from the target. +[ honor_timestamps: | default = true ] + +# Protocol for the scrape request: http or https +[ scheme: | default = http ] + +# URL parameters for the scrape request +params: + [ : [, ...] ] + +# Set the value of the `Authorization` header in the scrape request through basic authentication. password/password_file are mutually exclusive, with password_file taking precedence. +basic_auth: + [ username: ] + [ password: ] + [ password_file: ] + +# Set the value of the `Authorization` header in the scrape request through bearer token authentication. bearer_token/bearer_token_file are mutually exclusive, with bearer_token taking precedence. +[ bearer_token: ] + +# Set the value of the `Authorization` header in the scrape request through bearer token authentication. bearer_token/bearer_token_file are mutually exclusive, with bearer_token taking precedence. +[ bearer_token_file: ] + +# Whether the scrape connection should use a TLS secure channel, configure the corresponding TLS parameters +tls_config: + [ ] + +# Use a proxy service to scrape the metrics from the target, specify the address of the proxy service. +[ proxy_url: ] + +# Specify the targets using static configuration, see explanation below. +static_configs: + [ - ... ] + +# CVM service discovery configuration, see explanation below. +cvm_sd_configs: + [ - ... ] + +# After scraping the data, rewrite the labels of the corresponding target using the relabel mechanism. Executes multiple relabel rules in order. +# See explanation below for relabel_config. +relabel_configs: + [ - ... ] + +# Before writing the scraped data, rewrite the values of the labels using the relabel mechanism. Executes multiple relabel rules in order. +# See explanation below for relabel_config. +metric_relabel_configs: + [ - ... ] + +# Limit the number of data points per scrape, 0: no limit, default is 0 +[ sample_limit: | default = 0 ] + +# Limit the number of targets per scrape, 0: no limit, default is 0 +[ target_limit: | default = 0 ] +``` + +## Pod Monitor + +The explanation for the corresponding configmaps is as follows: + +```yaml +# Prometheus Operator CRD version +apiVersion: monitoring.coreos.com/v1 +# Corresponding Kubernetes resource type, here it is PodMonitor +kind: PodMonitor +# Corresponding Kubernetes Metadata, only the name needs to be concerned. If jobLabel is not specified, the value of the job label in the scraped metrics will be / +metadata: + name: redis-exporter # Specify a unique name + namespace: cm-prometheus # Fixed namespace, no need to modify +# Describes the selection and configuration of the target Pods to be scraped + labels: + operator.insight.io/managed-by: insight # Label indicating managed by Insight +spec: + # Specify the label of the corresponding Pod, pod monitor will use this value as the job label value. + # If viewing the Pod YAML, use the values in pod.metadata.labels. + # If viewing Deployment/Daemonset/Statefulset, use spec.template.metadata.labels. + [ jobLabel: string ] + # Adds the corresponding Pod's Labels to the Target's Labels + [ podTargetLabels: []string ] + # Limit the number of data points per scrape, 0: no limit, default is 0 + [ sampleLimit: uint64 ] + # Limit the number of targets per scrape, 0: no limit, default is 0 + [ targetLimit: uint64 ] + # Configure the Prometheus HTTP endpoints that need to be scraped and exposed. Multiple endpoints can be configured. + podMetricsEndpoints: + [ - ... ] # See explanation below for endpoint + # Select the namespaces where the monitored Pods are located. Leave it blank to select all namespaces. + [ namespaceSelector: ] + # Select all namespaces + [ any: bool ] + # Specify the list of namespaces to be selected + [ matchNames: []string ] + # Specify the Label values of the Pods to be monitored in order to locate the target Pods [K8S metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#labelselector-v1-meta) + selector: + [ matchExpressions: array ] + [ example: - {key: tier, operator: In, values: [cache]} ] + [ matchLabels: object ] + [ example: k8s-app: redis-exporter ] +``` + +### Example 1 + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: redis-exporter # Specify a unique name + namespace: cm-prometheus # Fixed namespace, do not modify + labels: + operator.insight.io/managed-by: insight # Label indicating managed by Insight, required. +spec: + podMetricsEndpoints: + - interval: 30s + port: metric-port # Specify the Port Name corresponding to Prometheus Exporter in the pod YAML + path: /metrics # Specify the value of the Path corresponding to Prometheus Exporter, if not specified, default is /metrics + relabelings: + - action: replace + sourceLabels: + - instance + regex: (.*) + targetLabel: instance + replacement: "crs-xxxxxx" # Adjust to the corresponding Redis instance ID + - action: replace + sourceLabels: + - instance + regex: (.*) + targetLabel: ip + replacement: "1.x.x.x" # Adjust to the corresponding Redis instance IP + namespaceSelector: # Select the namespaces where the monitored Pods are located + matchNames: + - redis-test + selector: # Specify the Label values of the Pods to be monitored in order to locate the target pods + matchLabels: + k8s-app: redis-exporter +``` + +### Example 2 + +```yaml +job_name: prometheus +scrape_interval: 30s +static_configs: +- targets: + - 127.0.0.1:9090 +``` + +## Service Monitor + +The explanation for the corresponding configmaps is as follows: + +```yaml +# Prometheus Operator CRD version +apiVersion: monitoring.coreos.com/v1 +# Corresponding Kubernetes resource type, here it is ServiceMonitor +kind: ServiceMonitor +# Corresponding Kubernetes Metadata, only the name needs to be concerned. If jobLabel is not specified, the value of the job label in the scraped metrics will be the name of the Service. +metadata: + name: redis-exporter # Specify a unique name + namespace: cm-prometheus # Fixed namespace, no need to modify +# Describes the selection and configuration of the target Pods to be scraped + labels: + operator.insight.io/managed-by: insight # Label indicating managed by Insight, required. +spec: + # Specify the label(metadata/labels) of the corresponding Pod, service monitor will use this value as the job label value. + [ jobLabel: string ] + # Adds the Labels of the corresponding service to the Target's Labels + [ targetLabels: []string ] + # Adds the Labels of the corresponding Pod to the Target's Labels + [ podTargetLabels: []string ] + # Limit the number of data points per scrape, 0: no limit, default is 0 + [ sampleLimit: uint64 ] + # Limit the number of targets per scrape, 0: no limit, default is 0 + [ targetLimit: uint64 ] + # Configure the Prometheus HTTP endpoints that need to be scraped and exposed. Multiple endpoints can be configured. + endpoints: + [ - ... ] # See explanation below for endpoint + # Select the namespaces where the monitored Pods are located. Leave it blank to select all namespaces. + [ namespaceSelector: ] + # Select all namespaces + [ any: bool ] + # Specify the list of namespaces to be selected + [ matchNames: []string ] + # Specify the Label values of the Pods to be monitored in order to locate the target Pods [K8S metav1.LabelSelector](https://v1-17.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) + selector: + [ matchExpressions: array ] + [ example: - {key: tier, operator: In, values: [cache]} ] + [ matchLabels: object ] + [ example: k8s-app: redis-exporter ] +``` + +### Example + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: go-demo # Specify a unique name + namespace: cm-prometheus # Fixed namespace, do not modify + labels: + operator.insight.io/managed-by: insight # Label indicating managed by Insight, required. +spec: + endpoints: + - interval: 30s + # Specify the Port Name corresponding to Prometheus Exporter in the service YAML + port: 8080-8080-tcp + # Specify the value of the Path corresponding to Prometheus Exporter, if not specified, default is /metrics + path: /metrics + relabelings: + # ** There must be a label named 'application', assuming there is a label named 'app' in k8s, + # we replace it with 'application' using the relabel 'replace' action + - action: replace + sourceLabels: [__meta_kubernetes_pod_label_app] + targetLabel: application + # Select the namespace where the monitored service is located + namespaceSelector: + matchNames: + - golang-demo + # Specify the Label values of the service to be monitored in order to locate the target service + selector: + matchLabels: + app: golang-app-demo +``` + +### endpoint_config + +The explanation for the corresponding configmaps is as follows: + +```yaml +# The name of the corresponding port. Please note that it's not the actual port number. +# Default: 80. Possible values are as follows: +# ServiceMonitor: corresponds to Service>spec/ports/name; +# PodMonitor: explained as follows: +# If viewing the Pod YAML, take the value from pod.spec.containers.ports.name. +# If viewing Deployment/DaemonSet/StatefulSet, take the value from spec.template.spec.containers.ports.name. +[ port: string | default = 80] +# The URI path for the scrape request. +[ path: string | default = /metrics ] +# The protocol for the scrape: http or https. +[ scheme: string | default = http] +# URL parameters for the scrape request. +[ params: map[string][]string] +# The interval between scrape requests. +[ interval: string | default = 30s ] +# The timeout for the scrape request. +[ scrapeTimeout: string | default = 30s] +# Whether the scrape connection should be made over a secure TLS channel, and the TLS configuration. +[ tlsConfig: TLSConfig ] +# Read the bearer token value from the specified file and include it in the headers of the scrape request. +[ bearerTokenFile: string ] +# Read the bearer token from the specified K8S secret key. Note that the secret namespace must match the PodMonitor/ServiceMonitor. +[ bearerTokenSecret: string ] +# Handling conflicts when scraped labels conflict with labels added by the backend Prometheus. +# true: Keep the scraped labels and ignore the conflicting labels from the backend Prometheus. +# false: For conflicting labels, prefix the scraped label with 'exported_' and add the labels added by the backend Prometheus. +[ honorLabels: bool | default = false ] +# Whether to use the timestamp generated on the target during the scrape. +# true: Use the timestamp on the target if available. +# false: Ignore the timestamp on the target. +[ honorTimestamps: bool | default = true ] +# Basic authentication credentials. Fill in the values of username/password from the corresponding K8S secret key. Note that the secret namespace must match the PodMonitor/ServiceMonitor. +[ basicAuth: BasicAuth ] +# Scrape the metrics from the target through a proxy server. Specify the address of the proxy server. +[ proxyUrl: string ] +# After scraping the data, rewrite the values of the labels on the target using the relabeling mechanism. Multiple relabel rules are executed in order. +# See explanation below for relabel_config +relabelings: +[ - ...] +# Before writing the scraped data, rewrite the values of the corresponding labels on the target using the relabeling mechanism. Multiple relabel rules are executed in order. +# See explanation below for relabel_config +metricRelabelings: +[ - ...] +``` + +### relabel_config + +The explanation for the corresponding configmaps is as follows: + +```yaml +# Specifies which labels to take from the original labels for relabeling. The values taken are concatenated using the separator defined in the configuration. +# For PodMonitor/ServiceMonitor, the corresponding configmap is sourceLabels. +[ source_labels: '[' [, ...] ']' ] +# Defines the character used to concatenate the values of the labels to be relabeled. Default is ';'. +[ separator: | default = ; ] + +# When the action is replace/hashmod, target_label is used to specify the corresponding label name. +# For PodMonitor/ServiceMonitor, the corresponding configmap is targetLabel. +[ target_label: ] + +# Regular expression used to match the values of the source labels. +[ regex: | default = (.*) ] + +# Used when action is hashmod, it takes the modulus value based on the MD5 hash of the source label's value. +[ modulus: ] + +# Used when action is replace, it defines the expression to replace when the regex matches. It can use regular expression replacement with regex. +[ replacement: | default = $1 ] + +# Actions performed based on the matched values of regex. The available actions are as follows, with replace being the default: +# replace: If the regex matches, replace the corresponding value with the value defined in replacement. Set the value using target_label and add the corresponding label. +# keep: If the regex doesn't match, discard the value. +# drop: If the regex matches, discard the value. +# hashmod: Take the modulus of the MD5 hash of the source label's value based on the value specified in modulus. +# Add a new label with a label name specified by target_label. +# labelmap: If the regex matches, replace the corresponding label name with the value specified in replacement. +# labeldrop: If the regex matches, delete the corresponding label. +# labelkeep: If the regex doesn't match, delete the corresponding label. +[ action: | default = replace ] +``` diff --git a/docs/en/docs/insight/user-guide/collection-manag/probe-module.md b/docs/en/docs/insight/user-guide/collection-manag/probe-module.md new file mode 100644 index 0000000..56388c4 --- /dev/null +++ b/docs/en/docs/insight/user-guide/collection-manag/probe-module.md @@ -0,0 +1,313 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-23 +--- + +# Custom probers + +Insight uses the Blackbox Exporter provided by Prometheus as a blackbox monitoring solution, allowing detection of target instances via HTTP, HTTPS, DNS, ICMP, TCP, and gRPC. It can be used in the following scenarios: + +- HTTP/HTTPS: URL/API availability monitoring +- ICMP: Host availability monitoring +- TCP: Port availability monitoring +- DNS: Domain name resolution + +In this page, we will explain how to configure custom probers in an existing Blackbox ConfigMap. + +ICMP prober is not enabled by default in Insight because it requires higher permissions. Therfore We will use the HTTP prober as an example to demonstrate how to modify the ConfigMap to achieve custom HTTP probing. + +## Procedure + +1. Go to __Clusters__ in __Container Management__ and enter the details of the target cluster. +2. Click the left navigation bar and select __ConfigMaps & Secrets__ -> __ConfigMaps__ . +3. Find the ConfigMap named __insight-agent-prometheus-blackbox-exporter__ and click __Edit YAML__ . + + Add custom probers under __modules__ : + +=== "HTTP Prober" + ```yaml + module: + http_2xx: + prober: http + timeout: 5s + http: + valid_http_versions: [HTTP/1.1, HTTP/2] + valid_status_codes: [] # Defaults to 2xx + method: GET + ``` + +=== "ICMP Prober" + + ```yaml + module: + ICMP: # Example of ICMP prober configuration + prober: icmp + timeout: 5s + icmp: + preferred_ip_protocol: ip4 + icmp_example: # Example 2 of ICMP prober configuration + prober: icmp + timeout: 5s + icmp: + preferred_ip_protocol: "ip4" + source_ip_address: "127.0.0.1" + ``` + Since ICMP requires higher permissions, we also need to elevate the pod permissions. Otherwise, an `operation not permitted` error will occur. There are two ways to elevate permissions: + + - Directly edit the `BlackBox Exporter` deployment file to enable it + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: insight-agent-prometheus-blackbox-exporter + namespace: insight-system + spec: + template: + spec: + containers: + - name: blackbox-exporter + image: # ... (image, args, ports, etc. remain unchanged) + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_RAW + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + ``` + + - Elevate permissions via `helm upgrade` + + ```diff + prometheus-blackbox-exporter: + enabled: true + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + runAsNonRoot: false + allowPrivilegeEscalation: false + capabilities: + add: ["NET_RAW"] + ``` + +!!! info + + For more probers, refer to [blackbox_exporter Configuration](https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md). + +## Other References + +The following YAML file contains various probers such as HTTP, TCP, SMTP, ICMP, and DNS. You can modify the configuration file of `insight-agent-prometheus-blackbox-exporter` according to your needs. + +??? note "Click to view the complete YAML file" + + ```yaml + kind: ConfigMap + apiVersion: v1 + metadata: + name: insight-agent-prometheus-blackbox-exporter + namespace: insight-system + labels: + app.kubernetes.io/instance: insight-agent + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-blackbox-exporter + app.kubernetes.io/version: v0.24.0 + helm.sh/chart: prometheus-blackbox-exporter-8.8.0 + annotations: + meta.helm.sh/release-name: insight-agent + meta.helm.sh/release-namespace: insight-system + data: + blackbox.yaml: | + modules: + HTTP_GET: + prober: http + timeout: 5s + http: + method: GET + valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] + follow_redirects: true + preferred_ip_protocol: "ip4" + HTTP_POST: + prober: http + timeout: 5s + http: + method: POST + body_size_limit: 1MB + TCP: + prober: tcp + timeout: 5s + # Not enabled by default: + # ICMP: + # prober: icmp + # timeout: 5s + # icmp: + # preferred_ip_protocol: ip4 + SSH: + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "^SSH-2.0-" + POP3S: + prober: tcp + tcp: + query_response: + - expect: "^+OK" + tls: true + tls_config: + insecure_skip_verify: false + http_2xx_example: # http prober example + prober: http + timeout: 5s # probe timeout + http: + valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] # Version in the response, usually default + valid_status_codes: [] # Defaults to 2xx # Valid range of response codes, probe successful if within this range + method: GET # request method + headers: # request headers + Host: vhost.example.com + Accept-Language: en-US + Origin: example.com + no_follow_redirects: false # allow redirects + fail_if_ssl: false + fail_if_not_ssl: false + fail_if_body_matches_regexp: + - "Could not connect to database" + fail_if_body_not_matches_regexp: + - "Download the latest version here" + fail_if_header_matches: # Verifies that no cookies are set + - header: Set-Cookie + allow_missing: true + regexp: '.*' + fail_if_header_not_matches: + - header: Access-Control-Allow-Origin + regexp: '(\*|example\.com)' + tls_config: # tls configuration for https requests + insecure_skip_verify: false + preferred_ip_protocol: "ip4" # defaults to "ip6" # Preferred IP protocol version + ip_protocol_fallback: false # no fallback to "ip6" + http_post_2xx: # http prober example with body + prober: http + timeout: 5s + http: + method: POST # probe request method + headers: + Content-Type: application/json + body: '{"username":"admin","password":"123456"}' # body carried during probe + http_basic_auth_example: # prober example with username and password + prober: http + timeout: 5s + http: + method: POST + headers: + Host: "login.example.com" + basic_auth: # username and password to be added during probe + username: "username" + password: "mysecret" + http_custom_ca_example: + prober: http + http: + method: GET + tls_config: # root certificate used during probe + ca_file: "/certs/my_cert.crt" + http_gzip: + prober: http + http: + method: GET + compression: gzip # compression method used during probe + http_gzip_with_accept_encoding: + prober: http + http: + method: GET + compression: gzip + headers: + Accept-Encoding: gzip + tls_connect: # TCP prober example + prober: tcp + timeout: 5s + tcp: + tls: true # use TLS + tcp_connect_example: + prober: tcp + timeout: 5s + imap_starttls: # IMAP email server probe configuration example + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "OK.*STARTTLS" + - send: ". STARTTLS" + - expect: "OK" + - starttls: true + - send: ". capability" + - expect: "CAPABILITY IMAP4rev1" + smtp_starttls: # SMTP email server probe configuration example + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "^220 ([^ ]+) ESMTP (.+)$" + - send: "EHLO prober\r" + - expect: "^250-STARTTLS" + - send: "STARTTLS\r" + - expect: "^220" + - starttls: true + - send: "EHLO prober\r" + - expect: "^250-AUTH" + - send: "QUIT\r" + irc_banner_example: + prober: tcp + timeout: 5s + tcp: + query_response: + - send: "NICK prober" + - send: "USER prober prober prober :prober" + - expect: "PING :([^ ]+)" + send: "PONG ${1}" + - expect: "^:[^ ]+ 001" + # icmp_example: # ICMP prober configuration example + # prober: icmp + # timeout: 5s + # icmp: + # preferred_ip_protocol: "ip4" + # source_ip_address: "127.0.0.1" + dns_udp_example: # DNS query example using UDP + prober: dns + timeout: 5s + dns: + query_name: "www.prometheus.io" # domain name to resolve + query_type: "A" # type corresponding to this domain + valid_rcodes: + - NOERROR + validate_answer_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + fail_if_all_match_regexp: + - ".*127.0.0.1" + fail_if_not_matches_regexp: + - "www.prometheus.io.\t300\tIN\tA\t127.0.0.1" + fail_if_none_matches_regexp: + - "127.0.0.1" + validate_authority_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + validate_additional_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + dns_soa: + prober: dns + dns: + query_name: "prometheus.io" + query_type: "SOA" + dns_tcp_example: # DNS query example using TCP + prober: dns + dns: + transport_protocol: "tcp" # defaults to "udp" + preferred_ip_protocol: "ip4" # defaults to "ip6" + query_name: "www.prometheus.io" + ``` diff --git a/docs/en/docs/insight/user-guide/collection-manag/service-monitor.md b/docs/en/docs/insight/user-guide/collection-manag/service-monitor.md new file mode 100644 index 0000000..c3e65b1 --- /dev/null +++ b/docs/en/docs/insight/user-guide/collection-manag/service-monitor.md @@ -0,0 +1,74 @@ +# Configure service discovery rules + +Observable Insight supports the way of creating CRD ServiceMonitor through __container management__ to meet your collection requirements for custom service discovery. +Users can use ServiceMonitor to define the scope of the Namespace discovered by the Pod and select the monitored Service through __matchLabel__ . + +## Prerequisites + +The cluster has the Helm application __insight-agent__ installed and in the __running__ state. + +## Steps + +1. Select __Data Collection__ on the left navigation bar to view the status of all cluster collection plug-ins. + + ![Data Collection](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/collectmanage01.png) + +2. Click a cluster name to enter the collection configuration details. + + ![Data Collection](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/collectmanage02.png) + +3. Click the link to jump to __Container Management__ to create a Service Monitor. + + ```yaml + apiVersion: monitoring.coreos.com/v1 + kind: ServiceMonitor + metadata: + name: micrometer-demo # (1) + namespace: insight-system # (2) + labels: + operator.insight.io/managed-by: insight + spec: + endpoints: # (3) + - honorLabels: true + interval: 15s + path: /actuator/prometheus + port: http + namespaceSelector: # (4) + matchNames: + - insight-system # (5) + selector: # (6) + matchLabels: + micrometer-prometheus-discovery: "true" + ``` + + 1. Specify the name of the ServiceMonitor. + 2. Specify the namespace of the ServiceMonitor. + 3. This is the service endpoint, which represents the address where Prometheus collects Metrics. + __endpoints__ is an array, and multiple __endpoints__ can be created at the same time. + Each __endpoint__ contains three fields, and the meaning of each field is as follows: + + - __interval__ : Specifies the collection cycle of Prometheus for the current __endpoint__ . + The unit is seconds, set to __15s__ in this example. + - __path__ : Specifies the collection path of Prometheus. + In this example, it is specified as __/actuator/prometheus__ . + - __port__ : Specifies the port through which the collected data needs to pass. + The set port is the __name__ set by the port of the Service being collected. + + 4. This is the scope of the Service that needs to be discovered. + __namespaceSelector__ contains two mutually exclusive fields, and the meaning of the fields is as follows: + + - __any__ : Only one value __true__ , when this field is set, it will listen to changes + of all Services that meet the Selector filtering conditions. + - __matchNames__ : An array value that specifies the scope of __namespace__ to be monitored. + For example, if you only want to monitor the Services in two namespaces, default and + insight-system, the __matchNames__ are set as follows: + + ```yaml + namespaceSelector: + matchNames: + - default + - insight-system + ``` + + 5. The namespace where the application that needs to expose metrics is located + 5. Used to select the Service diff --git a/docs/en/docs/insight/user-guide/dashboard/dashboard.md b/docs/en/docs/insight/user-guide/dashboard/dashboard.md new file mode 100644 index 0000000..d24c444 --- /dev/null +++ b/docs/en/docs/insight/user-guide/dashboard/dashboard.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# Dashboard + +Grafana is a cross-platform open source visual analysis tool. Insight uses open source Grafana +to provide monitoring services, and supports viewing resource consumption from multiple dimensions +such as clusters, nodes, and namespaces. + +For more information on open source Grafana, see +[Grafana Official Documentation](https://grafana.com/docs/grafana/latest/getting-started/?spm=a2c4g.11186623.0.0.1f34de53ksAH9a). + +## Steps + +1. Select __Dashboard__ from the left navigation bar . + + - In the __Insight / Overview__ dashboard, you can view the resource usage of multiple clusters and analyze resource usage, network, storage, and more based on dimensions such as namespaces and Pods. + + - Click the dropdown menu in the upper-left corner of the dashboard to switch between clusters. + + - Click the lower-right corner of the dashboard to switch the time range for queries. + + ![Dashboard](../images/dashboard00.png) + +2. Insight provides several recommended dashboards that allow monitoring from different dimensions + such as nodes, namespaces, and workloads. Switch between dashboards by clicking the + __insight-system / Insight / Overview__ section. + + ![Overview](../images/dashboard01.png) + +!!! note + + 1. For accessing Grafana UI, refer to [Access Native Grafana](../../user-guide/dashboard/login-grafana.md). + + 2. For importing custom dashboards, refer to [Importing Custom Dashboards](./import-dashboard.md). diff --git a/docs/en/docs/insight/user-guide/dashboard/import-dashboard.md b/docs/en/docs/insight/user-guide/dashboard/import-dashboard.md new file mode 100644 index 0000000..19a1e04 --- /dev/null +++ b/docs/en/docs/insight/user-guide/dashboard/import-dashboard.md @@ -0,0 +1,65 @@ +# Import Custom Dashboards + +By using Grafana CRD, you can incorporate the management and deployment of dashboards into the lifecycle management of Kubernetes. This enables version control, automated deployment, and cluster-level management of dashboards. This page describes how to import custom dashboards using CRD and the UI interface. + +## Steps + +1. Log in to the AI platform platform and go to __Container Management__ . Select the __kpanda-global-cluster__ from the cluster list. + +2. Choose __Custom Resources__ from the left navigation bar. Look for the __grafanadashboards.integreatly.org__ + file in the list and click it to view the details. + +3. Click __YAML Create__ and use the following template. Replace the dashboard JSON in the __Json__ field. + + - __namespace__ : Specify the target namespace. + - __name__ : Provide a name for the dashboard. + - __label__ : Mandatory. Set the label as __operator.insight.io/managed-by: insight__ . + + ```yaml + apiVersion: integreatly.org/v1alpha1 + kind: GrafanaDashboard + metadata: + labels: + app: insight-grafana-operator + operator.insight.io/managed-by: insight + name: sample-dashboard + namespace: insight-system + spec: + json: > + { + "id": null, + "title": "Simple Dashboard", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "graphTooltip": 1, + "panels": [], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "time_options": [], + "refresh_intervals": [] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": "5s", + "schemaVersion": 17, + "version": 0, + "links": [] + } + ``` + +4. After clicking __OK__ , wait for a while to view the newly imported dashboard in __Dashboard__ . + +!!! info + + If you need to customize the dashboard, refer to + [Add Dashboard Panel](https://grafana.com/docs/grafana/latest/dashboards/add-organize-panels/). diff --git a/docs/en/docs/insight/user-guide/dashboard/login-grafana.md b/docs/en/docs/insight/user-guide/dashboard/login-grafana.md new file mode 100644 index 0000000..47de1b1 --- /dev/null +++ b/docs/en/docs/insight/user-guide/dashboard/login-grafana.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# Access Native Grafana + +Please make sure that the Helm application __Insight__ in your global management cluster is in __Running__ state. + +The specific operation steps are as follows: + +1. Log in to the console to access native Grafana. + + Access address: `http://ip:port/ui/insight-grafana` + + For example: `http://10.6.10.233:30209/ui/insight-grafana` + +2. Click Login in the lower right corner, and use the default username and password to log in. + + - Default username: admin + + - Default password: admin + +3. Click __Log in__ to complete the login. diff --git a/docs/en/docs/insight/user-guide/dashboard/overview.md b/docs/en/docs/insight/user-guide/dashboard/overview.md new file mode 100644 index 0000000..f24bf68 --- /dev/null +++ b/docs/en/docs/insight/user-guide/dashboard/overview.md @@ -0,0 +1,21 @@ +--- +MTPE: WANG0608GitHub +date: 2024-07-09 +--- + +# Overview + +__Insight__ only collects data from clusters that have __insight-agent__ installed and running in a normal state. The overview provides an overview of resources across multiple clusters: + +- Alert Statistics: Provides statistics on active alerts across all clusters. +- Resource Consumption: Displays the resource usage trends for the top 5 clusters and nodes in the past hour, based on CPU usage, memory usage, and disk usage. +- By default, the sorting is based on CPU usage. You can switch the metric to sort clusters and nodes. +- Resource Trends: Shows the trends in the number of nodes over the past 15 days and the running trend of pods in the last hour. +- Service Requests Ranking: Displays the top 5 services with the highest request latency and error rates, along with their respective clusters and namespaces in the multi-cluster environment. + +## Operation procedure + +Select __Overview__ in the left navigation bar to enter the details page. + +![overview](../../image/overview.png){ width="1000"} + diff --git a/docs/en/docs/insight/user-guide/data-query/log.md b/docs/en/docs/insight/user-guide/data-query/log.md new file mode 100644 index 0000000..65c203e --- /dev/null +++ b/docs/en/docs/insight/user-guide/data-query/log.md @@ -0,0 +1,53 @@ +# Log query + +By default, Insight collects node logs, container logs, and Kubernetes audit logs. +In the log query page, you can search for standard output (stdout) logs within the permissions +of your login account. This includes node logs, product logs, and Kubernetes audit logs. +You can quickly find the desired logs among a large volume of logs. Additionally, you can +use the source information and contextual raw data of the logs to assist in troubleshooting and issue resolution. + +## Prerequisites + +The cluster has [insight-agent installed](../../quickstart/install/install-agent.md) +and the application is in __running__ state. + +## Query log + +1. In the left navigation bar, select __Data Query__ -> __Log Query__ . + + ![Log Query](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/log01.png) + +2. After selecting the query criteria, click __Search__ , and the log records in the form of graphs will be displayed. The most recent logs are displayed on top. + + ![Search](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/log02.png) + +3. In the __Filter__ panel, switch __Type__ and select __Node__ to check the logs of all nodes in the cluster. + + ![Node](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/log03.png) + +4. In the __Filter__ panel, switch __Type__ and select __Event__ to view the logs generated by all Kubernetes events in the cluster. + +**Lucene Syntax Explanation:** + +1. Use logical operators (AND, OR, NOT, "") to query multiple keywords. For example: keyword1 AND (keyword2 OR keyword3) NOT keyword4. +2. Use a tilde (~) for fuzzy queries. You can optionally specify a parameter after the "~" to control the similarity of the fuzzy query. If not specified, it defaults to 0.5. For example: error~. +3. Use wildcards (*, ?) as single-character placeholders to match any character. +4. Use square brackets [ ] or curly braces { } for range queries. Square brackets [ ] represent a closed interval and include the boundary values. Curly braces { } represent an open interval and exclude the boundary values. Range queries are applicable only to fields that can be sorted, such as numeric fields and date fields. For example `timestamp:[2022-01-01 TO 2022-01-31]`. +5. For more information, please refer to the [Lucene Syntax Explanation](../../reference/lucene.md). + +## View log context + +Clicking on the button next to a log will slide out a panel on the right side where you can view the +default 100 lines of context for that log. You can switch the __Display Rows__ option to view more contextual content. + +![view](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/log06.png) + +## Export log + +Click the download button located in the upper right corner of the list. + +- You can configure the exported log fields. The available fields may vary depending on the log type, + with the __Log Content__ field being mandatory. +- You can export the log query results in **.txt** or **.csv** format. + +![export](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/log05.png) diff --git a/docs/en/docs/insight/user-guide/data-query/metric.md b/docs/en/docs/insight/user-guide/data-query/metric.md new file mode 100644 index 0000000..90436a1 --- /dev/null +++ b/docs/en/docs/insight/user-guide/data-query/metric.md @@ -0,0 +1,33 @@ +# Metric query + +Metric query supports querying the index data of each container resource, and you can view the trend changes of the monitoring index. At the same time, advanced query supports native PromQL statements for Metric query. + +## Prerequisites + +- The cluster has [insight-agent installed](../../quickstart/install/install-agent.md) and the application is in __running__ state. + +## Common query + +1. In the left navigation bar, click __Data Query__ -> __metric Query__ . + +2. After selecting query conditions such as cluster, type, node, and metric name, click __Search__ , + and the corresponding metric chart and data details will be displayed on the right side of the screen. + + + +!!! tip + + Support custom time range. You can manually click the __Refresh__ icon or select a default time interval to refresh. + +## Advanced Search + +1. In the left navigation bar, click __Data Query__ -> __metric Query__ , + click the __Advanced Query__ tab to switch to the advanced query page. + + + +2. Enter a PromQL statement + (see [PromQL Syntax](https://prometheus.io/docs/prometheus/latest/querying/basics/)), + click __Query__ , and the query metric chart and data details will be displayed. + + \ No newline at end of file diff --git a/docs/en/docs/insight/user-guide/images/dashboard00.png b/docs/en/docs/insight/user-guide/images/dashboard00.png new file mode 100644 index 0000000..46a541b Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/dashboard00.png differ diff --git a/docs/en/docs/insight/user-guide/images/dashboard01.png b/docs/en/docs/insight/user-guide/images/dashboard01.png new file mode 100644 index 0000000..e4de048 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/dashboard01.png differ diff --git a/docs/en/docs/insight/user-guide/images/inhibition01.png b/docs/en/docs/insight/user-guide/images/inhibition01.png new file mode 100644 index 0000000..f4067db Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/inhibition01.png differ diff --git a/docs/en/docs/insight/user-guide/images/inhibition02.png b/docs/en/docs/insight/user-guide/images/inhibition02.png new file mode 100644 index 0000000..b75788b Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/inhibition02.png differ diff --git a/docs/en/docs/insight/user-guide/images/inhibition03.png b/docs/en/docs/insight/user-guide/images/inhibition03.png new file mode 100644 index 0000000..a38d4a7 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/inhibition03.png differ diff --git a/docs/en/docs/insight/user-guide/images/inhibition04.png b/docs/en/docs/insight/user-guide/images/inhibition04.png new file mode 100644 index 0000000..8411f3c Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/inhibition04.png differ diff --git a/docs/en/docs/insight/user-guide/images/msg-detail.png b/docs/en/docs/insight/user-guide/images/msg-detail.png new file mode 100644 index 0000000..bf069e0 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/msg-detail.png differ diff --git a/docs/en/docs/insight/user-guide/images/service00.png b/docs/en/docs/insight/user-guide/images/service00.png new file mode 100644 index 0000000..6ab222d Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/service00.png differ diff --git a/docs/en/docs/insight/user-guide/images/service01.png b/docs/en/docs/insight/user-guide/images/service01.png new file mode 100644 index 0000000..c16c258 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/service01.png differ diff --git a/docs/en/docs/insight/user-guide/images/servicemap.png b/docs/en/docs/insight/user-guide/images/servicemap.png new file mode 100644 index 0000000..accfcfd Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/servicemap.png differ diff --git a/docs/en/docs/insight/user-guide/images/template00.png b/docs/en/docs/insight/user-guide/images/template00.png new file mode 100644 index 0000000..5391031 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/template00.png differ diff --git a/docs/en/docs/insight/user-guide/images/template01.png b/docs/en/docs/insight/user-guide/images/template01.png new file mode 100644 index 0000000..619afc9 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/template01.png differ diff --git a/docs/en/docs/insight/user-guide/images/template02.png b/docs/en/docs/insight/user-guide/images/template02.png new file mode 100644 index 0000000..e007e60 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/template02.png differ diff --git a/docs/en/docs/insight/user-guide/images/template03.png b/docs/en/docs/insight/user-guide/images/template03.png new file mode 100644 index 0000000..67a3449 Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/template03.png differ diff --git a/docs/en/docs/insight/user-guide/images/template04.png b/docs/en/docs/insight/user-guide/images/template04.png new file mode 100644 index 0000000..564cf2f Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/template04.png differ diff --git a/docs/en/docs/insight/user-guide/images/template05.png b/docs/en/docs/insight/user-guide/images/template05.png new file mode 100644 index 0000000..fef14da Binary files /dev/null and b/docs/en/docs/insight/user-guide/images/template05.png differ diff --git a/docs/en/docs/insight/user-guide/infra/cluster.md b/docs/en/docs/insight/user-guide/infra/cluster.md new file mode 100644 index 0000000..06f053e --- /dev/null +++ b/docs/en/docs/insight/user-guide/infra/cluster.md @@ -0,0 +1,39 @@ +--- +MTPE: ModetaNiu +DATE: 2024-08-29 +--- + +# Cluster Monitoring + +Through cluster monitoring, you can view the basic information of the cluster, the resource consumption +and the trend of resource consumption over a period of time. + +## Prerequisites + +The cluster has [insight-agent installed](../../quickstart/install/install-agent.md) and the application +is in __running__ state. + +## Steps + +1. Go to the __Insight__ product module. + +2. Select __Infrastructure__ > __Clusters__ from the left navigation bar. On this page, you can view + the following information: + + - **Resource Overview**: Provides statistics on the number of normal/all nodes and workloads across multiple clusters. + - **Fault**: Displays the number of alerts generated in the current cluster. + - **Resource Consumption**: Shows the actual usage and total capacity of CPU, memory, and disk for the selected cluster. + - **Metric Explanations**: Describes the trends in CPU, memory, disk I/O, and network bandwidth. + + ![Monitor](../../image/cluster.png){ width="1000"} + +3. Click __Resource Level Monitor__, you can view more metrics of the current cluster. + +### Metric Explanations + +| Metric Name | Description | +| -- | -- | +| CPU Usage | The ratio of the actual CPU usage of all pod resources in the cluster to the total CPU capacity of all nodes.| +| CPU Allocation | The ratio of the sum of CPU requests of all pods in the cluster to the total CPU capacity of all nodes.| +| Memory Usage | The ratio of the actual memory usage of all pod resources in the cluster to the total memory capacity of all nodes.| +| Memory Allocation | The ratio of the sum of memory requests of all pods in the cluster to the total memory capacity of all nodes.| diff --git a/docs/en/docs/insight/user-guide/infra/container.md b/docs/en/docs/insight/user-guide/infra/container.md new file mode 100644 index 0000000..8dff288 --- /dev/null +++ b/docs/en/docs/insight/user-guide/infra/container.md @@ -0,0 +1,64 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-25 +hide: + - toc +--- + +# Container Insight + +Container insight is the process of monitoring workloads in cluster management. In the list, +you can view basic information and status of workloads. On the Workloads details page, you can +see the number of active alerts and the trend of resource consumption such as CPU and memory. + +## Prerequisites + +- The cluster has insight-agent installed, and all pods are in the __Running__ state. + +- To install insight-agent, please refer to: [Installing insight-agent online](../../quickstart/install/install-agent.md) or [Offline upgrade of insight-agent](../../quickstart/install/offline-install.md). + +## Steps + +Follow these steps to view service monitoring metrics: + +1. Go to the __Insight__ product module. + +2. Select __Infrastructure__ > __Workloads__ from the left navigation bar. + +3. Switch between tabs at the top to view data for different types of workloads. + + ![container insight](../../image/workload00.png){ width="1000"} + +4. Click the target workload name to view the details. + + 1. Faults: Displays the total number of active alerts for the workload. + 2. Resource Consumption: Shows the CPU, memory, and network usage of the workload. + 3. Monitoring Metrics: Provides the trends of CPU, Memory, Network, and disk usage for the workload over the past hour. + + ![container insight](../../image/workload.png){ width="1000"} + +5. Switch to the __Pods__ tab to view the status of various pods for the workload, including their nodes, restart counts, and other information. + + ![container insight](../../image/workload-1.png){ width="1000"} + +6. Switch to the __JVM monitor__ tab to view the JVM metrics for each pods + + + + !!! note + + 1. The JVM monitoring feature only supports the Java language. + 2. To enable the JVM monitoring feature, refer to [Getting Started with Monitoring Java Applications](../../quickstart/otel/java/index.md). + +### Metric Explanations + +| **Metric Name** | **Description** | +| -- | -- | +| CPU Usage | The sum of CPU usage for all pods under the workload.| +| CPU Requests | The sum of CPU requests for all pods under the workload.| +| CPU Limits | The sum of CPU limits for all pods under the workload.| +| Memory Usage | The sum of memory usage for all pods under the workload.| +| Memory Requests | The sum of memory requests for all pods under the workload.| +| Memory Limits | The sum of memory limits for all pods under the workload.| +| Disk Read/Write Rate | The total number of continuous disk reads and writes per second within the specified time range, representing a performance measure of the number of read and write operations per second on the disk.| +| Network Send/Receive Rate | The incoming and outgoing rates of network traffic, aggregated by workload, within the specified time range.| diff --git a/docs/en/docs/insight/user-guide/infra/event.md b/docs/en/docs/insight/user-guide/infra/event.md new file mode 100644 index 0000000..e68c14e --- /dev/null +++ b/docs/en/docs/insight/user-guide/infra/event.md @@ -0,0 +1,41 @@ +# Event Query + +AI platform Insight supports event querying by cluster and namespace. + +![event](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/event01.png) + +## Event Status Distribution + +By default, the events that occurred within the last 12 hours are displayed. +You can select a different time range in the upper right corner to view longer or shorter periods. +You can also customize the sampling interval from 1 minute to 5 hours. + +The event status distribution chart provides a visual representation of the intensity and dispersion of events. +This helps in evaluating and preparing for subsequent cluster operations and maintenance tasks. +If events are densely concentrated during specific time periods, you may need to allocate more resources or take corresponding measures to ensure cluster stability and high availability. +On the other hand, if events are dispersed, you can effectively schedule other maintenance tasks such as system optimization, upgrades, or handling other tasks during this period. + +By considering the event status distribution chart and the selected time range, you can better plan and manage your cluster operations and maintenance work, ensuring system stability and reliability. + +## Event Count and Statistics + +Through important event statistics, you can easily understand the number of image pull failures, health check failures, Pod execution failures, Pod scheduling failures, container OOM (Out-of-Memory) occurrences, volume mounting failures, and the total count of all events. These events are typically categorized as "Warning" and "Normal". + +## Event List + +The event list is presented chronologically based on time. You can sort the events by __Last Occurrend At__ and __Type__ . + +By clicking on the ⚙️ icon on the right side, you can customize the displayed columns according to your preferences and needs. + +Additionally, you can click the refresh icon to update the current event list when needed. + +![list](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/event02.png) + +In the operation column on the right, clicking the icon allows you to view the history of a specific event. + +![history](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/insight/images/event03.png) + +## Reference + +For detailed meanings of the built-in Events in the system, refer to the +[Kubernetes API Event List](https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/event-v1/). diff --git a/docs/en/docs/insight/user-guide/infra/namespace.md b/docs/en/docs/insight/user-guide/infra/namespace.md new file mode 100644 index 0000000..3eb7a8f --- /dev/null +++ b/docs/en/docs/insight/user-guide/infra/namespace.md @@ -0,0 +1,34 @@ +--- +hide: + - toc +--- + +# Namespace Monitoring + +With namespaces as the dimension, you can quickly query resource consumption and trends within a namespace. + +## Prerequisites + +- Insight Agent is [installed](../../quickstart/install/install-agent.md) in the cluster and the applications are in the __Running__ state. + +## Steps + +1. Go to the __Insight__ product module. + +2. Select __Infrastructure__ -> __Namespaces__ from the left navigation bar. On this page, you can view the following information: + + 1. **Switch Namespace**: Switch between clusters or namespaces at the top. + 2. **Resource Overview**: Provides statistics on the number of normal and total workloads within the selected namespace. + 3. **Incidents**: Displays the number of alerts generated within the selected namespace. + 4. **Events**: Shows the number of Warning level events within the selected namespace in the past 24 hours. + 5. **Resource Consumption**: Provides the sum of CPU and memory usage for Pods within the selected namespace, along with the CPU and memory quota information. + + +### Metric Explanations + +| Metric Name | Description | +| -- | -- | +| CPU Usage | The sum of CPU usage for Pods within the selected namespace. | +| Memory Usage | The sum of memory usage for Pods within the selected namespace. | +| Pod CPU Usage | The CPU usage for each Pod within the selected namespace. | +| Pod Memory Usage | The memory usage for each Pod within the selected namespace. | diff --git a/docs/en/docs/insight/user-guide/infra/node.md b/docs/en/docs/insight/user-guide/infra/node.md new file mode 100644 index 0000000..6b12e06 --- /dev/null +++ b/docs/en/docs/insight/user-guide/infra/node.md @@ -0,0 +1,30 @@ +--- +MTPE: ModetaNiu +DATE: 2024-08-29 +--- + +# Node Monitoring + +Through node monitoring, you can get an overview of the current health status of the nodes in the selected cluster +and the number of abnormal pod; on the current node details page, you can view the number of alerts and +the trend of resource consumption such as CPU, memory, and disk. + +## Prerequisites + +- The cluster has [insight-agent installed](../../quickstart/install/install-agent.md) and the application is in __running__ state. + +## Steps + +1. Go to the __Insight__ product module. + +2. Select __Infrastructure__ -> __Nodes__ from the left navigation bar. On this page, you can view the following information: + + - **Cluster**: Uses the dropdown at the top to switch between clusters. + - **Nodes**: Shows a list of nodes within the selected cluster. Click a specific node to view detailed information. + - **Alert**: Displays the number of alerts generated in the current cluster. + - **Resource Consumption**: Shows the actual usage and total capacity of CPU, memory, and disk for the selected node. + - **Metric Explanations**: Describes the trends in CPU, memory, disk I/O, and network traffic for the selected node. + + ![Node Monitoring](../../image/node.png){ width="1000"} + +3. Click __Resource Level Monitor__, you can view more metrics of the current cluster. diff --git a/docs/en/docs/insight/user-guide/infra/probe.md b/docs/en/docs/insight/user-guide/infra/probe.md new file mode 100644 index 0000000..c358e81 --- /dev/null +++ b/docs/en/docs/insight/user-guide/infra/probe.md @@ -0,0 +1,73 @@ +# Probe + +Probe refers to the use of black-box monitoring to regularly test the connectivity of targets through HTTP, TCP, and other methods, enabling quick detection of ongoing faults. + +Insight uses the Prometheus Blackbox Exporter tool to probe the network using protocols such as HTTP, HTTPS, DNS, TCP, and ICMP, and returns the probe results to understand the network status. + +## Prerequisites + +The __insight-agent__ has been successfully deployed in the target cluster and is in the __Running__ state. + +## View Probes + +1. Go to the __Insight__ product module. +2. Select __Infrastructure__ -> __Probes__ in the left navigation bar. + + - Click the cluster or namespace dropdown in the table to switch between clusters and namespaces. + - The list displays the name, probe method, probe target, connectivity status, and creation time of the probes by default. + - The connectivity status can be: + - Normal: The probe successfully connects to the target, and the target returns the expected response. + - Abnormal: The probe fails to connect to the target, or the target does not return the expected response. + - Pending: The probe is attempting to connect to the target. + - Supports fuzzy search of probe names. + + +## Create a Probe + +1. Click __Create Probe__ . +2. Fill in the basic information and click __Next__ . + + - Name: The name can only contain lowercase letters, numbers, and hyphens (-), and must start and end with a lowercase letter or number, with a maximum length of 63 characters. + - Cluster: Select the cluster for the probe task. + - Namespace: The namespace where the probe task is located. + + +3. Configure the probe parameters. + + - Blackbox Instance: Select the blackbox instance responsible for the probe. + - Probe Method: + - HTTP: Sends HTTP or HTTPS requests to the target URL to check its connectivity and response time. This can be used to monitor the availability and performance of websites or web applications. + - TCP: Establishes a TCP connection to the target host and port to check its connectivity and response time. This can be used to monitor TCP-based services such as web servers and database servers. + - Other: Supports custom probe methods by configuring ConfigMap. For more information, refer to: [Custom Probe Methods](../collection-manag/probe-module.md) + - Probe Target: The target address of the probe, supports domain names or IP addresses. + - Labels: Custom labels that will be automatically added to Prometheus' labels. + - Probe Interval: The interval between probes. + - Probe Timeout: The maximum waiting time when probing the target. + +4. After configuring, click **OK** to complete the creation. + +!!! warning + + After the probe task is created, it takes about 3 minutes to synchronize the configuration. During this period, no probes will be performed, and probe results cannot be viewed. + +## View Monitoring Dashboards + +Click __ ...__ in the operations column and click __View Monitoring Dashboard__ . + +| Metric Name | Description | +| -- | -- | +| Current Status Response | Represents the response status code of the HTTP probe request. | +| Ping Status | Indicates whether the probe request was successful. 1 indicates a successful probe request, and 0 indicates a failed probe request. | +| IP Protocol | Indicates the IP protocol version used in the probe request. | +| SSL Expiry | Represents the earliest expiration time of the SSL/TLS certificate. | +| DNS Response (Latency) | Represents the duration of the entire probe process in seconds. | +| HTTP Duration | Represents the duration of the entire process from sending the request to receiving the complete response. | + +## Edit a Probe + +Click __ ...__ in the operations column and click __Edit__ . + + +## Delete a Probe + +Click __ ...__ in the operations column and click __Delete__ . diff --git a/docs/en/docs/insight/user-guide/system-config/modify-config.md b/docs/en/docs/insight/user-guide/system-config/modify-config.md new file mode 100644 index 0000000..f744393 --- /dev/null +++ b/docs/en/docs/insight/user-guide/system-config/modify-config.md @@ -0,0 +1,190 @@ +# Modify system configuration + +Observability will persist the data of metrics, logs, and traces by default. Users can modify the system configuration according to This page. + +## How to modify the metric data retention period + +Refer to the following steps to modify the metric data retention period. + +1. run the following command: + + ```sh + kubectl edit vmcluster insight-victoria-metrics-k8s-stack -n insight-system + ``` + +2. In the Yaml file, the default value of __retentionPeriod__ is __14__ , and the unit is __day__ . You can modify the parameters according to your needs. + + ```Yaml + apiVersion: operator.victoriametrics.com/v1beta1 + kind: VMCluster + metadata: + annotations: + meta.helm.sh/release-name: insight + meta.helm.sh/release-namespace: insight-system + creationTimestamp: "2022-08-25T04:31:02Z" + finalizers: + - apps.victoriametrics.com/finalizer + generation: 2 + labels: + app.kubernetes.io/instance: insight + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: victoria-metrics-k8s-stack + app.kubernetes.io/version: 1.77.2 + helm.sh/chart: victoria-metrics-k8s-stack-0.9.3 + name: insight-victoria-metrics-k8s-stack + namespace: insight-system + resourceVersion: "123007381" + uid: 55cee8d6-c651-404b-b2c9-50603b405b54 + spec: + replicationFactor: 1 + retentionPeriod: "14" + vminsert: + extraArgs: + maxLabelsPerTimeseries: "45" + image: + repository: docker.m.daocloud.io/victoriametrics/vminsert + tag: v1.80.0-cluster + replicaCount: 1 + ``` + +3. After saving the modification, the pod of the component responsible for storing the metrics will automatically restart, just wait for a while. + +## How to modify the log data storage duration + +Refer to the following steps to modify the log data retention period: + +### Method 1: Modify the Json file + +1. Modify the __max_age__ parameter in the __rollover__ field in the following files, and set the retention period. The default storage period is __7d__ . Change `http://localhost:9200` to the address of __elastic__ . + + ```json + curl -X PUT "http://localhost:9200/_ilm/policy/insight-es-k8s-logs-policy?pretty" -H 'Content-Type: application/json' -d' + { + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "set_priority": { + "priority": 100 + }, + "rollover": { + "max_age": "7d", + "max_size": "10gb" + } + } + }, + "warm": { + "min_age": "10d", + "actions": { + "forcemerge": { + "max_num_segments": 1 + } + } + }, + "delete": { + "min_age": "30d", + "actions": { + "delete": {} + } + } + } + } + } + ``` + +2. After modification, run the above command. It will print out the content as shown below, then the modification is successful. + + ```json + { + "acknowledged": true + } + ``` + +### Method 2: Modify from the UI + +1. Log in __kibana__ , select __Stack Management__ in the left navigation bar. + + + +2. Select the left navigation __Index Lifecycle Polices__ , and find the index __insight-es-k8s-logs-policy__ , click to enter the details. + + + +3. Expand the __Hot phase__ configuration panel, modify the __Maximum age__ parameter, and set the retention period. The default storage period is __7d__ . + + + +4. After modification, click __Save policy__ at the bottom of the page to complete the modification. + + + +## How to modify the trace data storage duration + +Refer to the following steps to modify the trace data retention period: + +### Method 1: Modify the Json file + +1. Modify the __max_age__ parameter in the __rollover__ field in the following files, and set the retention period. The default storage period is __7d__ . At the same time, modify `http://localhost:9200` to the access address of __elastic__ . + + ```json + curl -X PUT "http://localhost:9200/_ilm/policy/jaeger-ilm-policy?pretty" -H 'Content-Type: application/json' -d' + { + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "set_priority": { + "priority": 100 + }, + "rollover": { + "max_age": "7d", + "max_size": "10gb" + } + } + }, + "warm": { + "min_age": "10d", + "actions": { + "forcemerge": { + "max_num_segments": 1 + } + } + }, + "delete": { + "min_age": "30d", + "actions": { + "delete": {} + } + } + } + } + } + ``` + +2. After modification, run the above command on the console. It will print out the content as shown below, then the modification is successful. + + ```json + { + "acknowledged": true + } + ``` + +### Method 2: Modify from the UI + +1. Log in __kibana__ , select __Stack Management__ in the left navigation bar. + + + +2. Select the left navigation __Index Lifecycle Polices__ , and find the index __jaeger-ilm-policy__ , click to enter the details. + + + +3. Expand the __Hot phase__ configuration panel, modify the __Maximum age__ parameter, and set the retention period. The default storage period is __7d__ . + + + +4. After modification, click __Save policy__ at the bottom of the page to complete the modification. + + \ No newline at end of file diff --git a/docs/en/docs/insight/user-guide/system-config/system-component.md b/docs/en/docs/insight/user-guide/system-config/system-component.md new file mode 100644 index 0000000..7a170fb --- /dev/null +++ b/docs/en/docs/insight/user-guide/system-config/system-component.md @@ -0,0 +1,21 @@ +# System Components + +On the system component page, you can quickly view the running status of the system components in Insight. When a system component fails, some features in Insight will be unavailable. + +1. Go to __Insight__ product module, +2. In the left navigation bar, select __System Management -> System Components__ . + +## Component description + +|Module| Component Name | Description | +| ----- | ------------- | ----------- | +|Metrics| vminsert-insight-victoria-metrics-k8s-stack | Responsible for writing the metric data collected by Prometheus in each cluster to the storage component. If this component is abnormal, the metric data of the worker cluster cannot be written. | +|Metrics| vmalert-insight-victoria-metrics-k8s-stack | Responsible for taking effect of the recording and alert rules configured in the VM Rule, and sending the triggered alert rules to alertmanager. | +|Metrics| vmalertmanager-insight-victoria-metrics-k8s-stack| is responsible for sending messages when alerts are triggered. If this component is abnormal, the alert information cannot be sent. | +|Metrics| vmselect-insight-victoria-metrics-k8s-stack | Responsible for querying metrics data. If this component is abnormal, the metric cannot be queried. | +|Metrics| vmstorage-insight-victoria-metrics-k8s-stack | Responsible for storing multicluster metrics data. | +| Dashboard | grafana-deployment | Provide monitoring panel capability. The exception of this component will make it impossible to view the built-in dashboard. | +|Link| insight-jaeger-collector | Responsible for receiving trace data in opentelemetry-collector and storing it. | +|Link| insight-jaeger-query | Responsible for querying the trace data collected in each cluster. | +|Link| insight-opentelemetry-collector | Responsible for receiving trace data forwarded by each sub-cluster | +|Log| elasticsearch | Responsible for storing the log data of each cluster. | \ No newline at end of file diff --git a/docs/en/docs/insight/user-guide/system-config/system-config.md b/docs/en/docs/insight/user-guide/system-config/system-config.md new file mode 100644 index 0000000..924919a --- /dev/null +++ b/docs/en/docs/insight/user-guide/system-config/system-config.md @@ -0,0 +1,22 @@ +--- +hide: + - toc +--- + +# System Configuration + + __System Configuration__ displays the default storage time of metrics, logs, traces and the default Apdex threshold. + +1. Click the right navigation bar and select __System Configuration__ . + + + +2. Currently only supports modifying the storage duration of historical alerts, click __Edit__ to enter the target duration. + + When the storage duration is set to "0", the historical alerts will not be cleared. + + + +!!! note + + To modify other configurations, please click to view [How to modify the system configuration? ](modify-config.md) diff --git a/docs/en/docs/insight/user-guide/trace/service.md b/docs/en/docs/insight/user-guide/trace/service.md new file mode 100644 index 0000000..b91006e --- /dev/null +++ b/docs/en/docs/insight/user-guide/trace/service.md @@ -0,0 +1,64 @@ +--- +MTPE: FanLin +Date: 2024-01-23 +--- + +# Service Insight + +In __Insight__ , a service refers to a group of workloads that provide the same behavior for incoming requests. +Service insight helps observe the performance and status of applications during the operation process by +using the OpenTelemetry SDK. + +For how to use OpenTelemetry, please refer to: [Using OTel to give your application insight](../../quickstart/otel/otel.md). + +## Glossary + +- **Service**: A service represents a group of workloads that provide the same behavior for incoming requests. + You can define the service name when using the OpenTelemetry SDK or use the name defined in Istio. +- **Operation**: An operation refers to a specific request or action handled by a service. Each span has an operation name. +- **Outbound Traffic**: Outbound traffic refers to all the traffic generated by the current service when making requests. +- **Inbound Traffic**: Inbound traffic refers to all the traffic initiated by the upstream service targeting the current service. + +## Steps + +The Services List page displays key metrics such as throughput rate, error rate, and request latency for all services +that have been instrumented with distributed tracing. You can filter services based on clusters or namespaces and sort +the list by throughput rate, error rate, or request latency. By default, the data displayed in the list is for the last hour, +but you can customize the time range. + +Follow these steps to view service insight metrics: + +1. Go to the __Insight__ product module. + +2. Select __Trace Tracking__ -> __Services__ from the left navigation bar. + + ![Trace Tracking](../images/service00.png){ width="1000"} + + !!! attention + + 1. If the namespace of a service in the list is __unknown__ , it means that the service has not been properly instrumented. + We recommend reconfiguring the instrumentation. + 2. If multiple services have the same name and none of them have the correct __Namespace__ environment variable configured, + the metrics displayed in the list and service details page will be aggregated for all those services. + +3. Click a service name (taking insight-system as an example) to view the detailed metrics and operation metrics for that service. + + 1. In the Service Topology section, you can view the service topology one layer above or below the current service. + When you hover over a node, you can see its information. + 2. In the Traffic Metrics section, you can view the monitoring metrics for all requests to the service within + the past hour (including inbound and outbound traffic). + 3. You can use the time selector in the upper right corner to quickly select a time range or specify a custom time range. + 4. Sorting is available for throughput, error rate, and request latency in the operation metrics. + 5. Clicking on the icon next to an individual operation will take you to the __Traces__ page to quickly search for related traces. + + ![Service Monitoring](../images/service01.png){: width="1000px"} + +### Service Metric Explanations + +| Metric | Description | +| ------ | ----------- | +| Throughput Rate | The number of requests processed within a unit of time. | +| Error Rate | The ratio of erroneous requests to the total number of requests within the specified time range. | +| P50 Request Latency | The response time within which 50% of requests complete. | +| P95 Request Latency | The response time within which 95% of requests complete. | +| P99 Request Latency | The response time within which 99% of requests complete. | diff --git a/docs/en/docs/insight/user-guide/trace/topology-helper.md b/docs/en/docs/insight/user-guide/trace/topology-helper.md new file mode 100644 index 0000000..e96faa8 --- /dev/null +++ b/docs/en/docs/insight/user-guide/trace/topology-helper.md @@ -0,0 +1,21 @@ +# Service Topology Element Explanations + +The service topology provided by Observability allows you to quickly identify the request relationships between services and determine the health status of services based on different colors. The health status is determined based on the request latency and error rate of the service's overall traffic. This article explains the elements in the service topology. + +## Node Status Explanation + +The node health status is determined based on the error rate and request latency of the service's overall traffic, following these rules: + +| Color | Status | Rules | +| ----- | ------ | ----- | +| Gray | Healthy | Error rate equals 0% and request latency is less than 100ms | +| Orange | Warning | Error rate (0, 5%] or request latency (100ms, 200ms] | +| Red | Abnormal | Error rate (5%, 100%] or request latency (200ms, +Infinity) | + +## Connection Status Explanation + +| Color | Status | Rules | +| ----- | ------ | ----- | +| Green | Healthy | Error rate equals 0% and request latency is less than 100ms | +| Orange | Warning | Error rate (0, 5%] or request latency (100ms, 200ms] | +| Red | Abnormal | Error rate (5%, 100%] or request latency (200ms, +Infinity) | diff --git a/docs/en/docs/insight/user-guide/trace/topology.md b/docs/en/docs/insight/user-guide/trace/topology.md new file mode 100644 index 0000000..ffccfd2 --- /dev/null +++ b/docs/en/docs/insight/user-guide/trace/topology.md @@ -0,0 +1,51 @@ +# Service Map + +Service map is a visual representation of the connections, communication, and dependencies between services. +It provides insights into the service-to-service interactions, allowing you to view the calls and performance of +services within a specified time range. The connections between nodes in the topology map represent the existence of +service-to-service calls during the queried time period. + +## Prerequisites + +1. Insight Agent is [installed](../../quickstart/install/install-agent.md) in the cluster and the applications are in the __Running__ state. +2. Services have been instrumented for distributed tracing using + [Operator](../../quickstart/otel/operator.md) or [OpenTelemetry SDK](../../quickstart/otel/golang/golang.md). + +## Steps + +1. Go to the __Insight__ product module. + +2. Select __Tracing__ -> __Service Map__ from the left navigation bar. + +3. In the Service Map, you can perform the following actions: + + - Click a node to slide out the details of the service on the right side. Here, + you can view metrics such as request latency, throughput, and error rate for the service. + Clicking on the service name takes you to the service details page. + - Hover over the connections to view the traffic metrics between the two services. + - Click __Display Settings__ , you can configure the display elements in the service map. + + ![Servicemap](../../user-guide/images/servicemap.png) + +### Other Nodes + +In the Service Map, there can be nodes that are not part of the cluster. These external nodes can be categorized into three types: + +- Database +- Message Queue +- Virtual Node + +1. If a service makes a request to a Database or Message Queue, these two types of nodes will be displayed + by default in the topology map. However, Virtual Nodes represent nodes outside the cluster or services + not integrated into the trace, and they will not be displayed by default in the map. + +2. When a service makes a request to MySQL, PostgreSQL, or Oracle Database, the detailed database type + can be seen in the map. + +#### Enabling Virtual Nodes + +1. Update the `insight-server` chart values, locate the parameter shown in the image below, and change `false` to `true`. + + ![change-parameters](../../image/servicemap.png) + +2. In the display settings of the service map, check the `Virtual Services` option to enable it. diff --git a/docs/en/docs/insight/user-guide/trace/trace.md b/docs/en/docs/insight/user-guide/trace/trace.md new file mode 100644 index 0000000..dc33aab --- /dev/null +++ b/docs/en/docs/insight/user-guide/trace/trace.md @@ -0,0 +1,56 @@ +# Trace Query + +On the trace query page, you can query detailed information about a call trace by TraceID or filter call traces based on various conditions. + +## Glossary + +- TraceID: Used to identify a complete request call trace. +- Operation: Describes the specific operation or event represented by a Span. +- Entry Span: The entry Span represents the first request of the entire call. +- Latency: The duration from receiving the request to completing the response for the entire call trace. +- Span: The number of Spans included in the entire trace. +- Start Time: The time when the current trace starts. +- Tag: A collection of key-value pairs that constitute Span tags. Tags are used to annotate and supplement Spans, and each Span can have multiple key-value tag pairs. + +## Steps + +Please follow these steps to search for a trace: + +1. Go to the __Insight__ product module. +2. Select __Tracing__ -> __Traces__ from the left navigation bar. + + ![jaeger](../../image/trace00.png) + + !!! note + + Sorting by Span, Latency, and Start At is supported in the list. + +3. Click the __TraceID Query__ in the filter bar to switch to TraceID search. + + - To search using TraceID, please enter the complete TraceID. + + + +## Other Operations + +### View Trace Details + +1. Click the TraceID of a trace in the trace list to view its detailed call information. + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace03.png) + +### Associated Logs + +1. Click the icon on the right side of the trace data to search for associated logs. + + - By default, it queries the log data within the duration of the trace and one minute after its completion. + - The queried logs include those with the trace's TraceID in their log text and container logs related to the trace invocation process. + +2. Click __View More__ to jump to the __Associated Log__ page with conditions. +3. By default, all logs are searched, but you can filter by the TraceID or the relevant container logs from the trace call process using the dropdown. + + ![tracelog](../../image/tracelog.png) + + !!! note + + Since trace may span across clusters or namespaces, if the user does not have sufficient permissions, they will be unable to query the associated logs for that trace. diff --git a/docs/en/docs/kpanda/images/access-download-cert.png b/docs/en/docs/kpanda/images/access-download-cert.png new file mode 100644 index 0000000..bf9946e Binary files /dev/null and b/docs/en/docs/kpanda/images/access-download-cert.png differ diff --git a/docs/en/docs/kpanda/images/add-global-node01.png b/docs/en/docs/kpanda/images/add-global-node01.png new file mode 100644 index 0000000..8f172cd Binary files /dev/null and b/docs/en/docs/kpanda/images/add-global-node01.png differ diff --git a/docs/en/docs/kpanda/images/add-global-node02.png b/docs/en/docs/kpanda/images/add-global-node02.png new file mode 100644 index 0000000..e74a1c3 Binary files /dev/null and b/docs/en/docs/kpanda/images/add-global-node02.png differ diff --git a/docs/en/docs/kpanda/images/backup1.png b/docs/en/docs/kpanda/images/backup1.png new file mode 100644 index 0000000..d24e5c6 Binary files /dev/null and b/docs/en/docs/kpanda/images/backup1.png differ diff --git a/docs/en/docs/kpanda/images/backup2.png b/docs/en/docs/kpanda/images/backup2.png new file mode 100644 index 0000000..919b89d Binary files /dev/null and b/docs/en/docs/kpanda/images/backup2.png differ diff --git a/docs/en/docs/kpanda/images/backup3.png b/docs/en/docs/kpanda/images/backup3.png new file mode 100644 index 0000000..eb71286 Binary files /dev/null and b/docs/en/docs/kpanda/images/backup3.png differ diff --git a/docs/en/docs/kpanda/images/backup4.png b/docs/en/docs/kpanda/images/backup4.png new file mode 100644 index 0000000..a259ad2 Binary files /dev/null and b/docs/en/docs/kpanda/images/backup4.png differ diff --git a/docs/en/docs/kpanda/images/backupd20481.png b/docs/en/docs/kpanda/images/backupd20481.png new file mode 100644 index 0000000..66998aa Binary files /dev/null and b/docs/en/docs/kpanda/images/backupd20481.png differ diff --git a/docs/en/docs/kpanda/images/backupd20482.png b/docs/en/docs/kpanda/images/backupd20482.png new file mode 100644 index 0000000..b75c0bb Binary files /dev/null and b/docs/en/docs/kpanda/images/backupd20482.png differ diff --git a/docs/en/docs/kpanda/images/backupd20483.png b/docs/en/docs/kpanda/images/backupd20483.png new file mode 100644 index 0000000..2349a39 Binary files /dev/null and b/docs/en/docs/kpanda/images/backupd20483.png differ diff --git a/docs/en/docs/kpanda/images/backupd20484.png b/docs/en/docs/kpanda/images/backupd20484.png new file mode 100644 index 0000000..9562f3d Binary files /dev/null and b/docs/en/docs/kpanda/images/backupd20484.png differ diff --git a/docs/en/docs/kpanda/images/backupd20485.png b/docs/en/docs/kpanda/images/backupd20485.png new file mode 100644 index 0000000..9d7431d Binary files /dev/null and b/docs/en/docs/kpanda/images/backupd20485.png differ diff --git a/docs/en/docs/kpanda/images/backupd20486.png b/docs/en/docs/kpanda/images/backupd20486.png new file mode 100644 index 0000000..9aab903 Binary files /dev/null and b/docs/en/docs/kpanda/images/backupd20486.png differ diff --git a/docs/en/docs/kpanda/images/cluster-access03.png b/docs/en/docs/kpanda/images/cluster-access03.png new file mode 100644 index 0000000..7cf3506 Binary files /dev/null and b/docs/en/docs/kpanda/images/cluster-access03.png differ diff --git a/docs/en/docs/kpanda/images/cluster-integrate02.png b/docs/en/docs/kpanda/images/cluster-integrate02.png new file mode 100644 index 0000000..b09bbbf Binary files /dev/null and b/docs/en/docs/kpanda/images/cluster-integrate02.png differ diff --git a/docs/en/docs/kpanda/images/clusterlist.png b/docs/en/docs/kpanda/images/clusterlist.png new file mode 100644 index 0000000..d65b7ce Binary files /dev/null and b/docs/en/docs/kpanda/images/clusterlist.png differ diff --git a/docs/en/docs/kpanda/images/exclusive01.png b/docs/en/docs/kpanda/images/exclusive01.png new file mode 100644 index 0000000..f7bc398 Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive01.png differ diff --git a/docs/en/docs/kpanda/images/exclusive02.png b/docs/en/docs/kpanda/images/exclusive02.png new file mode 100644 index 0000000..9407b88 Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive02.png differ diff --git a/docs/en/docs/kpanda/images/exclusive03.png b/docs/en/docs/kpanda/images/exclusive03.png new file mode 100644 index 0000000..2cd1bf0 Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive03.png differ diff --git a/docs/en/docs/kpanda/images/exclusive04.png b/docs/en/docs/kpanda/images/exclusive04.png new file mode 100644 index 0000000..6651cdd Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive04.png differ diff --git a/docs/en/docs/kpanda/images/exclusive05.png b/docs/en/docs/kpanda/images/exclusive05.png new file mode 100644 index 0000000..07ab612 Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive05.png differ diff --git a/docs/en/docs/kpanda/images/exclusive06.png b/docs/en/docs/kpanda/images/exclusive06.png new file mode 100644 index 0000000..9bd3e61 Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive06.png differ diff --git a/docs/en/docs/kpanda/images/exclusive07.png b/docs/en/docs/kpanda/images/exclusive07.png new file mode 100644 index 0000000..efba2da Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive07.png differ diff --git a/docs/en/docs/kpanda/images/exclusive08.png b/docs/en/docs/kpanda/images/exclusive08.png new file mode 100644 index 0000000..9f114e2 Binary files /dev/null and b/docs/en/docs/kpanda/images/exclusive08.png differ diff --git a/docs/en/docs/kpanda/images/faq01.png b/docs/en/docs/kpanda/images/faq01.png new file mode 100644 index 0000000..225d370 Binary files /dev/null and b/docs/en/docs/kpanda/images/faq01.png differ diff --git a/docs/en/docs/kpanda/images/faq02.png b/docs/en/docs/kpanda/images/faq02.png new file mode 100644 index 0000000..f261535 Binary files /dev/null and b/docs/en/docs/kpanda/images/faq02.png differ diff --git a/docs/en/docs/kpanda/images/gpu_mig01.jpg b/docs/en/docs/kpanda/images/gpu_mig01.jpg new file mode 100644 index 0000000..ab2858b Binary files /dev/null and b/docs/en/docs/kpanda/images/gpu_mig01.jpg differ diff --git a/docs/en/docs/kpanda/images/gpu_mig02.jpg b/docs/en/docs/kpanda/images/gpu_mig02.jpg new file mode 100644 index 0000000..ff54af6 Binary files /dev/null and b/docs/en/docs/kpanda/images/gpu_mig02.jpg differ diff --git a/docs/en/docs/kpanda/images/gpu_mig03.png b/docs/en/docs/kpanda/images/gpu_mig03.png new file mode 100644 index 0000000..1ad5d4d Binary files /dev/null and b/docs/en/docs/kpanda/images/gpu_mig03.png differ diff --git a/docs/en/docs/kpanda/images/gpu_mig04.png b/docs/en/docs/kpanda/images/gpu_mig04.png new file mode 100644 index 0000000..a01cdab Binary files /dev/null and b/docs/en/docs/kpanda/images/gpu_mig04.png differ diff --git a/docs/en/docs/kpanda/images/imagequest.png b/docs/en/docs/kpanda/images/imagequest.png new file mode 100644 index 0000000..8a9ccc8 Binary files /dev/null and b/docs/en/docs/kpanda/images/imagequest.png differ diff --git a/docs/en/docs/kpanda/images/ingress01.png b/docs/en/docs/kpanda/images/ingress01.png new file mode 100644 index 0000000..f8df33a Binary files /dev/null and b/docs/en/docs/kpanda/images/ingress01.png differ diff --git a/docs/en/docs/kpanda/images/ingress02.png b/docs/en/docs/kpanda/images/ingress02.png new file mode 100644 index 0000000..7118e8c Binary files /dev/null and b/docs/en/docs/kpanda/images/ingress02.png differ diff --git a/docs/en/docs/kpanda/images/ingress03.png b/docs/en/docs/kpanda/images/ingress03.png new file mode 100644 index 0000000..151adc8 Binary files /dev/null and b/docs/en/docs/kpanda/images/ingress03.png differ diff --git a/docs/en/docs/kpanda/images/knative-request-flow.png b/docs/en/docs/kpanda/images/knative-request-flow.png new file mode 100644 index 0000000..dfa6eb4 Binary files /dev/null and b/docs/en/docs/kpanda/images/knative-request-flow.png differ diff --git a/docs/en/docs/kpanda/images/note.svg b/docs/en/docs/kpanda/images/note.svg new file mode 100644 index 0000000..5e473ae --- /dev/null +++ b/docs/en/docs/kpanda/images/note.svg @@ -0,0 +1,18 @@ + + + + Icon/16/Prompt备份@0.5x + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/images/update-kpanda.png b/docs/en/docs/kpanda/images/update-kpanda.png new file mode 100644 index 0000000..ddc50c4 Binary files /dev/null and b/docs/en/docs/kpanda/images/update-kpanda.png differ diff --git a/docs/en/docs/kpanda/images/upload-helm-01.png b/docs/en/docs/kpanda/images/upload-helm-01.png new file mode 100644 index 0000000..40ad734 Binary files /dev/null and b/docs/en/docs/kpanda/images/upload-helm-01.png differ diff --git a/docs/en/docs/kpanda/images/upload-helm-02.png b/docs/en/docs/kpanda/images/upload-helm-02.png new file mode 100644 index 0000000..7039a63 Binary files /dev/null and b/docs/en/docs/kpanda/images/upload-helm-02.png differ diff --git a/docs/en/docs/kpanda/user-guide/backup/deployment.md b/docs/en/docs/kpanda/user-guide/backup/deployment.md new file mode 100644 index 0000000..3ff7ccd --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/backup/deployment.md @@ -0,0 +1,62 @@ +--- +MTPE: FanLin +Date: 2024-01-19 +--- + +# Application Backup + +This article explains how to backup applications in AI platform. The demo application used in this tutorial is called __dao-2048__ , which is a deployment. + +## Prerequisites + +Before backing up a deployment, the following prerequisites must be met: + +- [Integrate a Kubernetes cluster](../clusters/integrate-cluster.md) or [create a Kubernetes cluster](../clusters/create-cluster.md) in the [Container Management](../../intro/index.md) module, and be able to access the UI interface of the cluster. + +- Create a [Namespace](../namespaces/createns.md) and a [User](../../../ghippo/user-guide/access-control/user.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- [Install the velero component](install-velero.md), and ensure the velero component is running properly. + +- [Create a deployment](../workloads/create-deployment.md) (the workload in this tutorial is named __dao-2048__ ), and label the deployment with __app: dao-2048__ . + +## Backup workload + +Follow the steps below to backup the deployment __dao-2048__ . + +1. Enter the Container Management module, click __Backup Recovery__ -> __Application Backup__ on the left navigation bar, and enter the __Application Backup__ list page. + + ![Cluster List](../../images/backupd20481.png) + +2. On the __Application Backup__ list page, select the cluster where the velero and __dao-2048__ applications have been installed. Click __Backup Plan__ in the upper right corner to create a new backup cluster. + + ![Application Backup](../../images/backupd20482.png) + +3. Refer to the instructions below to fill in the backup configuration. + + - Name: The name of the new backup plan. + - Source Cluster: The cluster where the application backup plan is to be executed. + - Object Storage Location: The access path of the object storage configured when installing velero on the source cluster. + - Namespace: The namespaces that need to be backed up, multiple selections are supported. + - Advanced Configuration: Back up specific resources in the namespace based on resource labels, such as an application, or do not back up specific resources in the namespace based on resource labels during backup. + + ![Backup Resource](../../images/backupd20483.png) + +4. Refer to the instructions below to set the backup execution frequency, and then click __Next__ . + + - Backup Frequency: Set the time period for task execution based on minutes, hours, days, weeks, and months. Support custom Cron expressions with numbers and `*` , **after inputting the expression, the meaning of the current expression will be prompted**. For detailed expression syntax rules, refer to [Cron Schedule Syntax](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax). + - Retention Time (days): Set the storage time of backup resources, the default is 30 days, and will be deleted after expiration. + - Backup Data Volume (PV): Whether to back up the data in the data volume (PV), support direct copy and use CSI snapshot. + - Direct Replication: directly copy the data in the data volume (PV) for backup; + - Use CSI snapshots: Use CSI snapshots to back up data volumes (PVs). Requires a CSI snapshot type available for backup in the cluster. + + ![Backup Policy](../../images/backupd20484.png) + +5. Click __OK__ , the page will automatically return to the application backup plan list, find the newly created __dao-2048__ backup plan, and perform the __Immediate Execution__ operation. + + ![Immediate Execution](../../images/backupd20485.png) + +6. At this point, the __Last Execution State__ of the cluster will change to __in progress__ . After the backup is complete, you can click the name of the backup plan to view the details of the backup plan. + + ![Backup Details](../../images/backupd20486.png) diff --git a/docs/en/docs/kpanda/user-guide/backup/etcd-backup.md b/docs/en/docs/kpanda/user-guide/backup/etcd-backup.md new file mode 100644 index 0000000..10a37ce --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/backup/etcd-backup.md @@ -0,0 +1,159 @@ +--- +MTPE: ModetaNiu +Date: 2024-06-05 +--- + +# etcd backup + +etcd backup is based on cluster data as the core backup. In cases such as hardware device damage, development and test configuration errors, etc., the backup cluster data can be restored through etcd backup. + +This section will introduce how to realize the etcd backup for clusters. +Also see [etcd Backup and Restore Best Practices](../../best-practice/etcd-backup.md). + +## Prerequisites + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. + +- Created a [namespace](../namespaces/createns.md), + [user](../../../ghippo/user-guide/access-control/user.md), + and granted [`NS Admin`](../permissions/permission-brief.md#ns-admin) or higher permissions to the user. + For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +- Prepared a MinIO instance. It is recommended to create it through AI platform's MinIO middleware. + For specific steps, refer to [MinIO Object Storage](../../../middleware/minio/user-guide/create.md). + +## Create etcd backup + +Follow the steps below to create an etcd backup. + +1. Enter __Container Management__ -> __Backup Recovery__ -> __etcd Backup__ page, you can see all the current + backup policies. Click __Create Backup Policy__ on the right. + + ![Backup policy list](../images/etcd01.png) + +2. Fill in the __Basic Information__. Then, click __Next__ to automatically verify the connectivity of etcd. If + the verification passes, proceed to the next step. + + - First select the backup cluster and log in to the terminal + - Enter etcd, and the format is `https://${NodeIP}:${Port}`. + + - In a standard Kubernetes cluster, the default port for etcd is __2379__. + - In a Suanova 4.0 cluster, the default port for etcd is __12379__. + - In a public cloud managed cluster, you need to contact the relevant developers to obtain the etcd port number. + This is because the control plane components of public cloud clusters are maintained and managed by + the cloud service provider. Users cannot directly access or view these components, nor can they obtain + control plane port information through regular commands (such as kubectl). + + ??? note "Ways to obtain port number" + + 1. Find the etcd Pod in the __kube-system__ namespace + + ```shell + kubectl get po -n kube-system | grep etcd + ``` + + 2. Get the port number from the __listen-client-urls__ of the etcd Pod + + ```shell + kubectl get po -n kube-system ${etcd_pod_name} -oyaml | grep listen-client-urls # (1)! + ``` + + 1. Replace __etcd_pod_name__ with the actual Pod name + + The expected output is as follows, where the number after the node IP is the port number: + + ```shell + - --listen-client-urls=https://127.0.0.1:2379,https://10.6.229.191:2379 + ``` + + - Fill in the CA certificate, you can use the following command to view the certificate content. + Then, copy and paste it to the proper location: + + === "Standard Kubernetes Cluster" + + ```shell + cat /etc/kubernetes/ssl/etcd/ca.crt + ``` + + === "Suanova 4.0 Cluster" + + ```shell + cat /etc/daocloud/dce/certs/ca.crt + ``` + + - Fill in the Cert certificate, you can use the following command to view the content of the certificate. Then, copy and paste it to the proper location: + + === "Standard Kubernetes Cluster" + + ```shell + cat /etc/kubernetes/ssl/apiserver-etcd-client.crt + ``` + + === "Suanova 4.0 Cluster" + + ```shell + cat /etc/daocloud/dce/certs/etcd/server.crt + ``` + + - Fill in the Key, you can use the following command to view the content of the certificate and copy and paste it to the proper location: + + === "Standard Kubernetes Cluster" + + ```shell + cat /etc/kubernetes/ssl/apiserver-etcd-client.key + ``` + + === "Suanova 4.0 Cluster" + + ```shell + cat /etc/daocloud/dce/certs/etcd/server.key + ``` + + ![Create Basic Information](../images/etcd-get01.png) + + !!! note + + Click __How to get__ below the input box to see how to obtain the proper information on the UI page. + +3. Refer to the following information to fill in the __Backup Policy__. + + - Backup Method: Choose either manual backup or scheduled backup + + - Manual Backup: Immediately perform a full backup of etcd data based on the backup configuration. + - Scheduled Backup: Periodically perform full backups of etcd data according to the set backup frequency. + + - Backup Chain Length: the maximum number of backup data to retain. The default is 30. + - Backup Frequency: it can be per hour, per day, per week or per month, and can also be customized. + +4. Refer to the following information to fill in the __Storage Path__. + + - Storage Provider: Default is S3 storage + - Object Storage Access Address: The access address of MinIO + - Bucket: Create a Bucket in MinIO and fill in the Bucket name + - Username: The login username for MinIO + - Password: The login password for MinIO + +5. After clicking __OK__ , the page will automatically redirect to the backup policy list, where you can + view all the currently created ones. + + - Click the __┇__ action button on the right side of the policy to view logs, view YAML, update the policy, stop the policy, or execute the policy immediately. + - When the backup method is manual, you can click __Execute Now__ to perform the backup. + - When the backup method is scheduled, the backup will be performed according to the configured time. + +## View Backup Policy Logs + +Click __Logs__ to view the log content. By default, 100 lines are displayed. If you want to see more log information or download the logs, you can follow the prompts above the logs to go to the observability module. + +## View Backup POlicy Details + +Go to __Container Management__ -> __Backup Recovery__ -> __etcd Backup__ , click the __Backup Policy__ tab, and then click the policy to view the details. + +## View Recovery Point + +1. Go to __Container Management__ -> __Backup Recovery__ -> __etcd Backup__, and click the __Recovery Point__ tab. +2. After selecting the target cluster, you can view all the backup information under that cluster. + + Each time a backup is executed, a corresponding recovery point is generated, which can be used to quickly restore + the application from a successful recovery point. diff --git a/docs/en/docs/kpanda/user-guide/backup/index.md b/docs/en/docs/kpanda/user-guide/backup/index.md new file mode 100644 index 0000000..146f792 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/backup/index.md @@ -0,0 +1,52 @@ +--- +hide: + - toc +--- + +# Backup and Restore + +Backup and restore are essential aspects of system management. In practice, it is important to +first back up the data of the system at a specific point in time and securely store the backup. +In case of incidents such as data corruption, loss, or accidental deletion, the system can be +quickly restored based on the previous backup data, reducing downtime and minimizing losses. + +- In real production environments, services may be deployed across different clouds, regions, + or availability zones. If one infrastructure faces a failure, organizations need to quickly + restore applications in other available environments. In such cases, cross-cloud or cross-cluster + backup and restore become crucial. +- Large-scale systems often involve multiple roles and users with complex permission management systems. + With many operators involved, accidents caused by human error can lead to system failures. + In such scenarios, the ability to roll back the system quickly using previously backed-up data + is necessary. Relying solely on manual troubleshooting, fault repair, and system recovery can + be time-consuming, resulting in prolonged system unavailability and increased losses for organizations. +- Additionally, factors like network attacks, natural disasters, and equipment malfunctions can + also cause data accidents. + +Therefore, backup and restore are vital as the last line of defense for maintaining system stability +and ensuring data security. + +Backups are typically classified into three types: full backups, incremental backups, +and differential backups. Currently, AI platform supports full backups and incremental backups. + +The backup and restore provided by AI platform can be divided into two categories: +**Application Backup** and **ETCD Backup**. It supports both manual backups +and scheduled automatic backups using CronJobs. + +- Application Backup + + Application backup refers to backing up data of a specific workload in the cluster and then + restoring that data either within the same cluster or in another cluster. It supports backing up + all resources under a namespace or filtering resources by specific labels. + + Application backup also supports cross-cluster backup of stateful applications. + For detailed steps, refer to the [Backup and Restore MySQL Applications and Data Across Clusters](../../best-practice/backup-mysql-on-nfs.md) guide. + +- etcd Backup + + etcd is the data storage component of Kubernetes. Kubernetes stores its own component's data + and application data in etcd. Therefore, backing up etcd is equivalent to backing up the + entire cluster's data, allowing quick restoration of the cluster to a previous state in case of failures. + + It's worth noting that currently, restoring etcd backup data is only supported within the same + cluster (the original cluster). To learn more about related best practices, refer to the + [ETCD Backup and Restore](../../best-practice/etcd-backup.md) guide. diff --git a/docs/en/docs/kpanda/user-guide/backup/install-velero.md b/docs/en/docs/kpanda/user-guide/backup/install-velero.md new file mode 100644 index 0000000..2143ff3 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/backup/install-velero.md @@ -0,0 +1,83 @@ +--- +MTPE: FanLin +Date: 2024-01-18 +--- + +# Install the Velero Plugin + +velero is an open source tool for backing up and restoring Kubernetes cluster resources. It can back up resources in a Kubernetes cluster to cloud storage services, local storage, or other locations, and restore those resources to the same or a different cluster when needed. + +This section introduces how to deploy the Velero plugin in AI platform using the __Helm Apps__. + +## Prerequisites + +Before installing the __velero__ plugin, the following prerequisites need to be met: + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. +- Created a __velero__ [namespace](../namespaces/createns.md). +- You should have permissions not lower than + [NS Editor](../permissions/permission-brief.md#ns-editor). + For details, refer to [Namespace Authorization](../namespaces/createns.md). + +## Steps + +Please perform the following steps to install the __velero__ plugin for your cluster. + +1. On the cluster list page, find the target cluster that needs to install the __velero__ plugin, click the name of the cluster, click __Helm Apps__ -> __Helm chart__ in the left navigation bar, and enter __velero__ in the search bar to search . + + ![Find velero](../../images/backup1.png) + +2. Read the introduction of the __velero__ plugin, select the version and click the __Install__ button. This page will take __5.2.0__ version as an example to install, and it is recommended that you install __5.2.0__ and later versions. + + ![Install velero](../../images/backup2.png) + +3. Configure __basic info__ . + + - Name: Enter the plugin name, please note that the name can be up to 63 characters, can only contain lowercase letters, numbers and separators ("-"), and must start and end with lowercase letters or numbers, such as metrics-server-01. + - Namespace: Select the namespace for plugin installation, it must be __velero__ namespace. + - Version: The version of the plugin, here we take __5.2.0__ version as an example. + - Wait: When enabled, it will wait for all associated resources under the application to be ready before marking the application installation as successful. + - Deletion Failed: After it is enabled, the synchronization will be enabled by default and ready to wait. If the installation fails, the installation-related resources will be removed. + - Detailed Logs: Turn on the verbose output of the installation process log. + + ![Basic Info](../../images/backup3.png) + + !!! note + + After enabling __Ready Wait__ and/or __Failed Delete__ , it takes a long time for the app to be marked as __Running__ . + +4. Configure Velero chart __Parameter Settings__ according to the following instructions + + - __S3 Credentials__: Configure the authentication information of object storage (minio). + + - __Use secret__: Keep the default configuration __true__. + - __Secret name__: Keep the default configuration __velero-s3-credential__. + - __SecretContents.aws_access_key_id = __: Configure the username for accessing object storage, replace ____ with the actual parameter. + - __SecretContents.aws_secret_access_key = __: Configure the password for accessing object storage, replace ____ with the actual parameter. + + !!! note " __Use existing secret__ parameter example is as follows:" + + ```config + [default] + aws_access_key_id = minio + aws_secret_access_key = minio123 + ``` + + - __BackupStorageLocation__: The location where Velero backs up data. + - __S3 bucket__: The name of the storage bucket used to save backup data (must be a real storage bucket that already exists in minio). + - __Is default BackupStorage__: Keep the default configuration __true__. + - __S3 access mode__: The access mode of Velero to data, which can be selected + - __ReadWrite__: Allow Velero to read and write backup data; + - __ReadOnly__: Allow Velero to read backup data, but cannot modify backup data; + - __WriteOnly__: Only allow Velero to write backup data, and cannot read backup data. + + - __S3 Configs__: Detailed configuration of S3 storage (minio). + - __S3 region__: The geographical region of cloud storage. The default is to use the __us-east-1__ parameter, which is provided by the system administrator. + - __S3 force path style__: Keep the default configuration __true__. + - __S3 server URL__: The console access address of object storage (minio). Minio generally provides two services, UI access and console access. Please use the console access address here. + + ![Parameter Settings](../../images/backup4.png) + +5. Click the __OK__ button to complete the installation of the __Velero__ plugin. The system will automatically jump to the __Helm Apps__ list page. After waiting for a few minutes, refresh the page, and you can see the application just installed. diff --git a/docs/en/docs/kpanda/user-guide/clusterops/cluster-settings.md b/docs/en/docs/kpanda/user-guide/clusterops/cluster-settings.md new file mode 100644 index 0000000..0bdd180 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusterops/cluster-settings.md @@ -0,0 +1,18 @@ +--- +MTPE: FanLin +Date: 2024-02-26 +--- + +# Cluster Settings + +Cluster settings are used to customize advanced feature settings for your cluster, including whether to enable GPU, helm repo refresh cycle, Helm operation record retention, etc. + +- Enable GPU: GPUs and proper driver plug-ins need to be installed on the cluster in advance. + + Click the name of the target cluster, and click __Operations and Maintenance__ -> __Cluster Settings__ -> __Addons__ in the left navigation bar. + + ![Config GPU](../images/settings01.png) + +- Helm operation basic image, registry refresh cycle, number of operation records retained, whether to enable cluster deletion protection (the cluster cannot be uninstalled directly after enabling) + + ![Advanced Settings](../images/settings02.png) diff --git a/docs/en/docs/kpanda/user-guide/clusterops/latest-operations.md b/docs/en/docs/kpanda/user-guide/clusterops/latest-operations.md new file mode 100644 index 0000000..0a5359c --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusterops/latest-operations.md @@ -0,0 +1,22 @@ +--- +hide: + - toc +--- + +# recent operations + +On this page, you can view the recent cluster operation records and Helm operation records, as well as the YAML files and logs of each operation, and you can also delete a certain record. + + + +Set the number of reserved entries for Helm operations: + +By default, the system keeps the last 100 Helm operation records. If you keep too many entries, it may cause data redundancy, and if you keep too few entries, you may lose the key operation records you need. A reasonable reserved quantity needs to be set according to the actual situation. Specific steps are as follows: + +1. Click the name of the target cluster, and click __Recent Operations__ -> __Helm Operations__ -> __Set Number of Retained Items__ in the left navigation bar. + + + +2. Set how many Helm operation records need to be kept, and click __OK__ . + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/clusters/access-cluster.md b/docs/en/docs/kpanda/user-guide/clusters/access-cluster.md new file mode 100644 index 0000000..c0deb19 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/access-cluster.md @@ -0,0 +1,62 @@ +--- +MTPE: ModetaNiu +Date: 2024-06-06 +--- + +# Access Clusters + +Clusters integrated or created using the AI platform [Container Management](../../intro/index.md) platform can be accessed not only through the UI interface but also in two other ways for access control: + +- Access online via CloudShell +- Access via kubectl after downloading the cluster certificate + +!!! note + + When accessing the cluster, the user should have [Cluster Admin](../permissions/permission-brief.md) permission or higher. + +## Access via CloudShell + +1. Enter __Clusters__ page, select the cluster you want to access via CloudShell, click the __...__ icon on the right, and then click __Console__ from the dropdown list. + + ![screen](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-access01.png) + +2. Run __kubectl get node__ command in the Console to verify the connectivity between CloudShell and the cluster. If the console returns node information of the cluster, you can access and manage the cluster through CloudShell. + + + +## Access via kubectl + +If you want to access and manage remote clusters from a local node, make sure you have met these prerequisites: + +- Your local node and the cloud cluster are in a connected network. +- The cluster certificate has been downloaded to the local node. +- The kubectl tool has been installed on the local node. For detailed installation guides, see [Installing tools](https://kubernetes.io/docs/tasks/tools/). + +If everything is in place, follow these steps to access a cloud cluster from your local environment. + +1. Enter __Clusters__ page, find your target cluster, click __...__ on the right, and select __Download kubeconfig__ in the drop-down list. + + ![Enter the page of downloading certificates](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-access02.png) + +2. Set the Kubeconfig period and click __Download__ . + + ![Download certificates](../../images/access-download-cert.png) + +3. Open the downloaded certificate and copy its content to the __config__ file of the local node. + + By default, the kubectl tool will look for a file named __config__ in the __$HOME/.kube__ directory on the local node. This file stores access credentials of clusters. Kubectl can access the cluster with that configuration file. + +4. Run the following command on the local node to verify its connectivity with the cluster: + + ```sh + kubectl get pod -n default + ``` + + An expected output is as follows: + + ```none + NAME READY STATUS RESTARTS AGE + dao-2048-2048-58c7f7fc5-mq7h4 1/1 Running 0 30h + ``` + +Now you can access and manage the cluster locally with kubectl. diff --git a/docs/en/docs/kpanda/user-guide/clusters/cluster-role.md b/docs/en/docs/kpanda/user-guide/clusters/cluster-role.md new file mode 100644 index 0000000..31a5970 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/cluster-role.md @@ -0,0 +1,81 @@ +--- +MTPE: windsonsea +Date: 2024-07-19 +--- + +# Cluster Roles + +Suanova AI platform categorizes clusters based on different functionalities to help users better manage IT infrastructure. + +## Global Service Cluster + +This cluster is used to run AI platform components such as +[Container Management](../../intro/index.md), [Global Management](../../../ghippo/intro/index.md), +[Insight](../../../insight/intro/index.md), [Container Registry](../../../kangaroo/intro/index.md). +It generally does not carry business workloads. + +| Supported Features | Description | +| ------------------ | ----------- | +| K8s Version | 1.22+ | +| Operating System | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| Full Lifecycle Management | Supported | +| K8s Resource Management | Supported | +| Cloud Native Storage | Supported | +| Cloud Native Network | Calico, Cillium, Multus, and other CNIs | +| Policy Management | Supports network policies, quota policies, resource limits, disaster recovery policies, security policies | + +## Management Cluster + +This cluster is used to manage worker clusters and generally does not carry business workloads. + +- [Classic Mode](../../../install/commercial/deploy-requirements.md) deploys the global service cluster + and management cluster in different clusters, suitable for multi-data center, multi-architecture enterprise scenarios. +- [Simple Mode](../../../install/commercial/deploy-requirements.md) deploys the management cluster and + global service cluster in the same cluster. + +| Supported Features | Description | +| ------------------ | ----------- | +| K8s Version | 1.22+ | +| Operating System | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| Full Lifecycle Management | Supported | +| K8s Resource Management | Supported | +| Cloud Native Storage | Supported | +| Cloud Native Network | Calico, Cillium, Multus, and other CNIs | +| Policy Management | Supports network policies, quota policies, resource limits, disaster recovery policies, security policies | + +## Worker Cluster + +This is a cluster created using [Container Management](../../intro/index.md) and is mainly used to +carry business workloads. This cluster is managed by the management cluster. + +| Supported Features | Description | +| ------------------ | ----------- | +| K8s Version | Supports K8s 1.22 and above | +| Operating System | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| Full Lifecycle Management | Supported | +| K8s Resource Management | Supported | +| Cloud Native Storage | Supported | +| Cloud Native Network | Calico, Cillium, Multus, and other CNIs | +| Policy Management | Supports network policies, quota policies, resource limits, disaster recovery policies, security policies | + +## Integrated Cluster + +This cluster is used to integrate existing standard K8s clusters, including but not limited to self-built clusters +in local data centers, clusters provided by public cloud vendors, clusters provided by private cloud vendors, +edge clusters, Xinchuang clusters, heterogeneous clusters, and different Suanova clusters. +It is mainly used to carry business workloads. + +| Supported Features | Description | +| ------------------ | ----------- | +| K8s Version | 1.18+ | +| Supported Vendors | VMware Tanzu, Amazon EKS, Redhat Openshift, SUSE Rancher, Alibaba ACK, Huawei CCE, Tencent TKE, Standard K8s Cluster, Suanova | +| Full Lifecycle Management | Not Supported | +| K8s Resource Management | Supported | +| Cloud Native Storage | Supported | +| Cloud Native Network | Depends on the network mode of the integrated cluster's kernel | +| Policy Management | Supports network policies, quota policies, resource limits, disaster recovery policies, security policies | + +!!! note + + A cluster can have multiple cluster roles. For example, a cluster can be both + a global service cluster and a management cluster or a worker cluster. diff --git a/docs/en/docs/kpanda/user-guide/clusters/cluster-scheduler-plugin.md b/docs/en/docs/kpanda/user-guide/clusters/cluster-scheduler-plugin.md new file mode 100644 index 0000000..d84d5a6 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/cluster-scheduler-plugin.md @@ -0,0 +1,178 @@ +--- +MTPE: ModetaNiu +Date: 2024-06-06 +--- + +# Deploy Second Scheduler scheduler-plugins in a Cluster + +This page describes how to deploy a second scheduler-plugins in a cluster. + +## Why do we need scheduler-plugins? + +The cluster created through the platform will install the native K8s scheduler-plugin, but the native scheduler-plugin +has many limitations: + +- The native scheduler-plugin cannot meet scheduling requirements, so you can use either + [CoScheduling](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/pkg/coscheduling), + [CapacityScheduling](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/pkg/capacityscheduling) + or other types of scheduler-plugins. +- In special scenarios, a new scheduler-plugin is needed to complete scheduling tasks without affecting the process of + the native scheduler-plugin. +- Distinguish scheduler-plugins with different functionalities and achieve different scheduling scenarios by switching + scheduler-plugin names. + +This page takes the scenario of using the vgpu scheduler-plugin while combining the coscheduling plugin capability +of scheduler-plugins as an example to introduce how to install and use scheduler-plugins. + +## Installing scheduler-plugins + +### Prerequisites + +- kubean is a new feature introduced in v0.13.0, please ensure that your version is v0.13.0 or higher. +- The installation version of scheduler-plugins is v0.27.8, please ensure that the cluster version is compatible with it. + Refer to the document [Compatibility Matrix](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master?tab=readme-ov-file#compatibility-matrix). + +### Installation Process + +1. Add the scheduler-plugins parameter in **Create Cluster** -> **Advanced Settings** -> **Custom Parameters**. + + ```yaml + scheduler_plugins_enabled:true + scheduler_plugins_plugin_config: + - name: Coscheduling + args: + permitWaitingTimeSeconds: 10 # default is 60 + ``` + + Parameters: + + - `scheduler_plugins_enabled` Set to true to enable the scheduler-plugins capability. + - You can enable or disable certain plugins by setting the `scheduler_plugins_enabled_plugins` or + `scheduler_plugins_disabled_plugins` options. + See [K8s Official Plugin Names](https://github.com/kubernetes-sigs/scheduler-plugins?tab=readme-ov-file#plugins) + for reference. + - If you need to set parameters for custom plugins, please configure `scheduler_plugins_plugin_config`, + for example: set the `permitWaitingTimeoutSeconds` parameter for coscheduling. + See [K8s Official Plugin Configuration](https://github.com/kubernetes-sigs/scheduler-plugins/blob/master/manifests/coscheduling/scheduler-config.yaml) for reference. + + + +2. After successful cluster creation, the system will automatically install the scheduler-plugins and + controller component loads. You can check the workload status in the proper cluster's deployment. + + + +## Using scheduler-plugins + +Here is an example of how to use scheduler-plugins by demonstrating a scenario where the vgpu scheduler is used in combination with the coscheduling plugin capability of scheduler-plugins. + +1. Install vgpu in the Helm Charts and set the values.yaml parameters. + + - `schedulerName: scheduler-plugins-scheduler`: This is the scheduler name for scheduler-plugins installed by + kubean, and currently cannot be modified. + - `scheduler.kubeScheduler.enabled: false`: Do not install kube-scheduler and use vgpu-scheduler as a separate extender. + + + +1. Extend vgpu-scheduler on scheduler-plugins. + + ```bash + [root@master01 charts]# kubectl get cm -n scheduler-plugins scheduler-config -ojsonpath="{.data.scheduler-config\.yaml}" + ``` + + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1 + kind: KubeSchedulerConfiguration + leaderElection: + leaderElect: false + profiles: + # Compose all plugins in one profile + - schedulerName: scheduler-plugins-scheduler + plugins: + multiPoint: + enabled: + - name: Coscheduling + - name: CapacityScheduling + - name: NodeResourceTopologyMatch + - name: NodeResourcesAllocatable + disabled: + - name: PrioritySort + pluginConfig: + - args: + permitWaitingTimeSeconds: 10 + name: Coscheduling + ``` + + Modify configmap of scheduler-config for scheduler-plugins: + + ```bash + [root@master01 charts]# kubectl get cm -n scheduler-plugins scheduler-config -ojsonpath="{.data.scheduler-config\.yaml}" + ``` + + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1 + kind: KubeSchedulerConfiguration + leaderElection: + leaderElect: false + profiles: + # Compose all plugins in one profile + - schedulerName: scheduler-plugins-scheduler + plugins: + multiPoint: + enabled: + - name: Coscheduling + - name: CapacityScheduling + - name: NodeResourceTopologyMatch + - name: NodeResourcesAllocatable + disabled: + - name: PrioritySort + pluginConfig: + - args: + permitWaitingTimeSeconds: 10 + name: Coscheduling + extenders: + - urlPrefix: "${urlPrefix}" + filterVerb: filter + bindVerb: bind + nodeCacheCapable: true + ignorable: true + httpTimeout: 30s + weight: 1 + enableHTTPS: true + tlsConfig: + insecure: true + managedResources: + - name: nvidia.com/vgpu + ignoredByScheduler: true + - name: nvidia.com/gpumem + ignoredByScheduler: true + - name: nvidia.com/gpucores + ignoredByScheduler: true + - name: nvidia.com/gpumem-percentage + ignoredByScheduler: true + - name: nvidia.com/priority + ignoredByScheduler: true + - name: cambricon.com/mlunum + ignoredByScheduler: true + ``` + +1. After installing vgpu-scheduler, the system will automatically create a service (svc), and the urlPrefix + specifies the URL of the svc. + + !!! note + + - The svc refers to the pod service load. You can use the following command in the namespace where the + nvidia-vgpu plugin is installed to get the external access information for port 443. + + ```shell + kubectl get svc -n ${namespace} + ``` + + - The urlPrefix format is `https://${ip address}:${port}` + +1. Restart the scheduler pod of scheduler-plugins to load the new configuration file. + + !!! note + + When creating a vgpu application, you do not need to specify the name of a scheduler-plugin. The vgpu-scheduler webhook + will automatically change the scheduler's name to "scheduler-plugins-scheduler" without manual specification. diff --git a/docs/en/docs/kpanda/user-guide/clusters/cluster-status.md b/docs/en/docs/kpanda/user-guide/clusters/cluster-status.md new file mode 100644 index 0000000..a488884 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/cluster-status.md @@ -0,0 +1,35 @@ +--- +MTPE: ModetaNiu +date: 2024-06-06 +--- + +# Cluster Status + +AI platform Container Management module can manage two types of clusters: integrated clusters and created clusters. + +- Integrated clusters: clusters created in other platforms and now integrated into AI platform. +- Created clusters: clusters created in AI platform. + +For more information about cluster types, see [Cluster Role](cluster-role.md). + +We designed several status for these two clusters. + +## Integrated Clusters + +| Status | Description | +| ------ | ----------- | +| Integrating | The cluster is being integrated into AI platform. | +| Removing | The cluster is being removed from AI platform. | +| Running | The cluster is running as expected. | +| Unknown | The cluster is lost. Data displayed in the AI platform UI is the cached data before the disconnection, which does not represent real-time data. Any operation during this status will not take effect. You should check cluster network connectivity or host status. | + +## Created Clusters + +| Status | Description | +| ------ | ----------- | +| Creating | The cluster is being created. | +| Updating | The Kubernetes version of the cluster is being operating. | +| Deleting | The cluster is being deleted. | +| Running | The cluster is running as expected. | +| Unknown | The cluster is lost. Data displayed in the AI platform UI is the cached data before the disconnection, which does not represent real-time data. Any operation during this status will not take effect. You should check cluster network connectivity or host status. | +| Failed | The cluster creation is failed. You should check the logs for detailed reasons. | diff --git a/docs/en/docs/kpanda/user-guide/clusters/cluster-version.md b/docs/en/docs/kpanda/user-guide/clusters/cluster-version.md new file mode 100644 index 0000000..b0fc5e6 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/cluster-version.md @@ -0,0 +1,63 @@ +--- +MTPE: windsonsea +date: 2024-01-08 +--- + +# Supported Kubernetes Versions + +In AI platform, the [integrated clusters](cluster-status.md) and [created clusters](./cluster-status.md) have different version support mechanisms. + +This page focuses on the version support mechanism for created clusters. + +The Kubernetes community supports three version ranges: 1.26, 1.27, and 1.28. When a new version +is released by the community, the supported version range is incremented. For example, if the +latest version released by the community is 1.27, the supported version range by the community +will be 1.27, 1.28, and 1.29. + +To ensure the security and stability of the clusters, when creating clusters +in AI platform, the supported version range will always be one version lower than the community's +version. + +For instance, if the Kubernetes community supports v1.25, v1.26, and v1.27, then the +version range for creating worker clusters in AI platform will be +v1.24, v1.25, and v1.26. Additionally, a stable version, such as 1.24.7, will be recommended to users. + +Furthermore, the version range for creating worker clusters in AI platform +will remain highly synchronized with the community. When the community version increases +incrementally, the version range for creating worker clusters in +AI platform will also increase by one version. + +## Supported Kubernetes Versions + + + + + + + + + + + + + + + + + + + + +
Kubernetes Community VersionsCreated Worker Cluster VersionsRecommended Versions for Created Worker ClusterAI platform InstallerRelease Date
+
    +
  • 1.26
  • +
  • 1.27
  • +
  • 1.28
  • +
+
+
    +
  • 1.26
  • +
  • 1.27
  • +
  • 1.28
  • +
+
1.27.5v0.13.02023.11.30
diff --git a/docs/en/docs/kpanda/user-guide/clusters/create-cluster.md b/docs/en/docs/kpanda/user-guide/clusters/create-cluster.md new file mode 100644 index 0000000..3698c58 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/create-cluster.md @@ -0,0 +1,96 @@ +--- +date: 2023-08-08 +hide: + - toc +--- + +# Create Worker Clusters + +In AI platform Container Management, clusters can have four [roles](./cluster-role.md): +global service cluster, management cluster, worker cluster, and integrated cluster. +An integrated cluster can only be integrated from third-party vendors (see [Integrate Cluster](./integrate-cluster.md)). + +This page explains how to create a Worker Cluster. By default, when creating a new Worker Cluster, the operating system type and CPU architecture of the worker nodes should be consistent with the Global Service Cluster. If you want to create a cluster with a different operating system or architecture than the Global Management Cluster, refer to [Creating an Ubuntu Worker Cluster on a CentOS Management Platform](../../best-practice/create-ubuntu-on-centos-platform.md) for instructions. + +It is recommended to use the [supported operating systems in AI platform](../../../install/commercial/deploy-requirements.md) to create the cluster. If your local nodes are not within the supported range, you can refer to [Creating a Cluster on Non-Mainstream Operating Systems](../../best-practice/use-otherlinux-create-custer.md) for instructions. + +## Prerequisites + +Certain prerequisites must be met before creating a cluster: + +- Prepare enough nodes to be joined into the cluster. +- It is recommended to use Kubernetes version 1.25.7. For the specific version range, refer to the + [AI platform Cluster Version Support System](./cluster-version.md). Currently, the supported version + range for created worker clusters is `v1.26.0-v1.28`. If you need to create a cluster with a + lower version, refer to the [Supporterd Cluster Versions](./cluster-version.md). +- The target host must allow IPv4 forwarding. If using IPv6 in Pods and Services, + the target server needs to allow IPv6 forwarding. +- AI platform does not provide firewall management. You need to pre-define the firewall rules of + the target host by yourself. To avoid errors during cluster creation, it is recommended + to disable the firewall of the target host. +- See [Node Availability Check](../nodes/node-check.md). + +## Steps + +1. Enter the Container Management module, click __Create Cluster__ on the upper right corner of the __Clusters__ page. + + ![click create button](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-create01.png) + +2. Fill in the basic information by referring to the following instructions. + + - Cluster Name: only contain lowercase letters, numbers, and hyphens ("-"). Must start and end with a lowercase letter or number and totally up to 63 characters. + - Managed By: Choose a cluster to manage this new cluster through its lifecycle, such as creating, upgrading, node scaling, deleting the new cluster, etc. + - Runtime: Select the runtime environment of the cluster. Currently support containerd and docker (see [How to Choose Container Runtime](runtime.md)). + - Kubernetes Version: Allow span of three major versions, such as from 1.23-1.25, subject to the versions supported by the management cluster. + + ![basic info](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-create02.png) + +3. Fill in the node configuration information and click __Node Check__ . + + - High Availability: When enabled, at least 3 controller nodes are required. When disabled, only 1 controller node is needed. + + > It is recommended to use High Availability mode in production environments. + + - Credential Type: Choose whether to access nodes using username/password or public/private keys. + + > If using public/private key authentication, SSH keys for the nodes need to be configured in advance. Refer to [Using SSH Key Authentication for Nodes](../nodes/node-authentication.md). + + - Same Password: When enabled, all nodes in the cluster will have the same access password. Enter the unified password for accessing all nodes in the field below. If disabled, you can set separate usernames and passwords for each node. + - Node Information: Set note names and IPs. + - NTP Time Synchronization: When enabled, time will be automatically synchronized across all nodes. Provide the NTP server address. + + ![node check](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-create03.png) + +4. If node check is passed, click __Next__ . If the check failed, update __Node Information__ and check again. +5. Fill in the network configuration and click __Next__ . + + - CNI: Provide network services for Pods in the cluster. CNI cannot be changed after the cluster is created. Supports cilium and calico. Set __none__ means not installing CNI when creating the cluster. You may install a CNI later. + + > For CNI configuration details, see [Cilium Installation Parameters](../../../network/modules/cilium/install.md) or [Calico Installation Parameters](../../../network/modules/calico/install.md). + + - Container IP Range: Set an IP range for allocating IPs for containers in the cluster. IP range determines the max number of containers allowed in the cluster. Cannot be modified after creation. + - Service IP Range: Set an IP range for allocating IPs for container Services in the cluster. This range determines the max number of container Services that can be created in the cluster. Cannot be modified after creation. + +6. Fill in the plug-in configuration and click __Next__ . + +7. Fill in advanced settings and click __OK__ . + + - __kubelet_max_pods__ : Set the maximum number of Pods per node. The default is 110. + - __hostname_override__ : Reset the hostname (not recommended). + - __kubernetes_audit__ : Kubernetes audit log, enabled by default. + - __auto_renew_certificate__ : Automatically renew the certificate of the control plane on the first Monday of each month, enabled by default. + - __disable_firewalld&ufw__ : Disable the firewall to prevent the node from being inaccessible during installation. + - __Insecure_registries__ : Set the address of you private container registry. If you use a private container registry, fill in its address can bypass certificate authentication of the container engine and obtain the image. + - __yum_repos__ : Fill in the Yum source registry address. + +!!! success + + - After correctly filling in the above information, the page will prompt that the cluster is being created. + - Creating a cluster takes a long time, so you need to wait patiently. You can click the __Back to Clusters__ button to let it running backend. + - To view the current status, click __Real-time Log__ . + +!!! note + + - hen the cluster is in an unknown state, it means that the current cluster has been disconnected. + - The data displayed by the system is the cached data before the disconnection, which does not represent real data. + - Any operations performed in the disconnected state will not take effect. Please check the cluster network connectivity or Host Status. diff --git a/docs/en/docs/kpanda/user-guide/clusters/delete-cluster.md b/docs/en/docs/kpanda/user-guide/clusters/delete-cluster.md new file mode 100644 index 0000000..2d21cc8 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/delete-cluster.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# Delete/Remove Clusters + +Clusters created in AI platform [Container Management](../../intro/index.md) can be either deleted or removed. Clusters integrated into AI platform can only be removed. + +!!! Info + + If you want to delete an integrated cluster, you should delete it in the platform where it is created. + +In AI platform, the difference between __Delete__ and __Remove__ is: + +- __Delete__ will destroy the cluster and reset the data of all nodes under the cluster. All data will be totally cleared and lost. Making a backup before deleting a cluster is a recommended best practice. You can no longer use that cluster anymore. +- __Remove__ just removes the cluster from AI platform. It will not destroy the cluster and no data will be lost. You can still use the cluster in other platforms or re-integrate it into AI platform later if needed. + +!!! note + + - You should have [Admin](../../../ghippo/user-guide/access-control/role.md) + or [Kpanda Owner](../../../ghippo/user-guide/access-control/global.md) permissions + to perform delete or remove operations. + - Before deleting a cluster, you should turn off __Cluster Deletion Protection__ in + __Cluster Settings__ -> __Advanced Settings__ , otherwise the __Delete Cluster__ option will not be displayed. + - The __global service cluster__ cannot be deleted or removed. + +1. Enter the Container Management module, find your target cluster, click __ ...__ on the right, + and select __Delete cluster__ / __Remove__ in the drop-down list. + + ![screen](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-delete01.png) + +2. Enter the cluster name to confirm and click __Delete__ . + + ![screen](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-delete02.png) + +3. You will be auto directed to cluster lists. The status of this cluster will changed to __Deleting__ . It may take a while to delete/remove a cluster. diff --git a/docs/en/docs/kpanda/user-guide/clusters/integrate-cluster.md b/docs/en/docs/kpanda/user-guide/clusters/integrate-cluster.md new file mode 100644 index 0000000..b172d63 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/integrate-cluster.md @@ -0,0 +1,41 @@ +--- +MTPE: windsonsea +Date: 2024-07-19 +hide: + - toc +--- + +# Integrate Clusters + +With the features of integrating clusters, AI platform allows you to manage on-premise and cloud clusters of various providers in a unified manner. This is quite important in avoiding the risk of being locked in by a certain providers, helping enterprises safely migrate their business to the cloud. + +In AI platform Container Management module, you can integrate a cluster of the following providers: standard Kubernetes clusters, Redhat Openshift, SUSE Rancher, VMware Tanzu, Amazon EKS, Aliyun ACK, Huawei CCE, Tencent TKE, etc. + +## Prerequisites + +- Prepare a cluster of K8s v1.22+ and ensure its network connectivity. +- The operator should have the [NS Editor](../permissions/permission-brief.md) or higher permissions. + +## Steps + +1. Enter Container Management module, and click __Integrate Cluster__ in the upper right corner. + + ![screen](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-integrate01.png) + +2. Fill in the basic information by referring to the following instructions. + + - Cluster Name: It should be unique and cannot be changed after the integration. Maximum 63 characters, can only contain lowercase letters, numbers, and a separator ("-"), and must start and end with a lowercase letter or number. + - Cluster Alias: Enter any characters, no more than 60 characters. + - Release Distribution: the cluster provider, support mainstream vendors listed at the beginning. + +3. Fill in the KubeConfig of the target cluster and click __Verify Config__ . The cluster can be successfully connected only after the verification is passed. + + > Click __How do I get the KubeConfig?__ to see the specific steps for getting this file. + + ![screen](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/cluster-integrate03.png) + +4. Confirm that all parameters are filled in correctly and click __OK__ in the lower right corner of the page. + +!!! note + + The status of the newly integrated cluster is __Integrating__ , which will become __Running__ after the integration succeeds. diff --git a/docs/en/docs/kpanda/user-guide/clusters/integrate-rancher-cluster.md b/docs/en/docs/kpanda/user-guide/clusters/integrate-rancher-cluster.md new file mode 100644 index 0000000..019159b --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/integrate-rancher-cluster.md @@ -0,0 +1,222 @@ +--- +MTPE: ModetaNiu +date: 2024-06-06 +--- + +# Integrate the Rancher Cluster + +This page explains how to integrate a Rancher cluster. + +## Prerequisites + +- Prepare a Rancher cluster with administrator privileges and ensure network connectivity between the container management cluster and the target cluster. +- Be equipped with permissions not lower than [kpanda owner](../permissions/permission-brief.md). + +## Steps + +### Step 1: Create a ServiceAccount user with administrator privileges in the Rancher cluster + +1. Log in to the Rancher cluster with a role that has administrator privileges, and create a file named __sa.yaml__ + using the terminal. + + ```bash + vi sa.yaml + ``` + + Press the __i__ key to enter insert mode, then copy and paste the following content: + + ```yaml title="sa.yaml" + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: rancher-rke + rules: + - apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' + - nonResourceURLs: + - '*' + verbs: + - '*' + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: rancher-rke + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rancher-rke + subjects: + - kind: ServiceAccount + name: rancher-rke + namespace: kube-system + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: rancher-rke + namespace: kube-system + ``` + + Press the __Esc__ key to exit insert mode, then type __:wq__ to save and exit. + +2. Run the following command in the current directory to create a ServiceAccount named __rancher-rke__ + (referred to as __SA__ for short): + + ```bash + kubectl apply -f sa.yaml + ``` + + The expected output is as follows: + + ```console + clusterrole.rbac.authorization.k8s.io/rancher-rke created + clusterrolebinding.rbac.authorization.k8s.io/rancher-rke created + serviceaccount/rancher-rke created + ``` + +3. Create a secret named __rancher-rke-secret__ and bind the secret to the __rancher-rke__ SA. + + ```bash + kubectl apply -f - < + Annotations: kubernetes.io/service-account.name: rancher-rke + kubernetes.io/service-account.uid: d83df5d9-bd7d-488d-a046-b740618a0174 + + Type: kubernetes.io/service-account-token + + Data + ==== + ca.crt: 570 bytes + namespace: 11 bytes + token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjUtNE9nUWZLRzVpbEJORkZaNmtCQXhqVzRsZHU4MHhHcDBfb0VCaUo0V1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJyYW5jaGVyLXJrZS1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicmFuY2hlci1ya2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkODNkZjVkOS1iZDdkLTQ4OGQtYTA0Ni1iNzQwNjE4YTAxNzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cmFuY2hlci1ya2UifQ.VNsMtPEFOdDDeGt_8VHblcMRvjOwPXMM-79o9UooHx6q-VkHOcIOp3FOT2hnEdNnIsyODZVKCpEdCgyozX-3y5x2cZSZpocnkMcBbQm-qfTyUcUhAY7N5gcYUtHUhvRAsNWJcsDCn6d96gT_qo-ddo_cT8Ri39Lc123FDYOnYG-YGFKSgRQVy7Vyv34HIajZCCjZzy7i--eE_7o4DXeTjNqAFMFstUxxHBOXI3Rdn1zKQKqh5Jhg4ES7X-edSviSUfJUX-QV_LlAw5DuAyGPH7bDH4QaQ5k-p6cIctmpWZE-9wRDlKA4LYRblKE7MJcI6OmM4ldlMM0Jc8N-gCtl4w + ``` + +### Step 2: Update kubeconfig with the rancher-rke SA authentication on your local machine + +Perform the following steps on any local node where __kubelet__ is installed: + +1. Configure kubelet token. + + ```bash + kubectl config set-credentials rancher-rke --token= __rancher-rke-secret__ 里面的 token 信息 + ``` + + For example, + + ``` + kubectl config set-credentials eks-admin --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjUtNE9nUWZLRzVpbEJORkZaNmtCQXhqVzRsZHU4MHhHcDBfb0VCaUo0V1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJyYW5jaGVyLXJrZS1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicmFuY2hlci1ya2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkODNkZjVkOS1iZDdkLTQ4OGQtYTA0Ni1iNzQwNjE4YTAxNzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cmFuY2hlci1ya2UifQ.VNsMtPEFOdDDeGt_8VHblcMRvjOwPXMM-79o9UooHx6q-VkHOcIOp3FOT2hnEdNnIsyODZVKCpEdCgyozX-3y5x2cZSZpocnkMcBbQm-qfTyUcUhAY7N5gcYUtHUhvRAsNWJcsDCn6d96gT_qo-ddo_cT8Ri39Lc123FDYOnYG-YGFKSgRQVy7Vyv34HIajZCCjZzy7i--eE_7o4DXeTjNqAFMFstUxxHBOXI3Rdn1zKQKqh5Jhg4ES7X-edSviSUfJUX-QV_LlAw5DuAyGPH7bDH4QaQ5k-p6cIctmpWZE-9wRDlKA4LYRblKE7MJcI6OmM4ldlMM0Jc8N-gCtl4w + ``` + +2. Configure the kubelet APIServer information. + + ```bash + kubectl config set-cluster {cluster-name} --insecure-skip-tls-verify=true --server={APIServer} + ``` + + - __{cluster-name}__ : the name of your Rancher cluster. + - __{APIServer}__ : the access address of the cluster, usually refering to the IP address of the control node + port "6443", such as `https://10.X.X.X:6443` . + + For example, + + ```bash + kubectl config set-cluster rancher-rke --insecure-skip-tls-verify=true --server=https://10.X.X.X:6443 + ``` + +3. Configure the kubelet context. + + ```bash + kubectl config set-context {context-name} --cluster={cluster-name} --user={SA-usename} + ``` + + For example, + + ```bash + kubectl config set-context rancher-rke-context --cluster=rancher-rke --user=rancher-rke + ``` + +4. Specify the newly created context __rancher-rke-context__ in kubelet. + + ```bash + kubectl config use-context rancher-rke-context + ``` + +5. Fetch the kubeconfig information for the context __rancher-rke-context__ . + + ```bash + kubectl config view --minify --flatten --raw + ``` + + The output is expected to be: + + ```yaml + apiVersion: v1 + clusters: + - cluster: + insecure-skip-tls-verify: true + server: https://77C321BCF072682C70C8665ED4BFA10D.gr7.ap-southeast-1.eks.amazonaws.com + name: joincluster + contexts: + - context: + cluster: joincluster + user: eks-admin + name: ekscontext + current-context: ekscontext + kind: Config + preferences: {} + users: + - name: eks-admin + user: + token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImcxTjJwNkktWm5IbmRJU1RFRExvdWY1TGFWVUtGQ3VIejFtNlFQcUNFalEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2V + +### Step 3: Connect the cluster in the Suanova Interface + +Using the kubeconfig file fetched earlier, refer to the [Integrate Cluster](./integrate-cluster.md) documentation to integrate the Rancher cluster to the global cluster. diff --git a/docs/en/docs/kpanda/user-guide/clusters/runtime.md b/docs/en/docs/kpanda/user-guide/clusters/runtime.md new file mode 100644 index 0000000..60e22b2 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/runtime.md @@ -0,0 +1,19 @@ +# How to choose the container runtime + +The container runtime is an important component in kubernetes to manage the life cycle of containers and container images. Kubernetes made containerd the default container runtime in version 1.19, and removed support for the Dockershim component in version 1.24. + +Therefore, compared to the Docker runtime, we **recommend you to use the lightweight containerd as your container runtime**, because this has become the current mainstream runtime choice. + +In addition, some operating system distribution vendors are not friendly enough for Docker runtime compatibility. The runtime support of different operating systems is as follows: + +## Operating systems and supported runtimes + +| Operating System | Supported containerd Versions | Supported Docker Versions | +|--------------|---------------|------------| +| CentOS | 1.5.5, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11, 1.5.12, 1.5.13, 1.6.0, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.6.11, 1.6.12, 1.6.13, 1.6.14, 1.6.15 (default) | 18.09, 19.03, 20.10 (default) | +| RedHatOS | 1.5.5, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11, 1.5.12, 1.5.13, 1.6.0, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.6.11, 1.6.12, 1.6.13, 1.6.14, 1.6.15 (default) | 18.09, 19.03, 20.10 (default) | +| KylinOS | 1.5.5, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11, 1.5.12, 1.5.13, 1.6.0, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.6.11, 1.6.12, 1.6.13, 1.6.14, 1.6.15 (default) | 19.03 (Only supported by ARM architecture, Docker is not supported as a runtime under x86 architecture)| + +!!! note + + In the offline installation mode, you need to prepare the runtime offline package of the relevant operating system in advance. diff --git a/docs/en/docs/kpanda/user-guide/clusters/upgrade-cluster.md b/docs/en/docs/kpanda/user-guide/clusters/upgrade-cluster.md new file mode 100644 index 0000000..b29c5cb --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/clusters/upgrade-cluster.md @@ -0,0 +1,43 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# Cluster Upgrade + +The Kubernetes Community packages a small version every quarter, and the maintenance cycle of each version is only about 9 months. Some major bugs or security holes will not be updated after the version stops maintenance. Manually upgrading cluster operations is cumbersome and places a huge workload on administrators. + +In Suanova, you can upgrade the Kubernetes cluster with one click through the web UI interface. + +!!! danger + + After the version is upgraded, it will not be possible to roll back to the previous version, please proceed with caution. + +!!! note + + - Kubernetes versions are denoted as __x.y.z__ , where __x__ is the major version, __y__ is the minor version, and __z__ is the patch version. + - Cluster upgrades across minor versions are not allowed, e.g. a direct upgrade from 1.23 to 1.25 is not possible. + - **Access clusters do not support version upgrades. If there is no "cluster upgrade" in the left navigation bar, please check whether the cluster is an access cluster. ** + - The global service cluster can only be upgraded through the terminal. + - When upgrading a worker cluster, the [Management Cluster](cluster-role.md#management-clusters) of the worker cluster should have been connected to the container management module and be running normally. + +1. Click the name of the target cluster in the cluster list. + + + +2. Then click __Cluster Operation and Maintenance__ -> __Cluster Upgrade__ in the left navigation bar, and click __Version Upgrade__ in the upper right corner of the page. + + + +3. Select the version that can be upgraded, and enter the cluster name to confirm. + + + +4. After clicking __OK__ , you can see the upgrade progress of the cluster. + + + +5. The cluster upgrade is expected to take 30 minutes. You can click the __Real-time Log__ button to view the detailed log of the cluster upgrade. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/configmaps-secrets/create-configmap.md b/docs/en/docs/kpanda/user-guide/configmaps-secrets/create-configmap.md new file mode 100644 index 0000000..3b1fad3 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/configmaps-secrets/create-configmap.md @@ -0,0 +1,90 @@ +# Create ConfigMaps + +ConfigMaps store non-confidential data in the form of key-value pairs to achieve the effect of +mutual decoupling of configuration data and application code. ConfigMaps can be used as +environment variables for containers, command-line parameters, or configuration files in storage volumes. + +!!! note + + - The data saved in ConfigMaps cannot exceed 1 MiB. If you need to store larger volumes of data, + it is recommended to mount a storage volume or use an independent database or file service. + + - ConfigMaps do not provide confidentiality or encryption. If you want to store encrypted data, + it is recommended to use [secret](use-secret.md), or other third-party tools to ensure the + privacy of data. + +You can create ConfigMaps with two methods: + +- Graphical form creation +- YAML creation + +## Prerequisites + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. + +- Created a [namespace](../namespaces/createns.md), + [user](../../../ghippo/user-guide/access-control/user.md), + and authorized the user as [NS Editor](../permissions/permission-brief.md#ns-editor). + For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +## Graphical form creation + +1. Click the name of a cluster on the __Clusters__ page to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __ConfigMap and Secret__ -> __ConfigMap__ , and click the __Create ConfigMap__ button in the upper right corner. + + + +3. Fill in the configuration information on the __Create ConfigMap__ page, and click __OK__ . + + !!! note + + Click __Upload File__ to import an existing file locally to quickly create ConfigMaps. + + + +4. After the creation is complete, click More on the right side of the ConfigMap to edit YAML, update, export, delete and other operations. + + + +## YAML creation + +1. Click the name of a cluster on the __Clusters__ page to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __ConfigMap and Secret__ -> __ConfigMap__ , and click the __YAML Create__ button in the upper right corner. + + + +3. Fill in or paste the configuration file prepared in advance, and then click __OK__ in the lower right corner of the pop-up box. + + !!! note + + - Click __Import__ to import an existing file locally to quickly create ConfigMaps. + - After filling in the data, click __Download__ to save the configuration file locally. + + + +4. After the creation is complete, click More on the right side of the ConfigMap to edit YAML, update, export, delete and other operations. + + + +## ConfigMap YAML example + + ```yaml + kind: ConfigMap + apiVersion: v1 + metadata: + name: kube-root-ca.crt + namespace: default + annotations: + data: + version: '1.0' + ``` + +[Next step: Use ConfigMaps](use-configmap.md){ .md-button .md-button--primary } \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/configmaps-secrets/create-secret.md b/docs/en/docs/kpanda/user-guide/configmaps-secrets/create-secret.md new file mode 100644 index 0000000..7fa5d86 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/configmaps-secrets/create-secret.md @@ -0,0 +1,89 @@ +# Create Secret + +A secret is a resource object used to store and manage sensitive information such as passwords, +OAuth tokens, SSH, TLS credentials, etc. Using keys means you don't need to include sensitive secrets +in your application code. + +Secrets can be used in some cases: + +- Used as an environment variable of the container to provide some necessary information + required during the running of the container. +- Use secrets as pod data volumes. +- As the identity authentication credential for the container registry + when the kubelet pulls the container image. + +You can create ConfigMaps with two methods: + +- Graphical form creation +- YAML creation + +## Prerequisites + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster + +- Created a [namespace](../namespaces/createns.md), + [user](../../../ghippo/user-guide/access-control/user.md), + and authorized the user as [NS Editor](../permissions/permission-brief.md#ns-editor). + For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +## Create secret with wizard + +1. Click the name of a cluster on the __Clusters__ page to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __ConfigMap and Secret__ -> __Secret__ , and click the __Create Secret__ button in the upper right corner. + + + +3. Fill in the configuration information on the __Create Secret__ page, and click __OK__ . + + + + Note when filling in the configuration: + + - The name of the key must be unique within the same namespace + - Key type: + - Default (Opaque): Kubernetes default key type, which supports arbitrary data defined by users. + - TLS (kubernetes.io/tls): credentials for TLS client or server data access. + - Container registry information (kubernetes.io/dockerconfigjson): Credentials for Container registry access. + - username and password (kubernetes.io/basic-auth): Credentials for basic authentication. + - Custom: the type customized by the user according to business needs. + - Key data: the data stored in the key, the parameters that need to be filled in are different for different data + - When the key type is default (Opaque)/custom: multiple key-value pairs can be filled in. + - When the key type is TLS (kubernetes.io/tls): you need to fill in the certificate certificate and private key data. Certificates are self-signed or CA-signed credentials used for authentication. A certificate request is a request for a signature and needs to be signed with a private key. + - When the key type is container registry information (kubernetes.io/dockerconfigjson): you need to fill in the account and password of the private container registry. + - When the key type is username and password (kubernetes.io/basic-auth): Username and password need to be specified. + +## YAML creation + +1. Click the name of a cluster on the __Clusters__ page to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __ConfigMap and Secret__ -> __Secret__ , and click the __YAML Create__ button in the upper right corner. + + + +3. Fill in the YAML configuration on the __Create with YAML__ page, and click __OK__ . + + > Supports importing YAML files from local or downloading and saving filled files to local. + + + +## key YAML example + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: secretdemo + type: Opaque + data: + username: **** + password: **** + ``` + +[Next step: use secret](use-secret.md){ .md-button .md-button--primary } \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/configmaps-secrets/use-configmap.md b/docs/en/docs/kpanda/user-guide/configmaps-secrets/use-configmap.md new file mode 100644 index 0000000..29578da --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/configmaps-secrets/use-configmap.md @@ -0,0 +1,147 @@ +# Use ConfigMaps + +ConfigMap (ConfigMap) is an API object of Kubernetes, which is used to save non-confidential data into key-value pairs, and can store configurations that other objects need to use. +When used, the container can use it as an environment variable, a command-line argument, or a configuration file in a storage volume. By using ConfigMaps, configuration data and application code can be separated, providing a more flexible way to modify application configuration. + +!!! note + + ConfigMaps do not provide confidentiality or encryption. If the data to be stored is confidential, please use [secret](use-secret.md), or use other third-party tools to ensure the privacy of the data instead of ConfigMaps. + In addition, when using ConfigMaps in containers, the container and ConfigMaps must be in the same cluster namespace. + +## scenes to be used + +You can use ConfigMaps in Pods. There are many use cases, mainly including: + +- Use ConfigMaps to set the environment variables of the container + +- Use ConfigMaps to set the command line parameters of the container + +- Use ConfigMaps as container data volumes + +## Set the environment variables of the container + +You can use the ConfigMap as the environment variable of the container through the graphical interface or the terminal command line. + +!!! note + + The ConfigMap import is to use the ConfigMap as the value of the environment variable; the ConfigMap key value import is to use a certain parameter in the ConfigMap as the value of the environment variable. + +### Graphical interface operation + +When creating a workload through an image, you can set environment variables for the container by selecting __Import ConfigMaps__ or __Import ConfigMap Key Values__ on the __Environment Variables__ interface. + +1. Go to the [Image Creation Workload](../workloads/create-deployment.md) page, in the __Container Configuration__ step, select the __Environment Variables__ configuration, and click the __Add Environment Variable__ button. + + + +2. Select __ConfigMap Import__ or __ConfigMap Key Value Import__ in the environment variable type. + + - When the environment variable type is selected as __ConfigMap import__ , enter __variable name__ , __prefix__ name, __ConfigMap__ name in sequence. + + - When the environment variable type is selected as __ConfigMap key-value import__ , enter __variable name__ , __ConfigMap__ name, and __Secret__ name in sequence. + +### Command line operation + +You can set ConfigMaps as environment variables when creating a workload, using the valueFrom parameter to refer to the Key/Value in the ConfigMap. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod-1 +spec: + containers: + - name: test-container + image: busybox + command: [ "/bin/sh", "-c", "env" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: # (1) + configMapKeyRef: + name: kpanda-configmap # (2) + key: SPECIAL_LEVEL # (3) + restartPolicy: Never +``` + +1. Use __valueFrom__ to specify the value of the env reference ConfigMap +2. Referenced configuration file name +3. Referenced ConfigMap key + +## Set the command line parameters of the container + +You can use ConfigMaps to set the command or parameter value in the container, and use the environment variable substitution syntax __$(VAR_NAME)__ to do so. As follows. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod-3 +spec: + containers: + - name: test-container + image: busybox + command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: + configMapKeyRef: + name: kpanda-configmap + key: SPECIAL_LEVEL + - name: SPECIAL_TYPE_KEY + valueFrom: + configMapKeyRef: + name: kpanda-configmap + key: SPECIAL_TYPE + restartPolicy: Never +``` + +After the Pod runs, the output is as follows. + +```none +Hello Kpanda +``` + +## Used as container data volume + +You can use the ConfigMap as the environment variable of the container through the graphical interface or the terminal command line. + +### Graphical operation + +When creating a workload through an image, you can use the ConfigMap as the data volume of the container by selecting the storage type as "ConfigMap" on the "Data Storage" interface. + +1. Go to the [Image Creation Workload](../workloads/create-deployment.md) page, in the __Container Configuration__ step, select the __Data Storage__ configuration, and click __Add in the __ Node Path Mapping __ list __ button. + + + +2. Select __ConfigMap__ in the storage type, and enter __container path__ , __subpath__ and other information in sequence. + +### Command line operation + +To use a ConfigMap in a Pod's storage volume. + +Here is an example Pod that mounts a ConfigMap as a volume: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + -name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + configMap: + name: myconfigmap +``` + +If there are multiple containers in a Pod, each container needs its own __volumeMounts__ block, but you only need to set one __spec.volumes__ block per ConfigMap. + +!!! note + + When a ConfigMap is used as a data volume mounted on a container, the ConfigMap can only be read as a read-only file. \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/configmaps-secrets/use-secret.md b/docs/en/docs/kpanda/user-guide/configmaps-secrets/use-secret.md new file mode 100644 index 0000000..35b39d8 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/configmaps-secrets/use-secret.md @@ -0,0 +1,141 @@ +# use key + +A secret is a resource object used to store and manage sensitive information such as passwords, OAuth tokens, SSH, TLS credentials, etc. Using keys means you don't need to include sensitive secrets in your application code. + +## scenes to be used + +You can use keys in Pods in a variety of use cases, mainly including: + +- Used as an environment variable of the container to provide some necessary information required during the running of the container. +- Use secrets as pod data volumes. +- Used as the identity authentication credential for the container registry when the kubelet pulls the container image. + +## Use the key to set the environment variable of the container + +You can use the key as the environment variable of the container through the GUI or the terminal command line. + +!!! note + + Key import is to use the key as the value of an environment variable; key key value import is to use a parameter in the key as the value of an environment variable. + +### Graphical interface operation + +When creating a workload from an image, you can set environment variables for the container by selecting __Key Import__ or __Key Key Value Import__ on the __Environment Variables__ interface. + +1. Go to the [Image Creation Workload](../workloads/create-deployment.md) page. + + + +2. Select the __Environment Variables__ configuration in __Container Configuration__ , and click the __Add Environment Variable__ button. + + + +3. Select __Key Import__ or __Key Key Value Import__ in the environment variable type. + + + + - When the environment variable type is selected as __Key Import__ , enter __Variable Name__ , __Prefix__ , and __Secret__ in sequence. + + - When the environment variable type is selected as __key key value import__ , enter __variable name__ , __Secret__ , __Secret__ name in sequence. + +### Command line operation + +As shown in the example below, you can set the secret as an environment variable when creating the workload, using the __valueFrom__ parameter to refer to the Key/Value in the Secret. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: secret-env-pod +spec: + containers: + -name: mycontainer + image: redis + env: + - name: SECRET_USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + optional: false # (1) + - name: SECRET_PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + optional: false # (2) + +``` + +1. This value is the default; means "mysecret", which must exist and contain a primary key named "username" +2. This value is the default; means "mysecret", which must exist and contain a primary key named "password" + +## Use the key as the pod's data volume + +### Graphical interface operation + +When creating a workload through an image, you can use the key as the data volume of the container by selecting the storage type as "key" on the "data storage" interface. + +1. Go to the [Image Creation Workload](../workloads/create-deployment.md) page. + + + +2. In the __Container Configuration__ , select the __Data Storage__ configuration, and click the __Add__ button in the __Node Path Mapping__ list. + + + +3. Select __Secret__ in the storage type, and enter __container path__ , __subpath__ and other information in sequence. + +### Command line operation + +The following is an example of a Pod that mounts a Secret named __mysecret__ via a data volume: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + -name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + optional: false # (1) +``` + +1. Default setting, means "mysecret" must already exist + +If the Pod contains multiple containers, each container needs its own __volumeMounts__ block, but only one __.spec.volumes__ setting is required for each Secret. + +## Used as the identity authentication credential for the container registry when the kubelet pulls the container image + +You can use the key as the identity authentication credential for the Container registry through the GUI or the terminal command line. + +### Graphical operation + +When creating a workload through an image, you can use the key as the data volume of the container by selecting the storage type as "key" on the "data storage" interface. + +1. Go to the [Image Creation Workload](../workloads/create-deployment.md) page. + + + +2. In the second step of __Container Configuration__ , select the __Basic Information__ configuration, and click the __Select Image__ button. + + + +3. Select the name of the private container registry in the drop-down list of `container registry' in the pop-up box. Please see [Create Secret](create-secret.md) for details on private image secret creation. + + + +4. Enter the image name in the private registry, click __OK__ to complete the image selection. + +!!! note + + When creating a key, you need to ensure that you enter the correct container registry address, username, password, and select the correct mirror name, otherwise you will not be able to obtain the mirror image in the container registry. \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/custom-resources/create.md b/docs/en/docs/kpanda/user-guide/custom-resources/create.md new file mode 100644 index 0000000..934e2a1 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/custom-resources/create.md @@ -0,0 +1,107 @@ +# CustomResourceDefinition (CRD) + +In Kubernetes, all objects are abstracted as resources, such as Pod, Deployment, Service, Volume, etc. are the default resources provided by Kubernetes. +This provides important support for our daily operation and maintenance and management work, but in some special cases, the existing preset resources cannot meet the needs of the business. +Therefore, we hope to expand the capabilities of the Kubernetes API, and CustomResourceDefinition (CRD) was born based on this requirement. + +The container management module supports interface-based management of custom resources, and its main features are as follows: + +- Obtain the list and detailed information of custom resources under the cluster +- Create custom resources based on YAML +- Create a custom resource example CR (Custom Resource) based on YAML +- Delete custom resources + +## Prerequisites + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created Kubernetes](../clusters/create-cluster.md), and you can access the cluster UI interface. + +- Created a [namespace](../namespaces/createns.md), + [user](../../../ghippo/user-guide/access-control/user.md), + and authorized the user as [`Cluster Admin`](../permissions/permission-brief.md#cluster-admin) + For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +## Create CRD via YAML + +1. Click a cluster name to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __Custom Resource__ , and click the __YAML Create__ button in the upper right corner. + + + +3. On the __Create with YAML__ page, fill in the YAML statement and click __OK__ . + + + +4. Return to the custom resource list page, and you can view the custom resource named `crontabs.stable.example.com` just created. + + + +**Custom resource example:** + +```yaml title="CRD example" +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + cronSpec: + type: string + image: + type: string + replicas: + type: integer + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct +``` + +## Create a custom resource example via YAML + +1. Click a cluster name to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __Custom Resource__ , and click the __YAML Create__ button in the upper right corner. + + + +3. Click the custom resource named `crontabs.stable.example.com` , enter the details, and click the __YAML Create__ button in the upper right corner. + + + +4. On the __Create with YAML__ page, fill in the YAML statement and click __OK__ . + + + +5. Return to the details page of `crontabs.stable.example.com` , and you can view the custom resource named __my-new-cron-object__ just created. + +**CR Example:** + +```yaml title="CR example" +apiVersion: "stable.example.com/v1" +kind: CronTab +metadata: + name: my-new-cron-object +spec: + cronSpec: "* * * * */5" + image: my-awesome-cron-image +``` diff --git a/docs/en/docs/kpanda/user-guide/gpu/FAQ.md b/docs/en/docs/kpanda/user-guide/gpu/FAQ.md new file mode 100644 index 0000000..0d0cfb4 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/FAQ.md @@ -0,0 +1,18 @@ +--- +hide: + - toc +--- + +# GPU FAQs + +## GPU processes are not visible while running nvidia-smi inside a pod + +Q: When running the `nvidia-smi` command inside a GPU-utilizing pod, +no GPU process information is visible in the full-card mode and vGPU mode. + +A: Due to `PID namespace` isolation, GPU processes are not visible inside the Pod. +To view GPU processes, you can use one of the following methods: + +- Configure the workload using the GPU with `hostPID: true` to enable viewing PIDs on the host. +- Run the `nvidia-smi` command in the driver pod of the gpu-operator to view processes. +- Run the `chroot /run/nvidia/driver nvidia-smi` command on the host to view processes. diff --git a/docs/en/docs/kpanda/user-guide/gpu/Iluvatar_usage.md b/docs/en/docs/kpanda/user-guide/gpu/Iluvatar_usage.md new file mode 100644 index 0000000..5dba06c --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/Iluvatar_usage.md @@ -0,0 +1,65 @@ +# How to Use Iluvatar GPU in Applications + +This section describes how to use Iluvatar virtual GPU on AI platform. + +## Prerequisites + +- Deployed AI platform container management platform and it is running smoothly. +- The container management module has been integrated with a Kubernetes cluster or a Kubernetes cluster has been created, and the UI interface of the cluster can be accessed. +- The Iluvatar GPU driver has been installed on the current cluster. Refer to the [Iluvatar official documentation](https://support.iluvatar.com/#/login) for driver installation instructions, or contact the Suanova ecosystem team for enterprise-level support at peg-pem@daocloud.io. +- The GPUs in the current cluster have not undergone any virtualization operations and not been occupied by other applications. + +## Procedure + +### Configuration via User Interface + +1. Check if the GPU card in the cluster has been detected. Click __Clusters__ -> __Cluster Settings__ -> __Addon Plugins__ , and check if the corresponding GPU type has been automatically enabled and detected. + Currently, the cluster will automatically enable __GPU__ and set the GPU type as __Iluvatar__ . + + + +2. Deploy a workload. Click __Clusters__ -> __Workloads__ and deploy a workload using the image. After selecting the type as __(Iluvatar)__ , configure the GPU resources used by the application: + + - Physical Card Count (iluvatar.ai/vcuda-core): Indicates the number of physical cards that the current pod needs to mount. The input value must be an integer and **less than or equal to** the number of cards on the host machine. + + - Memory Usage (iluvatar.ai/vcuda-memory): Indicates the amount of GPU memory occupied by each card. The value is in MB, with a minimum value of 1 and a maximum value equal to the entire memory of the card. + + + > If there are any issues with the configuration values, scheduling failures or resource allocation failures may occur. + +### Configuration via YAML + +To request GPU resources for a workload, add the __iluvatar.ai/vcuda-core: 1__ and __iluvatar.ai/vcuda-memory: 200__ to the requests and limits. +These parameters configure the application to use the physical card resources. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-iluvatar-gpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-iluvatar-gpu-demo + template: + metadata: + labels: + app: full-iluvatar-gpu-demo + spec: + containers: + - image: nginx:perl + name: container-0 + resources: + limits: + cpu: 250m + iluvatar.ai/vcuda-core: '1' + iluvatar.ai/vcuda-memory: '200' + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + imagePullSecrets: + - name: default-secret +``` diff --git a/docs/en/docs/kpanda/user-guide/gpu/ascend/Ascend_usage.md b/docs/en/docs/kpanda/user-guide/gpu/ascend/Ascend_usage.md new file mode 100644 index 0000000..f00f808 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/ascend/Ascend_usage.md @@ -0,0 +1,177 @@ +--- +MTPE: windsonsea +Date: 2024-07-30 +--- + +# Use Ascend NPU + +This section explains how to use Ascend NPU on the AI platform platform. + +## Prerequisites + +- The current NPU node has the Ascend driver installed. +- The current NPU node has the Ascend-Docker-Runtime component installed. +- The NPU MindX DL suite is installed on the current cluster. +- No virtualization is performed on the NPU card in the current cluster, + and it is not occupied by other applications. + +Refer to the [Ascend NPU Component Installation Document](ascend_driver_install.md) +to install the basic environment. + +## Quick Start + +This document uses the [AscentCL Image Classification Application](https://gitee.com/ascend/samples/tree/master/inference/modelInference/sampleResnetQuickStart/python) example from the Ascend sample library. + +1. Download the Ascend repository + + Run the following command to download the Ascend demo repository, + and remember the storage location of the code for subsequent use. + + ```git + git clone https://gitee.com/ascend/samples.git + ``` + +2. Prepare the base image + + This example uses the Ascent-pytorch base image, which can be obtained from the + [Ascend Container Registry](https://www.hiascend.com/developer/ascendhub). + +3. Prepare the YAML file + + ```yaml title="ascend-demo.yaml" + apiVersion: batch/v1 + kind: Job + metadata: + name: resnetinfer1-1-1usoc + spec: + template: + spec: + containers: + - image: ascendhub.huawei.com/public-ascendhub/ascend-pytorch:23.0.RC2-ubuntu18.04 # Inference image name + imagePullPolicy: IfNotPresent + name: resnet50infer + securityContext: + runAsUser: 0 + command: + - "/bin/bash" + - "-c" + - | + source /usr/local/Ascend/ascend-toolkit/set_env.sh && + TEMP_DIR=/root/samples_copy_$(date '+%Y%m%d_%H%M%S_%N') && + cp -r /root/samples "$TEMP_DIR" && + cd "$TEMP_DIR"/inference/modelInference/sampleResnetQuickStart/python/model && + wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/003_Atc_Models/resnet50/resnet50.onnx && + atc --model=resnet50.onnx --framework=5 --output=resnet50 --input_shape="actual_input_1:1,3,224,224" --soc_version=Ascend910 && + cd ../data && + wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg && + cd ../scripts && + bash sample_run.sh + resources: + requests: + huawei.com/Ascend910: 1 # Number of the Ascend 910 Processors + limits: + huawei.com/Ascend910: 1 # The value should be the same as that of requests + volumeMounts: + - name: hiai-driver + mountPath: /usr/local/Ascend/driver + readOnly: true + - name: slog + mountPath: /var/log/npu/conf/slog/slog.conf + - name: localtime # The container time must be the same as the host time + mountPath: /etc/localtime + - name: dmp + mountPath: /var/dmp_daemon + - name: slogd + mountPath: /var/slogd + - name: hbasic + mountPath: /etc/hdcBasic.cfg + - name: sys-version + mountPath: /etc/sys_version.conf + - name: aicpu + mountPath: /usr/lib64/aicpu_kernels + - name: tfso + mountPath: /usr/lib64/libtensorflow.so + - name: sample-path + mountPath: /root/samples + volumes: + - name: hiai-driver + hostPath: + path: /usr/local/Ascend/driver + - name: slog + hostPath: + path: /var/log/npu/conf/slog/slog.conf + - name: localtime + hostPath: + path: /etc/localtime + - name: dmp + hostPath: + path: /var/dmp_daemon + - name: slogd + hostPath: + path: /var/slogd + - name: hbasic + hostPath: + path: /etc/hdcBasic.cfg + - name: sys-version + hostPath: + path: /etc/sys_version.conf + - name: aicpu + hostPath: + path: /usr/lib64/aicpu_kernels + - name: tfso + hostPath: + path: /usr/lib64/libtensorflow.so + - name: sample-path + hostPath: + path: /root/samples + restartPolicy: OnFailure + ``` + + Some fields in the above YAML need to be modified according to the actual situation: + + 1. __atc ... --soc_version=Ascend910__ uses __Ascend910__, adjust this field depending on + your actual situation. You can use the __npu-smi info__ command to check the GPU model + and add the Ascend prefix. + 2. __samples-path__ should be adjusted according to the actual situation. + 3. __resources__ should be adjusted according to the actual situation. + +4. Deploy a Job and check its results + + Use the following command to create a Job: + + ```shell + kubectl apply -f ascend-demo.yaml + ``` + + Check the Pod running status: ![Ascend Pod Status](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/user-guide/gpu/images/ascend-demo-pod-status.png) + + After the Pod runs successfully, check the log results. The key prompt information on the screen is shown in + the figure below. The Label indicates the category identifier, Conf indicates the maximum confidence of + the classification, and Class indicates the belonging category. These values may vary depending on the + version and environment, so please refer to the actual situation: + + ![Ascend demo running result](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/user-guide/gpu/images/ascend-demo-pod-result.png) + + Result image display: + + ![Ascend demo running result image](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/user-guide/gpu/images/ascend-demo-infer-result.png) + +## UI Usage + +1. Confirm whether the cluster has detected the GPU card. Click __Clusters__ -> __Cluster Settings__ -> __Addon Plugins__ , + and check whether the proper GPU type is automatically enabled and detected. + Currently, the cluster will automatically enable __GPU__ and set the __GPU__ type to __Ascend__ . + + ![Cluster Settings](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/user-guide/gpu/images/cluster-setting-ascend-gpu.jpg) + +2. Deploy the workload. Click __Clusters__ -> __Workloads__ , deploy the workload through an image, + select the type (Ascend), and then configure the number of physical cards used by the application: + + **Number of Physical Cards (huawei.com/Ascend910)** : This indicates how many physical cards + the current Pod needs to mount. The input value must be an integer and **less than or equal to** + the number of cards on the host. + + ![Workload Usage](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/user-guide/gpu/images/workload_ascendgpu_userguide.jpg) + + > If there is an issue with the above configuration, it will result in + > scheduling failure and resource allocation issues. diff --git a/docs/en/docs/kpanda/user-guide/gpu/ascend/ascend_driver_install.md b/docs/en/docs/kpanda/user-guide/gpu/ascend/ascend_driver_install.md new file mode 100644 index 0000000..21fcb38 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/ascend/ascend_driver_install.md @@ -0,0 +1,173 @@ +--- +MTPE: ModetaNiu +Date: 2024-07-02 +--- + +# Installation of Ascend NPU Components + +This chapter provides installation guidance for Ascend NPU drivers, Device Plugin, NPU-Exporter, and other components. + +## Prerequisites + +1. Before installation, confirm the supported NPU models. For details, refer to the [Ascend NPU Matrix](../gpu_matrix.md). +2. Ensure that the kernel version required for the corresponding NPU model is compatible. For more details, + refer to the [Ascend NPU Matrix](../gpu_matrix.md). +3. Prepare the basic Kubernetes environment. + +## Installation Steps + +Before using NPU resources, you need to complete the firmware installation, NPU driver installation, +Docker Runtime installation, user creation, log directory creation, and NPU Device Plugin installation. +Refer to the following steps for details. + +### Install Firmware + +1. Confirm that the kernel version is within the range corresponding to the "binary installation" method, + and then you can directly install the NPU driver firmware. +2. For firmware and driver downloads, refer to: [Firmware Download Link](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=15&cann=6.3.RC2.alpha005&driver=1.0.20.alpha) +3. For firmware installation, refer to: [Install NPU Driver Firmware](https://www.hiascend.com/document/detail/zh/quick-installation/23.0.RC2/quickinstg/800_3000/quickinstg_800_3000_0001.html) + +### Install NPU Driver + +1. If the driver is not installed, refer to the official Ascend documentation for installation. For example, + for Ascend910, refer to: [910 Driver Installation Document](https://www.hiascend.com/document/detail/zh/Atlas%20200I%20A2/23.0.RC3/EP/installationguide/Install_87.html). +2. Run the command `npu-smi info`, and if the NPU information is returned normally, it indicates that the NPU driver + and firmware are ready. + +![Ascend-mindxdl Information](../images/npu-smi-info.png) + +### Install Docker Runtime + +1. Download Ascend Docker Runtime + + Community edition download link: https://www.hiascend.com/zh/software/mindx-dl/community + + ```sh + wget -c https://mindx.obs.cn-south-1.myhuaweicloud.com/OpenSource/MindX/MindX%205.0.RC2/MindX%20DL%205.0.RC2/Ascend-docker-runtime_5.0.RC2_linux-x86_64.run + ``` + + Install to the specified path by executing the following two commands in order, with parameters specifying the installation path: + + ```sh + chmod u+x Ascend-docker-runtime_5.0.RC2_linux-x86_64.run + ./Ascend-docker-runtime_{version}_linux-{arch}.run --install --install-path= + ``` + +2. Modify the containerd configuration file + + If containerd has no default configuration file, execute the following three commands in order to create the configuration file: + + ```bash + mkdir /etc/containerd + containerd config default > /etc/containerd/config.toml + vim /etc/containerd/config.toml + ``` + + If containerd has a configuration file: + + ```bash + vim /etc/containerd/config.toml + ``` + + Modify the runtime installation path according to the actual situation, mainly modifying the runtime field: + + ```toml + ... + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + [plugins."io.containerd.runtime.v1.linux"] + shim = "containerd-shim" + runtime = "/usr/local/Ascend/Ascend-Docker-Runtime/ascend-docker-runtime" + runtime_root = "" + no_shim = false + shim_debug = false + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + ... + ``` + + Execute the following command to restart containerd: + + ```bash + systemctl restart containerd + ``` + +### Create a User + +Execute the following commands on the node where the components are installed to create a user. + +```sh +# Ubuntu operating system +useradd -d /home/hwMindX -u 9000 -m -s /usr/sbin/nologin hwMindX +usermod -a -G HwHiAiUser hwMindX +# CentOS operating system +useradd -d /home/hwMindX -u 9000 -m -s /sbin/nologin hwMindX +usermod -a -G HwHiAiUser hwMindX +``` + +### Create Log Directory + +Create the parent directory for component logs and the log directories for each component on the corresponding node, +and set the appropriate owner and permissions for the directories. Execute the following command to create +the parent directory for component logs. + +```bash +mkdir -m 755 /var/log/mindx-dl +chown root:root /var/log/mindx-dl +``` + +Execute the following command to create the Device Plugin component log directory. + +```bash +mkdir -m 750 /var/log/mindx-dl/devicePlugin +chown root:root /var/log/mindx-dl/devicePlugin +``` + +!!! note + + Please create the corresponding log directory for each required component. In this example, only the Device Plugin component is needed. + For other component requirements, refer to the [official documentation](https://www.hiascend.com/document/detail/zh/mindx-dl/50rc3/clusterscheduling/clusterschedulingig/dlug_installation_016.html) + +### Create Node Labels + +Refer to the following commands to create labels on the corresponding nodes: + +```shell +# Create this label on computing nodes where the driver is installed +kubectl label node {nodename} huawei.com.ascend/Driver=installed +kubectl label node {nodename} node-role.kubernetes.io/worker=worker +kubectl label node {nodename} workerselector=dls-worker-node +kubectl label node {nodename} host-arch=huawei-arm // or host-arch=huawei-x86, select according to the actual situation +kubectl label node {nodename} accelerator=huawei-Ascend910 // select according to the actual situation +# Create this label on control nodes +kubectl label node {nodename} masterselector=dls-master-node +``` + +### Install Device Plugin and NpuExporter + +Functional module path: __Container Management__ -> __Cluster__, click the name of the target cluster, then click __Helm Apps__ -> __Helm Charts__ from the left navigation bar, and search for __ascend-mindxdl__. + +![Find ascend-mindxdl](../images/ascend-mindxdl.png) + +![Ascend-mindxdl](../images/detail-ascend.png) + +- __DevicePlugin__: Provides a general device plugin mechanism and standard device API interface for Kubernetes to use devices. It is recommended to use the default image and version. +- __NpuExporter__: Based on the Prometheus/Telegraf ecosystem, this component provides interfaces to help users monitor the Ascend series AI processors and container-level allocation status. It is recommended to use the default image and version. +- __ServiceMonitor__: Disabled by default. If enabled, you can view NPU-related monitoring in the observability module. To enable, ensure that the insight-agent is installed and running, otherwise, the ascend-mindxdl installation will fail. +- __isVirtualMachine__: Disabled by default. If the NPU node is a virtual machine scenario, enable the isVirtualMachine parameter. + +After a successful installation, two components will appear under the corresponding namespace, as shown below: + +![List of ascend-mindxdl](../images/list-ascend-mindxdl.png) + +At the same time, the corresponding NPU information will also appear on the node information: + +![Node labels](../images/label-ascend-mindxdl.png) + +Once everything is ready, you can select the corresponding NPU device when creating a workload through the page, as shown below: + + + +!!! note + + For detailed information of how to use, refer to [Using Ascend (Ascend) NPU](https://docs.daocloud.io/kpanda/user-guide/gpu/Ascend_usage/). diff --git a/docs/en/docs/kpanda/user-guide/gpu/ascend/vnpu.md b/docs/en/docs/kpanda/user-guide/gpu/ascend/vnpu.md new file mode 100644 index 0000000..527f7f3 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/ascend/vnpu.md @@ -0,0 +1,87 @@ +--- +MTPE: windsonsea +Date: 2024-07-12 +--- + +# Enable Ascend Virtualization + +Ascend virtualization is divided into dynamic virtualization and static virtualization. +This document describes how to enable and use Ascend static virtualization capabilities. + +## Prerequisites + +- Setup of Kubernetes cluster environment. +- The current NPU node has the Ascend driver installed. +- The current NPU node has the Ascend-Docker-Runtime component installed. +- The NPU MindX DL suite is installed on the current cluster. +- Supported NPU models: + + - Ascend 310P, verified + - Ascend 910b (20 cores), verified + - Ascend 910 (32 cores), officially supported but not verified + - Ascend 910 (30 cores), officially supported but not verified + + For more details, refer to the [official virtualization hardware documentation](https://www.hiascend.com/document/detail/zh/mindx-dl/50rc1/AVI/cpaug/cpaug_0005.html). + +Refer to the [Ascend NPU Component Installation Documentation](./ascend_driver_install.md) +for the basic environment setup. + +## Enable Virtualization Capabilities + +To enable virtualization capabilities, you need to manually modify the startup parameters +of the `ascend-device-plugin-daemonset` component. Refer to the following command: + +```init +- device-plugin -useAscendDocker=true -volcanoType=false -presetVirtualDevice=true +- logFile=/var/log/mindx-dl/devicePlugin/devicePlugin.log -logLevel=0 +``` + +### Split VNPU Instances + +Static virtualization requires manually splitting VNPU instances. Refer to the following command: + +```bash +npu-smi set -t create-vnpu -i 13 -c 0 -f vir02 +``` + +- `i` refers to the card id. +- `c` refers to the chip id. +- `vir02` refers to the split specification template. + +Card id and chip id can be queried using `npu-smi info`. The split specifications can be found in the +[Ascend official templates](https://www.hiascend.com/document/detail/zh/mindx-dl/500/AVI/cpaug/cpaug_006.html). + +After splitting the instance, you can query the split results using the following command: + +```bash +npu-smi info -t info-vnpu -i 13 -c 0 +``` + +The query result is as follows: + +![vnpu1](../images/vnpu1.png) + +### Restart `ascend-device-plugin-daemonset` + +After splitting the instance, manually restart the `device-plugin` pod, +then use the `kubectl describe` command to check the resources of the registered node: + +```bash +kubectl describe node {{nodename}} +``` + +![vnpu2](../images/vnpu2.png) + +## How to Use the Device + +When creating an application, specify the resource key as shown in the following YAML: + +```yaml +...... +resources: + requests: + huawei.com/Ascend310P-2c: 1 + limits: + huawei.com/Ascend310P-2c: 1 +...... +``` diff --git a/docs/en/docs/kpanda/user-guide/gpu/dynamic-regulation.md b/docs/en/docs/kpanda/user-guide/gpu/dynamic-regulation.md new file mode 100644 index 0000000..d1c0af2 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/dynamic-regulation.md @@ -0,0 +1,72 @@ +# GPU Scheduling Configuration (Binpack and Spread) + +This page introduces how to reduce GPU resource fragmentation and prevent single points of failure through +Binpack and Spread when using NVIDIA vGPU, achieving advanced scheduling for vGPU. The AI platform platform +provides Binpack and Spread scheduling policies across two dimensions: clusters and workloads, +meeting different usage requirements in various scenarios. + +## Prerequisites + +- GPU devices are correctly installed on the cluster nodes. +- The [gpu-operator component](./nvidia/install_nvidia_driver_of_operator.md) + and [Nvidia-vgpu component](./nvidia/vgpu/vgpu_addon.md) are correctly installed in the cluster. +- The NVIDIA-vGPU type exists in the GPU mode in the node list in the cluster. + +## Use Cases + +- Scheduling policy based on GPU dimension + + - Binpack: Prioritizes using the same GPU on a node, suitable for increasing GPU utilization and reducing resource fragmentation. + - Spread: Multiple Pods are distributed across different GPUs on nodes, suitable for high availability scenarios to avoid single card failures. + +- Scheduling policy based on node dimension + + - Binpack: Multiple Pods prioritize using the same node, suitable for increasing GPU utilization and reducing resource fragmentation. + - Spread: Multiple Pods are distributed across different nodes, suitable for high availability scenarios to avoid single node failures. + +## Use Binpack and Spread at Cluster-Level + +!!! note + + By default, workloads will follow the cluster-level Binpack and Spread. If a workload sets its + own Binpack and Spread scheduling policies that differ from the cluster, the workload will prioritize + its own scheduling policy. + +1. On the __Clusters__ page, select the cluster for which you want to adjust the Binpack and Spread scheduling + policies. Click the __┇__ icon on the right and select __GPU Scheduling Configuration__ from the dropdown list. + + ![Cluster List](images/gpu-scheduler-clusterlist.png) + +2. Adjust the GPU scheduling configuration according to your business scenario, and click __OK__ to save. + + ![Binpack Configuration](images/gpu-scheduler-clusterrule.png) + +## Use Binpack and Spread at Workload-Level + +!!! note + + When the Binpack and Spread scheduling policies at the workload level conflict with the + cluster-level configuration, the workload-level configuration takes precedence. + +Follow the steps below to create a deployment using an image and configure Binpack and Spread +scheduling policies within the workload. + +1. Click __Clusters__ in the left navigation bar, then click the name of the target cluster to + enter the __Cluster Details__ page. + + ![Cluster List](images/clusterlist1.png) + +2. On the Cluster Details page, click __Workloads__ -> __Deployments__ in the left navigation bar, + then click the __Create by Image__ button in the upper right corner of the page. + + ![Create Workload](images/gpu-createdeploy.png) + +3. Sequentially fill in the [Basic Information](../workloads/create-deployment.md#basic-information), + [Container Settings](../workloads/create-deployment.md#container-settings), + and in the __Container Configuration__ section, enable GPU configuration, selecting the GPU type as NVIDIA vGPU. + Click __Advanced Settings__, enable the Binpack / Spread scheduling policy, and adjust the GPU scheduling + configuration according to the business scenario. After configuration, click __Next__ to proceed to + [Service Settings](../workloads/create-deployment.md#service-settings) + and [Advanced Settings](../workloads/create-deployment.md#advanced-settings). + Finally, click __OK__ at the bottom right of the page to complete the creation. + diff --git a/docs/en/docs/kpanda/user-guide/gpu/gpu-metrics.md b/docs/en/docs/kpanda/user-guide/gpu/gpu-metrics.md new file mode 100644 index 0000000..9278339 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/gpu-metrics.md @@ -0,0 +1,59 @@ +# GPU Metrics + +This page lists some commonly used GPU metrics. + +## Cluster Level + +| Metric Name | Description | +| ----------- | ----------- | +| Number of GPUs | Total number of GPUs in the cluster | +| Average GPU Utilization | Average compute utilization of all GPUs in the cluster | +| Average GPU Memory Utilization | Average memory utilization of all GPUs in the cluster | +| GPU Power | Power consumption of all GPUs in the cluster | +| GPU Temperature | Temperature of all GPUs in the cluster | +| GPU Utilization Details | 24-hour usage details of all GPUs in the cluster (includes max, avg, current) | +| GPU Memory Usage Details | 24-hour memory usage details of all GPUs in the cluster (includes min, max, avg, current) | +| GPU Memory Bandwidth Utilization | For example, an Nvidia V100 GPU has a maximum memory bandwidth of 900 GB/sec. If the current memory bandwidth is 450 GB/sec, the utilization is 50% | + +## Node Level + +| Metric Name | Description | +| ----------- | ----------- | +| GPU Mode | Usage mode of GPUs on the node, including full-card mode, MIG mode, vGPU mode | +| Number of Physical GPUs | Total number of physical GPUs on the node | +| Number of Virtual GPUs | Number of vGPU devices created on the node | +| Number of MIG Instances | Number of MIG instances created on the node | +| GPU Memory Allocation Rate | Memory allocation rate of all GPUs on the node | +| Average GPU Utilization | Average compute utilization of all GPUs on the node | +| Average GPU Memory Utilization | Average memory utilization of all GPUs on the node | +| GPU Driver Version | Driver version information of GPUs on the node | +| GPU Utilization Details | 24-hour usage details of each GPU on the node (includes max, avg, current) | +| GPU Memory Usage Details | 24-hour memory usage details of each GPU on the node (includes min, max, avg, current) | + +## Pod Level + +| Category | Metric Name | Description | +| -------- | ----------- | ----------- | +| Application Overview GPU - Compute & Memory | Pod GPU Utilization | Compute utilization of the GPUs used by the current Pod | +| | Pod GPU Memory Utilization | Memory utilization of the GPUs used by the current Pod | +| | Pod GPU Memory Usage | Memory usage of the GPUs used by the current Pod | +| | Memory Allocation | Memory allocation of the GPUs used by the current Pod | +| | Pod GPU Memory Copy Ratio | Memory copy ratio of the GPUs used by the current Pod | +| GPU - Engine Overview | GPU Graphics Engine Activity Percentage | Percentage of time the Graphics or Compute engine is active during a monitoring cycle | +| | GPU Memory Bandwidth Utilization | Memory bandwidth utilization (Memory BW Utilization) indicates the fraction of cycles during which data is sent to or received from the device memory. This value represents the average over the interval, not an instantaneous value. A higher value indicates higher utilization of device memory.
A value of 1 (100%) indicates that a DRAM instruction is executed every cycle during the interval (in practice, a peak of about 0.8 (80%) is the maximum achievable).
A value of 0.2 (20%) indicates that 20% of the cycles during the interval are spent reading from or writing to device memory. | +| | Tensor Core Utilization | Percentage of time the Tensor Core pipeline is active during a monitoring cycle | +| | FP16 Engine Utilization | Percentage of time the FP16 pipeline is active during a monitoring cycle | +| | FP32 Engine Utilization | Percentage of time the FP32 pipeline is active during a monitoring cycle | +| | FP64 Engine Utilization | Percentage of time the FP64 pipeline is active during a monitoring cycle | +| | GPU Decode Utilization | Decode engine utilization of the GPU | +| | GPU Encode Utilization | Encode engine utilization of the GPU | +| GPU - Temperature & Power | GPU Temperature | Temperature of all GPUs in the cluster | +| | GPU Power | Power consumption of all GPUs in the cluster | +| | GPU Total Power Consumption | Total power consumption of the GPUs | +| GPU - Clock | GPU Memory Clock | Memory clock frequency | +| | GPU Application SM Clock | Application SM clock frequency | +| | GPU Application Memory Clock | Application memory clock frequency | +| | GPU Video Engine Clock | Video engine clock frequency | +| | GPU Throttle Reasons | Reasons for GPU throttling | +| GPU - Other Details | PCIe Transfer Rate | Data transfer rate of the GPU through the PCIe bus | +| | PCIe Receive Rate | Data receive rate of the GPU through the PCIe bus | diff --git a/docs/en/docs/kpanda/user-guide/gpu/gpu_matrix.md b/docs/en/docs/kpanda/user-guide/gpu/gpu_matrix.md new file mode 100644 index 0000000..1a35f92 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/gpu_matrix.md @@ -0,0 +1,318 @@ +--- +hide: + - toc +--- + +# GPU Support Matrix + +This page explains the matrix of supported GPUs and operating systems for AI platform. + +## NVIDIA GPU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GPU Manufacturer and TypeSupported GPU ModelsCompatible Operating System (Online)Recommended KernelRecommended Operating System and KernelInstallation Documentation
NVIDIA GPU (Full Card/vGPU) +
    +
  • NVIDIA Fermi (2.1) Architecture:
  • +
  • NVIDIA GeForce 400 Series
  • +
  • NVIDIA Quadro 4000 Series
  • +
  • NVIDIA Tesla 20 Series
  • +
  • NVIDIA Ampere Architecture Series (A100; A800; H100)
  • +
+
CentOS 7 + +Operating System: CentOS 7.9;
Kernel Version: 3.10.0-1160
Offline Installation with GPU Operator
CentOS 8Kernel 4.18.0-80 ~ 4.18.0-348
Ubuntu 20.04Kernel 5.4
Ubuntu 22.04Kernel 5.19
RHEL 7Kernel 3.10.0-123 ~ 3.10.0-1160
RHEL 8Kernel 4.18.0-80 ~ 4.18.0-348
NVIDIA MIG +
    +
  • Ampere Architecture Series:
  • +
  • A100
  • +
  • A800
  • +
  • H100
  • +
+
CentOS 7Kernel 3.10.0-123 ~ 3.10.0-1160Operating System: CentOS 7.9;
Kernel Version: 3.10.0-1160
Offline Installation with GPU Operator
CentOS 8Kernel 4.18.0-80 ~ 4.18.0-348
Ubuntu 20.04Kernel 5.4
Ubuntu 22.04Kernel 5.19
RHEL 7Kernel 3.10.0-123 ~ 3.10.0-1160
RHEL 8Kernel 4.18.0-80 ~ 4.18.0-348
+ +## Ascend NPU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GPU Manufacturer and TypeSupported NPU ModelsCompatible Operating System (Online)Recommended KernelRecommended Operating System and KernelInstallation Documentation
Ascend (Ascend 310) +
    +
  • Ascend 310;
  • +
  • Ascend 310P;
  • +
+
Ubuntu 20.04Details refer to: Kernel Version RequirementsOperating System: CentOS 7.9;
Kernel Version: 3.10.0-1160
300 and 310P Driver Documentation
CentOS 7.6
CentOS 8.2
KylinV10SP1 Operating System
openEuler Operating System
Ascend (Ascend 910P)Ascend 910Ubuntu 20.04Details refer to: Kernel Version RequirementsOperating System: CentOS 7.9;
Kernel Version: 3.10.0-1160
910 Driver Documentation
CentOS 7.6
CentOS 8.2
KylinV10SP1 Operating System
openEuler Operating System
+ +## Iluvatar GPU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GPU Manufacturer and TypeSupported GPU ModelsCompatible Operating System (Online)Recommended KernelRecommended Operating System and KernelInstallation Documentation
Iluvatar (Iluvatar vGPU) +
    +
  • BI100;
  • +
  • MR100;
  • +
+
CentOS 7 +
    +
  • Kernel 3.10.0-957.el7.x86_64 ~ 3.10.0-1160.42.2.el7.x86_64
  • +
+
Operating System: CentOS 7.9;
Kernel Version: 3.10.0-1160
Coming Soon
CentOS 8 +
    +
  • Kernel 4.18.0-80.el8.x86_64 ~ 4.18.0-305.19.1.el8_4.x86_64
  • +
+
Ubuntu 20.04 +
    +
  • Kernel 4.15.0-20-generic ~ 4.15.0-160-generic
  • +
  • Kernel 5.4.0-26-generic ~ 5.4.0-89-generic
  • +
  • Kernel 5.8.0-23-generic ~ 5.8.0-63-generic
  • +
+
Ubuntu 21.04 +
    +
  • Kernel 4.15.0-20-generic ~ 4.15.0-160-generic
  • +
  • Kernel 5.4.0-26-generic ~ 5.4.0-89-generic
  • +
  • Kernel 5.8.0-23-generic ~ 5.8.0-63-generic
  • +
+
openEuler 22.03 LTS +
    +
  • Kernel version >= 5.1 and <= 5.10
  • +
+
diff --git a/docs/en/docs/kpanda/user-guide/gpu/gpu_scheduler_config.md b/docs/en/docs/kpanda/user-guide/gpu/gpu_scheduler_config.md new file mode 100644 index 0000000..afe5496 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/gpu_scheduler_config.md @@ -0,0 +1,48 @@ +# GPU Scheduling Configuration + +This document mainly introduces the configuration of `GPU` scheduling, which can implement +advanced scheduling policies. Currently, the primary implementation is the `vgpu` scheduling policy. + +## vGPU Resource Scheduling Configuration + +`vGPU` provides two policies for resource usage: `binpack` and `spread`. These correspond to node-level +and GPU-level dimensions, respectively. The use case is whether you want to distribute workloads more +sparsely across different nodes and GPUs or concentrate them on the same node and GPU, +thereby making resource utilization more efficient and reducing resource fragmentation. + +You can modify the scheduling policy in your cluster by following these steps: + +1. Go to the cluster management list in the container management interface. +2. Click the settings button **...** next to the cluster. +3. Click **GPU Scheduling Configuration**. +4. Toggle the scheduling policy between node-level and GPU-level. By default, + the node-level policy is `binpack`, and the GPU-level policy is `spread`. + +![vgpu-scheduler](./images/vgpu-sc.png) + +The above steps modify the cluster-level scheduling policy. Users can also specify their own +scheduling policy at the workload level to change the scheduling results. Below is an example +of modifying the scheduling policy at the workload level: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: gpu-pod + annotations: + hami.io/node-scheduler-policy: "binpack" + hami.io/gpu-scheduler-policy: "binpack" +spec: + containers: + - name: ubuntu-container + image: ubuntu:18.04 + command: ["bash", "-c", "sleep 86400"] + resources: + limits: + nvidia.com/gpu: 1 + nvidia.com/gpumem: 3000 + nvidia.com/gpucores: 30 +``` + +In this example, both the node- and GPU-level scheduling policies are set to `binpack`. +This ensures that the workload is scheduled to maximize resource utilization and reduce fragmentation. diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/ascend-mindxdl.png b/docs/en/docs/kpanda/user-guide/gpu/images/ascend-mindxdl.png new file mode 100644 index 0000000..b7b16fd Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/ascend-mindxdl.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/cluster-ns.png b/docs/en/docs/kpanda/user-guide/gpu/images/cluster-ns.png new file mode 100644 index 0000000..a3d649d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/cluster-ns.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/clusterlist1.png b/docs/en/docs/kpanda/user-guide/gpu/images/clusterlist1.png new file mode 100644 index 0000000..eeb5fdd Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/clusterlist1.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/detail-ascend.png b/docs/en/docs/kpanda/user-guide/gpu/images/detail-ascend.png new file mode 100644 index 0000000..8d5b006 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/detail-ascend.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/driveimage.png b/docs/en/docs/kpanda/user-guide/gpu/images/driveimage.png new file mode 100644 index 0000000..e057a26 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/driveimage.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/driver.jpg b/docs/en/docs/kpanda/user-guide/gpu/images/driver.jpg new file mode 100644 index 0000000..7e59583 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/driver.jpg differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/gpu-createdeploy.png b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-createdeploy.png new file mode 100644 index 0000000..91baba8 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-createdeploy.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/gpu-operator-mig.png b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-operator-mig.png new file mode 100644 index 0000000..34df624 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-operator-mig.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/gpu-scheduler-clusterlist.png b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-scheduler-clusterlist.png new file mode 100644 index 0000000..bdf2bbf Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-scheduler-clusterlist.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/gpu-scheduler-clusterrule.png b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-scheduler-clusterrule.png new file mode 100644 index 0000000..ddfc201 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/gpu-scheduler-clusterrule.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/image-1.png b/docs/en/docs/kpanda/user-guide/gpu/images/image-1.png new file mode 100644 index 0000000..6e75986 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/image-1.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/image-2.png b/docs/en/docs/kpanda/user-guide/gpu/images/image-2.png new file mode 100644 index 0000000..1399f91 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/image-2.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/image.png b/docs/en/docs/kpanda/user-guide/gpu/images/image.png new file mode 100644 index 0000000..090d763 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/image.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/label-ascend-mindxdl.png b/docs/en/docs/kpanda/user-guide/gpu/images/label-ascend-mindxdl.png new file mode 100644 index 0000000..edea928 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/label-ascend-mindxdl.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/list-ascend-mindxdl.png b/docs/en/docs/kpanda/user-guide/gpu/images/list-ascend-mindxdl.png new file mode 100644 index 0000000..7a229f7 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/list-ascend-mindxdl.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig-select.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig-select.png new file mode 100644 index 0000000..3649d23 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig-select.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig2c.4g.20gb.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig2c.4g.20gb.png new file mode 100644 index 0000000..13b5887 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig2c.4g.20gb.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig_1c.4g.20gb.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig_1c.4g.20gb.png new file mode 100644 index 0000000..4233ecb Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig_1c.4g.20gb.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig_1g5gb.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig_1g5gb.png new file mode 100644 index 0000000..a8a88e9 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig_1g5gb.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig_4g20gb.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig_4g20gb.png new file mode 100644 index 0000000..f8b8151 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig_4g20gb.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig_7m.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig_7m.png new file mode 100644 index 0000000..2122431 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig_7m.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mig_overview.png b/docs/en/docs/kpanda/user-guide/gpu/images/mig_overview.png new file mode 100644 index 0000000..6b5e4d5 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mig_overview.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mixed.png b/docs/en/docs/kpanda/user-guide/gpu/images/mixed.png new file mode 100644 index 0000000..91b16e7 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mixed.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/mixed02.png b/docs/en/docs/kpanda/user-guide/gpu/images/mixed02.png new file mode 100644 index 0000000..c7b29d1 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/mixed02.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/node-gpu.png b/docs/en/docs/kpanda/user-guide/gpu/images/node-gpu.png new file mode 100644 index 0000000..198b579 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/node-gpu.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/npu-smi-info.png b/docs/en/docs/kpanda/user-guide/gpu/images/npu-smi-info.png new file mode 100644 index 0000000..b8a7177 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/npu-smi-info.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/operator-mig.png b/docs/en/docs/kpanda/user-guide/gpu/images/operator-mig.png new file mode 100644 index 0000000..a69f471 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/operator-mig.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/redhat0.12.2.png b/docs/en/docs/kpanda/user-guide/gpu/images/redhat0.12.2.png new file mode 100644 index 0000000..d0b45aa Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/redhat0.12.2.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/rhel7.9.png b/docs/en/docs/kpanda/user-guide/gpu/images/rhel7.9.png new file mode 100644 index 0000000..85d11bc Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/rhel7.9.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/single01.png b/docs/en/docs/kpanda/user-guide/gpu/images/single01.png new file mode 100644 index 0000000..16c96a6 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/single01.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/single02.png b/docs/en/docs/kpanda/user-guide/gpu/images/single02.png new file mode 100644 index 0000000..82c59fe Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/single02.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-addon.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-addon.png new file mode 100644 index 0000000..ccbadb6 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-addon.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-cluster.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-cluster.png new file mode 100644 index 0000000..5de4d3a Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-cluster.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-deployment.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-deployment.png new file mode 100644 index 0000000..552e469 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-deployment.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-pararm.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-pararm.png new file mode 100644 index 0000000..f2018dd Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-pararm.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-pod.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-pod.png new file mode 100644 index 0000000..c8ec011 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-pod.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-quota.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-quota.png new file mode 100644 index 0000000..a8944ef Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-quota.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-sc.png b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-sc.png new file mode 100644 index 0000000..59ccfd9 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vgpu-sc.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vnpu1.png b/docs/en/docs/kpanda/user-guide/gpu/images/vnpu1.png new file mode 100644 index 0000000..0b8e886 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vnpu1.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/images/vnpu2.png b/docs/en/docs/kpanda/user-guide/gpu/images/vnpu2.png new file mode 100644 index 0000000..4ae7318 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/gpu/images/vnpu2.png differ diff --git a/docs/en/docs/kpanda/user-guide/gpu/index.md b/docs/en/docs/kpanda/user-guide/gpu/index.md new file mode 100644 index 0000000..f9ad6d2 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/index.md @@ -0,0 +1,33 @@ +--- +hide: + - toc +--- + +# Overview of GPU Management + +This article introduces the capability of Suanova container management platform in unified operations and management of heterogeneous resources, with a focus on GPUs. + +## Background + +With the rapid development of emerging technologies such as AI applications, large-scale models, artificial intelligence, and autonomous driving, enterprises are facing an increasing demand for compute-intensive tasks and data processing. Traditional compute architectures represented by CPUs can no longer meet the growing computational requirements of enterprises. At this point, heterogeneous computing represented by GPUs has been widely applied due to its unique advantages in processing large-scale data, performing complex calculations, and real-time graphics rendering. + +Meanwhile, due to the lack of experience and professional solutions in scheduling and managing heterogeneous resources, the utilization efficiency of GPU devices is extremely low, resulting in high AI production costs for enterprises. The challenge of reducing costs, increasing efficiency, and improving the utilization of GPUs and other heterogeneous resources has become a pressing issue for many enterprises. + +## Introduction to GPU Capabilities + +The Suanova container management platform supports unified scheduling and operations management of GPUs, NPUs, and other heterogeneous resources, fully unleashing the computational power of GPU resources, and accelerating the development of enterprise AI and other emerging applications. The GPU management capabilities of Suanova are as follows: + +- Support for unified management of heterogeneous computing resources from domestic and foreign manufacturers such as NVIDIA, Huawei Ascend, and Days. +- Support for multi-card heterogeneous scheduling within the same cluster, with automatic recognition of GPUs in the cluster. +- Support for native management solutions for NVIDIA GPUs, vGPUs, and MIG, with cloud native capabilities. +- Support for partitioning a single physical card for use by different tenants, and allocate GPU resources to tenants and containers based on computing power and memory quotas. +- Support for multi-dimensional GPU resource monitoring at the cluster, node, and application levels, assisting operators in managing GPU resources. +- Compatibility with various training frameworks such as TensorFlow and PyTorch. + +## Introduction to GPU Operator + +Similar to regular computer hardware, NVIDIA GPUs, as physical devices, need to have the NVIDIA GPU driver installed in order to be used. To reduce the cost of using GPUs on Kubernetes, NVIDIA provides the NVIDIA GPU Operator component to manage various components required for using NVIDIA GPUs. These components include the NVIDIA driver (for enabling CUDA), NVIDIA container runtime, GPU node labeling, DCGM-based monitoring, and more. In theory, users only need to plug the GPU card into a compute device managed by Kubernetes, and they can use all the capabilities of NVIDIA GPUs through the GPU Operator. For more information about NVIDIA GPU Operator, refer to the [NVIDIA official documentation](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/index.html). For deployment instructions, refer to [Offline Installation of GPU Operator](nvidia/install_nvidia_driver_of_operator.md). + +Architecture diagram of NVIDIA GPU Operator: + + diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/full_gpu_userguide.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/full_gpu_userguide.md new file mode 100644 index 0000000..48422df --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/full_gpu_userguide.md @@ -0,0 +1,67 @@ +# Using the Whole NVIDIA GPU Card for an Application + +This section describes how to allocate the entire NVIDIA GPU card to a single application on the AI platform platform. + +## Prerequisites + +- AI platform container management platform has been [deployed](https://docs.daocloud.io/install/index.html) and is running properly. +- The container management module has been [connected to a Kubernetes cluster](../../clusters/integrate-cluster.md) or a Kubernetes cluster has been [created](../../clusters/create-cluster.md), and you can access the UI interface of the cluster. +- GPU Operator has been offline installed and NVIDIA DevicePlugin has been enabled on the current cluster. Refer to [Offline Installation of GPU Operator](install_nvidia_driver_of_operator.md) for instructions. +- The GPU card in the current cluster has not undergone any virtualization operations or been occupied by other applications. + +## Procedure + +### Configuring via the User Interface + +1. Check if the cluster has detected the GPUs. Click __Clusters__ -> __Cluster Settings__ -> __Addon Plugins__ to see if it has automatically enabled and detected the proper GPU types. + Currently, the cluster will automatically enable __GPU__ and set the __GPU Type__ as __Nvidia GPU__ . + + + +2. Deploy a workload. Click __Clusters__ -> __Workloads__ , and deploy the workload using the image method. After selecting the type ( __Nvidia GPU__ ), configure the number of physical cards used by the application: + + **Physical Card Count (nvidia.com/gpu)**: Indicates the number of physical cards that the current pod needs to mount. The input value must be an integer and **less than or equal to** the number of cards on the host machine. + + + + > If the above value is configured incorrectly, scheduling failures and resource allocation issues may occur. + +### Configuring via YAML + +To request GPU resources for a workload, add the __nvidia.com/gpu: 1__ parameter to the resource request and limit configuration in the YAML file. This parameter configures the number of physical cards used by the application. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-gpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-gpu-demo + template: + metadata: + labels: + app: full-gpu-demo + spec: + containers: + - image: chrstnhntschl/gpu_burn + name: container-0 + resources: + requests: + cpu: 250m + memory: 512Mi + nvidia.com/gpu: 1 # Number of GPUs requested + limits: + cpu: 250m + memory: 512Mi + nvidia.com/gpu: 1 # Upper limit of GPU usage + imagePullSecrets: + - name: default-secret +``` + +!!! note + + When using the `nvidia.com/gpu` parameter to specify the number of GPUs, the values for requests and limits must be consistent. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/index.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/index.md new file mode 100644 index 0000000..e6ed205 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/index.md @@ -0,0 +1,38 @@ +# NVIDIA GPU Card Usage Modes + +NVIDIA, as a well-known graphics computing provider, offers various software and hardware solutions to enhance computational power. Among them, NVIDIA provides the following three solutions for GPU usage: + +#### Full GPU + +Full GPU refers to allocating the entire NVIDIA GPU to a single user or application. In this configuration, the application can fully occupy all the resources of the GPU and achieve maximum computational performance. Full GPU is suitable for workloads that require a large amount of computational resources and memory, such as deep learning training, scientific computing, etc. + +#### vGPU (Virtual GPU) + +vGPU is a virtualization technology that allows one physical GPU to be partitioned into multiple virtual GPUs, with each virtual GPU assigned to different virtual machines or users. vGPU enables multiple users to share the same physical GPU and independently use GPU resources in their respective virtual environments. Each virtual GPU can access a certain amount of compute power and memory capacity. vGPU is suitable for virtualized environments and cloud computing scenarios, providing higher resource utilization and flexibility. + +#### MIG (Multi-Instance GPU) + +MIG is a feature introduced by the NVIDIA Ampere architecture that allows one physical GPU to be divided into multiple physical GPU instances, each of which can be independently allocated to different users or workloads. Each MIG instance has its own compute resources, memory, and PCIe bandwidth, just like an independent virtual GPU. MIG provides finer-grained GPU resource allocation and management and allows dynamic adjustment of the number and size of instances based on demand. MIG is suitable for multi-tenant environments, containerized applications, batch jobs, and other scenarios. + +Whether using vGPU in a virtualized environment or MIG on a physical GPU, NVIDIA provides users with more choices and optimized ways to utilize GPU resources. The Suanova container management platform fully supports the above NVIDIA capabilities. Users can easily access the full computational power of NVIDIA GPUs through simple UI operations, thereby improving resource utilization and reducing costs. + +- **Single Mode**: The node only exposes a single type of MIG device on all its GPUs. All GPUs on the node must: + - Be of the same model (e.g., A100-SXM-40GB), with matching MIG profiles only for GPUs of the same model. + - Have MIG configuration enabled, which requires a machine reboot to take effect. + - Create identical GI and CI for exposing "identical" MIG devices across all products. +- **Mixed Mode**: The node exposes mixed MIG device types on all its GPUs. Requesting a specific MIG device type requires the number of compute slices and total memory provided by the device type. + - All GPUs on the node must: Be in the same product line (e.g., A100-SXM-40GB). + - Each GPU can enable or disable MIG individually and freely configure any available mixture of MIG device types. + - The k8s-device-plugin running on the node will: + - Expose any GPUs not in MIG mode using the traditional `nvidia.com/gpu` resource type. + - Expose individual MIG devices using resource types that follow the pattern `nvidia.com/mig-g.gb` . + +For detailed instructions on enabling these configurations, refer to [Offline Installation of GPU Operator](install_nvidia_driver_of_operator.md). + +## How to Use + +You can refer to the following links to quickly start using Suanova's management capabilities for NVIDIA GPUs. + +- **[Using Full NVIDIA GPU](full_gpu_userguide.md)** +- **[Using NVIDIA vGPU](vgpu/vgpu_user.md)** +- **[Using NVIDIA MIG](mig/mig_usage.md)** diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/install_nvidia_driver_of_operator.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/install_nvidia_driver_of_operator.md new file mode 100644 index 0000000..30a5b3d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/install_nvidia_driver_of_operator.md @@ -0,0 +1,124 @@ +--- +MTPE: Fan-Lin +Date: 2024-01-24 +--- + +# Offline Install gpu-operator + +AI platform comes with pre-installed `driver` images for the following three operating systems: Ubuntu 22.04, Ubuntu 20.04, +and CentOS 7.9. The driver version is `535.104.12`. Additionally, it includes the required `Toolkit` images for each +operating system, so users no longer need to manually provide offline `toolkit` images. + +This page demonstrates using AMD architecture with CentOS 7.9 (3.10.0-1160). If you need to deploy on Red Hat 8.4, refer to +[Uploading Red Hat gpu-operator Offline Image to the Bootstrap Node Repository](./push_image_to_repo.md) +and [Building Offline Yum Source for Red Hat 8.4](./upgrade_yum_source_redhat8_4.md). + +## Prerequisites + +- The kernel version of the cluster nodes where the gpu-operator is to be deployed must be + completely consistent. The distribution and GPU card model of the nodes must fall within + the scope specified in the [GPU Support Matrix](../gpu_matrix.md). +- When installing the gpu-operator, select v23.9.0+2 or above. + +## Steps + +To install the gpu-operator plugin for your cluster, follow these steps: + +1. Log in to the platform and go to __Container Management__ -> __Clusters__ , check cluster eetails. + +2. On the __Helm Charts__ page, select __All Repositories__ and search for __gpu-operator__ . + +3. Select __gpu-operator__ and click __Install__ . + +4. Configure the installation parameters for __gpu-operator__ based on the instructions below to complete the installation. + +## Configure parameters + +- __systemOS__ : Select the operating system for the host. The current options are + `Ubuntu 22.04`, `Ubuntu 20.04`, `Centos 7.9`, and `other`. Please choose the correct operating system. + +### Basic information + +- __Name__ : Enter the plugin name +- __Namespace__ : Select the namespace for installing the plugin +- **Version**: The version of the plugin. Here, we use version **v23.9.0+2** as an example. +- **Failure Deletion**: If the installation fails, it will delete the already installed associated + resources. When enabled, **Ready Wait** will also be enabled by default. +- **Ready Wait**: When enabled, the application will be marked as successfully installed only + when all associated resources are in a ready state. +- **Detailed Logs**: When enabled, detailed logs of the installation process will be recorded. + +### Advanced settings + +#### Operator parameters + +- __InitContainer.image__ : Configure the CUDA image, recommended default image: __nvidia/cuda__ +- __InitContainer.repository__ : Repository where the CUDA image is located, defaults to __nvcr.m.daocloud.io__ repository +- __InitContainer.version__ : Version of the CUDA image, please use the default parameter + +#### Driver parameters + +- __Driver.enable__ : Configure whether to deploy the NVIDIA driver on the node, default is enabled. If you have already deployed the NVIDIA driver on the node before using the gpu-operator, please disable this. +- __Driver.image__ : Configure the GPU driver image, recommended default image: __nvidia/driver__ . +- __Driver.repository__ : Repository where the GPU driver image is located, default is nvidia's __nvcr.io__ repository. +- __Driver.usePrecompiled__ : Enable the precompiled mode to install the driver. +- __Driver.version__ : Version of the GPU driver image, use default parameters for offline deployment. + Configuration is only required for online installation. Different versions of the Driver image exist for + different types of operating systems. For more details, refer to + [Nvidia GPU Driver Versions](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags). + Examples of `Driver Version` for different operating systems are as follows: + + !!! note + + When using the built-in operating system version, there is no need to modify the image version. For other operating system versions, please refer to [Uploading Images to the Bootstrap Node Repository](./push_image_to_repo.md). + note that there is no need to include the operating system name such as Ubuntu, CentOS, or Red Hat in the version number. If the official image contains an operating system suffix, please manually remove it. + + - For Red Hat systems, for example, `525.105.17` + - For Ubuntu systems, for example, `535-5.15.0-1043-nvidia` + - For CentOS systems, for example, `525.147.05` + +- __Driver.RepoConfig.ConfigMapName__ : Used to record the name of the offline yum repository configuration file + for the gpu-operator. When using the pre-packaged offline bundle, refer to the following documents for + different types of operating systems. + + - [Building CentOS 7.9 Offline Yum Repository](./upgrade_yum_source_centos7_9.md) + - [Building Red Hat 8.4 Offline Yum Repository](./upgrade_yum_source_redhat8_4.md) + +#### Toolkit parameters + +__Toolkit.enable__ : Enabled by default. This component allows containerd/docker +to support running containers that require GPUs. + +#### MIG parameters + +For detailed configuration methods, refer to [Enabling MIG Functionality](mig/create_mig.md). + +**MigManager.Config.name** : The name of the MIG split configuration file, used to define the MIG (GI, CI) +split policy. The default is __default-mig-parted-config__ . For custom parameters, refer to +[Enabling MIG Functionality](mig/create_mig.md). + +### Next Steps + +After completing the configuration and creation of the above parameters: + +- If using **full-card mode** , [GPU resources can be used when creating applications](full_gpu_userguide.md). + +- If using **vGPU mode** , after completing the above configuration and creation, + proceed to [vGPU Addon Installation](vgpu/vgpu_addon.md). + +- If using **MIG mode** and you need to use a specific split specification for individual GPU nodes, + otherwise, split according to the __default__ value in `MigManager.Config`. + + - For **single** mode, add label to nodes as follows: + + ```sh + kubectl label nodes {node} nvidia.com/mig.config="all-1g.10gb" --overwrite + ``` + + - For **mixed** mode, add label to nodes as follows: + + ```sh + kubectl label nodes {node} nvidia.com/mig.config="custom-config" --overwrite + ``` + + After spliting, applications can [use MIG GPU resources](mig/mig_usage.md). diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/create_mig.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/create_mig.md new file mode 100644 index 0000000..54047bb --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/create_mig.md @@ -0,0 +1,124 @@ +--- +MTPE: Fan-Lin +Date: 2024-01-23 +--- + +# Enabling MIG Features + +This section describes how to enable NVIDIA MIG features. NVIDIA currently provides two strategies for exposing MIG devices on Kubernetes nodes: + +- **Single mode** : Nodes expose a single type of MIG device on all their GPUs. +- **Mixed mode** : Nodes expose a mixture of MIG device types on all their GPUs. + +For more details, refer to the [NVIDIA GPU Card Usage Modes](../index.md). + +## Prerequisites + +- Check the system requirements for the GPU driver installation on the target node: [GPU Support Matrix](../../gpu_matrix.md) +- Ensure that the cluster nodes have GPUs of the corresponding models + ([NVIDIA H100](https://www.nvidia.com/en-us/data-center/h100/), + [A100](https://www.nvidia.com/en-us/data-center/a100/), + and [A30](https://www.nvidia.com/en-us/data-center/products/a30-gpu/) Tensor Core GPUs). + For more information, see the [GPU Support Matrix](gpu_matrix.md). +- All GPUs on the nodes must belong to the same product line (e.g., A100-SXM-40GB). + +## Install GPU Operator Addon + +### Parameter Configuration + +When [installing the Operator](../install_nvidia_driver_of_operator.md), you need to set the MigManager Config parameter accordingly. The default setting is **default-mig-parted-config**. You can also customize the sharding policy configuration file: + +![single](../../images/gpu-operator-mig.png) + +### Custom Sharding Policy + +```yaml + ## Custom GI Instance Configuration + all-disabled: + - devices: all + mig-enabled: false + all-enabled: + - devices: all + mig-enabled: true + mig-devices: {} + all-1g.10gb: + - devices: all + mig-enabled: true + mig-devices: + 1g.5gb: 7 + all-1g.10gb.me: + - devices: all + mig-enabled: true + mig-devices: + 1g.10gb+me: 1 + all-1g.20gb: + - devices: all + mig-enabled: true + mig-devices: + 1g.20gb: 4 + all-2g.20gb: + - devices: all + mig-enabled: true + mig-devices: + 2g.20gb: 3 + all-3g.40gb: + - devices: all + mig-enabled: true + mig-devices: + 3g.40gb: 2 + all-4g.40gb: + - devices: all + mig-enabled: true + mig-devices: + 4g.40gb: 1 + all-7g.80gb: + - devices: all + mig-enabled: true + mig-devices: + 7g.80gb: 1 + all-balanced: + - device-filter: ["0x233110DE", "0x232210DE", "0x20B210DE", "0x20B510DE", "0x20F310DE", "0x20F510DE"] + devices: all + mig-enabled: true + mig-devices: + 1g.10gb: 2 + 2g.20gb: 1 + 3g.40gb: 1 + # After setting, CI instances will be partitioned according to the specified configuration + custom-config: + - devices: all + mig-enabled: true + mig-devices: + 3g.40gb: 2 +``` + +In the above **YAML**, set **custom-config** to partition **CI** instances according to the specifications. + +```yaml +custom-config: + - devices: all + mig-enabled: true + mig-devices: + 1c.3g.40gb: 6 +``` + +After completing the settings, you can [use GPU MIG resources](mig_usage.md) when confirming the deployment of the application. + +## Switch Node GPU Mode + +After successfully installing the GPU operator, the node is in full card mode by default. There will be an indicator on the node management page, as shown below: + +![mixed](../../images/node-gpu.png) + +Click the __┇__ at the right side of the node list, select a GPU mode to switch, +and then choose the proper MIG mode and sharding policy. Here, we take MIXED mode as an example: + +![mig](../../images/mig-select.png) + +There are two configurations here: + +1. MIG Policy: Mixed and Single. +2. Sharding Policy: The policy here needs to match the key in the **default-mig-parted-config** (or user-defined sharding policy) configuration file. + +After clicking **OK** button, wait for about a minute and refresh the page. The MIG mode will be switched to: + diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/index.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/index.md new file mode 100644 index 0000000..a7c2df1 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/index.md @@ -0,0 +1,65 @@ +# Overview of NVIDIA Multi-Instance GPU (MIG) + +## MIG Scenarios + +- **Multi-Tenant Cloud Environments**: + + MIG allows cloud service providers to partition a physical GPU into multiple independent GPU instances, which can be allocated to different tenants. This enables resource isolation and independence, meeting the GPU computing needs of multiple tenants. + +- **Containerized Applications**: + + MIG enables finer-grained GPU resource management in containerized environments. By partitioning a physical GPU into multiple MIG instances, each container can be assigned with dedicated GPU compute resources, providing better performance isolation and resource utilization. + +- **Batch Processing Jobs**: + + For batch processing jobs requiring large-scale parallel computing, MIG provides higher computational performance and larger memory capacity. Each MIG instance can utilize a portion of the physical GPU's compute resources, accelerating the processing of large-scale computational tasks. + +- **AI/Machine Learning Training**: + + MIG offers increased compute power and memory capacity for training large-scale deep learning models. By partitioning the physical GPU into multiple MIG instances, each instance can independently carry out model training, improving training efficiency and throughput. + +In general, NVIDIA MIG is suitable for scenarios that require finer-grained allocation and management of GPU resources. It enables resource isolation, improved performance utilization, and meets the GPU computing needs of multiple users or applications. + +## Overview of MIG + +NVIDIA Multi-Instance GPU (MIG) is a new feature introduced by NVIDIA on H100, A100, and A30 series GPUs. Its purpose is to divide a physical GPU into multiple GPU instances to provide finer-grained resource sharing and isolation. MIG can split a GPU into up to seven GPU instances, allowing a single physical GPU card to provide separate GPU resources to multiple users, maximizing GPU utilization. + +This feature enables multiple applications or users to share GPU resources simultaneously, improving the utilization of computational resources and increasing system scalability. + +With MIG, each GPU instance's processor has an independent and isolated path throughout the entire memory system, including cross-switch ports on the chip, L2 cache groups, memory controllers, and DRAM address buses, all uniquely allocated to a single instance. + +This ensures that the workload of individual users can run with predictable throughput and latency, along with identical L2 cache allocation and DRAM bandwidth. MIG can partition available GPU compute resources (such as streaming multiprocessors or SMs and GPU engines like copy engines or decoders) to provide defined quality of service (QoS) and fault isolation for different clients such as virtual machines, containers, or processes. MIG enables multiple GPU instances to run in parallel on a single physical GPU. + +MIG allows multiple vGPUs (and virtual machines) to run in parallel on a single GPU instance while retaining the isolation guarantees provided by vGPU. For more details on using vGPU and MIG for GPU partitioning, refer to [NVIDIA Multi-Instance GPU and NVIDIA Virtual Compute Server](https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/solutions/resources/documents1/TB-10226-001_v01.pdf). + +## MIG Architecture + +The following diagram provides an overview of MIG, illustrating how it virtualizes one physical GPU card into seven GPU instances that can be used by multiple users. + + + +## Important Concepts + +* __SM__ (Streaming Multiprocessor): The core computational unit of a GPU responsible for executing graphics rendering and general-purpose computing tasks. Each SM contains a group of CUDA cores, as well as shared memory, register files, and other resources, capable of executing multiple threads concurrently. Each MIG instance has a certain number of SMs and other related resources, along with the allocated memory slices. +* __GPU Memory Slice__ : The smallest portion of GPU memory, including the corresponding memory controller and cache. A GPU memory slice is approximately one-eighth of the total GPU memory resources in terms of capacity and bandwidth. +* __GPU SM Slice__ : The smallest computational unit of SMs on a GPU. When configuring in MIG mode, the GPU SM slice is approximately one-seventh of the total available SMs in the GPU. +* __GPU Slice__ : The GPU slice represents the smallest portion of the GPU, consisting of a single GPU memory slice and a single GPU SM slice combined together. +* __GPU Instance__ (GI): A GPU instance is the combination of a GPU slice and GPU engines (DMA, NVDEC, etc.). Anything within a GPU instance always shares all GPU memory slices and other GPU engines, but its SM slice can be further subdivided into Compute Instances (CIs). A GPU instance provides memory QoS. Each GPU slice contains dedicated GPU memory resources, limiting available capacity and bandwidth while providing memory QoS. Each GPU memory slice gets one-eighth of the total GPU memory resources, and each GPU SM slice gets one-seventh of the total SM count. +* __Compute Instance__ (CI): A Compute Instance represents the smallest computational unit within a GPU instance. It consists of a subset of SMs, along with dedicated register files, shared memory, and other resources. Each CI has its own CUDA context and can run independent CUDA kernels. The number of CIs in a GPU instance depends on the number of available SMs and the configuration chosen during MIG setup. +* __Instance Slice__ : An Instance Slice represents a single CI within a GPU instance. It is the combination of a subset of SMs and a portion of the GPU memory slice. Each Instance Slice provides isolation and resource allocation for individual applications or users running on the GPU instance. + +## Key Benefits of MIG + +- **Resource Sharing**: MIG allows a single physical GPU to be divided into multiple GPU instances, providing efficient sharing of GPU resources among different users or applications. This maximizes GPU utilization and enables improved performance isolation. + +- **Fine-Grained Resource Allocation**: With MIG, GPU resources can be allocated at a finer granularity, allowing for more precise partitioning and allocation of compute power and memory capacity. + +- **Improved Performance Isolation**: Each MIG instance operates independently with its dedicated resources, ensuring predictable throughput and latency for individual users or applications. This improves performance isolation and prevents interference between different workloads running on the same GPU. + +- **Enhanced Security and Fault Isolation**: MIG provides better security and fault isolation by ensuring that each user or application has its dedicated GPU resources. This prevents unauthorized access to data and mitigates the impact of faults or errors in one instance on others. + +- **Increased Scalability**: MIG enables the simultaneous usage of GPU resources by multiple users or applications, increasing system scalability and accommodating the needs of various workloads. + +- **Efficient Containerization**: By using MIG in containerized environments, GPU resources can be effectively allocated to different containers, improving performance isolation and resource utilization. + +Overall, MIG offers significant advantages in terms of resource sharing, fine-grained allocation, performance isolation, security, scalability, and containerization, making it a valuable feature for various GPU computing scenarios. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/mig_command.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/mig_command.md new file mode 100644 index 0000000..ac5ed00 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/mig_command.md @@ -0,0 +1,25 @@ +# MIG Related Commands + +GI Related Commands: + +| Subcommand | Description | +| --------------------------------------- | ----------------------------- | +| nvidia-smi mig -lgi | View the list of created GI instances | +| nvidia-smi mig -dgi -gi {Instance ID} | Delete a specific GI instance | +| nvidia-smi mig -lgip | View the profile of GI | +| nvidia-smi mig -cgi {profile id} | Create a GI using the specified profile ID | + +CI Related Commands: + +| Subcommand | Description | +| ------------------------------------------------------- | ------------------------------------------------------------ | +| nvidia-smi mig -lcip { -gi {gi Instance ID}} | View the profile of CI, specifying __-gi__ will show the CIs that can be created for a particular GI instance | +| nvidia-smi mig -lci | View the list of created CI instances | +| nvidia-smi mig -cci {profile id} -gi {gi instance id} | Create a CI instance with the specified GI | +| nvidia-smi mig -dci -ci {ci instance id} | Delete a specific CI instance | + +GI+CI Related Commands: + +| Subcommand | Description | +| ------------------------------------------------------------ | -------------------- | +| nvidia-smi mig -i 0 -cgi {gi profile id} -C {ci profile id} | Create a GI + CI instance directly | diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/mig_usage.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/mig_usage.md new file mode 100644 index 0000000..bc3551d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/mig/mig_usage.md @@ -0,0 +1,94 @@ +# Using MIG GPU Resources + +This section explains how applications can use MIG GPU resources. + +## Prerequisites + +- AI platform container management platform is deployed and running successfully. +- The container management module is integrated with a Kubernetes cluster or a Kubernetes cluster is created, and the UI interface of the cluster can be accessed. +- NVIDIA DevicePlugin and MIG capabilities are enabled. Refer to [Offline installation of GPU Operator](../install_nvidia_driver_of_operator.md) for details. +- The nodes in the cluster have GPUs of the corresponding models. + +## Using MIG GPU through the UI + +1. Confirm if the cluster has recognized the GPU card type. + + Go to __Cluster Details__ -> __Nodes__ and check if it has been correctly recognized as MIG. + + + +2. When deploying an application using an image, you can select and use NVIDIA MIG resources. + +- Example of MIG Single Mode (used in the same way as a full GPU card): + + !!! note + + The MIG single policy allows users to request and use GPU resources in the same way as a full GPU card (`nvidia.com/gpu`). The difference is that these resources can be a portion of the GPU (MIG device) rather than the entire GPU. Learn more from the [GPU MIG Mode Design](https://docs.google.com/document/d/1bshSIcWNYRZGfywgwRHa07C0qRyOYKxWYxClbeJM-WM/edit#heading=h.jklusl667vn2). + +- MIG Mixed Mode + +## Using MIG through YAML Configuration + +__MIG Single__ mode: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mig-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: mig-demo + template: + metadata: + creationTimestamp: null + labels: + app: mig-demo + spec: + containers: + - name: mig-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/gpu: 2 # (1)! + imagePullPolicy: Always + restartPolicy: Always +``` + +1. Number of MIG GPUs to request + +__MIG Mixed__ mode: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mig-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: mig-demo + template: + metadata: + creationTimestamp: null + labels: + app: mig-demo + spec: + containers: + - name: mig-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/mig-4g.20gb: 1 # (1)! + imagePullPolicy: Always + restartPolicy: Always +``` + +1. Expose MIG device through nvidia.com/mig-g.gb resource type + +After entering the container, you can check if only one MIG device is being used: diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/push_image_to_repo.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/push_image_to_repo.md new file mode 100644 index 0000000..699723c --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/push_image_to_repo.md @@ -0,0 +1,84 @@ +# Uploading Red Hat GPU Operator Offline Image to Bootstrap Repository + +This guide explains how to upload an offline image to the bootstrap repository using the __nvcr.io/nvidia/driver:525.105.17-rhel8.4__ offline driver image for Red Hat 8.4 as an example. + +## Prerequisites + +1. The bootstrap node and its components are running properly. +2. Prepare a node that has internet access and can access the bootstrap node. Docker should also be installed on this node. You can refer to [Installing Docker](../../../../install/community/kind/online.md) for installation instructions. + +## Procedure + +### Step 1: Obtain the Offline Image on an Internet-Connected Node + +Perform the following steps on the internet-connected node: + +1. Pull the __nvcr.io/nvidia/driver:525.105.17-rhel8.4__ offline driver image: + + ```bash + docker pull nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +2. Once the image is pulled, save it as a compressed archive named __nvidia-driver.tar__ : + + ```bash + docker save nvcr.io/nvidia/driver:525.105.17-rhel8.4 > nvidia-driver.tar + ``` + +3. Copy the compressed image archive __nvidia-driver.tar__ to the bootstrap node: + + ```bash + scp nvidia-driver.tar user@ip:/root + ``` + + For example: + + ```bash + scp nvidia-driver.tar root@10.6.175.10:/root + ``` + +### Step 2: Push the Image to the Bootstrap Repository + +Perform the following steps on the bootstrap node: + +1. Log in to the bootstrap node and import the compressed image archive __nvidia-driver.tar__ : + + ```bash + docker load -i nvidia-driver.tar + ``` + +2. View the imported image: + + ```bash + docker images -a | grep nvidia + ``` + + Expected output: + + ```bash + nvcr.io/nvidia/driver e3ed7dee73e9 1 days ago 1.02GB + ``` + +3. Retag the image to correspond to the target repository in the remote Registry repository: + + ```bash + docker tag /: + ``` + + Replace ____ with the name of the Nvidia image from the previous step, ____ with the address of the Registry service on the bootstrap node, ____ with the name of the repository you want to push the image to, and ____ with the desired tag for the image. + + For example: + + ```bash + docker tag nvcr.io/nvidia/driver 10.6.10.5/nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +4. Push the image to the bootstrap repository: + + ```bash + docker push {ip}/nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +## What's Next + +Refer to [Building Red Hat 8.4 Offline Yum Source](./upgrade_yum_source_redhat8_4.md) and [Offline Installation of GPU Operator](./install_nvidia_driver_of_operator.md) to deploy the GPU Operator to your cluster. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/ubuntu22.04_offline_install_driver.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/ubuntu22.04_offline_install_driver.md new file mode 100644 index 0000000..5645170 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/ubuntu22.04_offline_install_driver.md @@ -0,0 +1,36 @@ +# Offline Install gpu-operator Driver on Ubuntu 22.04 + +Prerequisite: Installed gpu-operator v23.9.0+2 or higher versions + +## Prepare Offline Image + +1. Check the kernel version + + ```bash + $ uname -r + 5.15.0-78-generic + ``` + +1. Check the GPU Driver image version applicable to your kernel, + at `https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags`. + Use the kernel to query the image version and save the image using `ctr export`. + + ```bash + ctr i pull nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ctr i export --all-platforms driver.tar.gz nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ``` + +1. Import the image into the cluster's container registry + + ```bash + ctr i import driver.tar.gz + ctr i tag nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 {your_registry}/nvcr.m.daocloud.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ctr i push {your_registry}/nvcr.m.daocloud.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 --skip-verify=true + ``` + +## Install the Driver + +1. Install the gpu-operator addon and set `driver.usePrecompiled=true` +2. Set `driver.version=535`, note that it should be 535, not 535.104.12 + +![Install Driver](../images/driver.jpg) diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/upgrade_yum_source_centos7_9.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/upgrade_yum_source_centos7_9.md new file mode 100644 index 0000000..d196edc --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/upgrade_yum_source_centos7_9.md @@ -0,0 +1,254 @@ +# Build CentOS 7.9 Offline Yum Source + +The AI platform comes with a pre-installed GPU Operator offline package for CentOS 7.9 with kernel version 3.10.0-1160. +or other OS types or kernel versions, users need to manually build an offline yum source. + +This guide explains how to build an offline yum source for CentOS 7.9 with a specific kernel version and use it when installing the GPU Operator by specifying the __RepoConfig.ConfigMapName__ parameter. + +## Prerequisites + +1. The user has already installed the v0.12.0 or later version of the addon offline package on the platform. +1. Prepare a file server that is accessible from the cluster network, such as Nginx or MinIO. +1. Prepare a node that has internet access, can access the cluster where the GPU Operator will + be deployed, and can access the file server. Docker should also be installed on this node. + You can refer to [Installing Docker](../../../../install/community/kind/online.md#install-docker) for installation instructions. + +## Procedure + +This guide uses CentOS 7.9 with kernel version 3.10.0-1160.95.1.el7.x86_64 as an example to explain how to upgrade the pre-installed GPU Operator offline package's yum source. + +### Check OS and Kernel Versions of Cluster Nodes + +Run the following commands on both the control node of the Global cluster and the node where +GPU Operator will be deployed. If the OS and kernel versions of the two nodes are consistent, +there is no need to build a yum source. You can directly refer to the +[Offline Installation of GPU Operator](./install_nvidia_driver_of_operator.md) document for +installation. If the OS or kernel versions of the two nodes are not consistent, +please proceed to the [next step](#create-the-offline-yum-source). + +1. Run the following command to view the distribution name and version of the node where GPU Operator will be deployed in the cluster. + + ```bash + cat /etc/redhat-release + ``` + + Expected output: + + ``` + CentOS Linux release 7.9 (Core) + ``` + + The output shows the current node's OS version as `CentOS 7.9`. + +2. Run the following command to view the kernel version of the node where GPU Operator will be deployed in the cluster. + + ```bash + uname -a + ``` + + Expected output: + + ``` + Linux localhost.localdomain 3.10.0-1160.95.1.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux + ``` + + The output shows the current node's kernel version as `3.10.0-1160.el7.x86_64`. + +### Create the Offline Yum Source + +Perform the following steps on a node that has internet access and can access the file server: + +1. Create a script file named __yum.sh__ by running the following command: + + ```bash + vi yum.sh + ``` + + Then press the **i** key to enter insert mode and enter the following content: + + ```bash + export TARGET_KERNEL_VERSION=$1 + + cat >> run.sh << \EOF + #! /bin/bash + echo "start install kernel repo" + echo ${KERNEL_VERSION} + mkdir centos-base + + if [ "$OS" -eq 7 ]; then + yum install --downloadonly --downloaddir=./centos-base perl + yum install --downloadonly --downloaddir=./centos-base elfutils-libelf.x86_64 + yum install --downloadonly --downloaddir=./redhat-base elfutils-libelf-devel.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-headers-${KERNEL_VERSION}.el7.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-devel-${KERNEL_VERSION}.el7.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-${KERNEL_VERSION}.el7.x86_64 + yum install -y --downloadonly --downloaddir=./centos-base groff-base + elif [ "$OS" -eq 8 ]; then + yum install --downloadonly --downloaddir=./centos-base perl + yum install --downloadonly --downloaddir=./centos-base elfutils-libelf.x86_64 + yum install --downloadonly --downloaddir=./redhat-base elfutils-libelf-devel.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-headers-${KERNEL_VERSION}.el8.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-devel-${KERNEL_VERSION}.el8.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-${KERNEL_VERSION}.el8.x86_64 + yum install -y --downloadonly --downloaddir=./centos-base groff-base + else + echo "Error os version" + fi + + createrepo centos-base/ + ls -lh centos-base/ + tar -zcf centos-base.tar.gz centos-base/ + echo "end install kernel repo" + EOF + + cat >> Dockerfile << EOF + FROM centos:7 + ENV KERNEL_VERSION="" + ENV OS=7 + RUN yum install -y createrepo + COPY run.sh . + ENTRYPOINT ["/bin/bash","run.sh"] + EOF + + docker build -t test:v1 -f Dockerfile . + docker run -e KERNEL_VERSION=$TARGET_KERNEL_VERSION --name centos7.9 test:v1 + docker cp centos7.9:/centos-base.tar.gz . + tar -xzf centos-base.tar.gz + ``` + + Press the __Esc__ key to exit insert mode, then enter __:wq__ to save and exit. + +2. Run the __yum.sh__ file: + + ```bash + bash -x yum.sh TARGET_KERNEL_VERSION + ``` + + The `TARGET_KERNEL_VERSION` parameter is used to specify the kernel version of the cluster nodes. + + Note: You don't need to include the distribution identifier (e.g., __ .el7.x86_64__ ). + For example: + + ```bash + bash -x yum.sh 3.10.0-1160.95.1 + ``` + +Now you have generated an offline yum source, __centos-base__ , +for the kernel version __3.10.0-1160.95.1.el7.x86_64__ . + +### Upload the Offline Yum Source to the File Server + +Perform the following steps on a node that has internet access and can access the file server. +This step is used to upload the generated yum source from the previous step to a file server +that can be accessed by the cluster where the GPU Operator will be deployed. The file server +can be Nginx, MinIO, or any other file server that supports the HTTP protocol. + +In this example, we will use the built-in MinIO as the file server. The MinIO details are as follows: + +- Access URL: `http://10.5.14.200:9000` (usually __{bootstrap-node IP} + {port-9000}__ ) +- Login username: rootuser +- Login password: rootpass123 + +1. Run the following command in the current directory of the node to establish a connection between the node's local __mc__ command-line tool and the MinIO server: + + ```bash + mc config host add minio http://10.5.14.200:9000 rootuser rootpass123 + ``` + + The expected output should resemble the following: + + ```bash + Added __minio__ successfully. + ``` + + __mc__ is the command-line tool provided by MinIO for interacting with the MinIO server. For more details, refer to the [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) documentation. + +2. In the current directory of the node, create a bucket named __centos-base__ : + + ```bash + mc mb -p minio/centos-base + ``` + + The expected output should resemble the following: + + ```bash + Bucket created successfully __minio/centos-base__ . + ``` + +3. Set the access policy of the bucket __centos-base__ to allow public download. This will enable access during the installation of the GPU Operator: + + ```bash + mc anonymous set download minio/centos-base + ``` + + The expected output should resemble the following: + + ```bash + Access permission for __minio/centos-base__ is set to __download__ + ``` + +4. In the current directory of the node, copy the generated __centos-base__ offline yum source to the __minio/centos-base__ bucket on the MinIO server: + + ```bash + mc cp centos-base minio/centos-base --recursive + ``` + +### Create a ConfigMap to Store the Yum Source Info in the Cluster + +Perform the following steps on the control node of the cluster where the GPU Operator will be deployed. + +1. Run the following command to create a file named __CentOS-Base.repo__ that specifies the configmap for the yum source storage: + + ```bash + # The file name must be CentOS-Base.repo, otherwise it cannot be recognized during the installation of the GPU Operator + cat > CentOS-Base.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # The file server address where the yum source is placed in step 3 + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # The file server address where the yum source is placed in step 3 + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. Based on the created __CentOS-Base.repo__ file, create a configmap named __local-repo-config__ in the __gpu-operator__ namespace: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=CentOS-Base.repo=/etc/yum.repos.d/extension.repo + ``` + + The expected output should resemble the following: + + ``` + configmap/local-repo-config created + ``` + + The __local-repo-config__ configmap will be used to provide the value for the __RepoConfig.ConfigMapName__ parameter during the installation of the GPU Operator. You can customize the configuration file name. + +3. View the content of the __local-repo-config__ configmap: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + + The expected output should resemble the following: + + ```yaml + apiVersion: v1 + data: + CentOS-Base.repo: "[extension-0]\nbaseurl = http://10.6.232.5:32618/centos-base# The file server path where the yum source is placed in step 2\ngpgcheck = 0\nname = kubean extension 0\n \n[extension-1]\nbaseurl = http://10.6.232.5:32618/centos-base # The file server path where the yum source is placed in step 2\ngpgcheck = 0\nname = kubean extension 1\n" + kind: ConfigMap + metadata: + creationTimestamp: "2023-10-18T01:59:02Z" + name: local-repo-config + namespace: gpu-operator + resourceVersion: "59445080" + uid: c5f0ebab-046f-442c-b932-f9003e014387 + ``` + +You have successfully created an offline yum source configuration file for the cluster where the +GPU Operator will be deployed. You can use it during the [offline installation of the GPU Operator](./install_nvidia_driver_of_operator.md) +by specifying the __RepoConfig.ConfigMapName__ parameter. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/upgrade_yum_source_redhat8_4.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/upgrade_yum_source_redhat8_4.md new file mode 100644 index 0000000..78d61e9 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/upgrade_yum_source_redhat8_4.md @@ -0,0 +1,208 @@ +# Building Red Hat 8.4 Offline Yum Source + +The AI platform comes with pre-installed CentOS v7.9 and GPU Operator offline packages with kernel v3.10.0-1160. For other OS types or nodes with different kernels, users need to manually build the offline yum source. + +This guide explains how to build an offline yum source package for Red Hat 8.4 based on any node in the Global cluster. It also demonstrates how to use it during the installation of the GPU Operator by specifying the __RepoConfig.ConfigMapName__ parameter. + +## Prerequisites + +1. The user has already installed the addon offline package v0.12.0 or higher on the platform. +2. The OS of the cluster nodes where the GPU Operator will be deployed must be Red Hat v8.4, and the kernel version must be identical. +3. Prepare a file server that can communicate with the cluster network where the GPU Operator will be deployed, such as Nginx or MinIO. +4. Prepare a node that can access the internet, the cluster where the GPU Operator will be deployed, and the file server. Ensure that Docker is already installed on this node. +5. The nodes in the Global cluster must be Red Hat 8.4 4.18.0-305.el8.x86_64. + +## Procedure + +This guide uses a node with Red Hat 8.4 4.18.0-305.el8.x86_64 as an example to demonstrate how to build an offline yum source package for Red Hat 8.4 based on any node in the Global cluster. It also explains how to use it during the installation of the GPU Operator by specifying the __RepoConfig.ConfigMapName__ parameter. + +### Step 1: Download the Yum Source from the Bootstrap Node + +Perform the following steps on the master node of the Global cluster. + +1. Use SSH or any other method to access any node in the Global cluster and run the following command: + + ```bash + cat /etc/yum.repos.d/extension.repo # View the contents of extension.repo. + ``` + + The expected output should resemble the following: + + ```ini + [extension-0] + baseurl = http://10.5.14.200:9000/kubean/redhat/$releasever/os/$basearch + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/kubean/redhat-iso/$releasever/os/$basearch/AppStream + gpgcheck = 0 + name = kubean extension 1 + + [extension-2] + baseurl = http://10.5.14.200:9000/kubean/redhat-iso/$releasever/os/$basearch/BaseOS + gpgcheck = 0 + name = kubean extension 2 + ``` + +2. Create a folder named __redhat-base-repo__ under the root directory: + + ```bash + mkdir redhat-base-repo + ``` + +3. Download the RPM packages from the yum source to your local machine: + + Download the RPM packages from __extension-1__ : + + ```bash + reposync -p redhat-base-repo -n --repoid=extension-1 + ``` + + Download the RPM packages from __extension-2__ : + + ```bash + reposync -p redhat-base-repo -n --repoid=extension-2 + ``` + +### Step 2: Download the __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ Package + +Perform the following steps on a node with internet access. Before proceeding, ensure that there is network connectivity between the node with internet access and the master node of the Global cluster. + +1. Run the following command on the node with internet access to download the __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ package: + + ```bash + wget https://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/elfutils-libelf-devel-0.187-4.el8.x86_64.rpm + ``` + +2. Transfer the __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ package from the current directory to the node mentioned in step 1: + + ```bash + scp elfutils-libelf-devel-0.187-4.el8.x86_64.rpm user@ip:~/redhat-base-repo/extension-2/Packages/ + ``` + + For example: + + ```bash + scp elfutils-libelf-devel-0.187-4.el8.x86_64.rpm root@10.6.175.10:~/redhat-base-repo/extension-2/Packages/ + ``` + +### Step 3: Generate the Local Yum Repository + +Perform the following steps on the master node of the Global cluster mentioned in Step 1. + +1. Enter the yum repository directories: + + ```bash + cd ~/redhat-base-repo/extension-1/Packages + cd ~/redhat-base-repo/extension-2/Packages + ``` + +2. Generate the repository index for the directories: + + ```bash + createrepo_c ./ + ``` + +You have now generated the offline yum source named __redhat-base-repo__ for kernel version __4.18.0-305.el8.x86_64__ . + +### Step 4: Upload the Local Yum Repository to the File Server + +In this example, we will use Minio, which is built-in as the file server in the bootstrap node. However, you can choose any file server that suits your needs. Here are the details for Minio: + +- Access URL: `http://10.5.14.200:9000` (usually the {bootstrap-node-IP} + {port-9000}) +- Login username: rootuser +- Login password: rootpass123 + +1. On the current node, establish a connection between the local __mc__ command-line tool and the Minio server by running the following command: + + ```bash + mc config host add minio + ``` + + For example: + + ```bash + mc config host add minio http://10.5.14.200:9000 rootuser rootpass123 + ``` + + The expected output should be similar to: + + ```bash + Added __minio__ successfully. + ``` + + The __mc__ command-line tool is provided by the Minio file server as a client command-line tool. For more details, refer to the [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html) documentation. + +2. Create a bucket named __redhat-base__ in the current location: + + ```bash + mc mb -p minio/redhat-base + ``` + + The expected output should be similar to: + + ```bash + Bucket created successfully __minio/redhat-base__ . + ``` + +3. Set the access policy of the __redhat-base__ bucket to allow public downloads so that it can be accessed during the installation of the GPU Operator: + + ```bash + mc anonymous set download minio/redhat-base + ``` + + The expected output should be similar to: + + ```bash + Access permission for __minio/redhat-base__ is set to __download__ + ``` + +4. Copy the offline yum repository files ( __redhat-base-repo__ ) from the current location to the Minio server's __minio/redhat-base__ bucket: + + ```bash + mc cp redhat-base-repo minio/redhat-base --recursive + ``` + +### Step 5: Create a ConfigMap to Store Yum Repository Information in the Cluster + +Perform the following steps on the control node of the cluster where you will deploy the GPU Operator. + +1. Run the following command to create a file named __redhat.repo__ , which specifies the configuration information for the yum repository storage: + + ```bash + # The file name must be redhat.repo, otherwise it won't be recognized when installing gpu-operator + cat > redhat.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/redhat-base/redhat-base-repo/Packages # The file server address where the yum source is stored in Step 1 + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/redhat-base/redhat-base-repo/Packages # The file server address where the yum source is stored in Step 1 + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. Based on the created __redhat.repo__ file, create a configmap named __local-repo-config__ in the __gpu-operator__ namespace: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=./redhat.repo + ``` + + The expected output should be similar to: + + ``` + configmap/local-repo-config created + ``` + + The __local-repo-config__ configuration file is used to provide the value for the __RepoConfig.ConfigMapName__ parameter during the installation of the GPU Operator. You can choose a different name for the configuration file. + +3. View the contents of the __local-repo-config__ configuration file: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + +You have successfully created the offline yum source configuration file for the cluster where the GPU Operator will be deployed. You can use it by specifying the __RepoConfig.ConfigMapName__ parameter during the [offline installation of the GPU Operator](./install_nvidia_driver_of_operator.md). diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/hami.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/hami.md new file mode 100644 index 0000000..e7b393f --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/hami.md @@ -0,0 +1,23 @@ +--- +hide: + - toc +--- + +# Build a vGPU Memory Oversubscription Image + +The vGPU memory oversubscription feature in the [Hami Project](https://github.com/Project-HAMi/HAMi) +no longer exists. To use this feature, you need to rebuild with the `libvgpu.so` file +that supports memory oversubscription. + +```bash title="Dockerfile" +FROM docker.m.daocloud.io/projecthami/hami:v2.3.11 +COPY libvgpu.so /k8s-vgpu/lib/nvidia/ +``` + +Run the following command to build the image: + +```bash +docker build -t release.daocloud.io/projecthami/hami:v2.3.11 -f Dockerfile . +``` + +Then, push the image to `release.daocloud.io`. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/vgpu_addon.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/vgpu_addon.md new file mode 100644 index 0000000..e8c69c1 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/vgpu_addon.md @@ -0,0 +1,36 @@ +# Installing NVIDIA vGPU Addon + +To virtualize a single NVIDIA GPU into multiple virtual GPUs and allocate them to different virtual machines or users, you can use NVIDIA's vGPU capability. +This section explains how to install the vGPU plugin in the AI platform platform, which is a prerequisite for using NVIDIA vGPU capability. + +## Prerequisites + +- Refer to the [GPU Support Matrix](../../gpu_matrix.md) to confirm that the nodes in the cluster have GPUs of the corresponding models. +- The current cluster has deployed NVIDIA drivers through the Operator. For specific instructions, refer to [Offline Installation of GPU Operator](../install_nvidia_driver_of_operator.md). + +## Procedure + +1. Path: __Container Management__ -> __Cluster Management__ -> Click the target cluster -> __Helm Apps__ -> __Helm Charts__ -> Search for __nvidia-vgpu__ . + + ![Alt text](../../images/vgpu-addon.png) + +2. During the installation of vGPU, several basic modification parameters are provided. If you need to modify advanced parameters, click the YAML column to make changes: + + - __deviceMemoryScaling__ : NVIDIA device memory scaling factor, the input value must be an integer, with a default value of 1. It can be greater than 1 (enabling virtual memory, experimental feature). For an NVIDIA GPU with a memory size of M, if we configure the __devicePlugin.deviceMemoryScaling__ parameter as S, in a Kubernetes cluster where we have deployed our device plugin, the vGPUs assigned from this GPU will have a total memory of __S * M__ . + + - __deviceSplitCount__ : An integer type, with a default value of 10. Number of GPU splits, each GPU cannot be assigned more tasks than its configuration count. If configured as N, each GPU can have up to N tasks simultaneously. + + - __Resources__ : Represents the resource usage of the vgpu-device-plugin and vgpu-schedule pods. + + ![Alt text](../../images/vgpu-pararm.png) + +3. After a successful installation, you will see two types of pods in the specified namespace, indicating that the NVIDIA vGPU plugin has been successfully installed: + + ![Alt text](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/user-guide/gpu/images/vgpu-pod.png) + +After a successful installation, you can [deploy applications using vGPU resources](vgpu_user.md). + +!!! note + + NVIDIA vGPU Addon does not support upgrading directly from the older v2.0.0 to the + latest v2.0.0+1; To upgrade, please uninstall the older version and then reinstall the latest version. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/vgpu_user.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/vgpu_user.md new file mode 100644 index 0000000..f6cf167 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/vgpu/vgpu_user.md @@ -0,0 +1,63 @@ +# Using NVIDIA vGPU in Applications + +This section explains how to use the vGPU capability in the AI platform platform. + +## Prerequisites + +- The nodes in the cluster have GPUs of the corresponding models. +- vGPU Addon has been successfully installed. Refer to [Installing GPU Addon](vgpu_addon.md) for details. +- GPU Operator is installed, and the __Nvidia.DevicePlugin__ capability is **disabled**. Refer to [Offline Installation of GPU Operator](../install_nvidia_driver_of_operator.md) for details. + +## Procedure + +### Using vGPU through the UI + +1. Confirm if the cluster has detected GPUs. Click the __Clusters__ -> __Cluster Settings__ -> __Addon Plugins__ and check if the GPU plugin has been automatically enabled and the corresponding GPU type has been detected. Currently, the cluster will automatically enable the __GPU__ addon and set the __GPU Type__ as __Nvidia vGPU__ . + + + +2. Deploy a workload by clicking __Clusters__ -> __Workloads__ . When deploying a workload using an image, select the type __Nvidia vGPU__ , and you will be prompted with the following parameters: + + - **Number of Physical Cards (nvidia.com/vgpu)** : Indicates how many physical cards need to be mounted by the current pod. The input value must be an integer and **less than or equal to** the number of cards on the host machine. + - **GPU Cores (nvidia.com/gpucores)**: Indicates the GPU cores utilized by each card, with a value range from 0 to 100. + Setting it to 0 means no enforced isolation, while setting it to 100 means exclusive use of the entire card. + - **GPU Memory (nvidia.com/gpumem)**: Indicates the GPU memory occupied by each card, with a value in MB. The minimum value is 1, and the maximum value is the total memory of the card. + + > If there are issues with the configuration values above, it may result in scheduling failure or inability to allocate resources. + + + +### Using vGPU through YAML Configuration + +Refer to the following workload configuration and add the parameter __nvidia.com/vgpu: '1'__ in the resource requests and limits section to configure the number of physical cards used by the application. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-vgpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-vgpu-demo + template: + metadata: + creationTimestamp: null + labels: + app: full-vgpu-demo + spec: + containers: + - name: full-vgpu-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/gpucores: '20' # Request 20% of GPU cores for each card + nvidia.com/gpumem: '200' # Request 200MB of GPU memory for each card + nvidia.com/vgpu: '1' # Request 1 GPU card + imagePullPolicy: Always + restartPolicy: Always +``` + +This YAML configuration requests the application to use vGPU resources. It specifies that each card should utilize 20% of GPU cores, 200MB of GPU memory, and requests 1 GPU card. diff --git a/docs/en/docs/kpanda/user-guide/gpu/nvidia/yum_source_redhat7_9.md b/docs/en/docs/kpanda/user-guide/gpu/nvidia/yum_source_redhat7_9.md new file mode 100644 index 0000000..c4313dc --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/nvidia/yum_source_redhat7_9.md @@ -0,0 +1,120 @@ +--- +MTPE: windsonsea +date: 2024-06-14 +--- + +# Build an Offline Yum Repository for Red Hat 7.9 + +## Introduction + +AI platform comes with a pre-installed CentOS 7.9 with GPU Operator offline package for kernel 3.10.0-1160. +You need to manually build an offline yum repository for other OS types or nodes with different kernels. + +This page explains how to build an offline yum repository for Red Hat 7.9 based on any node in the Global cluster, and how to use the `RepoConfig.ConfigMapName` parameter when installing the GPU Operator. + +## Prerequisites + +1. The cluster nodes where the GPU Operator is to be deployed must be Red Hat 7.9 with the exact same kernel version. +1. Prepare a file server that can be connected to the cluster network where the GPU Operator is to be deployed, such as nginx or minio. +1. Prepare a node that can access the internet, the cluster where the GPU Operator is to be deployed, + and the file server. [Docker installation](../../../../install/community/kind/online.md#install-docker) must be completed on this node. +1. The nodes in the global service cluster must be Red Hat 7.9. + +## Steps + +### 1. Build Offline Yum Repo for Relevant Kernel + +1. [Download rhel7.9 ISO](https://developers.redhat.com/products/rhel/download#assembly-field-downloads-page-content-61451) + + ![Download rhel7.9 ISO](../images/rhel7.9.png) + +2. Download the [rhel7.9 ospackage](https://github.com/kubean-io/kubean/releases) that corresponds to your Kubean version. + + Find the version number of Kubean in the **Container Management** section of the Global cluster under **Helm Apps**. + + + + Download the rhel7.9 ospackage for that version from the + [Kubean repository](https://github.com/kubean-io/kubean/releases). + + ![Kubean repository](../images/redhat0.12.2.png) + +3. Import offline resources using the installer. + + Refer to the [Import Offline Resources document](../../../../install/import.md). + +### 2. Download Offline Driver Image for Red Hat 7.9 OS + +[Click here to view the download url](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags). + +![Driver image](../images/driveimage.png) + +### 3. Upload Red Hat GPU Operator Offline Image to Boostrap Node Repository + +Refer to [Upload Red Hat GPU Operator Offline Image to Boostrap Node Repository](./push_image_to_repo.md). + +!!! note + + This reference is based on rhel8.4, so make sure to modify it for rhel7.9. + +### 4. Create ConfigMaps in the Cluster to Save Yum Repository Information + +Run the following command on the control node of the cluster where the GPU Operator is to be deployed. + +1. Run the following command to create a file named __CentOS-Base.repo__ to specify the configuration information where the yum repository is stored. + + ```bash + # The file name must be CentOS-Base.repo, otherwise it will not be recognized when installing gpu-operator + cat > CentOS-Base.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # The server file address of the boostrap node, usually {boostrap node IP} + {9000 port} + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # The server file address of the boostrap node, usually {boostrap node IP} + {9000 port} + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. Based on the created __CentOS-Base.repo__ file, create a profile named __local-repo-config__ in the gpu-operator namespace: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=CentOS-Base.repo=/etc/yum.repos.d/extension.repo + ``` + + The expected output is as follows: + + ```console + configmap/local-repo-config created + ``` + + The __local-repo-config__ profile is used to provide the value of the `RepoConfig.ConfigMapName` parameter when installing gpu-operator, and the profile name can be customized by the user. + +3. View the contents of the __local-repo-config__ profile: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + + The expected output is as follows: + + ```yaml title="local-repo-config.yaml" + apiVersion: v1 + data: + CentOS-Base.repo: "[extension-0]\nbaseurl = http://10.6.232.5:32618/centos-base # The file path where yum repository is placed in Step 2 \ngpgcheck = 0\nname = kubean extension 0\n \n[extension-1]\nbaseurl + = http://10.6.232.5:32618/centos-base # The file path where yum repository is placed in Step 2 \ngpgcheck = 0\nname + = kubean extension 1\n" + kind: ConfigMap + metadata: + creationTimestamp: "2023-10-18T01:59:02Z" + name: local-repo-config + namespace: gpu-operator + resourceVersion: "59445080" + uid: c5f0ebab-046f-442c-b932-f9003e014387 + ``` + +At this point, you have successfully created the offline yum repository profile for the cluster +where the GPU Operator is to be deployed. The `RepoConfig.ConfigMapName` parameter was used during the +[Offline Installation of GPU Operator](./install_nvidia_driver_of_operator.md). diff --git a/docs/en/docs/kpanda/user-guide/gpu/vgpu_quota.md b/docs/en/docs/kpanda/user-guide/gpu/vgpu_quota.md new file mode 100644 index 0000000..c338032 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/vgpu_quota.md @@ -0,0 +1,25 @@ +# GPU Quota Management + +This section describes how to use vGPU capabilities on the AI platform platform. + +## Prerequisites + +The corresponding GPU driver (NVIDIA GPU, NVIDIA MIG, Days, Ascend) has been deployed on the current cluster either through an Operator or manually. + +## Procedure + +Follow these steps to manage GPU quotas in AI platform: + +1. Go to Namespaces and click __Quota Management__ to configure the GPU resources that can be used by a specific namespace. + + + +2. The currently supported card types for quota management in a namespace are: NVIDIA vGPU, NVIDIA MIG, Days, and Ascend. + + - **NVIDIA vGPU Quota Management**: Configure the specific quota that can be used. This will create a ResourcesQuota CR. + + - Physical Card Count (nvidia.com/vgpu): Indicates the number of physical cards that the current pod needs to mount. The input value must be an integer and **less than or equal to** the number of cards on the host machine. + - GPU Core Count (nvidia.com/gpucores): Indicates the GPU compute power occupied by each card. The value ranges from 0 to 100. If configured as 0, it is considered not to enforce isolation. If configured as 100, it is considered to exclusively occupy the entire card. + - GPU Memory Usage (nvidia.com/gpumem): Indicates the amount of GPU memory occupied by each card. The value is in MB, with a minimum value of 1 and a maximum value equal to the entire memory of the card. + + diff --git a/docs/en/docs/kpanda/user-guide/gpu/volcano/volcano-gang-scheduler.md b/docs/en/docs/kpanda/user-guide/gpu/volcano/volcano-gang-scheduler.md new file mode 100644 index 0000000..7996e47 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/volcano/volcano-gang-scheduler.md @@ -0,0 +1,197 @@ +--- +MTPE: ModetaNiu +date: 2024-06-12 +--- + +# Using Volcano's Gang Scheduler + +The Gang scheduling policy is one of the core scheduling algorithms of the volcano-scheduler. +It satisfies the "All or nothing" scheduling requirement during the scheduling process, preventing +arbitrary scheduling of Pods that could waste cluster resources. The specific algorithm observes +whether the number of scheduled Pods under a Job meets the minimum running quantity. +When the Job's minimum running quantity is satisfied, scheduling actions are performed for all Pods under the Job; +otherwise, no actions are taken. + +## Use Cases + +The Gang scheduling algorithm, based on the concept of a Pod group, is particularly suitable for scenarios +that require multi-process collaboration. AI scenarios often involve complex workflows, such as Data Ingestion, +Data Analysis, Data Splitting, Training, Serving, and Logging, which require a group of containers to work together. +This makes the Gang scheduling policy based on pods very appropriate. + +In multi-threaded parallel computing communication scenarios under the MPI computation framework, +Gang scheduling is also very suitable because it requires master and slave processes to work together. +High relevance among containers in a pod may lead to resource contention, and overall scheduling allocation +can effectively resolve deadlocks. + +In scenarios with insufficient cluster resources, the Gang scheduling policy significantly improves +the utilization of cluster resources. For example, if the cluster can currently accommodate only 2 Pods, +but the minimum number of Pods required for scheduling is 3, then all Pods of this Job will remain pending until +the cluster can accommodate 3 Pods, at which point the Pods will be scheduled. This effectively prevents the +partial scheduling of Pods, which would not meet the requirements and would occupy resources, making other Jobs unable to run. + +## Concept Explanation + +The Gang Scheduler is the core scheduling plugin of Volcano, and it is enabled by default upon installing Volcano. +When creating a workload, you only need to specify the scheduler name as Volcano. + +Volcano schedules based on PodGroups. When creating a workload, there is no need to manually create PodGroup resources; +Volcano will automatically create them based on the workload information. Below is an example of a PodGroup: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + name: test + namespace: default +spec: + minMember: 1 # (1)! + minResources: # (2)! + cpu: "3" + memory: "2048Mi" + priorityClassName: high-prority # (3)! + queue: default # (4)! +``` + +1. Represents the **minimum** number of Pods or jobs that need to run under this PodGroup. If the cluster resources + do not meet the requirements to run the number of jobs specified by miniMember, the scheduler will not + schedule any jobs within this PodGroup. +2. Represents the minimum resources required to run this PodGroup. If the allocatable resources of the cluster + do not meet the minResources, the scheduler will not schedule any jobs within this PodGroup. +3. Represents the priority of this PodGroup, used by the scheduler to sort all PodGroups within the queue during scheduling. + **system-node-critical** and **system-cluster-critical** are two reserved values indicating the highest priority. + If not specifically designated, the default priority or zero priority is used. +4. Represents the queue to which this PodGroup belongs. The queue must be pre-created and in the open state. + +## Use Case + +In a multi-threaded parallel computing communication scenario under the MPI computation framework, we need to ensure +that all Pods can be successfully scheduled to ensure the job is completed correctly. Setting minAvailable to 4 +means that 1 mpimaster and 3 mpiworkers are required to run. + +```yaml +apiVersion: batch.volcano.sh/v1alpha1 +kind: Job +metadata: + name: lm-mpi-job + labels: + "volcano.sh/job-type": "MPI" +spec: + minAvailable: 4 + schedulerName: volcano + plugins: + ssh: [] + svc: [] + policies: + - event: PodEvicted + action: RestartJob + tasks: + - replicas: 1 + name: mpimaster + policies: + - event: TaskCompleted + action: CompleteJob + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + MPI_HOST=`cat /etc/volcano/mpiworker.host | tr "\n" ","`; + mkdir -p /var/run/sshd; /usr/sbin/sshd; + mpiexec --allow-run-as-root --host ${MPI_HOST} -np 3 mpi_hello_world; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpimaster + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "500m" + limits: + cpu: "500m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret + - replicas: 3 + name: mpiworker + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + mkdir -p /var/run/sshd; /usr/sbin/sshd -D; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpiworker + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "1000m" + limits: + cpu: "1000m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret +``` + +Generate the resources for PodGroup: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + annotations: + creationTimestamp: "2024-05-28T09:18:50Z" + generation: 5 + labels: + volcano.sh/job-type: MPI + name: lm-mpi-job-9c571015-37c7-4a1a-9604-eaa2248613f2 + namespace: default + ownerReferences: + - apiVersion: batch.volcano.sh/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Job + name: lm-mpi-job + uid: 9c571015-37c7-4a1a-9604-eaa2248613f2 + resourceVersion: "25173454" + uid: 7b04632e-7cff-4884-8e9a-035b7649d33b +spec: + minMember: 4 + minResources: + count/pods: "4" + cpu: 3500m + limits.cpu: 3500m + pods: "4" + requests.cpu: 3500m + minTaskMember: + mpimaster: 1 + mpiworker: 3 + queue: default +status: + conditions: + - lastTransitionTime: "2024-05-28T09:19:01Z" + message: '3/4 tasks in gang unschedulable: pod group is not ready, 1 Succeeded, + 3 Releasing, 4 minAvailable' + reason: NotEnoughResources + status: "True" + transitionID: f875efa5-0358-4363-9300-06cebc0e7466 + type: Unschedulable + - lastTransitionTime: "2024-05-28T09:18:53Z" + reason: tasks in gang are ready to be scheduled + status: "True" + transitionID: 5a7708c8-7d42-4c33-9d97-0581f7c06dab + type: Scheduled + phase: Pending + succeeded: 1 +``` + +From the PodGroup, it can be seen that it is associated with the workload through ownerReferences and +sets the minimum number of running Pods to 4. diff --git a/docs/en/docs/kpanda/user-guide/gpu/volcano/volcano_user_guide.md b/docs/en/docs/kpanda/user-guide/gpu/volcano/volcano_user_guide.md new file mode 100644 index 0000000..b5e6f97 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/gpu/volcano/volcano_user_guide.md @@ -0,0 +1,282 @@ +--- +MTPE: windsonsea +date: 2024-06-25 +--- + +# Use Volcano for AI Compute + +## Usage Scenarios + +Kubernetes has become the de facto standard for orchestrating and managing cloud-native applications, +and an increasing number of applications are choosing to migrate to K8s. The fields of artificial intelligence +and machine learning inherently involve a large number of compute-intensive tasks, and developers are very willing +to build AI platforms based on Kubernetes to fully leverage its resource management, application orchestration, +and operations monitoring capabilities. However, the default Kubernetes scheduler was initially designed +primarily for long-running services and has many shortcomings in batch and elastic scheduling for AI and +big data tasks. For example, resource contention issues: + +Take TensorFlow job scenarios as an example. TensorFlow jobs include two different roles, PS and Worker, +and the Pods for these two roles need to work together to complete the entire job. If only one type of +role Pod is running, the entire job cannot be executed properly. The default scheduler schedules Pods +one by one and is unaware of the PS and Worker roles in a Kubeflow TFJob. In a high-load cluster +(insufficient resources), multiple jobs may each be allocated some resources to run a portion of +their Pods, but the jobs cannot complete successfully, leading to resource waste. For instance, +if a cluster has 4 GPUs and both TFJob1 and TFJob2 each have 4 Workers, TFJob1 and TFJob2 +might each be allocated 2 GPUs. However, both TFJob1 and TFJob2 require 4 GPUs to run. +This mutual waiting for resource release creates a deadlock situation, resulting in GPU resource waste. + +## Volcano Batch Scheduling System + +Volcano is the first Kubernetes-based container batch computing platform under CNCF, focusing on +high-performance computing scenarios. It fills in the missing functionalities of Kubernetes +in fields such as machine learning, big data, and scientific computing, providing essential +support for these high-performance workloads. Additionally, Volcano seamlessly integrates +with mainstream computing frameworks like Spark, TensorFlow, and PyTorch, and supports +hybrid scheduling of heterogeneous devices, including CPUs and GPUs, effectively resolving +the deadlock issues mentioned above. + +The following sections will introduce how to install and use Volcano. + +## Install Volcano + +1. Find Volcano in **Cluster Details** -> **Helm Apps** -> **Helm Charts** and install it. + + ![Volcano helm chart](../../images/volcano-01.png) + + ![Install Volcano](../../images/volcano-02.png) + +2. Check and confirm whether Volcano is installed successfully, that is, whether the components volcano-admission, + volcano-controllers, and volcano-scheduler are running properly. + + ![Volcano components](../../images/volcano-03.png) + +Typically, Volcano is used in conjunction with the [AI Lab](../../../../baize/intro/index.md) +to achieve an effective closed-loop process for the development and training of datasets, Notebooks, and task training. + +## Volcano Use Cases + +- Volcano is a standalone scheduler. To enable the Volcano scheduler when creating workloads, + simply specify the scheduler's name (`schedulerName: volcano`). +- The `volcanoJob` resource is an extension of the Job in Volcano, + breaking the Job down into smaller working units called tasks, which can interact with each other. + +### Volcano Supports TensorFlow + +Here is an example: + +```yaml +apiVersion: batch.volcano.sh/v1alpha1 +kind: Job +metadata: + name: tensorflow-benchmark + labels: + "volcano.sh/job-type": "Tensorflow" +spec: + minAvailable: 3 + schedulerName: volcano + plugins: + env: [] + svc: [] + policies: + - event: PodEvicted + action: RestartJob + tasks: + - replicas: 1 + name: ps + template: + spec: + imagePullSecrets: + - name: default-secret + containers: + - command: + - sh + - -c + - | + PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | tr "\n" ","`; + WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | tr "\n" ","`; + 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 --job_name=ps --task_index=${VK_TASK_INDEX} --ps_hosts=${PS_HOST} --worker_hosts=${WORKER_HOST} + image: docker.m.daocloud.io/volcanosh/example-tf:0.0.1 + name: tensorflow + ports: + - containerPort: 2222 + name: tfjob-port + resources: + requests: + cpu: "1000m" + memory: "2048Mi" + limits: + cpu: "1000m" + memory: "2048Mi" + workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks + restartPolicy: OnFailure + - replicas: 2 + name: worker + policies: + - event: TaskCompleted + action: CompleteJob + template: + spec: + imagePullSecrets: + - name: default-secret + containers: + - command: + - sh + - -c + - | + PS_HOST=`cat /etc/volcano/ps.host | sed 's/$/&:2222/g' | tr "\n" ","`; + WORKER_HOST=`cat /etc/volcano/worker.host | sed 's/$/&:2222/g' | tr "\n" ","`; + 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 --job_name=worker --task_index=${VK_TASK_INDEX} --ps_hosts=${PS_HOST} --worker_hosts=${WORKER_HOST} + image: docker.m.daocloud.io/volcanosh/example-tf:0.0.1 + name: tensorflow + ports: + - containerPort: 2222 + name: tfjob-port + resources: + requests: + cpu: "2000m" + memory: "2048Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks + restartPolicy: OnFailure +``` + +### Parallel Computing with MPI + +In multi-threaded parallel computing communication scenarios under the MPI computing framework, +we need to ensure that all Pods are successfully scheduled to guarantee the task's proper completion. +Setting `minAvailable` to 4 indicates that 1 `mpimaster` and 3 `mpiworkers` are required to run. +By simply setting the `schedulerName` field value to "volcano," you can enable the Volcano scheduler. + +Here is an example: + +```yaml +apiVersion: batch.volcano.sh/v1alpha1 +kind: Job +metadata: + name: lm-mpi-job + labels: + "volcano.sh/job-type": "MPI" +spec: + minAvailable: 4 + schedulerName: volcano + plugins: + ssh: [] + svc: [] + policies: + - event: PodEvicted + action: RestartJob + tasks: + - replicas: 1 + name: mpimaster + policies: + - event: TaskCompleted + action: CompleteJob + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + MPI_HOST=`cat /etc/volcano/mpiworker.host | tr "\n" ","`; + mkdir -p /var/run/sshd; /usr/sbin/sshd; + mpiexec --allow-run-as-root --host ${MPI_HOST} -np 3 mpi_hello_world; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpimaster + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "500m" + limits: + cpu: "500m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret + - replicas: 3 + name: mpiworker + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + mkdir -p /var/run/sshd; /usr/sbin/sshd -D; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpiworker + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "1000m" + limits: + cpu: "1000m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret +``` + +Resources to generate PodGroup: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + annotations: + creationTimestamp: "2024-05-28T09:18:50Z" + generation: 5 + labels: + volcano.sh/job-type: MPI + name: lm-mpi-job-9c571015-37c7-4a1a-9604-eaa2248613f2 + namespace: default + ownerReferences: + - apiVersion: batch.volcano.sh/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Job + name: lm-mpi-job + uid: 9c571015-37c7-4a1a-9604-eaa2248613f2 + resourceVersion: "25173454" + uid: 7b04632e-7cff-4884-8e9a-035b7649d33b +spec: + minMember: 4 + minResources: + count/pods: "4" + cpu: 3500m + limits.cpu: 3500m + pods: "4" + requests.cpu: 3500m + minTaskMember: + mpimaster: 1 + mpiworker: 3 + queue: default +status: + conditions: + - lastTransitionTime: "2024-05-28T09:19:01Z" + message: '3/4 tasks in gang unschedulable: pod group is not ready, 1 Succeeded, + 3 Releasing, 4 minAvailable' + reason: NotEnoughResources + status: "True" + transitionID: f875efa5-0358-4363-9300-06cebc0e7466 + type: Unschedulable + - lastTransitionTime: "2024-05-28T09:18:53Z" + reason: tasks in gang are ready to be scheduled + status: "True" + transitionID: 5a7708c8-7d42-4c33-9d97-0581f7c06dab + type: Scheduled + phase: Pending + succeeded: 1 +``` + +From the PodGroup, it can be seen that it is associated with the workload through +`ownerReferences` and sets the minimum number of running Pods to 4. + +If you want to learn more about the features and usage scenarios of Volcano, +refer to [Volcano Introduction](https://volcano.sh/en/docs/). diff --git a/docs/en/docs/kpanda/user-guide/helm/Import-addon.md b/docs/en/docs/kpanda/user-guide/helm/Import-addon.md new file mode 100644 index 0000000..6678021 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/helm/Import-addon.md @@ -0,0 +1,97 @@ +# Import Custom Helm Apps into Built-in Addons + +This article explains how to import Helm appss into the system's built-in addons in both offline and online environments. + +## Offline Environment + +An offline environment refers to an environment that cannot connect to the internet or is a closed private network environment. + +### Prerequisites + +- [charts-syncer](https://github.com/DaoCloud/charts-syncer) is available and running. + If not, you can [click here to download](https://github.com/DaoCloud/charts-syncer/releases). +- The Helm Chart has been adapted for [charts-syncer](https://github.com/DaoCloud/charts-syncer). + This means adding a __.relok8s-images.yaml__ file to the Helm Chart. This file should include all the images used in the Chart, + including any images that are not directly used in the Chart but are used similar to images used in an Operator. + +!!! note + + - Refer to [image-hints-file](https://github.com/vmware-tanzu/asset-relocation-tool-for-kubernetes#image-hints-file) for instructions on how to write a Chart. + It is required to separate the registry and repository of the image because the registry/repository needs to be replaced or modified when loading the image. + - The installer's fire cluster has [charts-syncer](https://github.com/DaoCloud/charts-syncer) installed. + If you are importing a custom Helm apps into the installer's fire cluster, you can skip the download and proceed to the adaptation. + If [charts-syncer](https://github.com/DaoCloud/charts-syncer) binary is not installed, you can [download it immediately](https://github.com/DaoCloud/charts-syncer/releases). + +### Sync Helm Chart + +1. Go to __Container Management__ -> __Helm Apps__ -> __Helm Repositories__ , search for the addon, and obtain the built-in repository address and username/password (the default username/password for the system's built-in repository is rootuser/rootpass123). + + +1. Sync the Helm Chart to the built-in repository addon of the container management system + + * Write the following configuration file, modify it according to your specific configuration, and save it as __sync-dao-2048.yaml__ . + + ```yaml + source: # helm charts source information + repo: + kind: HARBOR # It can also be any other supported Helm Chart repository type, such as CHARTMUSEUM + url: https://release-ci.daocloud.io/chartrepo/community # Change to the chart repo URL + #auth: # username/password, if no password is set, leave it blank + #username: "admin" + #password: "Harbor12345" + charts: # charts to sync + - name: dao-2048 # helm charts information, if not specified, sync all charts in the source helm repo + versions: + - 1.4.1 + target: # helm charts target information + containerRegistry: 10.5.14.40 # image repository URL + repo: + kind: CHARTMUSEUM # It can also be any other supported Helm Chart repository type, such as HARBOR + url: http://10.5.14.40:8081 # Change to the correct chart repo URL, you can verify the address by using helm repo add $HELM-REPO + auth: # username/password, if no password is set, leave it blank + username: "rootuser" + password: "rootpass123" + containers: + # kind: HARBOR # If the image repository is HARBOR and you want charts-syncer to automatically create an image repository, fill in this field + # auth: # username/password, if no password is set, leave it blank + # username: "admin" + # password: "Harbor12345" + + # leverage .relok8s-images.yaml file inside the Charts to move the container images too + relocateContainerImages: true + ``` + + * Run the charts-syncer command to sync the Chart and its included images + + ```sh + charts-syncer sync --config sync-dao-2048.yaml --insecure --auto-create-repository + ``` + + The expected output is: + + ```console + I1222 15:01:47.119777 8743 sync.go:45] Using config file: "examples/sync-dao-2048.yaml" + W1222 15:01:47.234238 8743 syncer.go:263] Ignoring skipDependencies option as dependency sync is not supported if container image relocation is true or syncing from/to intermediate directory + I1222 15:01:47.234685 8743 sync.go:58] There is 1 chart out of sync! + I1222 15:01:47.234706 8743 sync.go:66] Syncing "dao-2048_1.4.1" chart... + .relok8s-images.yaml hints file found + Computing relocation... + + Relocating dao-2048@1.4.1... + Pushing 10.5.14.40/daocloud/dao-2048:v1.4.1... + Done + Done moving /var/folders/vm/08vw0t3j68z9z_4lcqyhg8nm0000gn/T/charts-syncer869598676/dao-2048-1.4.1.tgz + ``` + +1. Once the previous step is completed, go to __Container Management__ -> __Helm Apps__ -> __Helm Repositories__ , find the corresponding addon, + click __Sync Repository__ in the action column, and you will see the uploaded Helm apps in the Helm template. + +1. You can then proceed with normal installation, upgrade, and uninstallation. + + + +## Online Environment + +The Helm Repo address for the online environment is __release.daocloud.io__ . +If the user does not have permission to add Helm Repo, they will not be able to import custom Helm appss into the system's built-in addons. +You can add your own Helm repository and then integrate your Helm repository into the platform using the same steps as syncing Helm Chart in the offline environment. diff --git a/docs/en/docs/kpanda/user-guide/helm/README.md b/docs/en/docs/kpanda/user-guide/helm/README.md new file mode 100644 index 0000000..381d20b --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/helm/README.md @@ -0,0 +1,27 @@ +--- +hide: + - toc +--- + +# Helm Charts + +Helm is a package management tool for Kubernetes, which makes it easy for users to quickly discover, share and use applications built with Kubernetes. The fifth generation [Container Management Module](../../intro/index.md) provides hundreds of Helm charts, covering storage, network, monitoring, database and other main cases. With these templates, you can quickly deploy and easily manage Helm apps through the UI interface. In addition, it supports adding more personalized templates through [Add Helm repository](helm-repo.md) to meet various needs. + +![Helm Charts](../images/helm14.png) + +**Key Concepts**: + +There are a few key concepts to understand when using Helm: + +- Chart: A Helm installation package, which contains the images, dependencies, and resource definitions required to run an application, and may also contain service definitions in the Kubernetes cluster, similar to the formula in Homebrew, dpkg in APT, or rpm files in Yum. Charts are called __Helm Charts__ in AI platform. + +- Release: A Chart instance running on the Kubernetes cluster. A Chart can be installed multiple times in the same cluster, and each installation will create a new Release. Release is called __Helm Apps__ in AI platform. + +- Repository: A repository for publishing and storing Charts. Repository is called __Helm Repositories__ in AI platform. + +For more details, refer to [Helm official website](https://helm.sh/). + +**Related operations**: + +- [Manage Helm apps](helm-app.md), including installing, updating, uninstalling Helm apps, viewing Helm operation records, etc. +- [Manage Helm repository](helm-repo.md), including installing, updating, deleting Helm repository, etc. diff --git a/docs/en/docs/kpanda/user-guide/helm/helm-app.md b/docs/en/docs/kpanda/user-guide/helm/helm-app.md new file mode 100644 index 0000000..4fe0e5b --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/helm/helm-app.md @@ -0,0 +1,105 @@ +# Manage Helm Apps + +The container management module supports interface-based management of Helm, including creating Helm instances using Helm charts, customizing Helm instance arguments, and managing the full lifecycle of Helm instances. + +This section will take [cert-manager](https://cert-manager.io/docs/) as an example to introduce how to create and manage Helm apps through the container management interface. + +## Prerequisites + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. + +- Created a [namespace](../namespaces/createns.md), + [user](../../../ghippo/user-guide/access-control/user.md), + and granted [`NS Admin`](../permissions/permission-brief.md#ns-admin) or higher permissions to the user. + For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +## Install the Helm app + +Follow the steps below to install the Helm app. + +1. Click a cluster name to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __Helm Apps__ -> __Helm Chart__ to enter the Helm chart page. + + On the Helm chart page, select the [Helm repository](helm-repo.md) named __addon__ , and all the Helm chart templates under the __addon__ repository will be displayed on the interface. + Click the Chart named __cert-manager__ . + + + +3. On the installation page, you can see the relevant detailed information of the Chart, select the version to be installed in the upper right corner of the interface, and click the __Install__ button. Here select v1.9.1 version for installation. + + + +4. Configure __Name__ , __Namespace__ and __Version Information__ . You can also customize arguments by modifying YAML in the **argument Configuration** area below. Click __OK__ . + + + +5. The system will automatically return to the list of Helm apps, and the status of the newly created Helm app is __Installing__ , and the status will change to __Running__ after a period of time. + + + +## Update the Helm app + +After we have completed the installation of a Helm app through the interface, we can perform an update operation on the Helm app. Note: Update operations using the UI are only supported for Helm apps installed via the UI. + +Follow the steps below to update the Helm app. + +1. Click a cluster name to enter __Cluster Details__ . + + + +2. In the left navigation bar, click __Helm Apps__ to enter the Helm app list page. + + On the Helm app list page, select the Helm app that needs to be updated, click the __ ...__ operation button on the right side of the list, and select the __Update__ operation in the drop-down selection. + + + +3. After clicking the __Update__ button, the system will jump to the update interface, where you can update the Helm app as needed. Here we take updating the http port of the __dao-2048__ application as an example. + + + +4. After modifying the corresponding arguments. You can click the __Change__ button under the argument configuration to compare the files before and after the modification. After confirming that there is no error, click the __OK__ button at the bottom to complete the update of the Helm app. + + + +5. The system will automatically return to the Helm app list, and a pop-up window in the upper right corner will prompt __update successful__ . + + + +## View Helm operation records + +Every installation, update, and deletion of Helm apps has detailed operation records and logs for viewing. + +1. In the left navigation bar, click __Cluster Operations__ -> __Recent Operations__ , and then select the __Helm Operations__ tab at the top of the page. Each record corresponds to an install/update/delete operation. + + + +2. To view the detailed log of each operation: Click __┇__ on the right side of the list, and select __Log__ from the pop-up menu. + + + +3. At this point, the detailed operation log will be displayed in the form of console at the bottom of the page. + + + +## Delete the Helm app + +Follow the steps below to delete the Helm app. + +1. Find the cluster where the Helm app to be deleted resides, click the cluster name, and enter __Cluster Details__ . + + + +2. In the left navigation bar, click __Helm Apps__ to enter the Helm app list page. + + On the Helm app list page, select the Helm app you want to delete, click the __ ...__ operation button on the right side of the list, and select __Delete__ from the drop-down selection. + + + +3. Enter the name of the Helm app in the pop-up window to confirm, and then click the __Delete__ button. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/helm/helm-repo.md b/docs/en/docs/kpanda/user-guide/helm/helm-repo.md new file mode 100644 index 0000000..3e61b5f --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/helm/helm-repo.md @@ -0,0 +1,106 @@ +--- +MTPE: FanLin +Date: 2024-02-29 +--- + +# Manage Helm Repository + +The Helm repository is a repository for storing and publishing Charts. The Helm application module supports HTTP(s) protocol to access Chart packages in the repository. By default, the system has 4 built-in helm repos as shown in the table below to meet common needs in the production process of enterprises. + +| Repository | Description | Example | +| --------- | ------------ | ------- | +| partner | Various high-quality features provided by ecological partners Chart | tidb | +| system | Chart that must be relied upon by system core functional components and some advanced features. For example, insight-agent must be installed to obtain cluster monitoring information | Insight | +| addon | Common Chart in business cases | cert-manager | +| community | The most popular open source components in the Kubernetes community Chart | Istio | + +In addition to the above preset repositories, you can also add third-party Helm repositories yourself. This page will introduce how to add and update third-party Helm repositories. + +## Prerequisites + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. + +- Created a [namespace](../namespaces/createns.md), + [user](../../../ghippo/user-guide/access-control/user.md), + and granted [`NS Admin`](../permissions/permission-brief.md#ns-admin) or higher permissions to the user. + For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +- If using a private repository, you should have read and write permissions to the repository. + +## Introduce third-party Helm repository + +The following takes the public container repository of Kubevela as an example to introduce and manage the helm repo. + +1. Find the cluster that needs to be imported into the third-party helm repo, click the cluster name, and enter cluster details. + + ![Clusters](../images/crd01.png) + +2. In the left navigation bar, click __Helm Apps__ -> __Helm Repositories__ to enter the helm repo page. + + ![Helm Repo](../images/helmrepo01.png) + +3. Click the __Create Repository__ button on the helm repo page to enter the Create repository page, and configure relevant arguments according to the table below. + + - Repository Name: Set the repository name. It can be up to 63 characters long and may only include lowercase letters, + numbers, and separators __-__. It must start and end with a lowercase letter or number, for example, kubevela. + - Repository URL: The HTTP(S) address pointing to the target Helm repository. For example, . + - Skip TLS Verification: If the added Helm repository uses an HTTPS address and requires skipping TLS verification, + you can check this option. The default is unchecked. + - Authentication Method: The method used for identity verification after connecting to the repository URL. + For public repositories, you can select __None__. For private repositories, you need to enter a + username/password for identity verification. + - Labels: Add labels to this Helm repository. For example, key: repo4; value: Kubevela. + - Annotations: Add annotations to this Helm repository. For example, key: repo4; value: Kubevela. + - Description: Add a description for this Helm repository. For example: This is a Kubevela public Helm repository. + + ![Config](../images/helmrepo02.png) + +4. Click __OK__ to complete the creation of the Helm repository. The page will automatically jump to the list of Helm repositories. + + ![Confirm](../images/helmrepo03.png) + +## Update the Helm repository + +When the address information of the helm repo changes, the address, authentication method, label, annotation, and description information of the helm repo can be updated. + +1. Find the cluster where the repository to be updated is located, click the cluster name, and enter cluster details . + + ![Clusters](../images/crd01.png) + +2. In the left navigation bar, click __Helm Apps__ -> __Helm Repositories__ to enter the helm repo list page. + + ![Helm Repo](../images/helmrepo01.png) + +3. Find the Helm repository that needs to be updated on the repository list page, click the __┇__ button on the right side of the list, and click __Update__ in the pop-up menu. + + ![Update](../images/helmrepo04.png) + +4. Update on the __Update Helm Repository__ page, and click __OK__ when finished. + + ![Confirm](../images/helmrepo05.png) + +5. Return to the helm repo list, and the screen prompts that the update is successful. + +## Delete the Helm repository + +In addition to importing and updating repositorys, you can also delete unnecessary repositories, including system preset repositories and third-party repositories. + +1. Find the cluster where the repository to be deleted is located, click the cluster name, and enter cluster details . + + ![Clusters](../images/crd01.png) + +2. In the left navigation bar, click __Helm Apps__ -> __Helm Repositories__ to enter the helm repo list page. + + ![Helm Repo](../images/helmrepo01.png) + +3. Find the Helm repository that needs to be updated on the repository list page, click the __┇__ button on the right side of the list, and click __Delete__ in the pop-up menu. + + ![Delete](../images/helmrepo07.png) + +4. Enter the repository name to confirm, and click __Delete__ . + + ![Confirm](../images/helmrepo08.png) + +5. Return to the list of Helm repositories, and the screen prompts that the deletion is successful. diff --git a/docs/en/docs/kpanda/user-guide/helm/multi-archi-helm.md b/docs/en/docs/kpanda/user-guide/helm/multi-archi-helm.md new file mode 100644 index 0000000..63ad815 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/helm/multi-archi-helm.md @@ -0,0 +1,93 @@ +--- +MTPE: windsonsea +date: 2024-01-17 +--- + +# Import and Upgrade Multi-Arch Helm Apps + +In a multi-arch cluster, it is common to use Helm charts that support multiple architectures to address deployment issues caused by architectural differences. This guide will explain how to integrate single-arch Helm apps into multi-arch deployments and how to integrate multi-arch Helm apps. + +## Import + +### Import Single-arch + +Prepare the offline package `addon-offline-full-package-${version}-${arch}.tar.gz`. + +Specify the path in the __clusterConfig.yml__ configuration file, for example: + +```yaml +addonPackage: + path: "/home/addon-offline-full-package-v0.9.0-amd64.tar.gz" +``` + +Then run the import command: + +```shell +~/dce5-installer cluster-create -c /home/dce5/sample/clusterConfig.yaml -m /home/dce5/sample/manifest.yaml -d -j13 +``` + +### Integrate Multi-arch + +Prepare the offline package `addon-offline-full-package-${version}-${arch}.tar.gz`. + +Take `addon-offline-full-package-v0.9.0-arm64.tar.gz` as an example and run the import command: + +```shell +~/dce5-installer import-addon -c /home/dce5/sample/clusterConfig.yaml --addon-path=/home/addon-offline-full-package-v0.9.0-arm64.tar.gz +``` + +## Upgrade + +### Upgrade Single-arch + +Prepare the offline package `addon-offline-full-package-${version}-${arch}.tar.gz`. + +Specify the path in the __clusterConfig.yml__ configuration file, for example: + +```yaml +addonPackage: + path: "/home/addon-offline-full-package-v0.11.0-amd64.tar.gz" +``` + +Then run the import command: + +```shell +~/dce5-installer cluster-create -c /home/dce5/sample/clusterConfig.yaml -m /home/dce5/sample/manifest.yaml -d -j13 +``` + +### Multi-arch Integration + +Prepare the offline package `addon-offline-full-package-${version}-${arch}.tar.gz`. + +Take `addon-offline-full-package-v0.11.0-arm64.tar.gz` as an example and run the import command: + +```shell +~/dce5-installer import-addon -c /home/dce5/sample/clusterConfig.yaml --addon-path=/home/addon-offline-full-package-v0.11.0-arm64.tar.gz +``` + +## Notes + +### Disk Space + +The offline package is quite large and requires sufficient space for decompression and loading of images. Otherwise, it may interrupt the process with a "no space left" error. + +### Retry after Failure + +If the multi-arch fusion step fails, you need to clean up the residue before retrying: + +```shell +rm -rf addon-offline-target-package +``` + +### Registry Space + +If the offline package for fusion contains registry spaces that are inconsistent with the imported offline package, an error may occur during the fusion process due to the non-existence of the registry spaces: + +![helm](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/multi-arch-helm.png) + +Solution: Simply create the registry space before the fusion. For example, in the above error, creating the registry space "localhost" in advance can prevent the error. + +### Architecture Conflict + +When upgrading to a version lower than 0.12.0 of the addon, the charts-syncer in the target offline package does not check the existence of the image before pushing, so it will recombine the multi-arch into a single architecture during the upgrade process. +For example, if the addon is implemented as a multi-arch in v0.10, upgrading to v0.11 will overwrite the multi-arch addon with a single architecture. However, upgrading to v0.12.0 or above can still maintain the multi-arch. diff --git a/docs/en/docs/kpanda/user-guide/helm/upload-helm.md b/docs/en/docs/kpanda/user-guide/helm/upload-helm.md new file mode 100644 index 0000000..3e50d51 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/helm/upload-helm.md @@ -0,0 +1,66 @@ +--- +MTPE: ModetaNiu +Date: 2024-05-27 +hide: + - toc +--- + +# Upload Helm Charts + +This article explains how to upload Helm charts. See the steps below. + +1. Add a Helm repository, refer to [Adding a Third-Party Helm Repository](./helm-repo.md) for the procedure. + +2. Upload the Helm Chart to the Helm repository. + + === "Upload with Client" + + !!! note + + This method is suitable for Harbor, ChartMuseum, JFrog type repositories. + + 1. Log in to a node that can access the Helm repository, upload the Helm binary to the node, + and install the cm-push plugin (VPN is needed and [Git](https://git-scm.com/downloads) should be installed in advance). + + Refer to the [plugin installation process](https://github.com/chartmuseum/helm-push). + + 2. Push the Helm Chart to the Helm repository by executing the following command: + + ```shell + helm cm-push ${charts-dir} ${HELM_REPO_URL} --username ${username} --password ${password} + ``` + + Argument descriptions: + + - `charts-dir`: The directory of the Helm Chart, or the packaged Chart (i.e., .tgz file). + - `HELM_REPO_URL`: The URL of the Helm repository. + - `username`/`password`: The username and password for the Helm repository with push permissions. + - If you want to access via HTTPS and skip the certificate verification, you can add the argument `--insecure`. + + === "Upload with Web Page" + + !!! note + + This method is only applicable to Harbor repositories. + + 1. Log into the Harbor repository, ensuring the logged-in user has permissions to push; + + 2. Go to the relevant project, select the __Helm Charts__ tab, click the __Upload__ button on the page to upload the Helm Chart. + + ![upload Helm Chart](../../images/upload-helm-01.png) + +3. Sync Remote Repository Data + + === "Manual Sync" + + By default, the cluster does not enable **Helm Repository Auto-Refresh**, so you need to perform a manual sync operation. The general steps are: + + Go to **Helm Applications** -> **Helm Repositories**, click the **┇** button on the right side of the repository list, and select **Sync Repository** to complete the repository data synchronization. + + ![Upload Helm Chart](../../images/upload-helm-02.png) + + === "Auto Sync" + + If you need to enable the Helm repository auto-sync feature, you can go to **Cluster Maintenance** -> **Cluster Settings** -> **Advanced Settings** and turn on the Helm repository auto-refresh switch. + + diff --git a/docs/en/docs/kpanda/user-guide/images/addnode01.png b/docs/en/docs/kpanda/user-guide/images/addnode01.png new file mode 100644 index 0000000..a84af0f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/addnode01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/addnode02.png b/docs/en/docs/kpanda/user-guide/images/addnode02.png new file mode 100644 index 0000000..6f3159e Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/addnode02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/addnode03.png b/docs/en/docs/kpanda/user-guide/images/addnode03.png new file mode 100644 index 0000000..1ae6dbe Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/addnode03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/autoscaling01.png b/docs/en/docs/kpanda/user-guide/images/autoscaling01.png new file mode 100644 index 0000000..7642ebb Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/autoscaling01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/autoscaling02.png b/docs/en/docs/kpanda/user-guide/images/autoscaling02.png new file mode 100644 index 0000000..939398f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/autoscaling02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/autoscaling03.png b/docs/en/docs/kpanda/user-guide/images/autoscaling03.png new file mode 100644 index 0000000..972b96b Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/autoscaling03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/autoscaling04.png b/docs/en/docs/kpanda/user-guide/images/autoscaling04.png new file mode 100644 index 0000000..f855c91 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/autoscaling04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/crd01.png b/docs/en/docs/kpanda/user-guide/images/crd01.png new file mode 100644 index 0000000..911190b Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/crd01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/create-depolyment.png b/docs/en/docs/kpanda/user-guide/images/create-depolyment.png new file mode 100644 index 0000000..c6cc672 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/create-depolyment.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createScale.png b/docs/en/docs/kpanda/user-guide/images/createScale.png new file mode 100644 index 0000000..3ea6164 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createScale.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createScale04.png b/docs/en/docs/kpanda/user-guide/images/createScale04.png new file mode 100644 index 0000000..add3efd Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createScale04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createScale05.png b/docs/en/docs/kpanda/user-guide/images/createScale05.png new file mode 100644 index 0000000..5d33b2a Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createScale05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createScale06.png b/docs/en/docs/kpanda/user-guide/images/createScale06.png new file mode 100644 index 0000000..023250d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createScale06.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createVpaScale.png b/docs/en/docs/kpanda/user-guide/images/createVpaScale.png new file mode 100644 index 0000000..fa2699d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createVpaScale.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createVpaScale01.png b/docs/en/docs/kpanda/user-guide/images/createVpaScale01.png new file mode 100644 index 0000000..00bf4c9 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createVpaScale01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/createVpaScale02.png b/docs/en/docs/kpanda/user-guide/images/createVpaScale02.png new file mode 100644 index 0000000..7c64108 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/createVpaScale02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob01.png b/docs/en/docs/kpanda/user-guide/images/cronjob01.png new file mode 100644 index 0000000..8aee70f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob02.png b/docs/en/docs/kpanda/user-guide/images/cronjob02.png new file mode 100644 index 0000000..6d914f0 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob03.png b/docs/en/docs/kpanda/user-guide/images/cronjob03.png new file mode 100644 index 0000000..da22a19 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob04.png b/docs/en/docs/kpanda/user-guide/images/cronjob04.png new file mode 100644 index 0000000..372b8b9 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob05.png b/docs/en/docs/kpanda/user-guide/images/cronjob05.png new file mode 100644 index 0000000..ca500ac Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob06.png b/docs/en/docs/kpanda/user-guide/images/cronjob06.png new file mode 100644 index 0000000..d0feb44 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob06.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob07.png b/docs/en/docs/kpanda/user-guide/images/cronjob07.png new file mode 100644 index 0000000..94d4bd2 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob07.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob08.png b/docs/en/docs/kpanda/user-guide/images/cronjob08.png new file mode 100644 index 0000000..40550fe Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob08.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob09.png b/docs/en/docs/kpanda/user-guide/images/cronjob09.png new file mode 100644 index 0000000..cd4a960 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob09.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/cronjob10.png b/docs/en/docs/kpanda/user-guide/images/cronjob10.png new file mode 100644 index 0000000..b75cb10 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/cronjob10.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon006.png b/docs/en/docs/kpanda/user-guide/images/daemon006.png new file mode 100644 index 0000000..dec7498 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon006.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon01.png b/docs/en/docs/kpanda/user-guide/images/daemon01.png new file mode 100644 index 0000000..34b12b4 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon02.png b/docs/en/docs/kpanda/user-guide/images/daemon02.png new file mode 100644 index 0000000..c789766 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon02Yaml.png b/docs/en/docs/kpanda/user-guide/images/daemon02Yaml.png new file mode 100644 index 0000000..3777342 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon02Yaml.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon03Yaml.png b/docs/en/docs/kpanda/user-guide/images/daemon03Yaml.png new file mode 100644 index 0000000..045b7ae Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon03Yaml.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon05.png b/docs/en/docs/kpanda/user-guide/images/daemon05.png new file mode 100644 index 0000000..a4d8568 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon06.png b/docs/en/docs/kpanda/user-guide/images/daemon06.png new file mode 100644 index 0000000..df6024c Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon06.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon12.png b/docs/en/docs/kpanda/user-guide/images/daemon12.png new file mode 100644 index 0000000..cd9bb5e Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon12.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon14.png b/docs/en/docs/kpanda/user-guide/images/daemon14.png new file mode 100644 index 0000000..992bc11 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon14.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon15.png b/docs/en/docs/kpanda/user-guide/images/daemon15.png new file mode 100644 index 0000000..7dfb36d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon15.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon16.png b/docs/en/docs/kpanda/user-guide/images/daemon16.png new file mode 100644 index 0000000..57a2688 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon16.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/daemon17.png b/docs/en/docs/kpanda/user-guide/images/daemon17.png new file mode 100644 index 0000000..e4e4acb Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/daemon17.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deletenode01.png b/docs/en/docs/kpanda/user-guide/images/deletenode01.png new file mode 100644 index 0000000..a97d115 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deletenode01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deletenode02.png b/docs/en/docs/kpanda/user-guide/images/deletenode02.png new file mode 100644 index 0000000..42346a7 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deletenode02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy01.png b/docs/en/docs/kpanda/user-guide/images/deploy01.png new file mode 100644 index 0000000..ec90e8c Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy02.png b/docs/en/docs/kpanda/user-guide/images/deploy02.png new file mode 100644 index 0000000..3d93974 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy02Yaml.png b/docs/en/docs/kpanda/user-guide/images/deploy02Yaml.png new file mode 100644 index 0000000..5c6ba51 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy02Yaml.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy03Yaml.png b/docs/en/docs/kpanda/user-guide/images/deploy03Yaml.png new file mode 100644 index 0000000..1b0723d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy03Yaml.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy04.png b/docs/en/docs/kpanda/user-guide/images/deploy04.png new file mode 100644 index 0000000..9e7ccd5 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy05.png b/docs/en/docs/kpanda/user-guide/images/deploy05.png new file mode 100644 index 0000000..e809cc2 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy06.png b/docs/en/docs/kpanda/user-guide/images/deploy06.png new file mode 100644 index 0000000..cf269bd Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy06.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy07.png b/docs/en/docs/kpanda/user-guide/images/deploy07.png new file mode 100644 index 0000000..91b5a75 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy07.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy08.png b/docs/en/docs/kpanda/user-guide/images/deploy08.png new file mode 100644 index 0000000..77787a8 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy08.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy09.png b/docs/en/docs/kpanda/user-guide/images/deploy09.png new file mode 100644 index 0000000..c93abe0 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy09.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy10.png b/docs/en/docs/kpanda/user-guide/images/deploy10.png new file mode 100644 index 0000000..9322773 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy10.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy12.png b/docs/en/docs/kpanda/user-guide/images/deploy12.png new file mode 100644 index 0000000..fb622bc Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy12.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy13.png b/docs/en/docs/kpanda/user-guide/images/deploy13.png new file mode 100644 index 0000000..52fa4a4 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy13.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy14.png b/docs/en/docs/kpanda/user-guide/images/deploy14.png new file mode 100644 index 0000000..b08f31f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy14.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy15.png b/docs/en/docs/kpanda/user-guide/images/deploy15.png new file mode 100644 index 0000000..ae36dc5 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy15.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy16.png b/docs/en/docs/kpanda/user-guide/images/deploy16.png new file mode 100644 index 0000000..d21ed6a Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy16.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy17.png b/docs/en/docs/kpanda/user-guide/images/deploy17.png new file mode 100644 index 0000000..90ecd59 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy17.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/deploy18.png b/docs/en/docs/kpanda/user-guide/images/deploy18.png new file mode 100644 index 0000000..3afaf85 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/deploy18.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/etcd-get01.png b/docs/en/docs/kpanda/user-guide/images/etcd-get01.png new file mode 100644 index 0000000..db3a66e Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/etcd-get01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/etcd01.png b/docs/en/docs/kpanda/user-guide/images/etcd01.png new file mode 100644 index 0000000..4c6fdaf Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/etcd01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helm14.png b/docs/en/docs/kpanda/user-guide/images/helm14.png new file mode 100644 index 0000000..e417320 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helm14.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo01.png b/docs/en/docs/kpanda/user-guide/images/helmrepo01.png new file mode 100644 index 0000000..bde8cff Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo02.png b/docs/en/docs/kpanda/user-guide/images/helmrepo02.png new file mode 100644 index 0000000..20c7921 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo03.png b/docs/en/docs/kpanda/user-guide/images/helmrepo03.png new file mode 100644 index 0000000..6b6f464 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo04.png b/docs/en/docs/kpanda/user-guide/images/helmrepo04.png new file mode 100644 index 0000000..692ca29 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo05.png b/docs/en/docs/kpanda/user-guide/images/helmrepo05.png new file mode 100644 index 0000000..ed8ff0c Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo07.png b/docs/en/docs/kpanda/user-guide/images/helmrepo07.png new file mode 100644 index 0000000..e37311a Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo07.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/helmrepo08.png b/docs/en/docs/kpanda/user-guide/images/helmrepo08.png new file mode 100644 index 0000000..93c3905 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/helmrepo08.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-home.png b/docs/en/docs/kpanda/user-guide/images/inspection-home.png new file mode 100644 index 0000000..4d519c8 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-home.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-list-more.png b/docs/en/docs/kpanda/user-guide/images/inspection-list-more.png new file mode 100644 index 0000000..c398c10 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-list-more.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-report-01.png b/docs/en/docs/kpanda/user-guide/images/inspection-report-01.png new file mode 100644 index 0000000..fbf4219 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-report-01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-report-02.png b/docs/en/docs/kpanda/user-guide/images/inspection-report-02.png new file mode 100644 index 0000000..f882c8f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-report-02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-report-03.png b/docs/en/docs/kpanda/user-guide/images/inspection-report-03.png new file mode 100644 index 0000000..a6ab83a Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-report-03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-start-alone.png b/docs/en/docs/kpanda/user-guide/images/inspection-start-alone.png new file mode 100644 index 0000000..46f6e4e Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-start-alone.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/inspection-start.png b/docs/en/docs/kpanda/user-guide/images/inspection-start.png new file mode 100644 index 0000000..5fe79f3 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/inspection-start.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installcronhpa.png b/docs/en/docs/kpanda/user-guide/images/installcronhpa.png new file mode 100644 index 0000000..f599efc Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installcronhpa.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installcronhpa1.png b/docs/en/docs/kpanda/user-guide/images/installcronhpa1.png new file mode 100644 index 0000000..80e7400 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installcronhpa1.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installcronhpa2.png b/docs/en/docs/kpanda/user-guide/images/installcronhpa2.png new file mode 100644 index 0000000..5724365 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installcronhpa2.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installvpa.png b/docs/en/docs/kpanda/user-guide/images/installvpa.png new file mode 100644 index 0000000..5730007 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installvpa.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installvpa1.png b/docs/en/docs/kpanda/user-guide/images/installvpa1.png new file mode 100644 index 0000000..b195312 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installvpa1.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installvpa2.png b/docs/en/docs/kpanda/user-guide/images/installvpa2.png new file mode 100644 index 0000000..fa44d57 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installvpa2.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/installvpa3.png b/docs/en/docs/kpanda/user-guide/images/installvpa3.png new file mode 100644 index 0000000..e844f92 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/installvpa3.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job01.png b/docs/en/docs/kpanda/user-guide/images/job01.png new file mode 100644 index 0000000..35c24d5 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job02-1.png b/docs/en/docs/kpanda/user-guide/images/job02-1.png new file mode 100644 index 0000000..22ae751 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job02-1.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job02.png b/docs/en/docs/kpanda/user-guide/images/job02.png new file mode 100644 index 0000000..1991282 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job03.png b/docs/en/docs/kpanda/user-guide/images/job03.png new file mode 100644 index 0000000..0835f18 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job04.png b/docs/en/docs/kpanda/user-guide/images/job04.png new file mode 100644 index 0000000..1ca56a0 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job06.png b/docs/en/docs/kpanda/user-guide/images/job06.png new file mode 100644 index 0000000..9121fb9 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job06.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job07.png b/docs/en/docs/kpanda/user-guide/images/job07.png new file mode 100644 index 0000000..6487c15 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job07.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job08.png b/docs/en/docs/kpanda/user-guide/images/job08.png new file mode 100644 index 0000000..8b616fc Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job08.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/job09.png b/docs/en/docs/kpanda/user-guide/images/job09.png new file mode 100644 index 0000000..f929a25 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/job09.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/knative-install-1.png b/docs/en/docs/kpanda/user-guide/images/knative-install-1.png new file mode 100644 index 0000000..5d9fd3f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/knative-install-1.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/knative-install-2.png b/docs/en/docs/kpanda/user-guide/images/knative-install-2.png new file mode 100644 index 0000000..238abee Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/knative-install-2.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/knative-install-3.png b/docs/en/docs/kpanda/user-guide/images/knative-install-3.png new file mode 100644 index 0000000..7dc5084 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/knative-install-3.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/labels01.png b/docs/en/docs/kpanda/user-guide/images/labels01.png new file mode 100644 index 0000000..2372d15 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/labels01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/labels02.png b/docs/en/docs/kpanda/user-guide/images/labels02.png new file mode 100644 index 0000000..1edf7f1 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/labels02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/node-details01.png b/docs/en/docs/kpanda/user-guide/images/node-details01.png new file mode 100644 index 0000000..4c69151 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/node-details01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/node-details02.png b/docs/en/docs/kpanda/user-guide/images/node-details02.png new file mode 100644 index 0000000..30e92ca Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/node-details02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/node-details03.png b/docs/en/docs/kpanda/user-guide/images/node-details03.png new file mode 100644 index 0000000..ae52531 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/node-details03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ns00.png b/docs/en/docs/kpanda/user-guide/images/ns00.png new file mode 100644 index 0000000..5e5e193 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ns00.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ns01.png b/docs/en/docs/kpanda/user-guide/images/ns01.png new file mode 100644 index 0000000..3595b46 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ns01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ns02.png b/docs/en/docs/kpanda/user-guide/images/ns02.png new file mode 100644 index 0000000..732b9fe Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ns02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ns03.png b/docs/en/docs/kpanda/user-guide/images/ns03.png new file mode 100644 index 0000000..1be3a0f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ns03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ns04.png b/docs/en/docs/kpanda/user-guide/images/ns04.png new file mode 100644 index 0000000..21e3250 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ns04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/permisson02.png b/docs/en/docs/kpanda/user-guide/images/permisson02.png new file mode 100644 index 0000000..90a5743 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/permisson02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ps01.png b/docs/en/docs/kpanda/user-guide/images/ps01.png new file mode 100644 index 0000000..c73ed64 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ps01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ps02.png b/docs/en/docs/kpanda/user-guide/images/ps02.png new file mode 100644 index 0000000..f2572bf Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ps02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ps03.png b/docs/en/docs/kpanda/user-guide/images/ps03.png new file mode 100644 index 0000000..cdc0ee2 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ps03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ps04.png b/docs/en/docs/kpanda/user-guide/images/ps04.png new file mode 100644 index 0000000..072f425 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ps04.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/ps05.png b/docs/en/docs/kpanda/user-guide/images/ps05.png new file mode 100644 index 0000000..44f0432 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/ps05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/schedule01.png b/docs/en/docs/kpanda/user-guide/images/schedule01.png new file mode 100644 index 0000000..2d39b1f Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/schedule01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/schedule02.png b/docs/en/docs/kpanda/user-guide/images/schedule02.png new file mode 100644 index 0000000..447356e Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/schedule02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/schedule03.png b/docs/en/docs/kpanda/user-guide/images/schedule03.png new file mode 100644 index 0000000..c6c6254 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/schedule03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/settings01.png b/docs/en/docs/kpanda/user-guide/images/settings01.png new file mode 100644 index 0000000..094a883 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/settings01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/settings02.png b/docs/en/docs/kpanda/user-guide/images/settings02.png new file mode 100644 index 0000000..b4925e7 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/settings02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state01.png b/docs/en/docs/kpanda/user-guide/images/state01.png new file mode 100644 index 0000000..a156720 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state02.png b/docs/en/docs/kpanda/user-guide/images/state02.png new file mode 100644 index 0000000..1a3ecd4 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state02Yaml.png b/docs/en/docs/kpanda/user-guide/images/state02Yaml.png new file mode 100644 index 0000000..562a3e3 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state02Yaml.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state03yaml.png b/docs/en/docs/kpanda/user-guide/images/state03yaml.png new file mode 100644 index 0000000..7758d16 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state03yaml.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state05.png b/docs/en/docs/kpanda/user-guide/images/state05.png new file mode 100644 index 0000000..8fcd4c8 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state05.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state06.png b/docs/en/docs/kpanda/user-guide/images/state06.png new file mode 100644 index 0000000..f2e70c3 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state06.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state09.png b/docs/en/docs/kpanda/user-guide/images/state09.png new file mode 100644 index 0000000..c9ab34d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state09.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state10.png b/docs/en/docs/kpanda/user-guide/images/state10.png new file mode 100644 index 0000000..09bf045 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state10.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state11.png b/docs/en/docs/kpanda/user-guide/images/state11.png new file mode 100644 index 0000000..078b8b0 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state11.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state12.png b/docs/en/docs/kpanda/user-guide/images/state12.png new file mode 100644 index 0000000..4fd887c Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state12.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state14.png b/docs/en/docs/kpanda/user-guide/images/state14.png new file mode 100644 index 0000000..ffc9ed6 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state14.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state15.png b/docs/en/docs/kpanda/user-guide/images/state15.png new file mode 100644 index 0000000..8434900 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state15.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state16.png b/docs/en/docs/kpanda/user-guide/images/state16.png new file mode 100644 index 0000000..dcd0a04 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state16.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/state17.png b/docs/en/docs/kpanda/user-guide/images/state17.png new file mode 100644 index 0000000..e99b0d4 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/state17.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/taint01.png b/docs/en/docs/kpanda/user-guide/images/taint01.png new file mode 100644 index 0000000..5acdbf4 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/taint01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/taint02.png b/docs/en/docs/kpanda/user-guide/images/taint02.png new file mode 100644 index 0000000..2b8a89d Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/taint02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/taint03.png b/docs/en/docs/kpanda/user-guide/images/taint03.png new file mode 100644 index 0000000..6107b63 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/taint03.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/volcano-01.png b/docs/en/docs/kpanda/user-guide/images/volcano-01.png new file mode 100644 index 0000000..565baa0 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/volcano-01.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/volcano-02.png b/docs/en/docs/kpanda/user-guide/images/volcano-02.png new file mode 100644 index 0000000..03f674e Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/volcano-02.png differ diff --git a/docs/en/docs/kpanda/user-guide/images/volcano-03.png b/docs/en/docs/kpanda/user-guide/images/volcano-03.png new file mode 100644 index 0000000..e916548 Binary files /dev/null and b/docs/en/docs/kpanda/user-guide/images/volcano-03.png differ diff --git a/docs/en/docs/kpanda/user-guide/inspect/config.md b/docs/en/docs/kpanda/user-guide/inspect/config.md new file mode 100644 index 0000000..9cbe615 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/inspect/config.md @@ -0,0 +1,45 @@ +--- +hide: + - toc +--- + +# Creating Inspection Configuration + +AI platform Container Management module provides cluster inspection functionality, which supports inspection at the cluster, node, and pod levels. + +- Cluster level: Check the running status of system components in the cluster, including cluster status, resource usage, and specific inspection items for control nodes such as __kube-apiserver__ and __etcd__ . +- Node level: Includes common inspection items for both control nodes and worker nodes, such as node resource usage, handle count, PID status, and network status. +- Pod level: Check the CPU and memory usage, running status, PV and PVC status of Pods. + +Here's how to create an inspection configuration. + +1. Click __Cluster Inspection__ in the left navigation bar. + + ![nav](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/inspect01.png) + +2. On the right side of the page, click __Inspection Configuration__ . + + ![create](../images/inspection-home.png) + +3. Fill in the inspection configuration based on the following instructions, then click __OK__ at the bottom of the page. + + - Cluster: Select the clusters that you want to inspect from the dropdown list. **If you select multiple clusters, multiple inspection configurations will be automatically generated (only the inspected clusters are inconsistent, all other configurations are identical).** + - Scheduled Inspection: When enabled, it allows for regular automatic execution of cluster inspections based on a pre-set inspection frequency. + - Inspection Frequency: Set the interval for automatic inspections, e.g., every Tuesday at 10 AM. It supports custom CronExpressios, refer to [Cron Schedule Syntax](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax) for more information. + - Number of Inspection Records to Retain: Specifies the maximum number of inspection records to be retained, including all inspection records for each cluster. + - Parameter Configuration: The parameter configuration is divided into three parts: cluster level, node level, and pod level. You can enable or disable specific inspection items based on your requirements. + + ![basic](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/inspect03.png) + +After creating the inspection configuration, it will be automatically displayed in the inspection configuration list. Click the more options button on the right of the configuration to immediately perform an inspection, modify the inspection configuration or delete the inspection configuration and reports. + +- Click __Inspection__ to perform an inspection once based on the configuration. +- Click __Inspection Configuration__ to modify the inspection configuration. +- Click __Delete__ to delete the inspection configuration and reports. + + ![basic](../images/inspection-list-more.png) + +!!! note + + - After creating the inspection configuration, if the __Scheduled Inspection__ configuration is enabled, inspections will be automatically executed at the specified time. + - If __Scheduled Inspection__ configuration is not enabled, you need to manually [trigger the inspection](inspect.md). \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/inspect/index.md b/docs/en/docs/kpanda/user-guide/inspect/index.md new file mode 100644 index 0000000..cafc067 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/inspect/index.md @@ -0,0 +1,27 @@ +--- +hide: + - toc +--- + +# Cluster Inspection + +Cluster inspection allows administrators to regularly or ad-hoc check the overall health of the cluster, +giving them proactive control over ensuring cluster security. With a well-planned inspection schedule, +this proactive cluster check allows administrators to monitor the cluster status at any time and address +potential issues in advance. It eliminates the previous dilemma of passive troubleshooting during failures, +enabling proactive monitoring and prevention. + +The cluster inspection feature provided by AI platform's container management module supports custom inspection +items at the cluster, node, and pod levels. After the inspection is completed, +it automatically generates visual inspection reports. + +- Cluster Level: Checks the running status of system components in the cluster, including cluster status, + resource usage, and specific inspection items for control nodes, such as the status of + __kube-apiserver__ and __etcd__ . +- Node Level: Includes common inspection items for both control nodes and worker nodes, + such as node resource usage, handle counts, PID status, and network status. +- pod Level: Checks the CPU and memory usage, running status of pods, + and the status of PV (Persistent Volume) and PVC (PersistentVolumeClaim). + +For information on security inspections or executing security-related inspections, +refer to the [supported security scan types](../security/index.md) in AI platform. diff --git a/docs/en/docs/kpanda/user-guide/inspect/inspect.md b/docs/en/docs/kpanda/user-guide/inspect/inspect.md new file mode 100644 index 0000000..dc6fccc --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/inspect/inspect.md @@ -0,0 +1,40 @@ +--- +hide: + - toc +--- + +# Start Cluster Inspection + +After creating an inspection configuration, if the __Scheduled Inspection__ configuration is enabled, inspections will be automatically executed at the specified time. If the __Scheduled Inspection__ configuration is not enabled, you need to manually trigger the inspection. + +This page explains how to manually perform a cluster inspection. + +## Prerequisites + +- [Integrate](../clusters/integrate-cluster.md) or [create](../clusters/create-cluster.md) a cluster in the Container Management module. +- Create an [inspection configuration](config.md). +- The selected cluster is in the __Running__ state and the insight component has been [installed in the cluster](../../../insight/quickstart/install/install-agent.md). + +## Steps + +When performing an inspection, you can choose to inspect multiple clusters in batches or perform a separate inspection for a specific cluster. + +=== "Batch Inspection" + + 1. Click __Cluster Inspection__ in the top-level navigation bar of the Container Management module, then click __Inspection__ on the right side of the page. + + ![start](../images/inspection-start.png) + + 2. Select the clusters you want to inspect, then click __OK__ at the bottom of the page. + + - If you choose to inspect multiple clusters at the same time, the system will perform inspections based on different inspection configurations for each cluster. + - If no inspection configuration is set for a cluster, the system will use the default configuration. + + ![start](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/kpanda/images/inspect05.png) + +=== "Individual Inspection" + + 1. Go to the Cluster Inspection page. + 2. Click the more options button ( __┇__ ) on the right of the corresponding inspection configuration, then select __Inspection__ from the popup menu. + + ![basic](../images/inspection-start-alone.png) diff --git a/docs/en/docs/kpanda/user-guide/inspect/report.md b/docs/en/docs/kpanda/user-guide/inspect/report.md new file mode 100644 index 0000000..49dc443 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/inspect/report.md @@ -0,0 +1,32 @@ +--- +hide: + - toc +--- + +# Check Inspection Reports + +After the [inspection execution](inspect.md) is completed, you can view the inspection records and detailed inspection reports. + +## Prerequisites + +- [Create an inspection configuration](config.md). +- Perform at least one inspection [execution](inspect.md). + +## Steps + +1. Go to the Cluster Inspection page and click the name of the target inspection cluster. + + ![start](../images/inspection-report-01.png) + +2. Click the name of the inspection record you want to view. + + - Each inspection execution generates an inspection record. + - When the number of inspection records exceeds the maximum retention specified in the [inspection configuration](config.md), the earliest record will be deleted starting from the execution time. + + ![start](../images/inspection-report-02.png) + +3. View the detailed information of the inspection, which may include an overview of cluster resources and the running status of system components. + + You can download the inspection report or delete the inspection report from the top right corner of the page. + + ![start](../images/inspection-report-03.png) diff --git a/docs/en/docs/kpanda/user-guide/namespaces/createns.md b/docs/en/docs/kpanda/user-guide/namespaces/createns.md new file mode 100644 index 0000000..558b9b3 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/namespaces/createns.md @@ -0,0 +1,57 @@ +# Namespaces + +Namespaces are an abstraction used in Kubernetes for resource isolation. A cluster can contain multiple namespaces with different names, and the resources in each namespace are isolated from each other. For a detailed introduction to namespaces, refer to [Namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/). + +This page will introduce the related operations of the namespace. + +## Create a namespace + +Supports easy creation of namespaces through forms, and quick creation of namespaces by writing or importing YAML files. + +!!! note + + - Before creating a namespace, you need to [Integrate a Kubernetes cluster](../clusters/integrate-cluster.md) or [Create a Kubernetes cluster](../clusters/create-cluster.md) in the container management module. + - The default namespace __default__ is usually automatically generated after cluster initialization. But for production clusters, for ease of management, it is recommended to create other namespaces instead of using the __default__ namespace directly. + +### Create with form + +1. On the cluster list page, click the name of the target cluster. + + ![Cluster Details](../images/crd01.png) + +2. Click __Namespace__ in the left navigation bar, then click the __Create__ button on the right side of the page. + + ![Click to Create](../images/ns01.png) + +3. Fill in the name of the namespace, configure the workspace and labels (optional), and then click __OK__. + + !!! info + + - After binding a namespace to a workspace, the resources of that namespace will be shared with the bound workspace. For a detailed explanation of workspaces, refer to [Workspaces and Hierarchies](../../../ghippo/user-guide/workspace/workspace.md). + + - After the namespace is created, you can still bind/unbind the workspace. + + ![Fill the Form](../images/ns02.png) + +4. Click __OK__ to complete the creation of the namespace. On the right side of the namespace list, click __┇__ to select update, bind/unbind workspace, quota management, delete, and more from the pop-up menu. + + ![More Operations](../images/ns03.png) + + +### Create from YAML + +1. On the __Cluster List__ page, click the name of the target cluster. + + ![Cluster Details](../images/crd01.png) + +2. Click __Namespace__ in the left navigation bar, then click the __YAML Create__ button on the right side of the page. + + ![Click to Create](../images/ns00.png) + +3. Enter or paste the prepared YAML content, or directly import an existing YAML file locally. + + > After entering the YAML content, click __Download__ to save the YAML file locally. + + ![Click to Create](../images/ns04.png) + +4. Finally, click __OK__ in the lower right corner of the pop-up box. diff --git a/docs/en/docs/kpanda/user-guide/namespaces/exclusive.md b/docs/en/docs/kpanda/user-guide/namespaces/exclusive.md new file mode 100644 index 0000000..5a362ab --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/namespaces/exclusive.md @@ -0,0 +1,208 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Namespace Exclusive Nodes + +Namespace exclusive nodes in a Kubernetes cluster allow a specific namespace to have exclusive access to one or more node's CPU, memory, and other resources through taints and tolerations. Once exclusive nodes are configured for a specific namespace, applications and services from other namespaces cannot run on the exclusive nodes. Using exclusive nodes allows important applications to have exclusive access to some computing resources, achieving physical isolation from other applications. + +!!! note + + Applications and services running on a node before it is set to be an exclusive node will not be affected and will continue to run normally on that node. Only when these Pods are deleted or rebuilt will they be scheduled to other non-exclusive nodes. + +## Preparation + +Check whether the kube-apiserver of the current cluster has enabled the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers. + +The use of namespace exclusive nodes requires users to enable the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers on the kube-apiserver. For more information about admission controllers, refer to [Kubernetes Admission Controllers Reference](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/). + +You can go to any Master node in the current cluster to check whether these two features are enabled in the __kube-apiserver.yaml__ file, or you can execute the following command on the Master node for a quick check: + +```bash +[root@g-master1 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep enable-admission-plugins + +# The expected output is as follows: +- --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction +``` + +## Enable Namespace Exclusive Nodes on Global Cluster + +Since the Global cluster runs platform basic components such as kpanda, ghippo, and insight, enabling namespace exclusive nodes on Global may cause system components to not be scheduled to the exclusive nodes when they restart, affecting the overall high availability of the system. Therefore, **we generally do not recommend users to enable the namespace exclusive node feature on the Global cluster**. + +If you do need to enable namespace exclusive nodes on the Global cluster, please follow the steps below: + +1. Enable the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers for the kube-apiserver of the Global cluster + + !!! note + + If the cluster has already enabled the above two admission controllers, please skip this step and go directly to configure system component tolerations. + + Go to any Master node in the current cluster to modify the __kube-apiserver.yaml__ configuration file, or execute the following command on the Master node for configuration: + + ```bash + [root@g-master1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml + + # The expected output is as follows: + apiVersion: v1 + kind: Pod + metadata: + ...... + spec: + containers: + - command: + - kube-apiserver + ...... + - --default-not-ready-toleration-seconds=300 + - --default-unreachable-toleration-seconds=300 + - --enable-admission-plugins=NodeRestriction #List of enabled admission controllers + - --enable-aggregator-routing=False + - --enable-bootstrap-token-auth=true + - --endpoint-reconciler-type=lease + - --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.crt + ...... + ``` + + Find the __--enable-admission-plugins__ parameter and add the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers (separated by commas). Refer to the following: + + ```bash + # Add __ ,PodNodeSelector,PodTolerationRestriction__ + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +2. Add toleration annotations to the namespace where the platform components are located + + After enabling the admission controllers, you need to add toleration annotations to the namespace where the platform components are located to ensure the high availability of the platform components. + + The system component namespaces for AI platform are as follows: + + | Namespace | System Components Included | + | ------------------- | ------------------------------------------------------------ | + | kpanda-system | kpanda | + | hwameiStor-system | hwameiStor | + | istio-system | istio | + | metallb-system | metallb | + | cert-manager-system | cert-manager | + | contour-system | contour | + | kubean-system | kubean | + | ghippo-system | ghippo | + | kcoral-system | kcoral | + | kcollie-system | kcollie | + | insight-system | insight, insight-agent: | + | ipavo-system | ipavo | + | kairship-system | kairship | + | karmada-system | karmada | + | amamba-system | amamba, jenkins | + | skoala-system | skoala | + | mspider-system | mspider | + | mcamel-system | mcamel-rabbitmq, mcamel-elasticsearch, mcamel-mysql, mcamel-redis, mcamel-kafka, mcamel-minio, mcamel-postgresql | + | spidernet-system | spidernet | + | kangaroo-system | kangaroo | + | gmagpie-system | gmagpie | + | dowl-system | dowl | + + Check whether there are the above namespaces in the current cluster, execute the following command, and add the annotation: `scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": "NoSchedule", "key": "ExclusiveNamespace"}]'` for each namespace. + + ```bash + kubectl annotate ns scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]' + ``` + Please make sure to replace `` with the name of the platform namespace you want to add the annotation to. + +3. Use the interface to set exclusive nodes for the namespace + + After confirming that the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers on the cluster API server have been enabled, please follow the steps below to use the AI platform UI management interface to set exclusive nodes for the namespace. + + 1. Click the cluster name in the cluster list page, then click __Namespace__ in the left navigation bar. + + ![Namespace](../../images/exclusive01.png) + + 2. Click the namespace name, then click the __Exclusive Node__ tab, and click __Add Node__ on the bottom right. + + ![Add Node](../../images/exclusive02.png) + + 3. Select which nodes you want to be exclusive to this namespace on the left side of the page. On the right side, you can clear or delete a selected node. Finally, click __OK__ at the bottom. + + ![Confirm](../../images/exclusive03.png) + + 4. You can view the current exclusive nodes for this namespace in the list. You can choose to __Stop Exclusivity__ on the right side of the node. + + > After cancelling exclusivity, Pods from other namespaces can also be scheduled to this node. + + ![Cancel Exclusivity](../../images/exclusive04.png) + +## Enable Namespace Exclusive Nodes on Non-Global Clusters + +To enable namespace exclusive nodes on non-Global clusters, please follow the steps below: + +1. Enable the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers for the kube-apiserver of the current cluster + + !!! note + + If the cluster has already enabled the above two admission controllers, please skip this step and go directly to using the interface to set exclusive nodes for the namespace. + + Go to any Master node in the current cluster to modify the __kube-apiserver.yaml__ configuration file, or execute the following command on the Master node for configuration: + + ```bash + [root@g-master1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml + + # The expected output is as follows: + apiVersion: v1 + kind: Pod + metadata: + ...... + spec: + containers: + - command: + - kube-apiserver + ...... + - --default-not-ready-toleration-seconds=300 + - --default-unreachable-toleration-seconds=300 + - --enable-admission-plugins=NodeRestriction #List of enabled admission controllers + - --enable-aggregator-routing=False + - --enable-bootstrap-token-auth=true + - --endpoint-reconciler-type=lease + - --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.crt + ...... + ``` + + Find the __--enable-admission-plugins__ parameter and add the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers (separated by commas). Refer to the following: + + ```bash + # Add __ ,PodNodeSelector,PodTolerationRestriction__ + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +2. Use the interface to set exclusive nodes for the namespace + + After confirming that the __PodNodeSelector__ and __PodTolerationRestriction__ admission controllers on the cluster API server have been enabled, please follow the steps below to use the AI platform UI management interface to set exclusive nodes for the namespace. + + 1. Click the cluster name in the cluster list page, then click __Namespace__ in the left navigation bar. + + ![Namespace](../../images/exclusive05.png) + + 2. Click the namespace name, then click the __Exclusive Node__ tab, and click __Add Node__ on the bottom right. + + ![Add Node](../../images/exclusive02.png) + + 3. Select which nodes you want to be exclusive to this namespace on the left side of the page. On the right side, you can clear or delete a selected node. Finally, click __OK__ at the bottom. + + ![Confirm](../../images/exclusive07.png) + + 4. You can view the current exclusive nodes for this namespace in the list. You can choose to __Stop Exclusivity__ on the right side of the node. + + > After cancelling exclusivity, Pods from other namespaces can also be scheduled to this node. + + ![Cancel Exclusivity](../../images/exclusive08.png) + +3. Add toleration annotations to the namespace where the components that need high availability are located (optional) + + Execute the following command to add the annotation: `scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]'` to the namespace where the components that need high availability are located. + + ```bash + kubectl annotate ns scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]' + ``` + + Please make sure to replace `` with the name of the platform namespace you want to add the annotation to. diff --git a/docs/en/docs/kpanda/user-guide/namespaces/podsecurity.md b/docs/en/docs/kpanda/user-guide/namespaces/podsecurity.md new file mode 100644 index 0000000..39569ab --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/namespaces/podsecurity.md @@ -0,0 +1,54 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Pod Security Policy + +Pod security policies in a Kubernetes cluster allow you to control the behavior of Pods in various aspects of security by configuring different levels and modes for specific namespaces. Only Pods that meet certain conditions will be accepted by the system. It sets three levels and three modes, allowing users to choose the most suitable scheme to set restriction policies according to their needs. + +!!! note + + Only one security policy can be configured for one security mode. Please be careful when configuring the enforce security mode for a namespace, as violations will prevent Pods from being created. + +This section will introduce how to configure Pod security policies for namespaces through the container management interface. + +## Prerequisites + +- The container management module has [integrated a Kubernetes cluster](../clusters/integrate-cluster.md) or [created a Kubernetes cluster](../clusters/create-cluster.md). The cluster version needs to be v1.22 or above, and you should be able to access the cluster's UI interface. + +- A [namespace has been created](../namespaces/createns.md), a [user has been created](../../../ghippo/user-guide/access-control/user.md), and the user has been granted [NS Admin](../permissions/permission-brief.md) or higher permissions. For details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +## Configure Pod Security Policies for Namespace + +1. Select the namespace for which you want to configure Pod security policies and go to the details page. Click __Configure Policy__ on the __Pod Security Policy__ page to go to the configuration page. + + ![Configure Policy List](../images/ps01.png) + +2. Click __Add Policy__ on the configuration page, and a policy will appear, including security level and security mode. The following is a detailed introduction to the security level and security policy. + + | Security Level | Description | + | ---------- | ------------------------------------------------------------ | + | Privileged | An unrestricted policy that provides the maximum possible range of permissions. This policy allows known privilege elevations. | + | Baseline | The least restrictive policy that prohibits known privilege elevations. Allows the use of default (minimum specified) Pod configurations. | + | Restricted | A highly restrictive policy that follows current best practices for protecting Pods. | + + | Security Mode | Description | + | -------- | ------------------------------------------------------------ | + | Audit | Violations of the specified policy will add new audit events in the audit log, and the Pod can be created. | + | Warn | Violations of the specified policy will return user-visible warning information, and the Pod can be created. | + | Enforce | Violations of the specified policy will prevent the Pod from being created. | + + ![Add Policy](../images/ps02.png) + +3. Different security levels correspond to different check items. If you don't know how to configure your namespace, you can __Policy ConfigMap Explanation__ at the top right corner of the page to view detailed information. + + ![ConfigMap Explanation01](../images/ps03.png) + +4. Click Confirm. If the creation is successful, the security policy you configured will appear on the page. + + ![Creation Success](../images/ps04.png) + +5. Click __┇__ to edit or delete the security policy you configured. + + ![Operation](../images/ps05.png) diff --git a/docs/en/docs/kpanda/user-guide/network/create-ingress.md b/docs/en/docs/kpanda/user-guide/network/create-ingress.md new file mode 100644 index 0000000..803e2c7 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/network/create-ingress.md @@ -0,0 +1,75 @@ +--- +MTPE: windsonsea +Date: 2024-10-15 +--- + +# Create an Ingress + +In a Kubernetes cluster, [Ingress](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ingress-v1beta1-networking-k8s-io) exposes services from outside the cluster to inside the cluster HTTP and HTTPS ingress. +Traffic ingress is controlled by rules defined on the Ingress resource. Here's an example of a simple Ingress that sends all traffic to the same Service: + +![ingress-diagram](https://docs.daocloud.io/daocloud-docs-images/docs/kpanda/images/ingress.svg) + +Ingress is an API object that manages external access to services in the cluster, and the typical access method is HTTP. Ingress can provide load balancing, SSL termination, and name-based virtual hosting. + +## Prerequisites + +- Container management module [connected to Kubernetes cluster](../clusters/integrate-cluster.md) or [created Kubernetes](../clusters/create-cluster.md), and can access the cluster UI interface. +- Completed a [namespace creation](../namespaces/createns.md), [user creation](../../../ghippo/user-guide/access-control/user.md), and authorize the user as [NS Editor](../permissions/permission-brief.md#ns-editor) role, for details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). +- Completed [Create Ingress Instance](../../../network/modules/ingress-nginx/install.md), [Deploy Application Workload](../workloads/create-deployment.md), and have [created the corresponding Service](create-services.md) +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create ingress + +1. After successfully logging in as the __NS Editor__ user, click __Clusters__ in the upper left corner to enter the __Clusters__ page. In the list of clusters, click a cluster name. + + ![Clusters](../../images/ingress01.png) + +2. In the left navigation bar, click __Container Network__ -> __Ingress__ to enter the service list, and click the __Create Ingress__ button in the upper right corner. + + ![Ingress](../../images/ingress02.png) + + !!! note + + It is also possible to __Create from YAML__ . + +3. Open __Create Ingress__ page to configure. There are two protocol types to choose from, refer to the following two parameter tables for configuration. + +### Create HTTP protocol ingress + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Ingress name | [Type] Required
[Meaning] Enter the name of the new ingress.
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter, lowercase English letters or numbers. | Ing-01 | +| Namespace | [Type] Required
[Meaning] Select the namespace where the new service is located. For more information about namespaces, refer to [Namespace Overview](../namespaces/createns.md).
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | default | +| Protocol | [Type] Required
[Meaning] Refers to the protocol that authorizes inbound access to the cluster service, and supports HTTP (no identity authentication required) or HTTPS (identity authentication needs to be configured) protocol. Here select the ingress of HTTP protocol. | HTTP | +| Domain Name | [Type] Required
[Meaning] Use the domain name to provide external access services. The default is the domain name of the cluster | testing.daocloud.io | +| LB Type | [Type] Required
[Meaning] The usage range of the Ingress instance. [Scope of use of Ingress](../../../network/modules/ingress-nginx/scope.md)
__Platform-level load balancer__ : In the same cluster, share the same Ingress instance, where all Pods can receive requests distributed by the load balancer.
__Tenant-level load balancer__ : Tenant load balancer, the Ingress instance belongs exclusively to the current namespace, or belongs to a certain workspace, and the set workspace includes the current namespace, and all Pods can receive it Requests distributed by this load balancer. | Platform Level Load Balancer | +| Ingress Class | [Type] Optional
[Meaning] Select the corresponding Ingress instance, and import traffic to the specified Ingress instance after selection. When it is None, the default DefaultClass is used. Please set the DefaultClass when creating an Ingress instance. For more information, refer to [Ingress Class](../../../network/modules/ingress-nginx/ingressclass.md)< br /> | Ngnix | +| Session persistence| [Type] Optional
[Meaning] Session persistence is divided into three types: __L4 source address hash__ , __Cookie Key__ , __L7 Header Name__ . Keep
__L4 Source Address Hash__ : : When enabled, the following tag is added to the Annotation by default: nginx.ingress.kubernetes.io/upstream-hash-by: "$binary_remote_addr"
__Cookie Key__ : When enabled, the connection from a specific client will be passed to the same Pod. After enabled, the following parameters are added to the Annotation by default:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes .io/affinity-mode: persistent
__L7 Header Name__ : After enabled, the following tag is added to the Annotation by default: nginx.ingress.kubernetes.io/upstream-hash-by: "$http_x_forwarded_for" | Close | +| Path Rewriting| [Type] Optional
[Meaning] __rewrite-target__ , in some cases, the URL exposed by the backend service is different from the path specified in the Ingress rule. If no URL rewriting configuration is performed, There will be an error when accessing. | close | +| Redirect | [Type] Optional
[Meaning] __permanent-redirect__ , permanent redirection, after entering the rewriting path, the access path will be redirected to the set address. | close | +| Traffic Distribution | [Type] Optional
[Meaning] After enabled and set, traffic distribution will be performed according to the set conditions.
__Based on weight__ : After setting the weight, add the following Annotation to the created Ingress: __nginx.ingress.kubernetes.io/canary-weight: "10"__
__Based on Cookie__ : set After the cookie rules, the traffic will be distributed according to the set cookie conditions
__Based on Header__ : After setting the header rules, the traffic will be distributed according to the set header conditions | Close | +| Labels | [Type] Optional
[Meaning] Add a label for the ingress
| - | +| Annotations | [Type] Optional
[Meaning] Add annotation for ingress
| - | + +### Create HTTPS protocol ingress + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Ingress name | [Type] Required
[Meaning] Enter the name of the new ingress.
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter, lowercase English letters or numbers. | Ing-01 | +| Namespace | [Type] Required
[Meaning] Select the namespace where the new service is located. For more information about namespaces, refer to [Namespace Overview](../namespaces/createns.md).
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | default | +| Protocol | [Type] Required
[Meaning] Refers to the protocol that authorizes inbound access to the cluster service, and supports HTTP (no identity authentication required) or HTTPS (identity authentication needs to be configured) protocol. Here select the ingress of HTTPS protocol. | HTTPS | +| Domain Name | [Type] Required
[Meaning] Use the domain name to provide external access services. The default is the domain name of the cluster | testing.daocloud.io | +| Secret | [Type] Required
[Meaning] Https TLS certificate, [Create Secret](../configmaps-secrets/create-secret.md). | | +| Forwarding policy | [Type] Optional
[Meaning] Specify the access policy of Ingress.
**Path**: Specifies the URL path for service access, the default is the root path/
**directoryTarget service**: Service name for ingress
**Target service port**: Port exposed by the service | | +| LB Type | [Type] Required
[Meaning] The usage range of the Ingress instance.
__Platform-level load balancer__ : In the same cluster, the same Ingress instance is shared, and all Pods can receive requests distributed by the load balancer.
__Tenant-level load balancer__ : Tenant load balancer, the Ingress instance belongs exclusively to the current namespace or to a certain workspace. This workspace contains the current namespace, and all Pods can receive the workload from this Balanced distribution of requests. | Platform Level Load Balancer | +| Ingress Class | [Type] Optional
[Meaning] Select the corresponding Ingress instance, and import traffic to the specified Ingress instance after selection. When it is None, the default DefaultClass is used. Please set the DefaultClass when creating an Ingress instance. For more information, refer to [Ingress Class](../../../network/modules/ingress-nginx/ingressclass.md)< br /> | None | +| Session persistence| [Type] Optional
[Meaning] Session persistence is divided into three types: __L4 source address hash__ , __Cookie Key__ , __L7 Header Name__ . Keep
__L4 Source Address Hash__ : : When enabled, the following tag is added to the Annotation by default: nginx.ingress.kubernetes.io/upstream-hash-by: "$binary_remote_addr"
__Cookie Key__ : When enabled, the connection from a specific client will be passed to the same Pod. After enabled, the following parameters are added to the Annotation by default:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes .io/affinity-mode: persistent
__L7 Header Name__ : After enabled, the following tag is added to the Annotation by default: nginx.ingress.kubernetes.io/upstream-hash-by: "$http_x_forwarded_for" | Close | +| Labels | [Type] Optional
[Meaning] Add a label for the ingress | | +| Annotations | [Type] Optional
[Meaning] Add annotation for ingress | | + +### Create ingress successfully + +After configuring all the parameters, click the __OK__ button to return to the ingress list automatically. On the right side of the list, click __┇__ to modify or delete the selected ingress. + +![Ingress List](../../images/ingress03.png) diff --git a/docs/en/docs/kpanda/user-guide/network/create-services.md b/docs/en/docs/kpanda/user-guide/network/create-services.md new file mode 100644 index 0000000..88edc46 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/network/create-services.md @@ -0,0 +1,82 @@ +# Create a Service + +In a Kubernetes cluster, each Pod has an internal independent IP address, but Pods in the workload may be created and deleted at any time, and directly using the Pod IP address cannot provide external services. + +This requires creating a service through which you get a fixed IP address, decoupling the front-end and back-end of the workload, and allowing external users to access the service. At the same time, the service also provides the Load Balancer feature, enabling users to access workloads from the public network. + +## Prerequisites + +- Container management module [connected to Kubernetes cluster](../clusters/integrate-cluster.md) or [created Kubernetes](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Completed a [namespace creation](../namespaces/createns.md), [user creation](../../../ghippo/user-guide/access-control/user.md), and authorize the user as [NS Editor](../permissions/permission-brief.md#ns-editor) role, for details, refer to [Namespace Authorization](../permissions/cluster-ns-auth.md). + +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create service + +1. After successfully logging in as the __NS Editor__ user, click __Clusters__ in the upper left corner to enter the __Clusters__ page. In the list of clusters, click a cluster name. + + + +2. In the left navigation bar, click __Container Network__ -> __Service__ to enter the service list, and click the __Create Service__ button in the upper right corner. + + + + !!! tip + + It is also possible to create a service via __YAML__ . + +3. Open the __Create Service__ page, select an access type, and refer to the following three parameter tables for configuration. + + + +### Create ClusterIP service + +Click __Intra-Cluster Access (ClusterIP)__ , which refers to exposing services through the internal IP of the cluster. The services selected for this option can only be accessed within the cluster. This is the default service type. Refer to the configuration parameters in the table below. + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Access type | [Type] Required
[Meaning] Specify the method of Pod service discovery, here select intra-cluster access (ClusterIP). | ClusterIP | +| Service Name | [Type] Required
[Meaning] Enter the name of the new service.
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | Svc-01 | +| Namespace | [Type] Required
[Meaning] Select the namespace where the new service is located. For more information about namespaces, refer to [Namespace Overview](../namespaces/createns.md).
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | default | +| Label selector | [Type] Required
[Meaning] Add a label, the Service selects a Pod according to the label, and click "Add" after filling. You can also refer to the label of an existing workload. Click __Reference workload label__ , select the workload in the pop-up window, and the system will use the selected workload label as the selector by default. | app:job01 | +| Port configuration| [Type] Required
[Meaning] To add a protocol port for a service, you need to select the port protocol type first. Currently, it supports TCP and UDP. For more information about the protocol, refer to [Protocol Overview](../../../dce/index.md).
**Port Name**: Enter the name of the custom port.
**Service port (port)**: The access port for Pod to provide external services.
**Container port (targetport)**: The container port that the workload actually monitors, used to expose services to the cluster. | | +| Session Persistence | [Type] Optional
[Meaning] When enabled, requests from the same client will be forwarded to the same Pod | Enabled | +| Maximum session hold time | [Type] Optional
[Meaning] After session hold is enabled, the maximum hold time is 30 seconds by default | 30 seconds | +| Annotation | [Type] Optional
[Meaning] Add annotation for service
| | + +### Create NodePort service + +Click __NodePort__ , which means exposing the service via IP and static port ( __NodePort__ ) on each node. The __NodePort__ service is routed to the automatically created __ClusterIP__ service. You can access a __NodePort__ service from outside the cluster by requesting __:__ . Refer to the configuration parameters in the table below. + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Access type | [Type] Required
[Meaning] Specify the method of Pod service discovery, here select node access (NodePort). | NodePort | +| Service Name | [Type] Required
[Meaning] Enter the name of the new service.
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | Svc-01 | +| Namespace | [Type] Required
[Meaning] Select the namespace where the new service is located. For more information about namespaces, refer to [Namespace Overview](../namespaces/createns.md).
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | default | +| Label selector | [Type] Required
[Meaning] Add a label, the Service selects a Pod according to the label, and click "Add" after filling. You can also refer to the label of an existing workload. Click __Reference workload label__ , select the workload in the pop-up window, and the system will use the selected workload label as the selector by default. | | +| Port configuration| [Type] Required
[Meaning] To add a protocol port for a service, you need to select the port protocol type first. Currently, it supports TCP and UDP. For more information about the protocol, refer to [Protocol Overview](../../../dce/index.md).
**Port Name**: Enter the name of the custom port.
**Service port (port)**: The access port for Pod to provide external services. *By default, the service port is set to the same value as the container port field for convenience. *
**Container port (targetport)**: The container port actually monitored by the workload.
**Node port (nodeport)**: The port of the node, which receives traffic from ClusterIP transmission. It is used as the entrance for external traffic access. | | +| Session Persistence| [Type] Optional
[Meaning] When enabled, requests from the same client will be forwarded to the same Pod
After enabled, __.spec.sessionAffinity__ of Service is __ClientIP__ , refer to for details : [Session Affinity for Service](https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity) | Enabled | +| Maximum session hold time| [Type] Optional
[Meaning] After session hold is enabled, the maximum hold time, the default timeout is 30 seconds
.spec.sessionAffinityConfig.clientIP.timeoutSeconds is set to 30 by default seconds | 30 seconds | +| Annotation | [Type] Optional
[Meaning] Add annotation for service
| | + +### Create LoadBalancer service + +Click __Load Balancer__ , which refers to using the cloud provider's load balancer to expose services to the outside. External load balancers can route traffic to automatically created __NodePort__ services and __ClusterIP__ services. Refer to the configuration parameters in the table below. + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Access type | [Type] Required
[Meaning] Specify the method of Pod service discovery, here select node access (NodePort). | NodePort | | +| Service Name | [Type] Required
[Meaning] Enter the name of the new service.
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | Svc-01 | | +| Namespace | [Type] Required
[Meaning] Select the namespace where the new service is located. For more information about namespaces, refer to [Namespace Overview](../namespaces/createns.md).
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | default | | +| External Traffic Policy | [Type] Required
[Meaning] Set external traffic policy.
**Cluster**: Traffic can be forwarded to Pods on all nodes in the cluster.
**Local**: Traffic is only sent to Pods on this node.
[Note] Please enter a string of 4 to 63 characters, which can contain lowercase English letters, numbers and dashes (-), and start with a lowercase English letter and end with a lowercase English letter or number. | | | +| Tag selector | [Type] Required
[Meaning] Add tag, Service Select the Pod according to the label, fill it out and click "Add". You can also refer to the label of an existing workload. Click __Reference workload label__ , select the workload in the pop-up window, and the system will use the selected workload label as the selector by default. | | | +| Load balancing type | [Type] Required
[Meaning] The type of load balancing used, currently supports MetalLB and others. | | | +| MetalLB IP Pool| [Type] Required
[Meaning] When the selected load balancing type is MetalLB, LoadBalancer Service will allocate IP addresses from this pool by default, and declare all IP addresses in this pool through APR, For details, refer to: [Install MetalLB](../../../network/modules/metallb/install.md) | | | +| Load balancing address| [Type] Required
[Meaning]
1. If you are using a public cloud CloudProvider, fill in the load balancing address provided by the cloud provider here;
2. If the above load balancing type is selected as MetalLB, the IP will be obtained from the above IP pool by default, if not filled, it will be obtained automatically. | | | +| Port configuration| [Type] Required
[Meaning] To add a protocol port for a service, you need to select the port protocol type first. Currently, it supports TCP and UDP. For more information about the protocol, refer to [Protocol Overview](../../../dce/index.md).
**Port Name**: Enter the name of the custom port.
**Service port (port)**: The access port for Pod to provide external services. By default, the service port is set to the same value as the container port field for convenience.
**Container port (targetport)**: The container port actually monitored by the workload.
**Node port (nodeport)**: The port of the node, which receives traffic from ClusterIP transmission. It is used as the entrance for external traffic access. | | | +| Annotation | [Type] Optional
[Meaning] Add annotation for service
| | | + +### Complete service creation + +After configuring all parameters, click the __OK__ button to return to the service list automatically. On the right side of the list, click __┇__ to modify or delete the selected service. diff --git a/docs/en/docs/kpanda/user-guide/network/network-policy.md b/docs/en/docs/kpanda/user-guide/network/network-policy.md new file mode 100644 index 0000000..78686cc --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/network/network-policy.md @@ -0,0 +1,70 @@ +# Network Policies + +Network policies in Kubernetes allow you to control network traffic at the IP address or port level (OSI layer 3 or layer 4). The container management module currently supports creating network policies based on Pods or namespaces, using label selectors to specify which traffic can enter or leave Pods with specific labels. + +For more details on network policies, refer to the official Kubernetes documentation on [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/). + +## Creating Network Policies + +Currently, there are two methods available for creating network policies: YAML and form-based creation. Each method has its advantages and disadvantages, catering to different user needs. + +YAML creation requires fewer steps and is more efficient, but it has a higher learning curve as it requires familiarity with configuring network policy YAML files. + +Form-based creation is more intuitive and straightforward. Users can simply fill in the corresponding values based on the prompts. However, this method involves more steps. + +### YAML Creation + +1. In the cluster list, click the name of the target cluster, then navigate to __Container Network__ -> __Network Policies__ -> __Create with YAML__ in the left navigation bar. + + +2. In the pop-up dialog, enter or paste the pre-prepared YAML file, then click __OK__ at the bottom of the dialog. + + +### Form-Based Creation + +1. In the cluster list, click the name of the target cluster, then navigate to __Container Network__ -> __Network Policies__ -> __Create Policy__ in the left navigation bar. + + +2. Fill in the basic information. + + The name and namespace cannot be changed after creation. + + +3. Fill in the policy configuration. + + The policy configuration includes ingress and egress policies. To establish a successful connection from a source Pod to a target Pod, both the egress policy of the source Pod and the ingress policy of the target Pod need to allow the connection. If either side does not allow the connection, the connection will fail. + + - Ingress Policy: Click __➕__ to begin configuring the policy. Multiple policies can be configured. The effects of multiple network policies are cumulative. Only when all network policies are satisfied simultaneously can a connection be successfully established. + + - Egress Policy + +## Viewing Network Policies + +1. In the cluster list, click the name of the target cluster, then navigate to __Container Network__ -> __Network Policies__ . Click the name of the network policy. + + +2. View the basic configuration, associated instances, ingress policies, and egress policies of the policy. + + +!!! info + + Under the "Associated Instances" tab, you can view instance monitoring, logs, container lists, YAML files, events, and more. + + +## Updating Network Policies + +There are two ways to update network policies. You can either update them through the form or by using a YAML file. + +- On the network policy list page, find the policy you want to update, and choose __Update__ in the action column on the right to update it via the form. Choose __Edit YAML__ to update it using a YAML file. + + +- Click the name of the network policy, then choose __Update__ in the top right corner of the policy details page to update it via the form. Choose __Edit YAML__ to update it using a YAML file. + +## Deleting Network Policies + +There are two ways to delete network policies. You can delete network policies either through the form or by using a YAML file. + +- On the network policy list page, find the policy you want to delete, and choose __Delete__ in the action column on the right to delete it via the form. Choose __Edit YAML__ to delete it using a YAML file. + + +- Click the name of the network policy, then choose __Delete__ in the top right corner of the policy details page to delete it via the form. Choose __Edit YAML__ to delete it using a YAML file. diff --git a/docs/en/docs/kpanda/user-guide/nodes/add-node.md b/docs/en/docs/kpanda/user-guide/nodes/add-node.md new file mode 100644 index 0000000..b9c9bf7 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/add-node.md @@ -0,0 +1,30 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Cluster Node Expansion + +As the number of business applications continues to grow, the resources of the cluster become increasingly tight. At this point, you can expand the cluster nodes based on kubean. After the expansion, applications can run on the newly added nodes, alleviating resource pressure. + +Only clusters [created through the container management module](../clusters/create-cluster.md) support node autoscaling. Clusters accessed from the outside do not support this operation. This article mainly introduces the expansion of **worker nodes** in the same architecture work cluster. If you need to add control nodes or heterogeneous work nodes to the cluster, refer to: [Expanding the control node of the work cluster](../../best-practice/add-master-node.md), [Adding heterogeneous nodes to the work cluster](../../best-practice/multi-arch.md), [Expanding the worker node of the global service cluster](../../best-practice/add-worker-node-on-global.md). + +1. On the __Clusters__ page, click the name of the target cluster. + + If the __Cluster Type__ contains the label __Integrated Cluster__, it means that the cluster does not support node autoscaling. + + ![Enter the cluster list page](../images/addnode01.png) + +2. Click __Nodes__ in the left navigation bar, and then click __Integrate Node__ in the upper right corner of the page. + + ![Integrate Node](../images/addnode02.png) + +3. Enter the host name and node IP and click __OK__. + + Click __➕ Add Worker Node__ to continue accessing more nodes. + + ![Node Check](../images/addnode03.png) + +!!! note + + Accessing the node takes about 20 minutes, please be patient. diff --git a/docs/en/docs/kpanda/user-guide/nodes/delete-node.md b/docs/en/docs/kpanda/user-guide/nodes/delete-node.md new file mode 100644 index 0000000..dce0f8e --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/delete-node.md @@ -0,0 +1,34 @@ +# Node Scales Down + +When the peak business period is over, in order to save resource costs, you can reduce the size of the cluster and unload redundant nodes, that is, node scaling. After a node is uninstalled, applications cannot continue to run on the node. + +## Prerequisites + +- The current operating user has the [`Cluster Admin`](../permissions/permission-brief.md) role authorization. +- Only through the container management module [created cluster](../clusters/create-cluster.md) can node autoscaling be supported, and the cluster accessed from the outside does not support this operation. +- Before uninstalling a node, you need to [pause scheduling the node](schedule.md), and expel the applications on the node to other nodes. +- Eviction method: log in to the controller node, and use the kubectl drain command to evict all Pods on the node. The safe eviction method allows the containers in the pod to terminate gracefully. + +## Precautions + +1. When cluster nodes scales down, they can only be uninstalled one by one, not in batches. + +2. If you need to uninstall cluster controller nodes, you need to ensure that the final number of controller nodes is an **odd number**. + +3. The **first controller** node cannot be offline when the cluster node scales down. If it is necessary to perform this operation, please contact the after-sales engineer. + +## Steps + +1. On the __Clusters__ page, click the name of the target cluster. + + If the __Cluster Type__ has the tag __Integrate Cluster__ , it means that the cluster does not support node autoscaling. + + ![Clusters](../images/addnode01.png) + +2. Click __Nodes__ on the left navigation bar, find the node to be uninstalled, click __┇__ and select __Remove__ . + + ![Remove Nodes](../images/deletenode01.png) + +3. Enter the node name, and click __Delete__ to confirm. + + ![Delete](../images/deletenode02.png) diff --git a/docs/en/docs/kpanda/user-guide/nodes/labels-annotations.md b/docs/en/docs/kpanda/user-guide/nodes/labels-annotations.md new file mode 100644 index 0000000..d896385 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/labels-annotations.md @@ -0,0 +1,29 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Labels and Annotations + +Labels are identifying key-value pairs added to Kubernetes objects such as Pods, nodes, and clusters, which can be combined with label selectors to find and filter Kubernetes objects that meet certain conditions. Each key must be unique for a given object. + +Annotations, like tags, are key/value pairs, but they do not have identification or filtering features. +Annotations can be used to add arbitrary metadata to nodes. +Annotation keys usually use the format __prefix(optional)/name(required)__ , for example __nfd.node.kubernetes.io/extended-resources__ . +If the prefix is ​​omitted, it means that the annotation key is private to the user. + +For more information about labels and annotations, refer to the official Kubernetes documentation [labels and selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) Or [Annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/). + +The steps to add/delete tags and annotations are as follows: + +1. On the __Clusters__ page, click the name of the target cluster. + + ![Clusters](../images/schedule01.png) + +2. Click __Nodes__ on the left navigation bar, click the __┇__ operation icon on the right side of the node, and click __Edit Labels__ or __Edit Annotations__ . + + ![暂停调度](../images/labels01.png) + +3. Click __➕ Add__ to add tags or annotations, click __X__ to delete tags or annotations, and finally click __OK__ . + + ![节点管理](../images/labels02.png) diff --git a/docs/en/docs/kpanda/user-guide/nodes/node-authentication.md b/docs/en/docs/kpanda/user-guide/nodes/node-authentication.md new file mode 100644 index 0000000..e5de285 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/node-authentication.md @@ -0,0 +1,68 @@ +# Node Authentication + +## Authenticate Nodes Using SSH Keys + +If you choose to authenticate the nodes of the cluster-to-be-created using SSH keys, you need to configure the public and private keys according to the following instructions. + +1. Run the following command on **any node within the management cluster of the cluster-to-be-created** to generate the public and private keys. + + ```shell + cd /root/.ssh + ssh-keygen -t rsa + ``` + +2. Run the __ls__ command to check if the keys have been successfully created in the management cluster. The correct output should be as follows: + + ```shell + ls + id_rsa id_rsa.pub known_hosts + ``` + + The file named __id_rsa__ is the private key, and the file named __id_rsa.pub__ is the public key. + +3. Run the following command to load the public key file __id_rsa.pub__ onto all the nodes of the cluster-to-be-created. + + ```shell + ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.0.0 + ``` + + Replace the user account and node IP in the above command with the username and IP of the nodes in the cluster-to-be-created. **The same operation needs to be performed on every node in the cluster-to-be-created**. + +4. Run the following command to view the private key file __id_rsa__ created in step 1. + + ```shell + cat /root/.ssh/id_rsa + ``` + + The output should be as follows: + + ```bash + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEA3UvyKINzY5BFuemQ+uJ6q+GqgfvnWwNC8HzZhpcMSjJy26MM + UtBEBJxy8fMi57XcjYxPibXW/wnd+32ICCycqCwByUmuXeCC1cjlCQDqjcAvXae7 + Y54IXGF7wm2IsMNwf0kjFEXjuS48FLDA0mGRaN3BG+Up5geXcHckg3K5LD8kXFFx + dEmSIjdyw55NaUitmEdHzN7cIdfi6Z56jcV8dcFBgWKUx+ebiyPmZBkXToz6GnMF + rswzzZCl+G6Jb2xTGy7g7ozb4BoZd1IpSD5EhDanRrESVE0C5YuJ5zUAC0CvVd1l + v67AK8Ko6MXToHp01/bcsvlM6cqgwUFXZKVeOwIDAQABAoIBAQCO36GQlo3BEjxy + M2HvGJmqrx+unDxafliRe4nVY2AD515Qf4xNSzke4QM1QoyenMOwf446krQkJPK0 + k+9nl6Xszby5gGCbK4BNFk8I6RaGPjZWeRx6zGUJf8avWJiPxx6yjz2esSC9RiR0 + F0nmiiefVMyAfgv2/5++dK2WUFNNRKLgSRRpP5bRaD5wMzzxtSSXrUon6217HO8p + 3RoWsI51MbVzhdVgpHUNABcoa0rpr9svT6XLKZxY8mxpKFYjM0Wv2JIDABg3kBvh + QbJ7kStCO3naZjKMU9UuSqVJs06cflGYw7Or8/tABR3LErNQKPjkhAQqt0DXw7Iw + 3tKdTAJBAoGBAP687U7JAOqQkcphek2E/A/sbO/d37ix7Z3vNOy065STrA+ZWMZn + pZ6Ui1B/oJpoZssnfvIoz9sn559X0j67TljFALFd2ZGS0Fqh9KVCqDvfk+Vst1dq + +3r/yZdTOyswoccxkJiC/GDwZGK0amJWqvob39JCZhDAKIGLbGMmjdAHAoGBAN5k + m1WGnni1nZ+3dryIwgB6z1hWcnLTamzSET6KhSuo946ET0IRG9xtlheCx6dqICbr + Vk1Y4NtRZjK/p/YGx59rDWf7E3I8ZMgR7mjieOcUZ4lUlA4l7ZIlW/2WZHW+nUXO + Ti20fqJ8qSp4BUvOvuth1pz2GLUHe2/Fxjf7HIstAoGBAPHpPr9r+TfIlPsJeRj2 + 6lzA3G8qWFRQfGRYjv0fjv0pA+RIb1rzgP/I90g5+63G6Z+R4WdcxI/OJJNY1iuG + uw9n/pFxm7U4JC990BPE6nj5iLz+clpNGYckNDBF9VG9vFSrSDLdaYkxoVNvG/xJ + a9Na90H4lm7f3VewrPy310KvAoGAZr+mwNoEh5Kpc6xo8Gxi7aPP/mlaUVD6X7Ki + gvmu02AqmC7rC4QqEiqTaONkaSXwGusqIWxJ3yp5hELmUBYLzszAEeV/s4zRp1oZ + g133LBRSTbHFAdBmNdqK6Nu+KGRb92980UMOKvZbliKDl+W6cbfvVu+gtKrzTc3b + aevb4TUCgYEAnJAxyVYDP1nJf7bjBSHXQu1E/DMwbtrqw7dylRJ8cAzI7IxfSCez + 7BYWq41PqVd9/zrb3Pbh2phiVzKe783igAIMqummcjo/kZyCwFsYBzK77max1jF5 + aPQsLbRS2aDz8kIH6jHPZ/R+15EROmdtLmA7vIJZGerWWQR0dUU+XXA= + ``` + +Copy the content of the private key and paste it into the interface's key input field. diff --git a/docs/en/docs/kpanda/user-guide/nodes/node-check.md b/docs/en/docs/kpanda/user-guide/nodes/node-check.md new file mode 100644 index 0000000..54cdd24 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/node-check.md @@ -0,0 +1,38 @@ +# Create a cluster node availability check + +When creating a cluster or adding nodes to an existing cluster, refer to the table below to check the node configuration to avoid cluster creation or expansion failure due to wrong node configuration. + +| Check Item | Description | +| ---------- | ----------- | +| OS | Refer to [Supported Architectures and Operating Systems](#supported-architectures-and-operating-systems) | +| SELinux | Off | +| Firewall | Off | +| Architecture Consistency | Consistent CPU architecture between nodes (such as ARM or x86) | +| Host Time | All hosts are out of sync within 10 seconds. | +| Network Connectivity | The node and its SSH port can be accessed normally by the platform. | +| CPU | Available CPU resources are greater than 4 Cores | +| Memory | Available memory resources are greater than 8 GB | + +## Supported architectures and operating systems + +| Architecture | Operating System | Remarks | +| ---- | ------------------------ | ---- | +| ARM | Kylin Linux Advanced Server release V10 (Sword) SP2 | Recommended | +| ARM | UOS Linux | | +| ARM | openEuler | | +| x86 | CentOS 7.x | Recommended | +| x86 | Redhat 7.x | Recommended | +| x86 | Redhat 8.x | Recommended | +| x86 | Flatcar Container Linux by Kinvolk | | +| x86 | Debian Bullseye, Buster, Jessie, Stretch | | +| x86 | Ubuntu 16.04, 18.04, 20.04, 22.04 | | +| x86 | Fedora 35, 36 | | +| x86 | Fedora CoreOS | | +| x86 | openSUSE Leap 15.x/Tumbleweed | | +| x86 | Oracle Linux 7, 8, 9 | | +| x86 | Alma Linux 8, 9 | | +| x86 | Rocky Linux 8, 9 | | +| x86 | Amazon Linux 2 | | +| x86 | Kylin Linux Advanced Server release V10 (Sword) - SP2 Haiguang | | +| x86 | UOS Linux | | +| x86 | openEuler | | diff --git a/docs/en/docs/kpanda/user-guide/nodes/node-details.md b/docs/en/docs/kpanda/user-guide/nodes/node-details.md new file mode 100644 index 0000000..e499d75 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/node-details.md @@ -0,0 +1,24 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Node Details + +After accessing or creating a cluster, you can view the information of each node in the cluster, including node status, labels, resource usage, Pod, monitoring information, etc. + +1. On the __Clusters__ page, click the name of the target cluster. + + ![Clusters](../images/schedule01.png) + +2. Click __Nodes__ on the left navigation bar to view the node status, role, label, CPU/memory usage, IP address, and creation time. + + ![Nodes](../images/node-details01.png) + +3. Click the node name to enter the node details page to view more information, including overview information, pod information, label annotation information, event list, status, etc. + + ![Node Details](../images/node-details02.png) + + In addition, you can also view the node's YAML file, monitoring information, labels and annotations, etc. + + ![Edit](../images/node-details03.png) diff --git a/docs/en/docs/kpanda/user-guide/nodes/schedule.md b/docs/en/docs/kpanda/user-guide/nodes/schedule.md new file mode 100644 index 0000000..d79fb8d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/schedule.md @@ -0,0 +1,24 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Node Scheduling + +Supports suspending or resuming scheduling of nodes. Pausing scheduling means stopping the scheduling of Pods to the node. Resuming scheduling means that Pods can be scheduled to that node. + +1. On the __Clusters__ page, click the name of the target cluster. + + ![Clusters](../images/taint01.png) + +2. Click __Nodes__ on the left navigation bar, click the __┇__ operation icon on the right side of the node, and click the __Cordon__ button to suspend scheduling the node. + + ![Cordon](../images/schedule01.png) + +3. Click the __┇__ operation icon on the right side of the node, and click the __Uncordon__ button to resume scheduling the node. + + ![Uncordon](../images/schedule02.png) + +The node scheduling status may be delayed due to network conditions. Click the __refresh icon__ on the right side of the search box to refresh the node scheduling status. + +![Refresh](../images/schedule03.png) diff --git a/docs/en/docs/kpanda/user-guide/nodes/taints.md b/docs/en/docs/kpanda/user-guide/nodes/taints.md new file mode 100644 index 0000000..745ccd0 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/nodes/taints.md @@ -0,0 +1,51 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Node Taints + +Taint can make a node exclude a certain type of Pod and prevent Pod from being scheduled on the node. +One or more taints can be applied to each node, and Pods that cannot tolerate these taints will not be scheduled on that node. + +## Precautions + +1. The current operating user should have [NS Editor](../permissions/permission-brief.md) role authorization or other higher permissions. +2. After adding a taint to a node, only Pods that can tolerate the taint can be scheduled to the node. + +## Steps + +1. Find the target cluster on the __Clusters__ page, and click the cluster name to enter the Cluster page. + + ![Clusters](../images/taint01.png) + +2. In the left navigation bar, click __Nodes__ , find the node that needs to modify the taint, click the __┇__ operation icon on the right and click the __Edit Taints__ button. + + ![Edit Taints](../images/taint02.png) + +3. Enter the key value information of the taint in the pop-up box, select the taint effect, and click __OK__ . + + Click __➕ Add__ to add multiple taints to the node, and click __X__ on the right side of the taint effect to delete the taint. + + Currently supports three taint effects: + + - `NoExecute`: This affects pods that are already running on the node as follows: + + - Pods that do not tolerate the taint are evicted immediately + - Pods that tolerate the taint without specifying `tolerationSeconds` in + their toleration specification remain bound forever + - Pods that tolerate the taint with a specified `tolerationSeconds` remain + bound for the specified amount of time. After that time elapses, the node + lifecycle controller evicts the Pods from the node. + + - `NoSchedule`: No new Pods will be scheduled on the tainted node unless they have a matching + toleration. Pods currently running on the node are **not** evicted. + + - `PreferNoSchedule`: This is a "preference" or "soft" version of `NoSchedule`. + The control plane will *try* to avoid placing a Pod that does not tolerate + the taint on the node, but it is not guaranteed, so this taint is not recommended to use in a production environment. + + ![Config](../images/taint03.png) + +For more details about taints, refer to the Kubernetes documentation +[Taints and Tolerance](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/). diff --git a/docs/en/docs/kpanda/user-guide/olm/import-miniooperator.md b/docs/en/docs/kpanda/user-guide/olm/import-miniooperator.md new file mode 100644 index 0000000..339624f --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/olm/import-miniooperator.md @@ -0,0 +1,153 @@ +# Importing MinIo Operator Offline + +This guide explains how to import the MinIo Operator offline in an environment without internet access. + +## Prerequisites + +- The current cluster is connected to the container management and the Global cluster has installed the __kolm__ component (search for helm templates for kolm). +- The current cluster has the __olm__ component installed with a version of 0.2.4 or higher (search for helm templates for olm). +- Ability to execute Docker commands. +- Prepare a container registry. + +## Steps + +1. Set the environment variables in the execution environment and use them in the subsequent steps by running the following command: + + ```bash + export OPM_IMG=10.5.14.200/quay.m.daocloud.io/operator-framework/opm:v1.29.0 + export BUNDLE_IMG=10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3 + ``` + + How to get the above image addresses: + + Go to __Container Management__ -> Select the current cluster -> __Helm Applications__ -> View the __olm__ component -> __Plugin Settings__ , and find the images needed for the opm, minio, minio bundle, and minio operator in the subsequent steps. + + + ```bash + Using the screenshot as an example, the four image addresses are as follows: + + # opm image + 10.5.14.200/quay.m.daocloud.io/operator-framework/opm:v1.29.0 + + # minio image + 10.5.14.200/quay.m.daocloud.io/minio/minio:RELEASE.2023-03-24T21-41-23Z + + # minio bundle image + 10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3 + + # minio operator image + 10.5.14.200/quay.m.daocloud.io/minio/operator:v5.0.3 + ``` + +2. Run the opm command to get the operators included in the offline bundle image. + + ```bash + # Create the operator directory + $ mkdir minio-operator && cd minio-operator + + # Get the operator yaml + $ docker run --user root -v $PWD/minio-operator:/minio-operator ${OPM_IMG} alpha bundle unpack --skip-tls-verify -v -d ${BUNDLE_IMG} -o ./minio-operator + + # Expected result + . + └── minio-operator + ├── manifests + │ ├── console-env_v1_configmap.yaml + │ ├── console-sa-secret_v1_secret.yaml + │ ├── console_v1_service.yaml + │ ├── minio-operator.clusterserviceversion.yaml + │ ├── minio.min.io_tenants.yaml + │ ├── operator_v1_service.yaml + │ ├── sts.min.io_policybindings.yaml + │ └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 3 directories, 9 files + ``` + +3. Replace all image addresses in the __minio-operator/manifests/minio-operator.clusterserviceversion.yaml__ file with the image addresses from the offline container registry. + + Before replacement: + + + After replacement: + + +4. Generate a Dockerfile for building the bundle image. + + ```bash + $ docker run --user root -v $PWD:/minio-operator -w /minio-operator ${OPM_IMG} alpha bundle generate --channels stable,beta -d /minio-operator/minio-operator/manifests -e stable -p minio-operator   + + # Expected result + . + ├── bundle.Dockerfile + └── minio-operator + ├── manifests + │ ├── console-env_v1_configmap.yaml + │ ├── console-sa-secret_v1_secret.yaml + │ ├── console_v1_service.yaml + │ ├── minio-operator.clusterserviceversion.yaml + │ ├── minio.min.io_tenants.yaml + │ ├── operator_v1_service.yaml + │ ├── sts.min.io_policybindings.yaml + │ └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 3 directories, 10 files + ``` + +5. Build the bundle image and push it to the offline registry. + + ```bash + # Set the new bundle image + export OFFLINE_BUNDLE_IMG=10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3-offline + + $ docker build . -f bundle.Dockerfile -t ${OFFLINE_BUNDLE_IMG}   + + $ docker push ${OFFLINE_BUNDLE_IMG} + ``` + +6. Generate a Dockerfile for building the catalog image. + + ```bash + $ docker run --user root -v $PWD:/minio-operator -w /minio-operator ${OPM_IMG} index add --bundles ${OFFLINE_BUNDLE_IMG} --generate --binary-image ${OPM_IMG} --skip-tls-verify + + # Expected result + . + ├── bundle.Dockerfile + ├── database + │ └── index.db + ├── index.Dockerfile + └── minio-operator + ├── manifests + │ ├── console-env_v1_configmap.yaml + │ ├── console-sa-secret_v1_secret.yaml + │ ├── console_v1_service.yaml + │ ├── minio.min.io_tenants.yaml + │ ├── minio-operator.clusterserviceversion.yaml + │ ├── operator_v1_service.yaml + │ ├── sts.min.io_policybindings.yaml + │ └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 4 directories, 12 files + ``` + +7. Build the catalog image. + + ```bash + # Set the new catalog image + export OFFLINE_CATALOG_IMG=10.5.14.200/release.daocloud.io/operator-framework/system-operator-index:v0.1.0-offline + + $ docker build . -f index.Dockerfile -t ${OFFLINE_CATALOG_IMG} + + $ docker push ${OFFLINE_CATALOG_IMG} + ``` + +8. Go to Container Management and update the built-in catsrc image for the helm application __olm__ (enter the catalog image specified in the construction of the catalog image, __${catalog-image}__ ). + +9. After the update is successful, the __minio-operator__ component will appear in the Operator Hub. + diff --git a/docs/en/docs/kpanda/user-guide/permissions/cluster-ns-auth.md b/docs/en/docs/kpanda/user-guide/permissions/cluster-ns-auth.md new file mode 100644 index 0000000..006c2c7 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/permissions/cluster-ns-auth.md @@ -0,0 +1,55 @@ +# Cluster and Namespace Authorization + +Container management implements authorization based on global authority management and global user/group management. If you need to grant users the highest authority for container management (can create, manage, and delete all clusters), refer to [What are Access Control](../../../ghippo/user-guide/access-control/iam.md). + +## Prerequisites + +Before authorizing users/groups, complete the following preparations: + +- The user/group to be authorized has been created in the global management, refer to [User](../../../ghippo/user-guide/access-control/user.md). + +- Only [ __Kpanda Owner__ ](../../../ghippo/user-guide/access-control/global.md) and [`Cluster Admin`](permission-brief.md) of the current cluster have Cluster authorization capability. For details, refer to [Permission Description](permission-brief.md). + +- only [ __Kpanda Owner__ ](../../../ghippo/user-guide/access-control/global.md), [`Cluster Admin`](permission-brief.md) for the current cluster, [`NS Admin`](permission-brief.md) of the current namespace has namespace authorization capability. + +## Cluster Authorization + +1. After the user logs in to the platform, click __Privilege Management__ under __Container Management__ on the left menu bar, which is located on the __Cluster Permissions__ tab by default. + + + +2. Click the __Add Authorization__ button. + + + +3. On the __Add Cluster Permission__ page, select the target cluster, the user/group to be authorized, and click __OK__ . + + Currently, the only cluster role supported is __Cluster Admin__ . For details about permissions, refer to [Permission Description](permission-brief.md). If you need to authorize multiple users/groups at the same time, you can click __Add User Permissions__ to add multiple times. + + + +4. Return to the cluster permission management page, and a message appears on the screen: __Cluster permission added successfully__ . + + + +## Namespace Authorization + +1. After the user logs in to the platform, click __Permissions__ under __Container Management__ on the left menu bar, and click the __Namespace Permissions__ tab. + + + +2. Click the __Add Authorization__ button. On the __Add Namespace Permission__ page, select the target cluster, target namespace, and user/group to be authorized, and click __OK__ . + + The currently supported namespace roles are NS Admin, NS Editor, and NS Viewer. For details about permissions, refer to [Permission Description](permission-brief.md). If you need to authorize multiple users/groups at the same time, you can click __Add User Permission__ to add multiple times. Click __OK__ to complete the permission authorization. + + + +3. Return to the namespace permission management page, and a message appears on the screen: __Cluster permission added successfully__ . + + + + !!! tip + + If you need to delete or edit permissions later, you can click __┇__ on the right side of the list and select __Edit__ or __Delete__ . + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/permissions/custom-kpanda-role.md b/docs/en/docs/kpanda/user-guide/permissions/custom-kpanda-role.md new file mode 100644 index 0000000..0b71051 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/permissions/custom-kpanda-role.md @@ -0,0 +1,107 @@ +--- +MTPE: ModetaNiu +Date: 2024-05-30 +--- + +# Adding RBAC Rules to System Roles + +*[kpanda]: A development codename for container management + +In the past, the RBAC rules for those system roles in container management were pre-defined and could +not be modified by users. +To support more flexible permission settings and to meet the customized needs for system roles, +now you can modify RBAC rules for system roles such as cluster admin, ns admin, ns editor, ns viewer. + +The following example demonstrates how to add a new ns-view rule, granting the authority to delete +workload deployments. Similar operations can be performed for other rules. + +## Prerequisites + +Before adding RBAC rules to system roles, the following prerequisites must be met: + +- Container management v0.27.0 and above. +- [Integrated Kubernetes cluster](../clusters/integrate-cluster.md) or + [created Kubernetes cluster](../clusters/create-cluster.md), and able to access the cluster's UI interface. +- Completed creation of a [namespace](../namespaces/createns.md) and [user account](../../../ghippo/user-guide/access-control/user.md), + and the granting of [NS Viewer](./permission-brief.md#ns-viewer). + For details, refer to [namespace authorization](./cluster-ns-auth.md). + +!!! note + + - RBAC rules **only need to be added** in the Global Cluster, and the Kpanda controller will synchronize + those added rules to all integrated subclusters. Synchronization may take some time to complete. + - RBAC rules **can only be added** in the Global Cluster. RBAC rules added in subclusters + will be overridden by the system role permissions of the Global Cluster. + - Only ClusterRoles with fixed Label are supported for adding rules. Replacing or deleting rules + is not supported, nor is adding rules by using role. The correspondence between built-in roles and + ClusterRole Label created by users is as follows. + + ```output + cluster-admin: rbac.kpanda.io/role-template-cluster-admin: "true" + cluster-edit: rbac.kpanda.io/role-template-cluster-edit: "true" + cluster-view: rbac.kpanda.io/role-template-cluster-view: "true" + ns-admin: rbac.kpanda.io/role-template-ns-admin: "true" + ns-edit: rbac.kpanda.io/role-template-ns-edit: "true" + ns-view: rbac.kpanda.io/role-template-ns-view: "true" + ``` + +## Steps + +1. [Create a deployment](../workloads/create-deployment.md) by a user with `admin` or `cluster admin` permissions. + + ![image-20240514112742395](../images/create-depolyment.png) + +1. Grant a user the `ns-viewer` role to provide them with the `ns-view` permission. + + ![image-20240514113009311](../images/permisson02.png) + +1. Switch the login user to ns-viewer, open the console to get the token for the ns-viewer user, + and use `curl` to request and delete the nginx deployment mentioned above. However, + a prompt appears as below, indicating the user doesn't have permission to delete it. + + ```bash + [root@master-01 ~]# curl -k -X DELETE 'https://${URL}/apis/kpanda.io/v1alpha1/clusters/cluster-member/namespaces/default/deployments/nginx' -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJOU044MG9BclBRMzUwZ2VVU2ZyNy1xMEREVWY4MmEtZmJqR05uRE1sd1lFIn0.eyJleHAiOjE3MTU3NjY1NzksImlhdCI6MTcxNTY4MDE3OSwiYXV0aF90aW1lIjoxNzE1NjgwMTc3LCJqdGkiOiIxZjI3MzJlNC1jYjFhLTQ4OTktYjBiZC1iN2IxZWY1MzAxNDEiLCJpc3MiOiJodHRwczovLzEwLjYuMjAxLjIwMTozMDE0Ny9hdXRoL3JlYWxtcy9naGlwcG8iLCJhdWQiOiJfX2ludGVybmFsLWdoaXBwbyIsInN1YiI6ImMxZmMxM2ViLTAwZGUtNDFiYS05ZTllLWE5OGU2OGM0MmVmMCIsInR5cCI6IklEIiwiYXpwIjoiX19pbnRlcm5hbC1naGlwcG8iLCJzZXNzaW9uX3N0YXRlIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiYXRfaGFzaCI6IlJhTHoyQjlKQ2FNc1RrbGVMR3V6blEiLCJhY3IiOiIwIiwic2lkIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJucy12aWV3ZXIiLCJsb2NhbGUiOiIifQ.As2ipMjfvzvgONAGlc9RnqOd3zMwAj82VXlcqcR74ZK9tAq3Q4ruQ1a6WuIfqiq8Kq4F77ljwwzYUuunfBli2zhU2II8zyxVhLoCEBu4pBVBd_oJyUycXuNa6HfQGnl36E1M7-_QG8b-_T51wFxxVb5b7SEDE1AvIf54NAlAr-rhDmGRdOK1c9CohQcS00ab52MD3IPiFFZ8_Iljnii-RpXKZoTjdcULJVn_uZNk_SzSUK-7MVWmPBK15m6sNktOMSf0pCObKWRqHd15JSe-2aA2PKBo1jBH3tHbOgZyMPdsLI0QdmEnKB5FiiOeMpwn_oHnT6IjT-BZlB18VkW8rA' + {"code":7,"message":"[RBAC] delete resources(deployments: nginx) is forbidden for user(ns-viewer) in cluster(cluster-member)","details":[]}[root@master-01 ~]# + [root@master-01 ~]# + ``` + +1. Create a ClusterRole on the global cluster, as shown in the yaml below. + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: append-ns-view # (1)! + labels: + rbac.kpanda.io/role-template-ns-view: "true" # (2)! + rules: + - apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "delete" ] + ``` + + 1. This field value can be arbitrarily specified, as long as it is not duplicated and complies with + the Kubernetes resource naming conventions. + 2. When adding rules to different roles, make sure to apply different labels. + +1. Wait for the kpanda controller to add a rule of user creation to the built-in role: ns-viewer, + then you can check if the rules added in the previous step are present for ns-viewer. + + ```bash + [root@master-01 ~]# kubectl get clusterrole role-template-ns-view -oyaml|grep deployments -C 10|tail -n 6 + ``` + ```yaml + - apiGroups: + - apps + resources: + - deployments + verbs: + - delete + ``` + +1. When using curl again to request the deletion of the aforementioned nginx deployment, this time the deletion + was successful. This means that ns-viewer has successfully added the rule to delete deployments. + + ```bash + [root@master-01 ~]# curl -k -X DELETE 'https://${URL}/apis/kpanda.io/v1alpha1/clusters/cluster-member/namespaces/default/deployments/nginx' -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJOU044MG9BclBRMzUwZ2VVU2ZyNy1xMEREVWY4MmEtZmJqR05uRE1sd1lFIn0.eyJleHAiOjE3MTU3NjY1NzksImlhdCI6MTcxNTY4MDE3OSwiYXV0aF90aW1lIjoxNzE1NjgwMTc3LCJqdGkiOiIxZjI3MzJlNC1jYjFhLTQ4OTktYjBiZC1iN2IxZWY1MzAxNDEiLCJpc3MiOiJodHRwczovLzEwLjYuMjAxLjIwMTozMDE0Ny9hdXRoL3JlYWxtcy9naGlwcG8iLCJhdWQiOiJfX2ludGVybmFsLWdoaXBwbyIsInN1YiI6ImMxZmMxM2ViLTAwZGUtNDFiYS05ZTllLWE5OGU2OGM0MmVmMCIsInR5cCI6IklEIiwiYXpwIjoiX19pbnRlcm5hbC1naGlwcG8iLCJzZXNzaW9uX3N0YXRlIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiYXRfaGFzaCI6IlJhTHoyQjlKQ2FNc1RrbGVMR3V6blEiLCJhY3IiOiIwIiwic2lkIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJucy12aWV3ZXIiLCJsb2NhbGUiOiIifQ.As2ipMjfvzvgONAGlc9RnqOd3zMwAj82VXlcqcR74ZK9tAq3Q4ruQ1a6WuIfqiq8Kq4F77ljwwzYUuunfBli2zhU2II8zyxVhLoCEBu4pBVBd_oJyUycXuNa6HfQGnl36E1M7-_QG8b-_T51wFxxVb5b7SEDE1AvIf54NAlAr-rhDmGRdOK1c9CohQcS00ab52MD3IPiFFZ8_Iljnii-RpXKZoTjdcULJVn_uZNk_SzSUK-7MVWmPBK15m6sNktOMSf0pCObKWRqHd15JSe-2aA2PKBo1jBH3tHbOgZyMPdsLI0QdmEnKB5FiiOeMpwn_oHnT6IjT-BZlB18VkW8rA' + ``` diff --git a/docs/en/docs/kpanda/user-guide/permissions/permission-brief.md b/docs/en/docs/kpanda/user-guide/permissions/permission-brief.md new file mode 100644 index 0000000..c157825 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/permissions/permission-brief.md @@ -0,0 +1,362 @@ +--- +MTPE: windsonsea +date: 2024-05-13 +--- + +# Container Management Permissions + +Container management permissions are based on a multi-dimensional permission management system created by global permission management and Kubernetes RBAC permission management. It supports cluster-level and namespace-level permission control, helping users to conveniently and flexibly set different operation permissions for IAM users and user groups (collections of users) under a tenant. + +## Cluster Permissions + +Cluster permissions are authorized based on Kubernetes RBAC's ClusterRoleBinding, allowing users/user groups to have cluster-related permissions. The current default cluster role is __Cluster Admin__ (does not have the permission to create or delete clusters). + +### __Cluster Admin__ + +__Cluster Admin__ has the following permissions: + +- Can manage, edit, and view the corresponding cluster +- Manage, edit, and view all workloads and all resources within the namespace +- Can authorize users for roles within the cluster (Cluster Admin, NS Admin, NS Editor, NS Viewer) + +The YAML example for this cluster role is as follows: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:49Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-cluster-admin + resourceVersion: "15168" + uid: f8f86d42-d5ef-47aa-b284-097615795076 +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +``` + +## Namespace Permissions + +Namespace permissions are authorized based on Kubernetes RBAC capabilities, allowing different users/user groups to have different operation permissions on resources under a namespace (including Kubernetes API permissions). For details, refer to: [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/). Currently, the default roles for container management are: NS Admin, NS Editor, NS Viewer. + +### __NS Admin__ + +__NS Admin__ has the following permissions: + +- Can view the corresponding namespace +- Manage, edit, and view all workloads and custom resources within the namespace +- Can authorize users for corresponding namespace roles (NS Editor, NS Viewer) + +The YAML example for this cluster role is as follows: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:49Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-admin + resourceVersion: "15173" + uid: 69f64c7e-70e7-4c7c-a3e0-053f507f2bc3 +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +``` + +### __NS Editor__ + +__NS Editor__ has the following permissions: + +- Can view corresponding namespaces where permissions are granted +- Manage, edit, and view all workloads within the namespace + +??? note "Click to view the YAML example of the cluster role" + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:50Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-edit + resourceVersion: "15175" + uid: ca9e690e-96c0-4978-8915-6e4c00c748fe + rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - persistentvolumeclaims/status + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - services/status + verbs: + - '*' + - apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - '*' + - apiGroups: + - "" + resources: + - namespaces + verbs: + - '*' + - apiGroups: + - apps + resources: + - controllerrevisions + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - replicasets + - replicasets/scale + - replicasets/status + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - horizontalpodautoscalers/status + verbs: + - '*' + - apiGroups: + - batch + resources: + - cronjobs + - cronjobs/status + - jobs + - jobs/status + verbs: + - '*' + - apiGroups: + - extensions + resources: + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - ingresses + - ingresses/status + - networkpolicies + - replicasets + - replicasets/scale + - replicasets/status + - replicationcontrollers/scale + verbs: + - '*' + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - poddisruptionbudgets/status + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: + - '*' + ``` + +### __NS Viewer__ + +__NS Viewer__ has the following permissions: + +- Can view the corresponding namespace +- Can view all workloads and custom resources within the corresponding namespace + +??? note "Click to view the YAML example of the cluster role" + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:50Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-view + resourceVersion: "15183" + uid: 853888fd-6ee8-42ac-b91e-63923918baf8 + rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - persistentvolumeclaims/status + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - services/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - controllerrevisions + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - replicasets + - replicasets/scale + - replicasets/status + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - horizontalpodautoscalers/status + verbs: + - get + - list + - watch + - apiGroups: + - batch + resources: + - cronjobs + - cronjobs/status + - jobs + - jobs/status + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - ingresses + - ingresses/status + - networkpolicies + - replicasets + - replicasets/scale + - replicasets/status + - replicationcontrollers/scale + verbs: + - get + - list + - watch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - poddisruptionbudgets/status + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: + - get + - list + - watch + ``` + +## Permissions FAQ + +1. What is the relationship between global permissions and container management permissions? + + Answer: Global permissions only authorize coarse-grained permissions, which can manage the creation, editing, and deletion of all clusters; while for fine-grained permissions, such as the management permissions of a single cluster, the management, editing, and deletion permissions of a single namespace, they need to be implemented based on Kubernetes RBAC container management permissions. Generally, users only need to be authorized in container management. + +2. Currently, only four default roles are supported. Can the __RoleBinding__ and __ClusterRoleBinding__ (Kubernetes fine-grained RBAC) for custom roles also take effect? + + Answer: Currently, custom permissions cannot be managed through the graphical interface, but the permission rules created using kubectl can still take effect. diff --git a/docs/en/docs/kpanda/user-guide/scale/create-hpa.md b/docs/en/docs/kpanda/user-guide/scale/create-hpa.md new file mode 100644 index 0000000..3388489 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/create-hpa.md @@ -0,0 +1,68 @@ +# Create HPA + +Suanova AI platform supports elastic scaling of Pod resources based on metrics (Horizontal Pod Autoscaling, HPA). +Users can dynamically adjust the number of copies of Pod resources by setting CPU utilization, memory usage, and custom metrics. +For example, after setting an auto scaling policy based on the CPU utilization metric for the workload, +when the CPU utilization of the Pod exceeds/belows the metric threshold you set, the workload controller +will automatically increase/decrease the number of Pod replicas. + +This page describes how to configure auto scaling based on built-in metrics and custom metrics for workloads. + +!!! note + + 1. HPA is only applicable to Deployment and StatefulSet, and only one HPA can be created per workload. + 2. If you create an HPA policy based on CPU utilization, you must set the configuration limit (Limit) for the workload in advance, otherwise the CPU utilization cannot be calculated. + 3. If built-in metrics and multiple custom metrics are used at the same time, HPA will calculate the number of scaling copies required based on multiple metrics, and take the larger value (but not exceed the maximum number of copies configured when setting the HPA policy) for elastic scaling . + +## Built-in metric elastic scaling policy + +The system has two built-in elastic scaling metrics of CPU and memory to meet users' basic business cases. + +### Prerequisites + +Before configuring the built-in index auto scaling policy for the workload, the following prerequisites need to be met: + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. + +- Created a [namespace](../namespaces/createns.md), [deployment](../workloads/create-deployment.md) + or [statefulset](../workloads/create-statefulset.md). + +- You should have permissions not lower than [NS Editor](../permissions/permission-brief.md#ns-editor). + For details, refer to [Namespace Authorization](../namespaces/createns.md). + +- Installed [metrics-server plugin install](install-metrics-server.md). + +### Steps + +Refer to the following steps to configure the built-in index auto scaling policy for the workload. + +1. Click __Clusters__ on the left navigation bar to enter the cluster list page. Click a cluster name to enter the __Cluster Details__ page. + + + +2. On the cluster details page, click __Workload__ in the left navigation bar to enter the workload list, and then click a workload name to enter the __Workload Details__ page. + + + +3. Click the Auto Scaling tab to view the auto scaling configuration of the current cluster. + + + +4. After confirming that the cluster has [installed the __metrics-server__ plug-in](install-metrics-server.md), and the plug-in is running normally, you can click the __New Scaling__ button. + + + +5. Create custom metric auto scaling policy parameters. + + + + - Policy name: Enter the name of the auto scaling policy. Please note that the name can contain up to 63 characters, and can only contain lowercase letters, numbers, and separators ("-"), and must start and end with lowercase letters or numbers, such as hpa- my-dep. + - Namespace: The namespace where the payload resides. + - Workload: The workload object that performs auto scaling. + - Target CPU Utilization: The CPU usage of the Pod under the workload resource. The calculation method is: the request (request) value of all Pod resources/workloads under the workload. When the actual CPU usage is greater/lower than the target value, the system automatically reduces/increases the number of Pod replicas. + - Target Memory Usage: The memory usage of the Pod under the workload resource. When the actual memory usage is greater/lower than the target value, the system automatically reduces/increases the number of Pod replicas. + - Replica range: the elastic scaling range of the number of Pod replicas. The default interval is 1 - 10. + +6. After completing the parameter configuration, click the __OK__ button to automatically return to the elastic scaling details page. Click __┇__ on the right side of the list to edit, delete, and view related events. diff --git a/docs/en/docs/kpanda/user-guide/scale/create-vpa.md b/docs/en/docs/kpanda/user-guide/scale/create-vpa.md new file mode 100644 index 0000000..042a0a2 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/create-vpa.md @@ -0,0 +1,58 @@ +--- +MTPE: FanLin +Date: 2024-02-23 +--- + +# Create VPAs + +The container Vertical Pod Autoscaler (VPA) calculates the most suitable CPU and memory request values ​​for the Pod by monitoring the Pod's resource application and usage over a period of time. Using VPA can allocate resources to each Pod in the cluster more reasonably, improve the overall resource utilization of the cluster, and avoid waste of cluster resources. + +AI platform supports VPA through containers. Based on this feature, the Pod request value can be dynamically adjusted according to the usage of container resources. AI platform supports manual and automatic modification of resource request values, and you can configure them according to actual needs. + +This page describes how to configure VPA for deployment. + +!!! warning + + Using VPA to modify a Pod resource request will trigger a Pod restart. Due to the limitations of Kubernetes itself, Pods may be scheduled to other nodes after restarting. + +## Prerequisites + +Before configuring a vertical scaling policy for deployment, the following prerequisites must be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md), [user](../../../ghippo/user-guide/access-control/user.md), [Deployments](../workloads/create-deployment.md) or [Statefulsets](../workloads/create-statefulset.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- The current cluster has installed [ __metrics-server__ ](install-metrics-server.md) and [ __VPA__ ](install-vpa.md) plugins. + +## Steps + +Refer to the following steps to configure the built-in index auto scaling policy for the deployment. + +1. Find the current cluster in __Clusters__ , and click the name of the target cluster. + + ![Clusters](../images/deploy01.png) + +2. Click __Deployments__ in the left navigation bar, find the deployment that needs to create a VPA, and click the name of the deployment. + + ![Deployments](../images/createScale.png) + +3. Click the __Auto Scaling__ tab to view the auto scaling configuration of the current cluster, and confirm that the relevant plug-ins have been installed and are running normally. + + ![VPA](../images/createVpaScale.png) + +4. Click the __Create Autoscaler__ button and configure the VPA vertical scaling policy parameters. + + ![Create Autoscaler](../images/createVpaScale01.png) + + - Policy name: Enter the name of the vertical scaling policy. Please note that the name can contain up to 63 characters, and can only contain lowercase letters, numbers, and separators ("-"), and must start and end with lowercase letters or numbers, such as vpa- my-dep. + - Scaling mode: Run the method of modifying the CPU and memory request values. Currently, vertical scaling supports manual and automatic scaling modes. + - Manual scaling: After the vertical scaling policy calculates the recommended resource configuration value, the user needs to manually modify the resource quota of the application. + - Auto-scaling: The vertical scaling policy automatically calculates and modifies the resource quota of the application. + - Target container: Select the container to be scaled vertically. + +5. After completing the parameter configuration, click the __OK__ button to automatically return to the elastic scaling details page. Click __┇__ on the right side of the list to perform edit and delete operations. + + ![Successfully Configurate](../images/createVpaScale02.png) diff --git a/docs/en/docs/kpanda/user-guide/scale/custom-hpa.md b/docs/en/docs/kpanda/user-guide/scale/custom-hpa.md new file mode 100644 index 0000000..3e3e56b --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/custom-hpa.md @@ -0,0 +1,182 @@ +# Creating HPA Based on Custom Metrics + +When the built-in CPU and memory metrics in the system do not meet your business needs, +you can add custom metrics by configuring ServiceMonitoring and achieve auto-scaling based +on these custom metrics. This article will introduce how to configure auto-scaling for +workloads based on custom metrics. + +!!! note + + 1. HPA is only applicable to Deployment and StatefulSet, and each workload can only create one HPA. + 2. If both built-in metrics and multiple custom metrics are used, HPA will calculate the required number + of scaled replicas based on multiple metrics respectively, and take the larger value + (but not exceeding the maximum number of replicas configured when setting the HPA policy) for scaling. + +## Prerequisites + +Before configuring the custom metrics auto-scaling policy for workloads, the following prerequisites must be met: + +- [Integrated Kubernetes cluster](../clusters/integrate-cluster.md) or + [created Kubernetes cluster](../clusters/create-cluster.md), and able to access the cluster's UI interface. +- Completed creation of a [namespace](../namespaces/createns.md), [deployment](../workloads/create-deployment.md), + or [statefulSet](../workloads/create-statefulset.md). +- The current user should have permissions higher than [NS Editor](../permissions/permission-brief.md#ns-editor). + For details, refer to [namespace authorization](../namespaces/createns.md). +- [metrics-server plugin](install-metrics-server.md) has been installed. +- [insight-agent plugin](../../../insight/quickstart/install/install-agent.md) has been installed. +- Prometheus-adapter plugin has been installed. + +## Steps + +Refer to the following steps to configure the auto-scaling policy based on metrics for workloads. + +1. Click __Clusters__ in the left navigation bar to enter the clusters page. + Click a cluster name to enter the __Cluster Overview__ page. + + ![Select a cluster](../images/autoscaling01.png) + +2. On the Cluster Details page, click __Workloads__ in the left navigation bar to enter the workload list, + and click a workload name to enter the __Workload Details__ page. + + ![Select a workload](../images/autoscaling02.png) + +3. Click the __Auto Scaling__ tab to view the current autoscaling configuration of the cluster. + + ![Autoscaling](../images/autoscaling03.png) + +4. Confirm that the cluster has [installed metrics-server](install-metrics-server.md), Insight, + and Prometheus-adapter plugins, and that the plugins are running normally, then click the __Create AutoScaler__ button. + + !!! note + + If the related plugins are not installed or the plugins are in an abnormal state, + you will not be able to see the entry for creating custom metrics auto-scaling on the page. + + ![Autoscaling](../images/autoscaling04.png) + +5. Create custom metrics auto-scaling policy parameters. + + + + - Policy Name: Enter the name of the auto-scaling policy. Note that the name can be up to 63 characters long, + can only contain lowercase letters, numbers, and separators ("-"), and must start and end with a lowercase letter + or number, e.g., hpa-my-dep. + - Namespace: The namespace where the workload is located. + - Workload: The workload object that performs auto-scaling. + - Resource Type: The type of custom metric being monitored, including Pod and Service types. + - Metric: The name of the custom metric created using ServiceMonitoring or the name of the system-built custom metric. + - Data Type: The method used to calculate the metric value, including target value and target average value. + When the resource type is Pod, only the target average value can be used. + +## Operation Example + +This case takes a Golang business program as an example. The example program exposes the +`httpserver_requests_total` metric and records HTTP requests. This metric can be used to +calculate the QPS value of the business program. + +### Deploy Business Program + +Use Deployment to deploy the business program: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: httpserver + namespace: httpserver +spec: + replicas: 1 + selector: + matchLabels: + app: httpserver + template: + metadata: + labels: + app: httpserver + spec: + containers: + - name: httpserver + image: registry.imroc.cc/test/httpserver:custom-metrics + imagePullPolicy: Always +--- + +apiVersion: v1 +kind: Service +metadata: + name: httpserver + namespace: httpserver + labels: + app: httpserver + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + prometheus.io/port: "http" +spec: + type: ClusterIP + ports: + - port: 80 + protocol: TCP + name: http + selector: + app: httpserver +``` + +### Prometheus Collects Business Monitoring + +If the insight-agent is installed, Prometheus can be configured by creating a ServiceMonitor CRD object. + +Operation steps: In **Cluster Details** -> **Custom Resources**, search for “servicemonitors.monitoring.coreos.com", +click the name to enter the details. Create the following example CRD in the **httpserver** namespace via YAML: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: httpserver + namespace: httpserver + labels: + operator.insight.io/managed-by: insight +spec: + endpoints: + - port: http + interval: 5s + namespaceSelector: + matchNames: + - httpserver + selector: + matchLabels: + app: httpserver +``` + + + +!!! note + + If Prometheus is installed via insight, the serviceMonitor must be labeled with + `operator.insight.io/managed-by: insight`. If installed by other means, this label is not required. + +### Configure Metric Rules in Prometheus-adapter + +steps: In **Clusters** -> **Helm Apps**, search for “prometheus-adapter",enter the update page through the action bar, +and configure custom metrics in YAML as follows: + +```yaml +rules: + custom: + - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) + name: + as: httpserver_requests_qps + matches: httpserver_requests_total + resources: + template: <<.Resource>> + seriesQuery: httpserver_requests_total +``` + + + +### Create Custom Metrics Auto-scaling Policy Parameters + +Follow the above steps to find the application httpserver in the Deployment +and create auto-scaling via custom metrics. + + diff --git a/docs/en/docs/kpanda/user-guide/scale/hpa-cronhpa-compatibility-rules.md b/docs/en/docs/kpanda/user-guide/scale/hpa-cronhpa-compatibility-rules.md new file mode 100644 index 0000000..ccfe8b4 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/hpa-cronhpa-compatibility-rules.md @@ -0,0 +1,47 @@ +# Compatibility Rules for HPA and CronHPA + +HPA stands for HorizontalPodAutoscaler, which refers to horizontal pod auto-scaling. + +CronHPA stands for Cron HorizontalPodAutoscaler, which refers to scheduled horizontal pod auto-scaling. + +## Conflict Between CronHPA and HPA + +Scheduled scaling with CronHPA triggers horizontal pod scaling at specified times. +To prevent sudden traffic surges, you may have configured HPA to ensure the normal operation +of your application. If both HPA and CronHPA are detected simultaneously, conflicts arise +because CronHPA and HPA operate independently without awareness of each other. +Consequently, the actions performed last will override those executed first. + +By comparing the definition templates of CronHPA and HPA, the following points can be observed: + +- Both CronHPA and HPA use the `scaleTargetRef` field to identify the scaling target. +- CronHPA schedules the number of replicas to scale based on crontab rules in jobs. +- HPA determines scaling based on resource utilization. + +!!! note + + If both CronHPA and HPA are set, there will be scenarios where CronHPA and HPA + simultaneously operate on a single `scaleTargetRef`. + +## Compatibility Solution for CronHPA and HPA + +As noted above, the fundamental reason that simultaneous use of CronHPA and HPA results in +the later action overriding the earlier one is that the two controllers cannot sense each other. +Therefore, the conflict can be resolved by enabling CronHPA to be aware of HPA's current state. + +The system will treat HPA as the scaling object for CronHPA, thus achieving scheduled scaling +for the Deployment object defined by the HPA. + +HPA's definition configures the Deployment in the `scaleTargetRef` field, and then the Deployment +uses its definition to locate the ReplicaSet, which ultimately adjusts the actual number of replicas. + +In AI platform, the `scaleTargetRef` in CronHPA is set to the HPA object, and it uses the HPA object +to find the actual `scaleTargetRef`, allowing CronHPA to be aware of HPA's current state. + + + +CronHPA senses HPA by adjusting HPA. CronHPA determines whether scaling is needed and modifies +the HPA upper limit by comparing the target number of replicas with the current number of replicas, +choosing the larger value. Similarly, CronHPA determines whether to modify the HPA lower limit by +comparing the target number of replicas from CronHPA with the configuration in HPA, +choosing the smaller value. diff --git a/docs/en/docs/kpanda/user-guide/scale/install-cronhpa.md b/docs/en/docs/kpanda/user-guide/scale/install-cronhpa.md new file mode 100644 index 0000000..b4d26e7 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/install-cronhpa.md @@ -0,0 +1,63 @@ +--- +MTPE: FanLin +Date: 2024-02-29 +--- + +# Install kubernetes-cronhpa-controller + +The container copy timing horizontal autoscaling policy (CronHPA) can provide stable computing resource guarantee for periodic high-concurrency applications, and __kubernetes-cronhpa-controller__ is a key component to implement CronHPA. + +This section describes how to install the __kubernetes-cronhpa-controller__ plugin. + +!!! note + + In order to use CornHPA, not only the __kubernetes-cronhpa-controller__ plugin needs to be installed, but also [install the __metrics-server__ plugin](install-metrics-server.md). + +## Prerequisites + +Before installing the __kubernetes-cronhpa-controller__ plugin, the following prerequisites need to be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +## Steps + +Refer to the following steps to install the __kubernetes-cronhpa-controller__ plugin for the cluster. + +1. On the __Clusters__ page, find the target cluster where the plugin needs to be installed, click the name of the cluster, then click __Workloads__ -> __Deployments__ on the left, and click the name of the target workload. + +2. On the workload details page, click the __Auto Scaling__ tab, and click __Install__ on the right side of __CronHPA__ . + + ![Auto Scaling](../images/installcronhpa.png) + +3. Read the relevant introduction of the plug-in, select the version and click the __Install__ button. It is recommended to install __1.3.0__ or later. + + ![Install](../images/installcronhpa1.png) + +4. Refer to the following instructions to configure the parameters. + + ![Config](../images/installcronhpa2.png) + + - Name: Enter the plugin name, please note that the name can be up to 63 characters, can only contain lowercase letters, numbers, and separators ("-"), and must start and end with lowercase letters or numbers, such as kubernetes-cronhpa-controller. + - Namespace: Select which namespace the plugin will be installed in, here we take __default__ as an example. + - Version: The version of the plugin, here we take the __1.3.0__ version as an example. + - Ready Wait: When enabled, it will wait for all associated resources under the application to be in the ready state before marking the application installation as successful. + - Failed to delete: If the plugin installation fails, delete the associated resources that have already been installed. When enabled, __Wait__ will be enabled synchronously by default. + - Detailed log: When enabled, a detailed log of the installation process will be recorded. + + !!! note + + After enabling __ready wait__ and/or __failed deletion__ , it takes a long time for the application to be marked as "running". + +5. Click __OK__ in the lower right corner of the page, and the system will automatically jump to the __Helm Apps__ list page. Wait a few minutes and refresh the page to see the application you just installed. + + !!! warning + + If you need to delete the __kubernetes-cronhpa-controller__ plugin, you should go to the __Helm Apps__ list page to delete it completely. + + If you delete the plug-in under the __Auto Scaling__ tab of the workload, this only deletes the workload copy of the plug-in, and the plug-in itself is still not deleted, and an error will be prompted when the plug-in is reinstalled later. + +6. Go back to the __Auto Scaling__ tab under the workload details page, and you can see that the interface displays __Plug-in installed__ . Now it's time to start creating CronHPA policies. diff --git a/docs/en/docs/kpanda/user-guide/scale/install-metrics-server.md b/docs/en/docs/kpanda/user-guide/scale/install-metrics-server.md new file mode 100644 index 0000000..e22ea16 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/install-metrics-server.md @@ -0,0 +1,143 @@ +--- +MTPE: FanLin +Date: 2024-02-29 +--- + +# Install metrics-server + +__metrics-server__ is the built-in resource usage metrics collection component of Kubernetes. +You can automatically scale Pod copies horizontally for workload resources by configuring HPA policies. + +This section describes how to install __metrics-server__ . + +## Prerequisites + +Before installing the __metrics-server__ plugin, the following prerequisites need to be met: + +- [Integrated the Kubernetes cluster](../clusters/integrate-cluster.md) or + [created the Kubernetes cluster](../clusters/create-cluster.md), + and you can access the UI interface of the cluster. + +- Created a [namespace](../namespaces/createns.md). + +- You should have permissions not lower than [NS Editor](../permissions/permission-brief.md#ns-editor). + For details, refer to [Namespace Authorization](../namespaces/createns.md). + +## Steps + +Please perform the following steps to install the __metrics-server__ plugin for the cluster. + +1. On the Auto Scaling page under workload details, click the __Install__ button to enter the __metrics-server__ plug-in installation interface. + + ![metrics-server](../images/createScale04.png) + +2. Read the introduction of the __metrics-server__ plugin, select the version and click the __Install__ button. This page will use the __3.8.2__ version as an example to install, and it is recommended that you install __3.8.2__ and later versions. + + ![Install](../images/createScale05.png) + +3. Configure basic parameters on the installation configuration interface. + + ![Config](../images/createScale06.png) + + - Name: Enter the plugin name, please note that the name can be up to 63 characters, can only contain lowercase letters, numbers and separators ("-"), and must start and end with lowercase letters or numbers, such as metrics-server-01. + - Namespace: Select the namespace for plugin installation, here we take __default__ as an example. + - Version: The version of the plugin, here we take __3.8.2__ version as an example. + - Ready Wait: When enabled, it will wait for all associated resources under the application to be ready before marking the application installation as successful. + - Failed to delete: After it is enabled, the synchronization will be enabled by default and ready to wait. If the installation fails, the installation-related resources will be removed. + - Verbose log: Turn on the verbose output of the installation process log. + + !!! note + + After enabling __Wait__ and/or __Deletion failed__ , it takes a long time for the app to be marked as __Running__ . + +4. Advanced parameter configuration + + - If the cluster network cannot access the __k8s.gcr.io__ repository, please try to modify the __repositort__ parameter to __repository: k8s.m.daocloud.io/metrics-server/metrics-server__ . + + - An SSL certificate is also required to install the __metrics-server__ plugin. To bypass certificate verification, you need to add __- --kubelet-insecure-tls__ parameter at __defaultArgs:__ . + + ??? note "Click to view and use the YAML parameters to replace the default __YAML__ " + + ```yaml + image: + repository: k8s.m.daocloud.io/metrics-server/metrics-server # Change the registry source address to k8s.m.daocloud.io + tag: '' + pullPolicy: IfNotPresent + imagePullSecrets: [] + nameOverride: '' + fullnameOverride: '' + serviceAccount: + create: true + annotations: {} + name: '' + rbac: + create: true + pspEnabled: false + apiService: + create: true + podLabels: {} + podAnnotations: {} + podSecurityContext: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + priorityClassName: system-cluster-critical + containerPort: 4443 + hostNetwork: + enabled: false + replicas: 1 + updateStrategy: {} + podDisruptionBudget: + enabled: false + minAvailable: null + maxUnavailable: null + defaultArgs: + - '--cert-dir=/tmp' + - '--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname' + - '--kubelet-use-node-status-port' + - '--metric-resolution=15s' + - --kubelet-insecure-tls # Bypass certificate verification + args: [] + livenessProbe: + httpGet: + path: /livez + port:https + scheme: HTTPS + initialDelaySeconds: 0 + periodSeconds: 10 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /readyz + port:https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 10 + failureThreshold: 3 + service: + type: ClusterIP + port: 443 + annotations: {} + labels: {} + metrics: + enabled: false + serviceMonitor: + enabled: false + additionalLabels: {} + interval: 1m + scrapeTimeout: 10s + resources: {} + extraVolumeMounts: [] + extraVolumes: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ``` + +5. Click the __OK__ button to complete the installation of the __metrics-server__ plug-in, and then the system will automatically jump to the __Helm Apps__ list page. After a few minutes, refresh the page and you will see the newly installed Applications. + +!!! note + + When deleting the __metrics-server__ plugin, the plugin can only be completely deleted on the __Helm Applications__ list page. If you only delete __metrics-server__ on the workload page, this only deletes the workload copy of the application, the application itself is still not deleted, and an error will be prompted when you reinstall the plugin later. \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/scale/install-vpa.md b/docs/en/docs/kpanda/user-guide/scale/install-vpa.md new file mode 100644 index 0000000..7e8bcb5 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/install-vpa.md @@ -0,0 +1,63 @@ +--- +MTPE: FanLin +Date: 2024-02-29 +--- + +# Install vpa + +The Vertical Pod Autoscaler, VPA, can make the resource allocation of the cluster more reasonable and avoid the waste of cluster resources. __vpa__ is the key component to realize the vertical autoscaling of the container. + +This section describes how to install the __vpa__ plugin. + + In order to use VPA policies, not only the __vpa__ plugin needs to be installed, but also [install the __metrics-server__ plugin](install-metrics-server.md). + +## Prerequisites + +Before installing the __vpa__ plugin, the following prerequisites need to be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +## Steps + +Refer to the following steps to install the __vpa__ plugin for the cluster. + +1. On the __Clusters__ page, find the target cluster where the plugin needs to be installed, click the name of the cluster, then click __Workloads__ -> __Deployments__ on the left, and click the name of the target workload. + +2. On the workload details page, click the __Auto Scaling__ tab, and click __Install__ on the right side of __VPA__ . + + ![vpa](../images/installvpa.png) + +3. Read the relevant introduction of the plug-in, select the version and click the __Install__ button. It is recommended to install __1.5.0__ or later. + + ![Install](../images/installvpa1.png) + +4. Review the configuration parameters described below. + + ![Config](../images/installvpa2.png) + + - Name: Enter the plugin name, please note that the name can be up to 63 characters, can only contain lowercase letters, numbers, and separators ("-"), and must start and end with lowercase letters or numbers, such as kubernetes-cronhpa-controller. + - Namespace: Select which namespace the plugin will be installed in, here we take __default__ as an example. + - Version: The version of the plugin, here we take the __1.5.0__ version as an example. + - Ready Wait: When enabled, it will wait for all associated resources under the application to be in the ready state before marking the application installation as successful. + - Failed to delete: If the plugin installation fails, delete the associated resources that have already been installed. When enabled, __Wait__ will be enabled synchronously by default. + - Detailed log: When enabled, a detailed log of the installation process will be recorded. + + !!! note + + After enabling __Wait__ and/or __Deletion failed__ , it takes a long time for the application to be marked as __running__ . + +5. Click __OK__ in the lower right corner of the page, and the system will automatically jump to the __Helm Apps__ list page. Wait a few minutes and refresh the page to see the application you just installed. + + !!! warning + + If you need to delete the __vpa__ plugin, you should go to the __Helm Apps__ list page to delete it completely. + + If you delete the plug-in under the __Auto Scaling__ tab of the workload, this only deletes the workload copy of the plug-in, and the plug-in itself is still not deleted, and an error will be prompted when the plug-in is reinstalled later. + +6. Go back to the __Auto Scaling__ tab under the workload details page, and you can see that the interface displays __Plug-in installed__ . Now you can start [Create VPA](create-vpa.md) policy. + + ![Finish Creation](../images/installvpa3.png) diff --git a/docs/en/docs/kpanda/user-guide/scale/knative/install.md b/docs/en/docs/kpanda/user-guide/scale/knative/install.md new file mode 100644 index 0000000..d0b245d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/knative/install.md @@ -0,0 +1,26 @@ +--- +MTPE: FanLin +Date: 2024-02-29 +--- + +# Installation + +Knative is a platform-agnostic solution for running serverless deployments. + +## Steps + +1. Log in to the cluster, click the sidebar __Helm Apps__ → __Helm Charts__ , enter __knative__ in the search box at the top right, and then press the enter key to search. + + ![Install-1](../../images/knative-install-1.png) + +2. Click the __knative-operator__ to enter the installation configuration interface. You can view the available versions and the Parameters optional items of Helm values on this interface. + + ![Install-2](../../images/knative-install-2.png) + +3. After clicking the install button, you will enter the installation configuration interface. + + ![Install-3](../../images/knative-install-3.png) + +4. Enter the name, installation tenant, and it is recommended to check __Wait__ and __Detailed Logs__ . + +5. In the settings below, you can tick __Serving__ and enter the installation tenant of the Knative Serving component, which will deploy the Knative Serving component after installation. This component is managed by the Knative Operator. diff --git a/docs/en/docs/kpanda/user-guide/scale/knative/knative.md b/docs/en/docs/kpanda/user-guide/scale/knative/knative.md new file mode 100644 index 0000000..30a771e --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/knative/knative.md @@ -0,0 +1,62 @@ +--- +MTPE: windsonsea +Date: 2024-07-19 +--- + +# Knative Introduction + +Knative provides a higher level of abstraction, simplifying and speeding up the process of building, deploying, and managing applications on Kubernetes. It allows developers to focus more on implementing business logic, while leaving most of the infrastructure and operations work to Knative, significantly improving productivity. + +## Components + +The Knative operator runs the following components. + +```shell +knative-operator knative-operator-58f7d7db5c-7f6r5 1/1 Running 0 6m55s +knative-operator operator-webhook-667dc67bc-qvrv4 1/1 Running 0 6m55s +``` + +The Knative serving components are as follows. + +```shell +knative-serving 3scale-kourier-gateway-d69fbfbd-bd8d8 1/1 Running 0 7m13s +knative-serving activator-7c6fddd698-wdlng 1/1 Running 0 7m3s +knative-serving autoscaler-8f4b876bb-kd25p 1/1 Running 0 7m17s +knative-serving autoscaler-hpa-5f7f74679c-vkc7p 1/1 Running 0 7m15s +knative-serving controller-789c896c46-tfvsv 1/1 Running 0 7m17s +knative-serving net-kourier-controller-7db578c889-7gd5l 1/1 Running 0 7m14s +knative-serving webhook-5c88b94c5-78x7m 1/1 Running 0 7m1s +knative-serving storage-version-migration-serving-serving-1.12.2-t7zvd 0/1 Completed 0 7m15s +``` + +| Component | Features | +|----------|-------------| +| Activator | Queues requests (if a Knative Service has scaled to zero). Calls the autoscaler to bring back services that have scaled down to zero and forward queued requests. The Activator can also act as a request buffer, handling bursts of traffic. | +| Autoscaler | Responsible for scaling Knative services based on configuration, metrics, and incoming requests. | +| Controller | Manages the state of Knative CRs. It monitors multiple objects, manages the lifecycle of dependent resources, and updates resource status. | +| Queue-Proxy | Sidecar container injected into each Knative Service. Responsible for collecting traffic data and reporting it to the Autoscaler, which then initiates scaling requests based on this data and preset rules. | +| Webhooks | Knative Serving has several Webhooks responsible for validating and mutating Knative resources. | + +## Ingress Traffic Entry Solutions + +| Solution | Use Case | +|----------|-------------| +| Istio | If Istio is already in use, it can be chosen as the traffic entry solution. | +| Contour | If Contour has been enabled in the cluster, it can be chosen as the traffic entry solution. | +| Kourier | If neither of the above two Ingress components are present, Knative's Envoy-based Kourier Ingress can be used as the traffic entry solution. | + +## Autoscaler Solutions Comparison + +| Autoscaler Type | Core Part of Knative Serving | Default Enabled | Scale to Zero Support | CPU-based Autoscaling Support | +| -------------- | ---------- | ------------ | ------------------ | -------------- | +| Knative Pod Autoscaler (KPA) | Yes | Yes | Yes | No | +| Horizontal Pod Autoscaler (HPA) | No | Needs to be enabled after installing Knative Serving | No | Yes | + +## CRD + +| Resource Type | API Name | Description | +| ------------- | -------- | ----------- | +| Services | `service.serving.knative.dev` | Automatically manages the entire lifecycle of Workloads, controls the creation of other objects, ensures applications have Routes, Configurations, and new revisions with each update. | +| Routes | `route.serving.knative.dev` | Maps network endpoints to one or more revision versions, supports traffic distribution and version routing. | +| Configurations | `configuration.serving.knative.dev` | Maintains the desired state of deployments, provides separation between code and configuration, follows the Twelve-Factor App methodology, modifying configurations creates new revisions. | +| Revisions | `revision.serving.knative.dev` | Snapshot of the workload at each modification time point, immutable object, automatically scales based on traffic. | diff --git a/docs/en/docs/kpanda/user-guide/scale/knative/playground.md b/docs/en/docs/kpanda/user-guide/scale/knative/playground.md new file mode 100644 index 0000000..c7ee68c --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/knative/playground.md @@ -0,0 +1,145 @@ +# Knative Practices + +In this section, we will delve into learning Knative through several practical exercises. + +## case 1 - Hello World + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +You can use `kubectl` to check the status of a deployed application that has been automatically configured with ingress and scalers by Knative. + +```shell +~ kubectl get service.serving.knative.dev/hello +NAME URL LATESTCREATED LATESTREADY READY REASON +hello http://hello.knative-serving.knative.loulan.me hello-00001 hello-00001 True +``` + +The deployed Pod YAML is as follows, consisting of two Pods: `user-container` and `queue-proxy`. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: hello-00003-deployment-5fcb8ccbf-7qjfk +spec: + containers: + - name: user-container + - name: queue-proxy +``` + +![knative-request-flow](../../../images/knative-request-flow.png) + +Request Flow: + +1. case1 When there is low traffic or no traffic, traffic will be routed to the activator. +2. case2 When there is high traffic, traffic will be routed directly to the Pod only if it exceeds the target-burst-capacity. + 1. Configured as 0, expansion from 0 is the only scenario. + 2. Configured as -1, the activator will always be present in the request path. + 3. Configured as >0, the number of additional concurrent requests that the system can handle before triggering scaling. +3. case3 When the traffic decreases again, traffic will be routed back to the activator if the traffic is lower than current_demand + target-burst-capacity > (pods * concurrency-target). + + The total number of pending requests + the number of requests that can exceed the target concurrency > the target concurrency per Pod * number of Pods. + +## case 2 - Based on Concurrent Elastic Scaling + +We first apply the following YAML definition under the cluster. + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "1" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +Execute the following command for testing, and you can observe the scaling of the Pods by using `kubectl get pods -A -w`. + +```shell +wrk -t2 -c4 -d6s http://hello.knative-serving.knative.daocloud.io/ +``` + +## case 3 - Based on concurrent elastic scaling, scale out in advance to reach a specific ratio. + +We can easily achieve this, for example, by limiting the concurrency to 10 per container. This can be implemented through `autoscaling.knative.dev/target-utilization-percentage: 70`, starting to scale out the Pods when 70% is reached. + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "10" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" +        autoscaling.knative.dev/target-utilization-percentage: "70" +        autoscaling.knative.dev/metric: "concurrency" +     spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +## case 4 - Canary Release/Traffic Percentage + +We can control the distribution of traffic to each version through `spec.traffic`. + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "1" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" + traffic: + - latestRevision: true + percent: 50 + - latestRevision: false + percent: 50 + revisionName: hello-00001 +``` diff --git a/docs/en/docs/kpanda/user-guide/scale/knative/scene.md b/docs/en/docs/kpanda/user-guide/scale/knative/scene.md new file mode 100644 index 0000000..64d0a5c --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/scale/knative/scene.md @@ -0,0 +1,15 @@ +# Use Cases + +## Suitable Cases + +* High concurrency business with short connections +* Businesses that require elastic scaling +* A large number of applications need to scale down to 0 to improve resource utilization +* AI Serving services that scale based on specific metrics + +## Unsuitable Cases + +* Long-lived connection business +* Latency-sensitive business +* Traffic splitting based on cookies +* Traffic splitting based on headers diff --git a/docs/en/docs/kpanda/user-guide/security/audit.md b/docs/en/docs/kpanda/user-guide/security/audit.md new file mode 100644 index 0000000..e6de9f0 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/security/audit.md @@ -0,0 +1,61 @@ +# Permission Scan + +To use the [Permission Scan](index.md) feature, you need to create a scan policy first. After executing the policy, a scan report will be automatically generated for viewing. + +## Create a Scan Policy + +1. On the left navigation bar of the homepage in the Container Management module, click __Security Management__ . + + + +2. Click __Permission Scan__ on the left navigation bar, then click the __Scan Policy__ tab and click __Create Scan Policy__ on the right. + + + +3. Fill in the configuration according to the following instructions, and then click __OK__ . + + - Cluster: Select the cluster to be scanned. The optional cluster list comes from the clusters accessed or created in the [Container Management](../../intro/index.md) module. If the desired cluster is not available, you can access or create a cluster in the Container Management module. + - Scan Type: + + - Immediate scan: Perform a scan immediately after the scan policy is created. It cannot be automatically/manually executed again later. + - Scheduled scan: Automatically repeat the scan at scheduled intervals. + + - Number of Scan Reports to Keep: Set the maximum number of scan reports to be kept. When the specified retention quantity is exceeded, delete from the earliest report. + + + +## Update/Delete Scan Policies + +After creating a scan policy, you can update or delete it as needed. + +Under the __Scan Policy__ tab, click the __┇__ action button to the right of a configuration: + +- For periodic scan policies: + + - Select __Execute Immediately__ to perform an additional scan outside the regular schedule. + - Select __Disable__ to interrupt the scanning plan until __Enable__ is clicked to resume executing the scan policy according to the scheduling plan. + - Select __Edit__ to update the configuration. You can update the scan configuration, type, scan cycle, and report retention quantity. The configuration name and the target cluster to be scanned cannot be changed. + - Select __Delete__ to delete the configuration. + +- For one-time scan policies: Only support the __Delete__ operation. + + + +## View Scan Reports + +1. Under the __Security Management__ -> __Permission Scanning__ -> __Scan Reports__ tab, click the report name. + + > Clicking __Delete__ on the right of a report allows you to manually delete the report. + + + +2. View the scan report content, including: + + - The target cluster scanned. + - The scan policy used. + - The total number of scan items, warnings, and errors. + - In periodic scan reports generated by periodic scan policies, you can also view the scan frequency. + - The start time of the scan. + - Check details, such as the checked resources, resource types, scan results, error types, and error details. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/security/cis/config.md b/docs/en/docs/kpanda/user-guide/security/cis/config.md new file mode 100644 index 0000000..c58eaa3 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/security/cis/config.md @@ -0,0 +1,38 @@ +# Scan Configuration + +The first step in using [CIS Scanning](../index.md) is to create a scan configuration. Based on the scan configuration, you can then create scan policies, execute scan policies, and finally view scan results. + +## Create a Scan Configuration + +The steps for creating a scan configuration are as follows: + +1. Click __Security Management__ in the left navigation bar of the homepage of the container management module. + + + +2. By default, enter the __Compliance Scanning__ page, click the __Scan Configuration__ tab, and then click __Create Scan Configuration__ in the upper-right corner. + + + +3. Fill in the configuration name, select the configuration template, and optionally check the scan items, then click __OK__ . + + Scan Template: Currently, two templates are provided. The __kubeadm__ template is suitable for general Kubernetes clusters. The __daocloud__ template ignores scan items that are not applicable to AI platform based on the __kubeadm__ template and the platform design of AI platform. + + + +## View Scan Configuration + +Under the scan configuration tab, clicking the name of a scan configuration displays the type of the configuration, the number of scan items, the creation time, the configuration template, and the specific scan items enabled for the configuration. + + + +## Updat/Delete Scan Configuration + +After a scan configuration has been successfully created, it can be updated or deleted according to your needs. + +Under the scan configuration tab, click the __┇__ action button to the right of a configuration: + +- Select __Edit__ to update the configuration. You can update the description, template, and scan items. The configuration name cannot be changed. +- Select __Delete__ to delete the configuration. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/security/cis/policy.md b/docs/en/docs/kpanda/user-guide/security/cis/policy.md new file mode 100644 index 0000000..a368bcb --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/security/cis/policy.md @@ -0,0 +1,39 @@ +# Scan Policy + +## Create a Scan Policy + +After creating a scan configuration, you can create a scan policy based on the configuration. + +1. Under the __Security Management__ -> __Compliance Scanning__ page, click the __Scan Policy__ tab on the right to create a scan policy. + + + +2. Fill in the configuration according to the following instructions and click __OK__ . + + - Cluster: Select the cluster to be scanned. The optional cluster list comes from the clusters accessed or created in the [Container Management](../../../intro/index.md) module. If the desired cluster is not available, you can access or create a cluster in the Container Management module. + - Scan Configuration: Select a pre-created scan configuration. The scan configuration determines which specific scan items need to be performed. + - Scan Type: + + - Immediate scan: Perform a scan immediately after the scan policy is created. It cannot be automatically/manually executed again later. + - Scheduled scan: Automatically repeat the scan at scheduled intervals. + + - Number of Scan Reports to Keep: Set the maximum number of scan reports to be kept. When the specified retention quantity is exceeded, delete from the earliest report. + + + +## Update/Delete Scan Policies + +After creating a scan policy, you can update or delete it as needed. + +Under the __Scan Policy__ tab, click the __┇__ action button to the right of a configuration: + +- For periodic scan policies: + + - Select __Execute Immediately__ to perform an additional scan outside the regular schedule. + - Select __Disable__ to interrupt the scanning plan until __Enable__ is clicked to resume executing the scan policy according to the scheduling plan. + - Select __Edit__ to update the configuration. You can update the scan configuration, type, scan cycle, and report retention quantity. The configuration name and the target cluster to be scanned cannot be changed. + - Select __Delete__ to delete the configuration. + +- For one-time scan policies: Only support the __Delete__ operation. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/security/cis/report.md b/docs/en/docs/kpanda/user-guide/security/cis/report.md new file mode 100644 index 0000000..d520c2d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/security/cis/report.md @@ -0,0 +1,26 @@ +--- +hide: + - toc +--- + +# Scan Report + +After executing a scan policy, a scan report will be generated automatically. You can view the scan report online or download it to your local computer. + +- Download and View + + Under the __Security Management__ -> __Compliance Scanning__ page, click the __Scan Report__ tab, then click the __┇__ action button to the right of a report and select __Download__ . + + +- View Online + + Clicking the name of a report allows you to view its content online, which includes: + + - The target cluster scanned. + - The scan policy and scan configuration used. + - The start time of the scan. + - The total number of scan items, the number passed, and the number failed. + - For failed scan items, repair suggestions are provided. + - For passed scan items, more secure operational suggestions are provided. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/security/hunter.md b/docs/en/docs/kpanda/user-guide/security/hunter.md new file mode 100644 index 0000000..01f23dc --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/security/hunter.md @@ -0,0 +1,57 @@ +# Vulnerability Scan + +To use the [Vulnerability Scan](index.md) feature, you need to create a scan policy first. After executing the policy, a scan report will be automatically generated for viewing. + +## Create a Scan Policy + +1. On the left navigation bar of the homepage in the Container Management module, click __Security Management__ . + + + +2. Click __Vulnerability Scan__ on the left navigation bar, then click the __Scan Policy__ tab and click __Create Scan Policy__ on the right. + + +3. Fill in the configuration according to the following instructions, and then click __OK__ . + + - Cluster: Select the cluster to be scanned. The optional cluster list comes from the clusters accessed or created in the [Container Management](../../intro/index.md) module. If the desired cluster is not available, you can access or create a cluster in the Container Management module. + - Scan Type: + + - Immediate scan: Perform a scan immediately after the scan policy is created. It cannot be automatically/manually executed again later. + - Scheduled scan: Automatically repeat the scan at scheduled intervals. + + - Number of Scan Reports to Keep: Set the maximum number of scan reports to be kept. When the specified retention quantity is exceeded, delete from the earliest report. + + +## Update/Delete Scan Policies + +After creating a scan policy, you can update or delete it as needed. + +Under the __Scan Policy__ tab, click the __┇__ action button to the right of a configuration: + +- For periodic scan policies: + + - Select __Execute Immediately__ to perform an additional scan outside the regular schedule. + - Select __Disable__ to interrupt the scanning plan until __Enable__ is clicked to resume executing the scan policy according to the scheduling plan. + - Select __Edit__ to update the configuration. You can update the scan configuration, type, scan cycle, and report retention quantity. The configuration name and the target cluster to be scanned cannot be changed. + - Select __Delete__ to delete the configuration. + +- For one-time scan policies: Only support the __Delete__ operation. + + + +## Viewe Scan Reports + +1. Under the __Security Management__ -> __Vulnerability Scanning__ -> __Scan Reports__ tab, click the report name. + + > Clicking __Delete__ on the right of a report allows you to manually delete the report. + + +2. View the scan report content, including: + + - The target cluster scanned. + - The scan policy used. + - The scan frequency. + - The total number of risks, high risks, medium risks, and low risks. + - The time of the scan. + - Check details such as vulnerability ID, vulnerability type, vulnerability name, vulnerability description, etc. + diff --git a/docs/en/docs/kpanda/user-guide/security/index.md b/docs/en/docs/kpanda/user-guide/security/index.md new file mode 100644 index 0000000..a66f00d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/security/index.md @@ -0,0 +1,61 @@ +# Types of Security Scans + +AI platform Container Management provides three types of security scans: + +- Compliance Scan: Conducts security scans on cluster nodes based on [CIS Benchmark](https://github.com/aquasecurity/kube-bench/tree/main/cfg). +- Authorization Scan: Checks for security and compliance issues in the Kubernetes cluster, records and verifies authorized access, object changes, events, and other activities related to the Kubernetes API. +- Vulnerability Scan: Scans the Kubernetes cluster for potential vulnerabilities and risks, such as unauthorized access, sensitive information leakage, weak authentication, container escape, etc. + +## Compliance Scan + +The object of compliance scanning is the cluster node. The scan result lists the scan items and results and provides repair suggestions for any failed scan items. For specific security rules used during scanning, refer to the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes). + +The focus of the scan varies when checking different types of nodes. + +- Scan the control plane node (Controller) + + - Focus on the security of system components such as __API Server__ , __controller-manager__ , __scheduler__ , __kubelet__ , etc. + - Check the security configuration of the Etcd database. + - Verify whether the cluster's authentication mechanism, authorization policy, and network security configuration meet security standards. + +- Scan worker nodes + + - Check if the configuration of container runtimes such as kubelet and Docker meets security standards. + - Verify whether the container image has been trusted and verified. + - Check if the network security configuration of the node meets security standards. + +!!! tip + + To use compliance scanning, you need to create a [scan configuration](cis/config.md) first, and then create a [scan policy](cis/policy.md) based on that configuration. After executing the scan policy, you can [view the scan report](cis/report.md). + +## Authorization Scan + +Authorization scanning focuses on security vulnerabilities caused by authorization issues. Authorization scans can help users identify security threats in Kubernetes clusters, identify which resources need further review and protection measures. By performing these checks, users can gain a clearer and more comprehensive understanding of their Kubernetes environment and ensure that the cluster environment meets Kubernetes' best practices and security standards. + +Specifically, authorization scanning supports the following operations: + +- Scans the health status of all nodes in the cluster. + +- Scans the running state of components in the cluster, such as __kube-apiserver__ , __kube-controller-manager__ , __kube-scheduler__ , etc. + +- Scans security configurations: Check Kubernetes' security configuration. + + - API security: whether unsafe API versions are enabled, whether appropriate RBAC roles and permission restrictions are set, etc. + - Container security: whether insecure images are used, whether privileged mode is enabled, whether appropriate security context is set, etc. + - Network security: whether appropriate network policy is enabled to restrict traffic, whether TLS encryption is used, etc. + - Storage security: whether appropriate encryption and access controls are enabled. + - Application security: whether necessary security measures are in place, such as password management, cross-site scripting attack defense, etc. + +- Provides warnings and suggestions: Security best practices that cluster administrators should perform, such as regularly rotating certificates, using strong passwords, restricting network access, etc. + +!!! tip + + To use authorization scanning, you need to create a scan policy first. After executing the scan policy, you can view the scan report. For details, refer to [Security Scanning](audit.md). + +## Vulnerability Scan + +Vulnerability scanning focuses on scanning potential malicious attacks and security vulnerabilities, such as remote code execution, SQL injection, XSS attacks, and some attacks specific to Kubernetes. The final scan report lists the security vulnerabilities in the cluster and provides repair suggestions. + +!!! tip + + To use vulnerability scanning, you need to create a scan policy first. After executing the scan policy, you can view the scan report. For details, refer to [Vulnerability Scan](hunter.md). \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/storage/pv.md b/docs/en/docs/kpanda/user-guide/storage/pv.md new file mode 100644 index 0000000..065d867 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/storage/pv.md @@ -0,0 +1,111 @@ +# data volume (PV) + +A data volume (PersistentVolume, PV) is a piece of storage in the cluster, which can be prepared in advance by the administrator, or dynamically prepared using a storage class (Storage Class). PV is a cluster resource, but it has an independent life cycle and will not be deleted when the Pod process ends. Mounting PVs to workloads can achieve data persistence for workloads. The PV holds the data directory that can be accessed by the containers in the Pod. + +## Create data volume + +Currently, there are two ways to create data volumes: YAML and form. These two ways have their own advantages and disadvantages, and can meet the needs of different users. + +- There are fewer steps and more efficient creation through YAML, but the threshold requirement is high, and you need to be familiar with the YAML file configuration of the data volume. + +- It is more intuitive and easier to create through the form, just fill in the corresponding values ​​according to the prompts, but the steps are more cumbersome. + +### YAML creation + +1. Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __Data Volume (PV)__ -> __Create with YAML__ in the left navigation bar. + + + +2. Enter or paste the prepared YAML file in the pop-up box, and click __OK__ at the bottom of the pop-up box. + + > Supports importing YAML files from local or downloading and saving filled files to local. + + + +### Form Creation + +1. Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __Data Volume (PV)__ -> __Create Data Volume (PV)__ in the left navigation bar. + + + +2. Fill in the basic information. + + - The data volume name, data volume type, mount path, volume mode, and node affinity cannot be changed after creation. + - Data volume type: For a detailed introduction to volume types, refer to the official Kubernetes document [Volumes](https://kubernetes.io/docs/concepts/storage/volumes/). + + - Local: The local storage of the Node node is packaged into a PVC interface, and the container directly uses the PVC without paying attention to the underlying storage type. Local volumes do not support dynamic configuration of data volumes, but support configuration of node affinity, which can limit which nodes can access the data volume. + - HostPath: Use files or directories on the file system of Node nodes as data volumes, and do not support Pod scheduling based on node affinity. + + - Mount path: mount the data volume to a specific directory in the container. + - access mode: + + - ReadWriteOnce: The data volume can be mounted by a node in read-write mode. + - ReadWriteMany: The data volume can be mounted by multiple nodes in read-write mode. + - ReadOnlyMany: The data volume can be mounted read-only by multiple nodes. + - ReadWriteOncePod: The data volume can be mounted read-write by a single Pod. + + - Recycling policy: + + - Retain: The PV is not deleted, but its status is only changed to __released__ , which needs to be manually recycled by the user. For how to manually reclaim, refer to [Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#retain). + - Recycle: keep the PV but empty its data, perform a basic wipe ( __rm -rf /thevolume/*__ ). + - Delete: When deleting a PV and its data. + + - Volume mode: + + - File system: The data volume will be mounted to a certain directory by the Pod. If the data volume is stored from a device and the device is currently empty, a file system is created on the device before the volume is mounted for the first time. + - Block: Use the data volume as a raw block device. This type of volume is given to the Pod as a block device without any file system on it, allowing the Pod to access the data volume faster. + + - Node affinity: + + + +## View data volume + +Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __Data Volume (PV)__ in the left navigation bar. + +- On this page, you can view all data volumes in the current cluster, as well as information such as the status, capacity, and namespace of each data volume. + +- Supports sequential or reverse sorting according to the name, status, namespace, and creation time of data volumes. + + + +- Click the name of a data volume to view the basic configuration, StorageClass information, labels, comments, etc. of the data volume. + + + +## Clone data volume + +By cloning a data volume, a new data volume can be recreated based on the configuration of the cloned data volume. + +1. Enter the clone page + + - On the data volume list page, find the data volume to be cloned, and select __Clone__ under the operation bar on the right. + + > You can also click the name of the data volume, click the operation button in the upper right corner of the details page and select __Clone__ . + + + +2. Use the original configuration directly, or modify it as needed, and click __OK__ at the bottom of the page. + +## Update data volume + +There are two ways to update data volumes. Support for updating data volumes via forms or YAML files. + +!!! note + + Only updating the alias, capacity, access mode, reclamation policy, label, and comment of the data volume is supported. + +- On the data volume list page, find the data volume that needs to be updated, select __Update__ under the operation bar on the right to update through the form, select __Edit YAML__ to update through YAML. + + + +- Click the name of the data volume to enter the details page of the data volume, select __Update__ in the upper right corner of the page to update through the form, select __Edit YAML__ to update through YAML. + + + +## Delete data volume + +On the data volume list page, find the data to be deleted, and select Delete in the operation column on the right. + +> You can also click the name of the data volume, click the operation button in the upper right corner of the details page and select __Delete__ . + diff --git a/docs/en/docs/kpanda/user-guide/storage/pvc.md b/docs/en/docs/kpanda/user-guide/storage/pvc.md new file mode 100644 index 0000000..e3894cf --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/storage/pvc.md @@ -0,0 +1,127 @@ +# Data volume declaration (PVC) + +A persistent volume claim (PersistentVolumeClaim, PVC) expresses a user's request for storage. PVC consumes PV resources and claims a data volume with a specific size and specific access mode. For example, the PV volume is required to be mounted in ReadWriteOnce, ReadOnlyMany or ReadWriteMany modes. + +## Create data volume statement + +Currently, there are two ways to create data volume declarations: YAML and form. These two ways have their own advantages and disadvantages, and can meet the needs of different users. + +- There are fewer steps and more efficient creation through YAML, but the threshold requirement is high, and you need to be familiar with the YAML file configuration of the data volume declaration. + +- It is more intuitive and easier to create through the form, just fill in the corresponding values ​​according to the prompts, but the steps are more cumbersome. + +### YAML creation + +1. Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __Data Volume Declaration (PVC)__ -> __Create with YAML__ in the left navigation bar. + + + +2. Enter or paste the prepared YAML file in the pop-up box, and click __OK__ at the bottom of the pop-up box. + + > Supports importing YAML files from local or downloading and saving filled files to local. + + + +### Form Creation + +1. Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __Data Volume Declaration (PVC)__ -> __Create Data Volume Declaration (PVC)__ in the left navigation bar. + + + +2. Fill in the basic information. + + - The name, namespace, creation method, data volume, capacity, and access mode of the data volume declaration cannot be changed after creation. + - Creation method: dynamically create a new data volume claim in an existing StorageClass or data volume, or create a new data volume claim based on a snapshot of a data volume claim. + + > The declared capacity of the data volume cannot be modified when the snapshot is created, and can be modified after the creation is complete. + + - After selecting the creation method, select the desired StorageClass/data volume/snapshot from the drop-down list. + - access mode: + + - ReadWriteOnce, the data volume declaration can be mounted by a node in read-write mode. + - ReadWriteMany, the data volume declaration can be mounted by multiple nodes in read-write mode. + - ReadOnlyMany, the data volume declaration can be mounted read-only by multiple nodes. + - ReadWriteOncePod, the data volume declaration can be mounted by a single Pod in read-write mode. + + + +## View data volume statement + +Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __Data Volume Declaration (PVC)__ in the left navigation bar. + +- On this page, you can view all data volume declarations in the current cluster, as well as information such as the status, capacity, and namespace of each data volume declaration. + +- Supports sorting in sequential or reverse order according to the declared name, status, namespace, and creation time of the data volume. + + + +- Click the name of the data volume declaration to view the basic configuration, StorageClass information, labels, comments and other information of the data volume declaration. + + + +## Expansion data volume statement + +1. In the left navigation bar, click __Container Storage__ -> __Data Volume Declaration (PVC)__ , and find the data volume declaration whose capacity you want to adjust. + + + +2. Click the name of the data volume declaration, and then click the operation button in the upper right corner of the page and select __Expansion__ . + + + +3. Enter the target capacity and click __OK__ . + + + +## Clone data volume statement + +By cloning a data volume claim, a new data volume claim can be recreated based on the configuration of the cloned data volume claim. + +1. Enter the clone page + + - On the data volume declaration list page, find the data volume declaration that needs to be cloned, and select __Clone__ under the operation bar on the right. + + > You can also click the name of the data volume declaration, click the operation button in the upper right corner of the details page and select __Clone__ . + + + +2. Use the original configuration directly, or modify it as needed, and click __OK__ at the bottom of the page. + + + +## Update data volume statement + +There are two ways to update data volume claims. Support for updating data volume claims via form or YAML file. + +!!! note + + Only aliases, labels, and annotations for data volume claims are updated. + +- On the data volume list page, find the data volume declaration that needs to be updated, select __Update__ in the operation bar on the right to update it through the form, and select __Edit YAML__ to update it through YAML. + + + +- Click the name of the data volume declaration, enter the details page of the data volume declaration, select __Update__ in the upper right corner of the page to update through the form, select __Edit YAML__ to update through YAML. + + + +## Delete data volume statement + +On the data volume declaration list page, find the data to be deleted, and select Delete in the operation column on the right. + +> You can also click the name of the data volume statement, click the operation button in the upper right corner of the details page and select __Delete__ . + + + +## common problem + +1. If there is no optional StorageClass or data volume in the list, you can [Create a StorageClass](sc.md) or [Create a data volume](pv.md). + +2. If there is no optional snapshot in the list, you can enter the details page of the data volume declaration and create a snapshot in the upper right corner. + + + +3. If the StorageClass (SC) used by the data volume declaration is not enabled for snapshots, snapshots cannot be made, and the page will not display the "Make Snapshot" option. +4. If the StorageClass (SC) used by the data volume declaration does not have the capacity expansion feature enabled, the data volume does not support capacity expansion, and the page will not display the capacity expansion option. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/storage/sc-share.md b/docs/en/docs/kpanda/user-guide/storage/sc-share.md new file mode 100644 index 0000000..01e13d5 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/storage/sc-share.md @@ -0,0 +1,14 @@ +# shared StorageClass + +The AI platform container management module supports sharing a StorageClass with multiple namespaces to improve resource utilization efficiency. + +1. Find the StorageClass that needs to be shared in the StorageClass list, and click __Authorize Namespace__ under the operation bar on the right. + + + +2. Click __Custom Namespace__ to select which namespaces this StorageClass needs to be shared to one by one. + + - Click __Authorize All Namespaces__ to share this StorageClass to all namespaces under the current cluster at one time. + - Click __Remove Authorization__ under the operation bar on the right side of the list to deauthorize and stop sharing this StorageClass to this namespace. + + \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/storage/sc.md b/docs/en/docs/kpanda/user-guide/storage/sc.md new file mode 100644 index 0000000..8ad09bf --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/storage/sc.md @@ -0,0 +1,68 @@ +# StorageClass (SC) + +A StorageClass refers to a large storage resource pool composed of many physical disks. This platform supports the creation of block StorageClass, local StorageClass, and custom StorageClass after accessing various storage vendors, and then dynamically configures data volumes for workloads. + +## Create StorageClass (SC) + +Currently, it supports creating StorageClass through YAML and forms. These two methods have their own advantages and disadvantages, and can meet the needs of different users. + +- There are fewer steps and more efficient creation through YAML, but the threshold requirement is high, and you need to be familiar with the YAML file configuration of the StorageClass. + +- It is more intuitive and easier to create through the form, just fill in the corresponding values ​​according to the prompts, but the steps are more cumbersome. + +### YAML creation + +1. Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __StorageClass (SC)__ -> __Create with YAML__ in the left navigation bar. + + + +2. Enter or paste the prepared YAML file in the pop-up box, and click __OK__ at the bottom of the pop-up box. + + > Supports importing YAML files from local or downloading and saving filled files to local. + + + +### Form Creation + +1. Click the name of the target cluster in the cluster list, and then click __Container Storage__ -> __StorageClass (SC)__ -> __Create StorageClass (SC)__ in the left navigation bar. + + + +2. Fill in the basic information and click __OK__ at the bottom. + + **CUSTOM STORAGE SYSTEM** + + - The StorageClass name, driver, and reclamation policy cannot be modified after creation. + - CSI storage driver: A standard Kubernetes-based container storage interface plug-in, which must comply with the format specified by the storage manufacturer, such as __rancher.io/local-path__ . + + - For how to fill in the CSI drivers provided by different vendors, refer to the official Kubernetes document [Storage Class](https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner). + - Recycling policy: When deleting a data volume, keep the data in the data volume or delete the data in it. + - Snapshot/Expansion: After it is enabled, the data volume/data volume declaration based on the StorageClass can support the expansion and snapshot features, but **the premise is that the underlying storage driver supports the snapshot and expansion features**. + + **HwameiStor storage system** + + - The StorageClass name, driver, and reclamation policy cannot be modified after creation. + - Storage system: HwameiStor storage system. + - Storage type: support LVM, raw disk type + - __LVM type__ : HwameiStor recommended usage method, which can use highly available data volumes, and the corresponding CSI storage driver is `lvm.hwameistor.io` . + - __Raw disk data volume__ : suitable for high availability cases, without high availability capability, the corresponding CSI driver is `hdd.hwameistor.io` . + - High Availability Mode: Before using the high availability capability, please make sure __DRBD component__ has been installed. After the high availability mode is turned on, the number of data volume copies can be set to 1 and 2. Convert data volume copy from 1 to 1 if needed. + - Recycling policy: When deleting a data volume, keep the data in the data volume or delete the data in it. + - Snapshot/Expansion: After it is enabled, the data volume/data volume declaration based on the StorageClass can support the expansion and snapshot features, but **the premise is that the underlying storage driver supports the snapshot and expansion features**. + + + +## Update StorageClass (SC) + +On the StorageClass list page, find the StorageClass that needs to be updated, and select Edit under the operation bar on the right to update the StorageClass. + + + +!!! info + + Select __View YAML__ to view the YAML file of the StorageClass, but editing is not supported. + +## Delete StorageClass (SC) + +On the StorageClass list page, find the StorageClass to be deleted, and select Delete in the operation column on the right. + diff --git a/docs/en/docs/kpanda/user-guide/workloads/create-cronjob.md b/docs/en/docs/kpanda/user-guide/workloads/create-cronjob.md new file mode 100644 index 0000000..9bb6a02 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/create-cronjob.md @@ -0,0 +1,209 @@ +--- +MTPE: FanLin +Date: 2024-02-29 +--- + +# Create CronJob + +This page introduces how to create a CronJob through images and YAML files. + +CronJobs are suitable for performing periodic operations, such as backup and report generation. These jobs can be configured to repeat periodically (for example: daily/weekly/monthly), and the time interval at which the job starts to run can be defined. + +## Prerequisites + +Before creating a CronJob, the following prerequisites need to be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md) and a [user](../../../ghippo/user-guide/access-control/user.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create by image + +Refer to the following steps to create a CronJob using the image. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the cluster details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __CronJobs__ in the left navigation bar, and then click the __Create by Image__ button in the upper right corner of the page. + + ![Create by image](../images/cronjob01.png) + +3. Fill in [Basic Information](create-cronjob.md#basic-information), [Container Settings](create-cronjob.md#container-settings), [CronJob Settings](create-cronjob.md#cronjob-settings), [Advanced Configuration](create-cronjob.md#advanced-configuration), click __OK__ in the lower right corner of the page to complete the creation. + + The system will automatically return to the __CronJobs__ list. Click __┇__ on the right side of the list to perform operations such as updating, deleting, and restarting the CronJob. + + ![Config](../images/cronjob06.png) + +### Basic information + +On the __Create CronJobs__ page, enter the information according to the table below, and click __Next__ . + +![Basic Information](../images/cronjob02.png) + +- Workload Name: Can contain up to 63 characters, can only contain lowercase letters, numbers, and a separator ("-"), and must start and end with a lowercase letter or number. The name of the same type of workload in the same namespace cannot be repeated, and the name of the workload cannot be changed after the workload is created. +- Namespace: Select which namespace to deploy the newly created CronJob in, and the default namespace is used by default. If you can't find the desired namespace, you can go to [Create a new namespace](../namespaces/createns.md) according to the prompt on the page. +- Description: Enter the description information of the workload and customize the content. The number of characters should not exceed 512. + +### Container settings + +Container setting is divided into six parts: basic information, life cycle, health check, environment variables, data storage, and security settings. Click the tab below to view the requirements of each part. + +> Container setting is only configured for a single container. To add multiple containers to a pod, click __+__ on the right to add multiple containers. + +=== "Basic information (required)" + + ![Basic Info](../images/cronjob03.png) + + When configuring container-related parameters, you must correctly fill in the container name and image parameters, otherwise you will not be able to proceed to the next step. After filling in the configuration with reference to the following requirements, click __OK__ . + + - Container Name: Up to 63 characters, lowercase letters, numbers and separators ("-") are supported. Must start and end with a lowercase letter or number, eg nginx-01. + - Image: Enter the address or name of the image. When entering the image name, the image will be pulled from the official [DockerHub](https://hub.docker.com/) by default. After accessing the [container registry](../../../kangaroo/intro/index.md) module of AI platform, you can click the right side to select the image ` to select the image. + - Image Pull Policy: After checking __Always pull the image__ , the image will be pulled from the registry every time the workload restarts/upgrades. If it is not checked, only the local mirror will be pulled, and only when the mirror does not exist locally, it will be re-pulled from the container registry. For more details, refer to [Image Pull Policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy). + - Privileged container: By default, the container cannot access any device on the host. After enabling the privileged container, the container can access all devices on the host and enjoy all the permissions of the running process on the host. + - CPU/Memory Quota: Requested value (minimum resource to be used) and limit value (maximum resource allowed to be used) of CPU/Memory resource. Please configure resources for containers as needed to avoid resource waste and system failures caused by excessive container resources. The default value is shown in the figure. + - GPU Exclusive: Configure the GPU usage for the container, only positive integers are supported. The GPU quota setting supports setting exclusive use of the entire GPU card or part of the vGPU for the container. For example, for an 8-core GPU card, enter the number __8__ to let the container exclusively use the entire length of the card, and enter the number __1__ to configure a 1-core vGPU for the container. + + > Before setting exclusive GPU, the administrator needs to install the GPU card and driver plug-in on the cluster nodes in advance, and enable the GPU feature in [Cluster Settings](../clusterops/cluster-settings.md). + +=== "Lifecycle (optional)" + + Set the commands that need to be executed when the container starts, after starting, and before stopping. For details, refer to [Container Lifecycle Configuration](pod-config/lifecycle.md). + + ![Lifecycle](../images/cronjob07.png) + +=== "Health Check (optional)" + + It is used to judge the health status of containers and applications, which helps to improve the availability of applications. For details, refer to [Container Health Check Configuration](pod-config/health-check.md). + + ![Health Check](../images/deploy07.png) + +=== "Environment variables (optional)" + + Configure container parameters within the Pod, add environment variables or pass configuration to the Pod, etc. For details, refer to [Container environment variable configuration](pod-config/env-variables.md). + + ![Environment Variables](../images/deploy08.png) + +=== "Data storage (optional)" + + Configure the settings for container mounting data volumes and data persistence. For details, refer to [Container Data Storage Configuration](pod-config/env-variables.md). + + ![Data storage](../images/deploy09.png) + +=== "Security settings (optional)" + + Containers are securely isolated through Linux's built-in account authority isolation mechanism. You can limit container permissions by using account UIDs (digital identity tokens) with different permissions. For example, enter __0__ to use the privileges of the root account. + + ![Security settings](../images/deploy10.png) + +### CronJob Settings + +![CronJob Settings](../images/cronjob04.png) + +- Concurrency Policy: Whether to allow multiple Job jobs to run in parallel. + + - __Allow__ : A new CronJob can be created before the previous job is completed, and multiple jobs can be parallelized. Too many jobs may occupy cluster resources. + - __Forbid__ : Before the previous job is completed, a new job cannot be created. If the execution time of the new job is up and the previous job has not been completed, CronJob will ignore the execution of the new job. + - __Replace__ : If the execution time of the new job is up, but the previous job has not been completed, the new job will replace the previous job. + + > The above rules only apply to multiple jobs created by the same CronJob. Multiple jobs created by multiple CronJobs are always allowed to run concurrently. + +- Policy Settings: Set the time period for job execution based on minutes, hours, days, weeks, and months. Support custom Cron expressions with numbers and `*` , **after inputting the expression, the meaning of the current expression will be prompted**. For detailed expression syntax rules, refer to [Cron Schedule Syntax](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax). +- Job Records: Set how many records of successful or failed jobs to keep. __0__ means do not keep. +- Timeout: When this time is exceeded, the job will be marked as failed to execute, and all Pods under the job will be deleted. When it is empty, it means that no timeout is set. The default is 360 s. +- Retries: the number of times the job can be retried, the default value is 6. +- Restart Policy: Set whether to restart the Pod when the job fails. + +### Service settings + +Configure [Service](../network/create-services.md) for the statefulset, so that the statefulset can be accessed externally. + +1. Click the __Create Service__ button. + + ![Create Service](../images/cronjob08.png) + +2. Refer to [Create Service](../network/create-services.md) to configure service parameters. + + ![Config Parameters](../images/deploy13.png) + +3. Click __OK__ and click __Next__ . + +### Advanced configuration + +The advanced configuration of CronJobs mainly involves labels and annotations. + +You can click the __Add__ button to add labels and annotations to the workload instance Pod. + +![Labels and Annotations](../images/cronjob05.png) + +## Create from YAML + +In addition to mirroring, you can also create timed jobs more quickly through YAML files. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the cluster details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __CronJobs__ in the left navigation bar, and then click the __Create from YAML__ button in the upper right corner of the page. + + ![Create](../images/cronjob09.png) + +3. Enter or paste the YAML file prepared in advance, click __OK__ to complete the creation. + + ![Confirm](../images/cronjob10.png) + +??? note "click to view the complete YAML" + + ```yaml + apiVersion: batch/v1 + kind: CronJob + metadata: + creationTimestamp: '2022-12-26T09:45:47Z' + generation: 1 + name: demo + namespace: default + resourceVersion: '92726617' + uid: d030d8d7-a405-4dcd-b09a-176942ef36c9 + spec: + concurrencyPolicy: Allow + failedJobsHistoryLimit: 1 + jobTemplate: + metadata: + creationTimestamp: null + spec: + activeDeadlineSeconds: 360 + backoffLimit: 6 + template: + metadata: + creationTimestamp: null + spec: + containers: + - image: nginx + imagePullPolicy: IfNotPresent + lifecycle: {} + name: container-3 + resources: + limits: + cpu: 250m + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + securityContext: + privileged: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + schedule: 0 0 13 * 5 + successfulJobsHistoryLimit: 3 + suspend: false + status: {} + ``` diff --git a/docs/en/docs/kpanda/user-guide/workloads/create-daemonset.md b/docs/en/docs/kpanda/user-guide/workloads/create-daemonset.md new file mode 100644 index 0000000..14c9e59 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/create-daemonset.md @@ -0,0 +1,376 @@ +--- +MTPE: FanLin +Date: 2024-02-28 +--- + +# Create DaemonSet + +This page introduces how to create a daemonSet through image and YAML files. + +DaemonSet is connected to [taint](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) through [node affinity]( ://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) feature ensures that a replica of a Pod is running on all or some of the nodes. For nodes that newly joined the cluster, DaemonSet automatically deploys the corresponding Pod on the new node and tracks the running status of the Pod. When a node is removed, the DaemonSet deletes all Pods it created. + +Common cases for daemons include: + +- Run cluster daemons on each node. +- Run a log collection daemon on each node. +- Run a monitoring daemon on each node. + +For simplicity, a DaemonSet can be started on each node for each type of daemon. For finer and more advanced daemon management, you can also deploy multiple DaemonSets for the same daemon. Each DaemonSet has different flags and has different memory, CPU requirements for different hardware types. + +## Prerequisites + +Before creating a DaemonSet, the following prerequisites need to be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md) and a [user](../../../ghippo/user-guide/access-control/user.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create by image + +Refer to the following steps to create a daemon using the image. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the cluster details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __DaemonSets__ in the left navigation bar, and then click the __Create by Image__ button in the upper right corner of the page. + + ![DaemonSet](../images/daemon01.png) + +3. Fill in [Basic Information](create-DaemonSet.md#basic-information), [Container Settings](create-DaemonSet.md#container-settings), [Service Settings](create-DaemonSet.md#service-settings), [Advanced Settings](create-DaemonSet.md#advanced-settings), click __OK__ in the lower right corner of the page to complete the creation. + + The system will automatically return the list of __DaemonSets__ . Click __┇__ on the right side of the list to perform operations such as updating, deleting, and restarting the DaemonSet. + + ![Daemons](../images/daemon05.png) + +### Basic information + +On the __Create DaemonSets__ page, after entering the information according to the table below, click __Next__ . + +![Basic Information](../images/daemon02.png) + +- Workload Name: Can contain up to 63 characters, can only contain lowercase letters, numbers, and a separator ("-"), and must start and end with a lowercase letter or number. The name of the same type of workload in the same namespace cannot be repeated, and the name of the workload cannot be changed after the workload is created. +- Namespace: Select which namespace to deploy the newly created DaemonSet in, and the default namespace is used by default. If you can't find the desired namespace, you can go to [Create a new namespace](../namespaces/createns.md) according to the prompt on the page. +- Description: Enter the description information of the workload and customize the content. The number of characters should not exceed 512. + +### Container settings + +Container setting is divided into six parts: basic information, life cycle, health check, environment variables, data storage, and security settings. Click the tab below to view the requirements of each part. + +> Container setting is only configured for a single container. To add multiple containers to a pod, click __+__ on the right to add multiple containers. + +=== "Basic information (required)" + + ![Basic Info](../images/daemon06.png) + + When configuring container-related parameters, you must correctly fill in the container name and image parameters, otherwise you will not be able to proceed to the next step. After filling in the settings with reference to the following requirements, click __OK__ . + + - Container Name: Up to 63 characters, lowercase letters, numbers and separators ("-") are supported. Must start and end with a lowercase letter or number, eg nginx-01. + - Image: Enter the address or name of the image. When entering the image name, the image will be pulled from the official [DockerHub](https://hub.docker.com/) by default. After accessing the [container registry](../../../kangaroo/intro/index.md) module of AI platform, you can click __Select Image__ on the right to select an image. + - Image Pull Policy: After checking __Always pull image__ , the image will be pulled from the registry every time the workload restarts/upgrades. If it is not checked, only the local image will be pulled, and only when the image does not exist locally, it will be re-pulled from the container registry. For more details, refer to [Image Pull Policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy). + - Privileged container: By default, the container cannot access any device on the host. After enabling the privileged container, the container can access all devices on the host and enjoy all the permissions of the running process on the host. + - CPU/Memory Quota: Requested value (minimum resource to be used) and limit value (maximum resource allowed to be used) of CPU/Memory resource. Please configure resources for containers as needed to avoid resource waste and system failures caused by excessive container resources. The default value is shown in the figure. + - GPU Exclusive: Configure the GPU usage for the container, only positive integers are supported. The GPU quota setting supports setting exclusive use of the entire GPU card or part of the vGPU for the container. For example, for an 8-core GPU card, enter the number __8__ to let the container exclusively use the entire length of the card, and enter the number __1__ to configure a 1-core vGPU for the container. + + > Before setting exclusive GPU, the administrator needs to install the GPU card and driver plug-in on the cluster nodes in advance, and enable the GPU feature in [Cluster Settings](../clusterops/cluster-settings.md). + +=== "Lifecycle (optional)" + + Set the commands that need to be executed when the container starts, after starting, and before stopping. For details, refer to [Container Lifecycle Configuration](pod-config/lifecycle.md). + + ![Lifecycle](../images/daemon006.png) + +=== "Health Check (optional)" + + It is used to judge the health status of containers and applications, which helps to improve the availability of applications. For details, refer to [Container Health Check Configuration](pod-config/health-check.md). + + ![Health Check](../images/deploy07.png) + +=== "Environment variables (optional)" + + Configure container parameters within the Pod, add environment variables or pass settings to the Pod, etc. For details, refer to [Container environment variable settings](pod-config/env-variables.md). + + ![Environment Variables](../images/deploy08.png) + +=== "Data storage (optional)" + + Configure the settings for container mounting data volumes and data persistence. For details, refer to [Container Data Storage Configuration](pod-config/env-variables.md). + + ![Data storage](../images/deploy09.png) + +=== "Security settings (optional)" + + Containers are securely isolated through Linux's built-in account authority isolation mechanism. You can limit container permissions by using account UIDs (digital identity tokens) with different permissions. For example, enter __0__ to use the privileges of the root account. + + ![Security settings](../images/deploy10.png) + +### Service settings + +Create a [Service (Service)](../network/create-services.md) for the daemon, so that the daemon can be accessed externally. + +1. Click the __Create Service__ button. + + ![Create Service](../images/daemon12.png) + +2. Configure service parameters, refer to [Create Service](../network/create-services.md) for details. + + ![Service Settings](../images/deploy13.png) + +3. Click __OK__ and click __Next__ . + +### Advanced settings + +Advanced setting includes four parts: load network settings, upgrade policy, scheduling policy, label and annotation. You can click the tabs below to view the requirements of each part. + +=== "Network Configuration" + + In some cases, the application will have redundant DNS queries. Kubernetes provides DNS-related settings options for applications, which can effectively reduce redundant DNS queries and increase business concurrency in certain cases. + + + + - DNS Policy + + - Default: Make the container use the domain name resolution file pointed to by the __--resolv-conf__ parameter of kubelet. This setting can only resolve external domain names registered on the Internet, but cannot resolve cluster internal domain names, and there is no invalid DNS query. + - ClusterFirstWithHostNet: The domain name file of the host to which the application is connected. + - ClusterFirst: application docking with Kube-DNS/CoreDNS. + - None: New option value introduced in Kubernetes v1.9 (Beta in v1.10). After setting to None, dnsConfig must be set, at this time the domain name of the containerThe parsing file will be completely generated through the settings of dnsConfig. + + - Nameservers: fill in the address of the domain name server, such as __10.6.175.20__ . + - Search domains: DNS search domain list for domain name query. When specified, the provided search domain list will be merged into the search field of the domain name resolution file generated based on dnsPolicy, and duplicate domain names will be deleted. Kubernetes allows up to 6 search domains. + - Options: Configuration options for DNS, where each object can have a name attribute (required) and a value attribute (optional). The content in this field will be merged into the options field of the domain name resolution file generated based on dnsPolicy. If some options of dnsConfig options conflict with the options of the domain name resolution file generated based on dnsPolicy, they will be overwritten by dnsConfig. + - Host Alias: the alias set for the host. + + ![DNS](../images/daemon17.png) + +=== "Upgrade Policy" + + - Upgrade Mode: __Rolling upgrade__ refers to gradually replacing instances of the old version with instances of the new version. During the upgrade process, business traffic will be load-balanced to the old and new instances at the same time, so the business will not be interrupted. __Rebuild and upgrade__ refers to deleting the workload instance of the old version first, and then installing the specified new version. During the upgrade process, the business will be interrupted. + - Max Unavailable Pods: Specify the maximum value or ratio of unavailable pods during the workload update process, the default is 25%. If it is equal to the number of instances, there is a risk of service interruption. + - Max Surge: The maximum or ratio of the total number of Pods exceeding the desired replica count of Pods during a Pod update. Default is 25%. + - Revision History Limit: Set the number of old versions retained when the version is rolled back. The default is 10. + - Minimum Ready: The minimum time for a Pod to be ready. Only after this time is the Pod considered available. The default is 0 seconds. + - Upgrade Max Duration: If the deployment is not successful after the set time, the workload will be marked as failed. Default is 600 seconds. + - Graceful Period: The execution period (0-9,999 seconds) of the command before the workload stops, the default is 30 seconds. + + ![Upgrade Policy](../images/daemon14.png) + +=== "Scheduling Policies" + + - Toleration time: When the node where the workload instance is located is unavailable, the time for rescheduling the workload instance to other available nodes, the default is 300 seconds. + - Node affinity: According to the label on the node, constrain which nodes the Pod can be scheduled on. + - Workload Affinity: Constrains which nodes a Pod can be scheduled to based on the labels of the Pods already running on the node. + - Workload anti-affinity: Constrains which nodes a Pod cannot be scheduled to based on the labels of Pods already running on the node. + - Topology domain: namely topologyKey, used to specify a group of nodes that can be scheduled. For example, __kubernetes.io/os__ indicates that as long as the node of an operating system meets the conditions of labelSelector, it can be scheduled to the node. + + > For details, refer to [Scheduling Policy](pod-config/scheduling-policy.md). + + ![Scheduling Policy](../images/daemon15.png) + +=== "Labels and Annotations" + + You can click the __Add__ button to add tags and annotations to workloads and pods. + + ![Labels and Annotations](../images/daemon16.png) + +## Create from YAML + +In addition to image, you can also create daemons more quickly through YAML files. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the __Cluster Details__ page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workload__ -> __Daemons__ in the left navigation bar, and then click the __YAML Create__ button in the upper right corner of the page. + + ![Deployments](../images/daemon02Yaml.png) + +3. Enter or paste the YAML file prepared in advance, click __OK__ to complete the creation. + + ![Confirm](../images/daemon03Yaml.png) + +??? note "Click to see an example YAML for creating a daemon" + + ```yaml + kind: DaemonSet + apiVersion: apps/v1 + metadata: + name: hwameistor-local-disk-manager + namespace: hwameistor + uid: ccbdc098-7de3-4a8a-96dd-d1cee159c92b + resourceVersion: '90999552' + generation: 1 + creationTimestamp: '2022-12-15T09:03:44Z' + labels: + app.kubernetes.io/managed-by: Helm + annotations: + deprecated.DaemonSet.template.generation: '1' + meta.helm.sh/release-name: hwameistor + meta.helm.sh/release-namespace:hwameistor + spec: + selector: + matchLabels: + app: hwameistor-local-disk-manager + template: + metadata: + creationTimestamp: null + labels: + app: hwameistor-local-disk-manager + spec: + volumes: + - name: udev + hostPath: + path: /run/udev + type: Directory + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + hostPath: + path: /dev + type: Directory + - name: socket-dir + hostPath: + path: /var/lib/kubelet/plugins/disk.hwameistor.io + type: DirectoryOrCreate + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: /var/lib/kubelet/pods + type: DirectoryOrCreate + containers: + - name: registrar + image: k8s-gcr.m.daocloud.io/sig-storage/csi-node-driver-registrar:v2.5.0 + args: + - '--v=5' + - '--csi-address=/csi/csi.sock' + - >- + --kubelet-registration-path=/var/lib/kubelet/plugins/disk.hwameistor.io/csi.sock + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + resources: {} + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + lifecycle: + preStop: + exec: + command: + - /bin/sh + - '-c' + - >- + rm -rf /registration/disk.hwameistor.io + /registration/disk.hwameistor.io-reg.sock + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + -name: managerimage: ghcr.m.daocloud.io/hwameistor/local-disk-manager:v0.6.1 + command: + - /local-disk-manager + args: + - '--endpoint=$(CSI_ENDPOINT)' + - '--nodeid=$(NODENAME)' + - '--csi-enable=true' + env: + - name: CSI_ENDPOINT + value: unix://var/lib/kubelet/plugins/disk.hwameistor.io/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: NODENAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OPERATOR_NAME + value: local-disk-manager + resources: {} + volumeMounts: + - name: udev + mountPath: /run/udev + - name: procmount + readOnly: true + mountPath: /host/proc + - name: devmount + mountPath: /dev + - name: registration-dir + mountPath: /var/lib/kubelet/plugins_registry + - name: plugin-dir + mountPath: /var/lib/kubelet/plugins + mountPropagation: Bidirectional + - name: pods-mount-dir + mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + privileged: true + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: hwameistor-admin + serviceAccount: hwameistor-admin + hostNetwork: true + hostPID: true + securityContext: {} + schedulerName: default-scheduler + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + - key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + effect: NoSchedule + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + revisionHistoryLimit: 10 + status: + currentNumberScheduled: 4 + numberMisscheduled: 0 + desiredNumberScheduled: 4 + numberReady: 4 + observedGeneration: 1 + updatedNumberScheduled: 4 + numberAvailable: 4 + ``` diff --git a/docs/en/docs/kpanda/user-guide/workloads/create-deployment.md b/docs/en/docs/kpanda/user-guide/workloads/create-deployment.md new file mode 100644 index 0000000..b2ae6e9 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/create-deployment.md @@ -0,0 +1,233 @@ +--- +MTPE: FanLin +Date: 2024-02-27 +--- + +# Create Deployment + +This page describes how to create deployments through images and YAML files. + +[Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) is a common resource in Kubernetes, mainly [Pod](https://kubernetes.io/docs/concepts/workloads/pods/) and [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/) provide declarative updates, support elastic scaling, rolling upgrades, and version rollbacks features. Declare the desired Pod state in the Deployment, and the Deployment Controller will modify the current state through the ReplicaSet to make it reach the pre-declared desired state. Deployment is stateless and does not support data persistence. It is suitable for deploying stateless applications that do not need to save data and can be restarted and rolled back at any time. + +Through the container management module of [AI platform](../../../dce/index.md), workloads on multicloud and multiclusters can be easily managed based on corresponding role permissions, including the creation of deployments, Full life cycle management such as update, deletion, elastic scaling, restart, and version rollback. + +## Prerequisites + +Before using image to create deployments, the following prerequisites need to be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md) and a [user](../../../ghippo/user-guide/access-control/user.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create by image + +Follow the steps below to create a deployment by image. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the Cluster Details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __Deployments__ in the left navigation bar, and then click the __Create by Image__ button in the upper right corner of the page. + + ![Deployment](../images/deploy02.png) + +3. Fill in [Basic Information](create-deployment.md#basic-information), [Container Setting](create-deployment.md#container-settings), [Service Setting](create-deployment.md#service-settings), [Advanced Setting](create-deployment.md#advanced-settings) in turn, click __OK__ in the lower right corner of the page to complete the creation. + + The system will automatically return the list of __Deployments__ . Click __┇__ on the right side of the list to perform operations such as update, delete, elastic scaling, restart, and version rollback on the load. If the workload status is abnormal, please check the specific abnormal information, refer to [Workload Status](../workloads/pod-config/workload-status.md). + + ![Menu](../images/deploy18.png) + +### Basic information + +- Workload Name: can contain up to 63 characters, can only contain lowercase letters, numbers, and a separator ("-"), and must start and end with a lowercase letter or number, such as deployment-01. The name of the same type of workload in the same namespace cannot be repeated, and the name of the workload cannot be changed after the workload is created. +- Namespace: Select the namespace where the newly created payload will be deployed. The default namespace is used by default. If you can't find the desired namespace, you can go to [Create a new namespace](../namespaces/createns.md) according to the prompt on the page. +- Pods: Enter the number of Pod instances for the load, and one Pod instance is created by default. +- Description: Enter the description information of the payload and customize the content. The number of characters cannot exceed 512. + +![Basic Information](../images/deploy04.png) + +### Container settings + +Container setting is divided into six parts: basic information, life cycle, health check, environment variables, data storage, and security settings. Click the tab below to view the requirements of each part. + +> Container setting is only configured for a single container. To add multiple containers to a pod, click __+__ on the right to add multiple containers. + +=== "Basic Information (Required)" + + When configuring container-related parameters, it is essential to correctly fill in the container name and image parameters; + otherwise, you will not be able to proceed to the next step. + After filling in the configuration according to the following requirements, click __OK__. + + ![Basic Info](../images/deploy05.png) + + - Container Type: The default is `Work Container`. For information on init containers, see the [K8s Official Documentation] + (https://kubernetes.io/docs/concepts/workloads/pods/init-containers/). + - Container Name: No more than 63 characters, supporting lowercase letters, numbers, and separators ("-"). + It must start and end with a lowercase letter or number, for example, nginx-01. + - Image: + - Image: Select an appropriate image from the list. When entering the image name, the default is to pull the image + from the official [DockerHub](https://hub.docker.com/). + After integrating the [Image Repository](../../../kangaroo/intro/index.md) module of AI platform, + you can click the __Choose an image__ button on the right to choose an image. + - Image Version: Select an appropriate version from the dropdown list. + - Image Pull Policy: By checking __Always pull the image__, the image will be pulled from the repository each time + the workload restarts/upgrades. + If unchecked, it will only pull the local image, and will pull from the repository only if the image does not exist locally. + For more details, refer to [Image Pull Policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy). + - Registry Secret: Optional. If the target repository requires a Secret to access, you need to [create secret](../configmaps-secrets/create-secret.md) first. + - Privileged Container: By default, the container cannot access any device on the host. After enabling the privileged container, + the container can access all devices on the host and has all the privileges of running processes on the host. + - CPU/Memory Request: The request value (the minimum resource needed) and the limit value (the maximum resource allowed) + for CPU/memory resources. Configure resources for the container as needed to avoid resource waste and system failures + caused by container resource overages. Default values are shown in the figure. + - GPU Configuration: Configure GPU usage for the container, supporting only positive integers. + The GPU quota setting supports configuring the container to exclusively use an entire GPU card or part of a vGPU. + For example, for a GPU card with 8 cores, entering the number __8__ means the container exclusively uses the entire card, + and entering the number __1__ means configuring 1 core of the vGPU for the container. + + > Before setting the GPU, the administrator needs to pre-install the GPU card and driver plugin on the cluster node + and enable the GPU feature in the [Cluster Settings](../clusterops/cluster-settings.md). + +=== "Lifecycle (optional)" + + Set the commands that need to be executed when the container starts, after starting, and before stopping. For details, refer to [Container Lifecycle Setting](pod-config/lifecycle.md). + + ![Lifecycle](../images/deploy06.png) + +=== "Health Check (optional)" + + It is used to judge the health status of containers and applications, which helps to improve the availability of applications. For details, refer to [Container Health Check Setting](pod-config/health-check.md). + + ![Health Check](../images/deploy07.png) + +=== "Environment variables (optional)" + + Configure container parameters within the Pod, add environment variables or pass setting to the Pod, etc. For details, refer to [Container environment variable setting](pod-config/env-variables.md). + + ![Environment variables](../images/deploy08.png) + +=== "Data storage (optional)" + + Configure the settings for container mounting data volumes and data persistence. For details, refer to [Container Data Storage Setting](pod-config/env-variables.md). + + ![Data storage](../images/deploy09.png) + +=== "Security settings (optional)" + + Containers are securely isolated through Linux's built-in account authority isolation mechanism. You can limit container permissions by using account UIDs (digital identity tokens) with different permissions. For example, enter __0__ to use the privileges of the root account. + + ![Security settings](../images/deploy10.png) + +### Service settings + +Configure [Service](../network/create-services.md) for the deployment, so that the deployment can be accessed externally. + +1. Click the __Create Service__ button. + + ![Create Service](../images/deploy12.png) + +2. Refer to [Create Service](../network/create-services.md) to configure service parameters. + + ![Service Settings](../images/deploy13.png) + +3. Click __OK__ and click __Next__ . + +### Advanced settings + +Advanced setting includes four parts: Network Settings, Upgrade Policy, Scheduling Policies, Labels and Annotations. You can click the tabs below to view the setting requirements of each part. + +=== "Network Settings" + + 1. For container NIC setting, refer to [Workload Usage IP Pool](../../../network/config/use-ippool/usage.md) + 2. DNS setting + + In some cases, the application will have redundant DNS queries. Kubernetes provides DNS-related setting options for applications, which can effectively reduce redundant DNS queries and increase business concurrency in certain cases. + + - DNS Policy + + - Default: Make container use kubelet's __-The domain name resolution file pointed to by the -resolv-conf__ parameter. This setting can only resolve external domain names registered on the Internet, but cannot resolve cluster internal domain names, and there is no invalid DNS query. + - ClusterFirstWithHostNet: The domain name file of the host to which the application is connected. + - ClusterFirst: application docking with Kube-DNS/CoreDNS. + - None: New option value introduced in Kubernetes v1.9 (Beta in v1.10). After setting to None, dnsConfig must be set. At this time, the domain name resolution file of the container will be completely generated through the setting of dnsConfig. + + - Nameservers: fill in the address of the domain name server, such as __10.6.175.20__ . + - Search domains: DNS search domain list for domain name query. When specified, the provided search domain list will be merged into the search field of the domain name resolution file generated based on dnsPolicy, and duplicate domain names will be deleted. Kubernetes allows up to 6 search domains. + - Options: Setting options for DNS, where each object can have a name attribute (required) and a value attribute (optional). The content in this field will be merged into the options field of the domain name resolution file generated based on dnsPolicy. If some options of dnsConfig options conflict with the options of the domain name resolution file generated based on dnsPolicy, they will be overwritten by dnsConfig. + - Host Alias: the alias set for the host. + + ![DNS](../images/deploy17.png) + +=== "Upgrade Policy" + + - Upgrade Mode: __Rolling upgrade__ refers to gradually replacing instances of the old version with instances of the new version. During the upgrade process, business traffic will be load-balanced to the old and new instances at the same time, so the business will not be interrupted. __Rebuild and upgrade__ refers to deleting the workload instance of the old version first, and then installing the specified new version. During the upgrade process, the business will be interrupted. + - Max Unavailable: Specify the maximum value or ratio of unavailable pods during the workload update process, the default is 25%. If it is equal to the number of instances, there is a risk of service interruption. + - Max Surge: The maximum or ratio of the total number of Pods exceeding the desired replica count of Pods during a Pod update. Default is 25%. + - Revision History Limit: Set the number of old versions retained when the version is rolled back. The default is 10. + - Minimum Ready: The minimum time for a Pod to be ready. Only after this time is the Pod considered available. The default is 0 seconds. + - Upgrade Max Duration: If the deployment is not successful after the set time, the workload will be marked as failed. Default is 600 seconds. + - Graceful Period: The execution period (0-9,999 seconds) of the command before the workload stops, the default is 30 seconds. + + ![Upgrade Policy](../images/deploy14.png) + +=== "Scheduling Policies" + + - Toleration time: When the node where the workload instance is located is unavailable, the time for rescheduling the workload instance to other available nodes, the default is 300 seconds. + - Node Affinity: According to the label on the node, constrain which nodes the Pod can be scheduled on. + - Workload Affinity: Constrains which nodes a Pod can be scheduled to based on the labels of the Pods already running on the node. + - Workload Anti-affinity: Constrains which nodes a Pod cannot be scheduled to based on the labels of Pods already running on the node. + + > For details, refer to [Scheduling Policy](pod-config/scheduling-policy.md). + + ![Scheduling Policy](../images/deploy15.png) + +=== "Labels and Annotations" + + You can click the __Add__ button to add tags and annotations to workloads and pods. + + ![Labels and Annotations](../images/deploy16.png) + +## Create from YAML + +In addition to image, you can also create deployments more quickly through YAML files. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the Cluster Details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __Deployments__ in the left navigation bar, and then click the __Create from YAML__ button in the upper right corner of the page. + + ![Deployments](../images/deploy02Yaml.png) + +3. Enter or paste the YAML file prepared in advance, click __OK__ to complete the creation. + + ![Confirm](../images/deploy03Yaml.png) + +??? note "Click to see an example YAML for creating a deployment" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-deployment + spec: + selector: + matchLabels: + app: nginx + replicas: 2 # (1)! + template: + metadata: + labels: + app: nginx + spec: + containers: + -name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + ``` + + 1. Tell the Deployment to run 2 Pods that match this template diff --git a/docs/en/docs/kpanda/user-guide/workloads/create-job.md b/docs/en/docs/kpanda/user-guide/workloads/create-job.md new file mode 100644 index 0000000..d9891e0 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/create-job.md @@ -0,0 +1,195 @@ +--- +MTPE: FanLin +Date: 2024-02-28 +--- + +# Create Job + +This page introduces how to create a job through image and YAML file. + +Job is suitable for performing one-time jobs. A Job creates one or more Pods, and the Job keeps retrying to run Pods until a certain number of Pods are successfully terminated. A Job ends when the specified number of Pods are successfully terminated. When a Job is deleted, all Pods created by the Job will be cleared. When a Job is paused, all active Pods in the Job are deleted until the Job is resumed. For more information about jobs, refer to [Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/). + +## Prerequisites + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md) and a [user](../../../ghippo/user-guide/access-control/user.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create by image + +Refer to the following steps to create a job using an image. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the cluster details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __Jobs__ in the left navigation bar, and then click the __Create by Image__ button in the upper right corner of the page. + + ![Jobs](../images/job01.png) + +3. Fill in [Basic Information](create-job.md#basic-information), [Container Settings](create-job.md#container-settings) and [Advanced Settings](create-job.md#advanced-settings), click __OK__ in the lower right corner of the page to complete the creation. + + The system will automatically return to the __job__ list. Click __┇__ on the right side of the list to perform operations such as updating, deleting, and restarting the job. + + ![Config](../images/job07.png) + +### Basic information + +On the __Create Jobs__ page, enter the basic information according to the table below, and click __Next__ . + +![Create Jobs](../images/job02.png) + +- Payload Name: Can contain up to 63 characters, can only contain lowercase letters, numbers, and a separator ("-"), and must start and end with a lowercase letter or number. The name of the same type of workload in the same namespace cannot be repeated, and the name of the workload cannot be changed after the workload is created. +- Namespace: Select which namespace to deploy the newly created job in, and the default namespace is used by default. If you can't find the desired namespace, you can go to [Create a new namespace](../namespaces/createns.md) according to the prompt on the page. +- Number of Instances: Enter the number of Pod instances for the workload. By default, 1 Pod instance is created. +- Description: Enter the description information of the workload and customize the content. The number of characters should not exceed 512. + +### Container settings + +Container setting is divided into six parts: basic information, life cycle, health check, environment variables, data storage, and security settings. Click the tab below to view the setting requirements of each part. + +> Container settings is only configured for a single container. To add multiple containers to a pod, click __+__ on the right to add multiple containers. + +=== "Basic information (required)" + + ![Basic Information](../images/job02-1.png) + + When configuring container-related parameters, you must correctly fill in the container name and image parameters, otherwise you will not be able to proceed to the next step. After filling in the settings with reference to the following requirements, click __OK__ . + + - Container Name: Up to 63 characters, lowercase letters, numbers and separators ("-") are supported. Must start and end with a lowercase letter or number, eg nginx-01. + - Image: Enter the address or name of the image. When entering the image name, the image will be pulled from the official [DockerHub](https://hub.docker.com/) by default. After accessing the [container registry](../../../kangaroo/intro/index.md) module of AI platform, you can click __Select Image__ on the right to select an image. + - Image Pull Policy: After checking __Always pull image__ , the image will be pulled from the registry every time the workload restarts/upgrades. If it is not checked, only the local image will be pulled, and only when the image does not exist locally, it will be re-pulled from the container registry. For more details, refer to [Image Pull Policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy). + - Privileged container: By default, the container cannot access any device on the host. After enabling the privileged container, the container can access all devices on the host and enjoy all the permissions of the running process on the host. + - CPU/Memory Quota: Requested value (minimum resource to be used) and limit value (maximum resource allowed to be used) of CPU/Memory resource. Please configure resources for containers as needed to avoid resource waste and system failures caused by excessive container resources. The default value is shown in the figure. + - GPU Exclusive: Configure the GPU usage for the container, only positive integers are supported. The GPU quota setting supports setting exclusive use of the entire GPU card or part of the vGPU for the container. For example, for an 8-core GPU card, enter the number __8__ to let the container exclusively use the entire length of the card, and enter the number __1__ to configure a 1-core vGPU for the container. + + > Before setting exclusive GPU, the administrator needs to install the GPU card and driver plug-in on the cluster nodes in advance, and enable the GPU feature in [Cluster Settings](../clusterops/cluster-settings.md). + +=== "Lifecycle (optional)" + + Set the commands that need to be executed when the container starts, after starting, and before stopping. For details, refer to [Container Lifecycle settings](pod-config/lifecycle.md). + + ![Lifecycle](../images/job06.png) + +=== "Health Check (optional)" + + It is used to judge the health status of containers and applications, which helps to improve the availability of applications. For details, refer to [Container Health Check settings](pod-config/health-check.md). + + ![Health Check](../images/deploy07.png) + +=== "Environment Variables (optional)" + + Configure container parameters within the Pod, add environment variables or pass settings to the Pod, etc. For details, refer to [Container environment variable settings](pod-config/env-variables.md). + + ![Environment Variables](../images/deploy08.png) + +=== "Data Storage (optional)" + + Configure the settings for container mounting data volumes and data persistence. For details, refer to [Container Data Storage settings](pod-config/env-variables.md). + + ![Data storage](../images/deploy09.png) + +=== "Security Settings (optional)" + + Containers are securely isolated through Linux's built-in account authority isolation mechanism. You can limit container permissions by using account UIDs (digital identity tokens) with different permissions. For example, enter __0__ to use the privileges of the root account. + + ![Security settings](../images/deploy10.png) + +### Advanced settings + +Advanced setting includes job settings, labels and annotations. + +=== "Job Settings" + + ![Job Settings](../images/job03.png) + + - Parallel Pods: the maximum number of Pods that can be created at the same time during job execution, and the parallel number should not be greater than the total number of Pods. Default is 1. + - Timeout: When this time is exceeded, the job will be marked as failed to execute, and all Pods under the job will be deleted. When it is empty, it means that no timeout is set. + - Restart Policy: Whether to restart the Pod when the setting fails. + +=== "Labels and Annotations" + + You can click the __Add__ button to add labels and annotations to the workload instance Pod. + + ![Labels and Annotations](../images/job04.png) + +## Create from YAML + +In addition to image, creation jobs can also be created more quickly through YAML files. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the cluster details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __Jobs__ in the left navigation bar, and then click the __Create from YAML__ button in the upper right corner of the page. + + ![Create](../images/job08.png) + +3. Enter or paste the YAML file prepared in advance, click __OK__ to complete the creation. + + ![Confirm](../images/job09.png) + +??? note "Click to view the complete YAML" + + ```yaml + kind: Job + apiVersion: batch/v1 + metadata: + name: demo + namespace: default + uid: a9708239-0358-4aa1-87d3-a092c080836e + resourceVersion: '92751876' + generation: 1 + creationTimestamp: '2022-12-26T10:52:22Z' + labels: + app: demo + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + job-name: demo + annotations: + revisions: >- + {"1":{"status":"running","uid":"a9708239-0358-4aa1-87d3-a092c080836e","start-time":"2022-12-26T10:52:22Z","completion-time":"0001-01-01T00:00:00Z"}} + spec: + parallelism: 1 + backoffLimit: 6 + selector: + matchLabels: + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + template: + metadata: + creationTimestamp: null + labels: + app: demo + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + job-name: demo + spec: + containers: + - name: container-4 + image: nginx + resources: + limits: + cpu: 250m + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + lifecycle: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + privileged: false + restartPolicy: Never + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: {} + schedulerName: default-scheduler + completionMode: NonIndexed + suspend: false + status: + startTime: '2022-12-26T10:52:22Z' + active: 1 + ``` diff --git a/docs/en/docs/kpanda/user-guide/workloads/create-statefulset.md b/docs/en/docs/kpanda/user-guide/workloads/create-statefulset.md new file mode 100644 index 0000000..8962e4d --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/create-statefulset.md @@ -0,0 +1,655 @@ +--- +MTPE: FanLin +Date: 2024-02-28 +--- + +# Create StatefulSet + +This page describes how to create a StatefulSet through image and YAML files. + +[StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) is a common resource in Kubernetes, and [Deployment](create-deployment.md), mainly used to manage the deployment and scaling of Pod collections. The main difference between the two is that Deployment is stateless and does not save data, while StatefulSet is stateful and is mainly used to manage stateful applications. In addition, Pods in a StatefulSet have a persistent ID, which makes it easy to identify the corresponding Pod when matching storage volumes. + +Through the container management module of [AI platform](../../../dce/index.md), workloads on multicloud and multiclusters can be easily managed based on corresponding role permissions, including the creation of StatefulSets, update, delete, elastic scaling, restart, version rollback and other full life cycle management. + +## Prerequisites + +Before using image to create StatefulSets, the following prerequisites need to be met: + +- In the [Container Management](../../intro/index.md) module [Access Kubernetes Cluster](../clusters/integrate-cluster.md) or [Create Kubernetes Cluster](../clusters/create-cluster.md), and can access the cluster UI interface. + +- Create a [namespace](../namespaces/createns.md) and a [user](../../../ghippo/user-guide/access-control/user.md). + +- The current operating user should have [NS Editor](../permissions/permission-brief.md#ns-editor) or higher permissions, for details, refer to [Namespace Authorization](../namespaces/createns.md). + +- When there are multiple containers in a single instance, please make sure that the ports used by the containers do not conflict, otherwise the deployment will fail. + +## Create by image + +Follow the steps below to create a statefulSet using image. + +1. Click __Clusters__ on the left navigation bar, then click the name of the target cluster to enter Cluster Details. + + ![Clusters](../images/deploy01.png) + +2. Click __Workloads__ -> __StatefulSets__ in the left navigation bar, and then click the __Create by Image__ button in the upper right corner. + + ![StatefulSets](../images/state02.png) + +3. Fill in [Basic Information](create-statefulset.md#basic-information), [Container Settings](create-statefulset.md#container-settings), [Service Settings](create-statefulset.md#service-settings), [Advanced Settings](create-statefulset.md#advanced-settings), click __OK__ in the lower right corner of the page to complete the creation. + + The system will automatically return to the list of __StatefulSets__ , and wait for the status of the workload to become __running__ . If the workload status is abnormal, refer to [Workload Status](../workloads/pod-config/workload-status.md) for specific exception information. + + Click __┇__ on the right side of the New Workload column to perform operations such as update, delete, elastic scaling, restart, and version rollback on the workload. + + ![Status](../images/state10.png) + +### Basic Information + +- Workload Name: can contain up to 63 characters, can only contain lowercase letters, numbers, and a separator ("-"), and must start and end with a lowercase letter or number, such as deployment-01. The name of the same type of workload in the same namespace cannot be repeated, and the name of the workload cannot be changed after the workload is created. +- Namespace: Select the namespace where the newly created payload will be deployed. The default namespace is used by default. If you can't find the desired namespace, you can go to [Create a new namespace](../namespaces/createns.md) according to the prompt on the page. +- Pods: Enter the number of Pod instances for the load, and one Pod instance is created by default. +- Description: Enter the description information of the payload and customize the content. The number of characters cannot exceed 512. + +![Basic Information](../images/state01.png) + +### Container settings + +Container setting is divided into six parts: basic information, life cycle, health check, environment variables, data storage, and security settings. Click the tab below to view the requirements of each part. + +> Container settings is only configured for a single container. To add multiple containers to a pod, click __+__ on the right to add multiple containers. + +=== "Basic information (required)" + + When configuring container-related parameters, you must correctly fill in the container name and image parameters, otherwise you will not be able to proceed to the next step. After filling in the settings with reference to the following requirements, click __OK__ . + + - Container Name: Up to 63 characters, lowercase letters, numbers and separators ("-") are supported. Must start and end with a lowercase letter or number, eg nginx-01. + - Image: Enter the address or name of the image. When entering the image name, the image will be pulled from the official [DockerHub](https://hub.docker.com/) by default. After accessing the [container registry](../../../kangaroo/intro/index.md) module of AI platform, you can click __Select Image__ on the right to select an image. + - Image Pull Policy: After checking __Always pull image__ , the image will be pulled from the registry every time the workload restarts/upgrades. If it is not checked, only the local image will be pulled, and only when the image does not exist locally, it will be re-pulled from the container registry. For more details, refer to [Image Pull Policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy). + - Privileged container: By default, the container cannot access any device on the host. After enabling the privileged container, the container can access all devices on the host and enjoy all the permissions of the running process on the host. + - CPU/Memory Quota: Requested value (minimum resource to be used) and limit value (maximum resource allowed to be used) of CPU/Memory resource. Please configure resources for containers as needed to avoid resource waste and system failures caused by excessive container resources. The default value is shown in the figure. + - GPU Exclusive: Configure the GPU usage for the container, only positive integers are supported. The GPU quota setting supports setting exclusive use of the entire GPU card or part of the vGPU for the container. For example, for an 8-core GPU card, enter the number __8__ to let the container exclusively use the entire length of the card, and enter the number __1__ to configure a 1-core vGPU for the container. + + > Before setting exclusive GPU, the administrator needs to install the GPU card and driver plug-in on the cluster nodes in advance, and enable the GPU feature in [Cluster Settings](../clusterops/cluster-settings.md). + + ![Basic Info](../images/state11.png) + +=== "Lifecycle (optional)" + + Set the commands that need to be executed when the container starts, after starting, and before stopping. For details, refer to [Container Lifecycle Configuration](pod-config/lifecycle.md). + + ![Lifecycle](../images/state06.png) + +=== "Health Check (optional)" + + Used to judge the health status of containers and applications. Helps improve app usability. For details, refer to [Container Health Check Configuration](pod-config/health-check.md). + + ![Health Check](../images/deploy07.png) + +=== "Environment Variables (optional)" + + Configure container parameters within the Pod, add environment variables or pass settings to the Pod, etc. For details, refer to [Container environment variable settings](pod-config/env-variables.md). + + ![Environment Variables](../images/deploy08.png) + +=== "Data Storage (optional)" + + Configure the settings for container mounting data volumes and data persistence. For details, refer to [Container Data Storage Configuration](pod-config/env-variables.md). + + ![Data Storage](../images/state09.png) + +=== "Security Settings (optional)" + + Containers are securely isolated through Linux's built-in account authority isolation mechanism. You can limit container permissions by using account UIDs (digital identity tokens) with different permissions. For example, enter __0__ to use the privileges of the root account. + + ![Security Settings](../images/deploy10.png) + +### Service settings + +Configure [Service (Service)](../network/create-services.md) for the statefulset, so that the statefulset can be accessed externally. + +1. Click the __Create Service__ button. + + ![Create Service](../images/state12.png) + +2. Refer to [Create Service](../network/create-services.md) to configure service parameters. + + ![Config Parameters](../images/deploy13.png) + +3. Click __OK__ and click __Next__ . + +### Advanced settings + +Advanced setting includes four parts: load network settings, upgrade policy, scheduling policy, label and annotation. You can click the tabs below to view the requirements of each part. + +=== "Network Configuration" + + 1. For container NIC settings, refer to [Workload Usage IP Pool](../../../network/config/use-ippool/usage.md) + 2. DNS settings + + In some cases, the application will have redundant DNS queries. Kubernetes provides DNS-related settings options for applications, which can effectively reduce redundant DNS queries and increase business concurrency in certain cases. + + - DNS Policy + + - Default: Make the container use the domain name resolution file pointed to by the __--resolv-conf__ parameter of kubelet. This setting can only resolve external domain names registered on the Internet, but cannot resolve cluster internal domain names, and there is no invalid DNS query. + - ClusterFirstWithHostNet: The domain name file of the application docking host. + - ClusterFirst: application docking with Kube-DNS/CoreDNS. + - None: New option value introduced in Kubernetes v1.9 (Beta in v1.10). After setting to None, dnsConfig must be set. At this time, the domain name resolution file of the container will be completely generated through the settings of dnsConfig. + + - Nameservers: fill in the address of the domain name server, such as __10.6.175.20__ . + - Search domains: DNS search domain list for domain name query. When specified, the provided search domain list will be merged into the search field of the domain name resolution file generated based on dnsPolicy, and duplicate domain names will be deleted. Kubernetes allows up to 6 search domains. + - Options: Configuration options for DNS, where each object can have a name attribute (required) and a value attribute (optional). The content in this field will be merged into the options field of the domain name resolution file generated based on dnsPolicy. If some options of dnsConfig options conflict with the options of the domain name resolution file generated based on dnsPolicy, they will be overwritten by dnsConfig. + - Host Alias: the alias set for the host. + + ![DNS](../images/state17.png) + +=== "Upgrade Policy" + + - Upgrade Mode: __Rolling upgrade__ refers to gradually replacing instances of the old version with instances of the new version. During the upgrade process, business traffic will be load-balanced to the old and new instances at the same time, so the business will not be interrupted. __Rebuild and upgrade__ refers to deleting the workload instance of the old version first, and then installing the specified new version. During the upgrade process, the business will be interrupted. + - Revision History Limit: Set the number of old versions retained when the version is rolled back. The default is 10. + - Graceful Period: The execution period (0-9,999 seconds) of the command before the workload stops, the default is 30 seconds. + + ![Upgrade Policy](../images/state14.png) + +=== "Container Management Policies" + + Kubernetes v1.7 and later versions can set Pod management policies through __.spec.podManagementPolicy__ , which supports the following two methods: + + - __OrderedReady__ : The default Pod management policy, which means that Pods are deployed in order. Only after the deployment of the previous Pod is successfully completed, the statefulset will start to deploy the next Pod. Pods are deleted in reverse order, with the last created being deleted first. + + - __Parallel__ : Create or delete containers in parallel, just like Pods of the Deployment type. The StatefulSet controller starts or terminates all containers in parallel. There is no need to wait for a Pod to enter the Running and ready state or to stop completely before starting or terminating other Pods. This option only affects the behavior of scaling operations, not the order of updates. + + ![Container Management Policies](../images/state05.png) + +=== "Scheduling Policies" + + - Tolerance time: When the node where the workload instance is located is unavailable, the time for rescheduling the workload instance to other available nodes, the default is 300 seconds. + - Node affinity: According to the label on the node, constrain which nodes the Pod can be scheduled on. + - Workload Affinity: Constrains which nodes a Pod can be scheduled to based on the labels of the Pods already running on the node. + - Workload anti-affinity: Constrains which nodes a Pod cannot be scheduled to based on the labels of Pods already running on the node. + - Topology domain: namely topologyKey, used to specify a group of nodes that can be scheduled. For example, __kubernetes.io/os__ indicates that as long as the node of an operating system meets the conditions of labelSelector, it can be scheduled to the node. + + > For details, refer to [Scheduling Policy](pod-config/scheduling-policy.md). + + ![Scheduling Policies](../images/state15.png) + +=== "Labels and Annotations" + + You can click the __Add__ button to add tags and annotations to workloads and pods. + + ![Labels and Annotations](../images/state16.png) + +## Create from YAML + +In addition to image, you can also create statefulsets more quickly through YAML files. + +1. Click __Clusters__ on the left navigation bar, and then click the name of the target cluster to enter the Cluster Details page. + + ![Clusters](../images/deploy01.png) + +2. On the cluster details page, click __Workloads__ -> __StatefulSets__ in the left navigation bar, and then click the __Create from YAML__ button in the upper right corner of the page. + + ![Workloads](../images/state02Yaml.png) + +3. Enter or paste the YAML file prepared in advance, click __OK__ to complete the creation. + + ![Confirm](../images/state03yaml.png) + +??? note "Click to see an example YAML for creating a statefulSet" + + ```yaml + kind: StatefulSet + apiVersion: apps/v1 + metadata: + name: test-mysql-123-mysql + namespace: default + uid: d3f45527-a0ab-4b22-9013-5842a06f4e0e + resourceVersion: '20504385' + generation: 1 + creationTimestamp: '2022-09-22T09:34:10Z' + ownerReferences: + - apiVersion: mysql.presslabs.org/v1alpha1 + kind: MysqlCluster + name: test-mysql-123 + uid: 5e877cc3-5167-49da-904e-820940cf1a6d + controller: true + blockOwnerDeletion: true + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + mysql.presslabs.org/cluster: test-mysql-123 + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: test-mysql-123 + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + app.kubernetes.io/version: 5.7.31 + mysql.presslabs.org/cluster: test-mysql-123 + annotations: + config_rev: '13941099' + prometheus.io/port: '9125' + prometheus.io/scrape: 'true' + secret_rev: '13941101' + spec: + volumes: + -name: conf + emptyDir: {} + - name: init-scripts + emptyDir: {} + - name: config-map + configMap: + name: test-mysql-123-mysql + defaultMode: 420 + - name: data + persistentVolumeClaim: + claimName: data + initContainers: + -name: init + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - clone-and-init + envFrom: + - secretRef: + name: test-mysql-123-mysql-operated + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef:apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: BACKUP_USER + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: BACKUP_USER + optional: true + - name: BACKUP_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: BACKUP_PASSWORD + optional: true + resources: {} + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: config-map + mountPath: /mnt/conf + - name: data + mountPath: /var/lib/mysql + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + containers: + - name: mysql + image: docker.m.daocloud.io/mysql:5.7.31 + ports: + - name: mysql + containerPort: 3306 + protocol: TCP + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: ORCH_CLUSTER_ALIAS + value: test-mysql-123.default + - name: ORCH_HTTP_API + value: http://mysql-operator.mcamel-system/api + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: ROOT_PASSWORD + optional: false + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: USER + optional: true + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: PASSWORD + optional: true + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: DATABASE + optional: true + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 100m + memory: 512Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: data + mountPath: /var/lib/mysql + livenessProbe: + exec: + command: + - mysqladmin + - '--defaults-file=/etc/mysql/client.conf' + - ping + initialDelaySeconds: 60 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + test $(mysql --defaults-file=/etc/mysql/client.conf -NB -e + 'SELECT COUNT(*) FROM sys_operator.status WHERE + name="configured" AND value="1"') -eq 1 + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 2 + successThreshold: 1 + failureThreshold: 3 + lifecycle:preStop: + exec: + command: + - bash + - /etc/mysql/pre-shutdown-ha.sh + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: sidecar + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - config-and-serve + ports: + - name: sidecar-http + containerPort: 8080 + protocol: TCP + envFrom: + - secretRef: + name: test-mysql-123-mysql-operated + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: XTRABACKUP_TARGET_DIR + value: /tmp/xtrabackup_backupfiles/ + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 10m + memory: 64Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: data + mountPath: /var/lib/mysql + readinessProbe: + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: metrics-exporter + image: prom/mysqld-exporter:v0.13.0 + args: + - '--web.listen-address=0.0.0.0:9125' + - '--web.telemetry-path=/metrics' + - '--collect.heartbeat' + - '--collect.heartbeat.database=sys_operator' + ports: + - name: prometheus + containerPort: 9125 + protocol: TCP + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: USER + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: METRICS_EXPORTER_USER + optional: false + - name: PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: METRICS_EXPORTER_PASSWORD + optional: false + - name: DATA_SOURCE_NAME + value: $(USER):$(PASSWORD)@(127.0.0.1:3306)/ + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 32Mi + livenessProbe: + httpGet: + path: /metrics + port: 9125 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 30 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: pt-heartbeat + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - pt-heartbeat + - '--update' + - '--replace' + - '--check-read-only' + - '--create-table' + - '--database' + - sys_operator + - '--table' + - heartbeat + - '--utc' + - '--defaults-file' + - /etc/mysql/heartbeat.conf + - '--fail-successive-errors=20' + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 10m + memory: 32Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: + runAsUser: 999 + fsGroup: 999 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: test-mysql-123 + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + app.kubernetes.io/version: 5.7.31 + mysql.presslabs.org/cluster: test-mysql-123 + topologyKey: kubernetes.io/hostname + schedulerName: default-scheduler + volumeClaimTemplates: + - kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: data + creationTimestamp: null + ownerReferences: + - apiVersion: mysql.presslabs.org/v1alpha1 + kind: MysqlCluster + name: test-mysql-123 + uid: 5e877cc3-5167-49da-904e-820940cf1a6d + controller: true + spec: + accessModes: + - ReadWriteOnce + resources: + limits: + storage: 1Gi + requests: + storage: 1Gi + storageClassName: local-path + volumeMode: Filesystem + status: + phase: Pending + serviceName: mysql + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: 0 + revisionHistoryLimit: 10 + status: + observedGeneration: 1 + replicas: 1 + readyReplicas: 1 + currentReplicas: 1 + updatedReplicas: 1 + currentRevision: test-mysql-123-mysql-6b8f5577c7 + updateRevision: test-mysql-123-mysql-6b8f5577c7 + collisionCount: 0 + availableReplicas: 1 + ``` diff --git a/docs/en/docs/kpanda/user-guide/workloads/pod-config/env-variables.md b/docs/en/docs/kpanda/user-guide/workloads/pod-config/env-variables.md new file mode 100644 index 0000000..1714e8f --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/pod-config/env-variables.md @@ -0,0 +1,19 @@ +# Configure environment variables + +An environment variable refers to a variable set in the container running environment, which is used to add environment flags to Pods or transfer configurations, etc. It supports configuring environment variables for Pods in the form of key-value pairs. + +Suanova container management adds a graphical interface to configure environment variables for Pods on the basis of native Kubernetes, and supports the following configuration methods: + +- **Key-value pair** (Key/Value Pair): Use a custom key-value pair as the environment variable of the container + +- **Resource reference** (Resource): Use the fields defined by Container as the value of environment variables, such as the memory limit of the container, the number of copies, etc. + +- **Variable/Variable Reference** (Pod Field): Use the Pod field as the value of an environment variable, such as the name of the Pod + +- **ConfigMap key value import** (ConfigMap key): Import the value of a key in the ConfigMap as the value of an environment variable + +- **Key key value import** (Secret Key): use the data from the Secret to define the value of the environment variable + +- **Key Import** (Secret): Import all key values ​​in Secret as environment variables + +- **ConfigMap import** (ConfigMap): import all key values ​​in the ConfigMap as environment variables \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/workloads/pod-config/health-check.md b/docs/en/docs/kpanda/user-guide/workloads/pod-config/health-check.md new file mode 100644 index 0000000..f4c2f72 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/pod-config/health-check.md @@ -0,0 +1,163 @@ +--- +MTPE: windsonsea +Date: 2024-10-15 +--- + +# Container health check + +Container health check checks the health status of containers according to user requirements. After configuration, if the application in the container is abnormal, the container will automatically restart and recover. Kubernetes provides Liveness checks, Readiness checks, and Startup checks. + +- **LivenessProbe** can detect application deadlock (the application is running, but cannot continue to run the following steps). Restarting containers in this state can help improve the availability of applications, even if there are bugs in them. + +- **ReadinessProbe** can detect when a container is ready to accept request traffic. A Pod can only be considered ready when all containers in a Pod are ready. One use of this signal is to control which Pod is used as the backend of the Service. If the Pod is not ready, it will be removed from the Service's load balancer. + +- **Startup check (StartupProbe)** can know when the application container is started. After configuration, it can control the container to check the viability and readiness after it starts successfully, so as to ensure that these liveness and readiness probes will not affect the start of the application. Startup detection can be used to perform liveness checks on slow-starting containers, preventing them from being killed before they start running. + +## Liveness and readiness checks + +The configuration of LivenessProbe is similar to that of ReadinessProbe, the only difference is to use __readinessProbe__ field instead of __livenessProbe__ field. + +**HTTP GET parameter description:** + +| Parameter | Description | +| --------- | ----------- | +| Path (Path) | The requested path for access. Such as: /healthz path in the example | +| Port (Port) | Service listening port. Such as: port 8080 in the example | +| protocol | access protocol, Http or Https | +| Delay time (initialDelaySeconds) | Delay check time, in seconds, this setting is related to the normal startup time of business programs. For example, if it is set to 30, it means that the health check will start 30 seconds after the container is started, which is the time reserved for business program startup. | +| Timeout (timeoutSeconds) | Timeout, in seconds. For example, if it is set to 10, it indicates that the timeout waiting period for executing the health check is 10 seconds. If this time is exceeded, the health check will be regarded as a failure. If set to 0 or not set, the default timeout waiting time is 1 second. | +| Timeout (timeoutSeconds) | Timeout, in seconds. For example, if it is set to 10, it indicates that the timeout waiting period for executing the health check is 10 seconds. If this time is exceeded, the health check will be regarded as a failure. If set to 0 or not set, the default timeout waiting time is 1 second. | +| SuccessThreshold (successThreshold) | The minimum number of consecutive successes that are considered successful after a probe fails. The default value is 1, and the minimum value is 1. This value must be 1 for liveness and startup probes. | +| Maximum number of failures (failureThreshold) | The number of retries when the probe fails. Giving up in case of a liveness probe means restarting the container. Pods that are abandoned due to readiness probes are marked as not ready. The default value is 3. The minimum value is 1. | + +### Check with HTTP GET request + +**YAML example:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-http +spec: + containers: + - name: liveness # Container name + image: k8s.gcr.io/liveness # Container image + args: + - /server # Arguments to pass to the container + livenessProbe: + httpGet: + path: /healthz # Access request path + port: 8080 # Service listening port + httpHeaders: + - name: Custom-Header # Custom header name + value: Awesome # Custom header value + initialDelaySeconds: 3 # Wait 3 seconds before the first probe + periodSeconds: 3 # Perform liveness detection every 3 seconds +``` + +According to the set rules, Kubelet sends an HTTP GET request to the service running in the container (the service is listening on port 8080) to perform the detection. The kubelet considers the container alive if the handler under the __/healthz__ path on the server returns a success code. If the handler returns a failure code, the kubelet kills the container and restarts it. Any return code greater than or equal to 200 and less than 400 indicates success, and any other return code indicates failure. The __/healthz__ handler returns a 200 status code for the first 10 seconds of the container's lifetime. The handler then returns a status code of 500. + +### Use TCP port check + +**TCP port parameter description:** + +| Parameter | Description | +| --------- | ----------- | +| Port (Port) | Service listening port. Such as: port 8080 in the example | +| Delay time (initialDelaySeconds) | Delay check time, in seconds, this setting is related to the normal startup time of business programs. For example, if it is set to 30, it means that the health check will start 30 seconds after the container is started, which is the time reserved for business program startup. | +| Timeout (timeoutSeconds) | Timeout, in seconds. For example, if it is set to 10, it indicates that the timeout waiting period for executing the health check is 10 seconds. If this time is exceeded, the health check will be regarded as a failure. If set to 0 or not set, the default timeout waiting time is 1 second. | + +For a container that provides TCP communication services, based on this configuration, the cluster establishes a TCP connection to the container according to the set rules. If the connection is successful, it proves that the detection is successful, otherwise the detection fails. If you choose the TCP port detection method, you must specify the port that the container listens to. + +**YAML example:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: goproxy + labels: + app: goproxy +spec: + containers: + - name: goproxy + image: k8s.gcr.io/goproxy:0.1 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 +``` + +This example uses both readiness and liveness probes. The kubelet sends the first readiness probe 5 seconds after the container is started. Attempt to connect to port 8080 of the __goproxy__ container. If the probe is successful, the Pod will be marked as ready and the kubelet will continue to run the check every 10 seconds. + +In addition to the readiness probe, this configuration includes a liveness probe. The kubelet will perform the first liveness probe 15 seconds after the container is started. The readiness probe will attempt to connect to the __goproxy__ container on port 8080. If the liveness probe fails, the container will be restarted. + +### Run command check + +**YAML example:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-exec +spec: + containers: + - name: liveness # Container name + image: k8s.gcr.io/busybox # Container image + args: + - /bin/sh # Command to run + - -c # Pass the following string as a command + - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600 # Command to execute + livenessProbe: + exec: + command: + - cat # Command to check liveness + - /tmp/healthy # File to check + initialDelaySeconds: 5 # Wait 5 seconds before the first probe + periodSeconds: 5 # Perform liveness detection every 5 seconds +``` + +The __periodSeconds__ field specifies that the kubelet performs a liveness probe every 5 seconds, and the __initialDelaySeconds__ field specifies that the kubelet waits for 5 seconds before performing the first probe. According to the set rules, the cluster periodically executes the command __cat /tmp/healthy__ in the container through the kubelet to detect. If the command executes successfully and the return value is 0, the kubelet considers the container to be healthy and alive. If this command returns a non-zero value, the kubelet will kill the container and restart it. + +### Protect slow-starting containers with pre-start checks + +Some applications require a long initialization time at startup. You need to use the same command to set startup detection. For HTTP or TCP detection, you can set the __failureThreshold * periodSeconds__ parameter to a long enough time to cope with the long startup time scene. + +**YAML example:** + +```yaml +ports: +- name: liveness-port + containerPort: 8080 + hostPort: 8080 + +livenessProbe: + httpGet: + path: /healthz + port: liveness-port + failureThreshold: 1 + periodSeconds: 10 + +startupProbe: + httpGet: + path: /healthz + port: liveness-port + failureThreshold: 30 + periodSeconds: 10 +``` + +With the above settings, the application will have up to 5 minutes (30 * 10 = 300s) to complete the startup process. Once the startup detection is successful, the survival detection task will take over the detection of the container and respond quickly to the container deadlock. If the start probe has been unsuccessful, the container is killed after 300 seconds and further disposition is performed according to the __restartPolicy__ . \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/workloads/pod-config/job-parameters.md b/docs/en/docs/kpanda/user-guide/workloads/pod-config/job-parameters.md new file mode 100644 index 0000000..4deda31 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/pod-config/job-parameters.md @@ -0,0 +1,51 @@ +--- +MTPE: windsonsea +Date: 2024-10-15 +--- + +# Description of job parameters + +According to the settings of __.spec.completions__ and __.spec.Parallelism__ , jobs (Job) can be divided into the following types: + +| Job Type | Description | +| -------- | ----------- | +| Non-parallel Job | Creates a Pod until its Job completes successfully | +| Parallel Jobs with deterministic completion counts | A Job is considered complete when the number of successful Pods reaches __.spec.completions__ | +| Parallel Job | Creates one or more Pods until one finishes successfully | + +**Parameter Description** + +| RestartPolicy | Creates a Pod until it terminates successfully | +| ------------- | ---------------------------------------------- | +| .spec.completions | Indicates the number of Pods that need to run successfully when the Job ends, the default is 1 | +| .spec.parallelism | Indicates the number of Pods running in parallel, the default is 1 | +| spec.backoffLimit | Indicates the maximum number of retries for a failed Pod, beyond which no more retries will continue. | +| .spec.activeDeadlineSeconds | Indicates the Pod running time. Once this time is reached, the Job, that is, all its Pods, will stop. And activeDeadlineSeconds has a higher priority than backoffLimit, that is, the job that reaches activeDeadlineSeconds will ignore the setting of backoffLimit. | + +The following is an example Job configuration, saved in myjob.yaml, which calculates π to 2000 digits and prints the output. + +```yaml +apiVersion: batch/v1 +kind: Job #The type of the current resource +metadata: + name: myjob +spec: + completions: 50 # Job needs to run 50 Pods at the end, in this example it prints π 50 times + parallelism: 5 # 5 Pods in parallel + backoffLimit: 5 # retry up to 5 times + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never #restart policy +``` + +**Related commands** + +```bash +kubectl apply -f myjob.yaml # Start job +kubectl get job # View this job +kubectl logs myjob-1122dswzs View Job Pod logs +``` diff --git a/docs/en/docs/kpanda/user-guide/workloads/pod-config/lifecycle.md b/docs/en/docs/kpanda/user-guide/workloads/pod-config/lifecycle.md new file mode 100644 index 0000000..0cf8c4a --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/pod-config/lifecycle.md @@ -0,0 +1,60 @@ +--- +MTPE: windsonsea +Date: 2024-10-15 +--- + +# Configure the container lifecycle + +Pods follow a predefined lifecycle, starting in the __Pending__ phase and entering the __Running__ state if at least one container in the Pod starts normally. If any container in the Pod ends in a failed state, the state becomes __Failed__ . The following __phase__ field values ​​indicate which phase of the lifecycle a Pod is in. + +| Value | Description | +| ----- | ----------- | +| __Pending__
| The Pod has been accepted by the system, but one or more containers have not yet been created or run. This phase includes waiting for the pod to be scheduled and downloading the image over the network. | +| __Running__
(Running) | The Pod has been bound to a node, and all containers in the Pod have been created. At least one container is still running, or in the process of starting or restarting. | +| __Succeeded__
(Success) | All containers in the Pod were successfully terminated and will not be restarted. | +| __Failed__
| All containers in the Pod have terminated, and at least one container terminated due to failure. That is, the container exited with a non-zero status or was terminated by the system. | +| __Unknown__
(Unknown) | The status of the Pod cannot be obtained for some reason, usually due to a communication failure with the host where the Pod resides. | + +When creating a workload in Suanova container management, images are usually used to specify the running environment in the container. By default, when building an image, the __Entrypoint__ and __CMD__ fields can be used to define the commands and parameters to be executed when the container is running. If you need to change the commands and parameters of the container image before starting, after starting, and before stopping, you can override the default commands and parameters in the image by setting the lifecycle event commands and parameters of the container. + +## Lifecycle configuration + +Configure the startup command, post-start command, and pre-stop command of the container according to business needs. + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Start command | Type: Optional
Meaning: The container will be started according to the start command. | | +| Command after startup | Type: optional
Meaning: command after container startup
| | +| Command before stopping | Type: Optional
Meaning: The command executed by the container after receiving the stop command. Ensure that the services running in the instance can be drained in advance when the instance is upgraded or deleted. | - | + +### start command + +Configure the startup command according to the table below. + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Run command | Type: Required
Meaning: Enter an executable command, and separate multiple commands with spaces. If the command itself has spaces, you need to add ("").
Meaning: When there are multiple commands, it is recommended to use /bin/sh or other shells to run the command, and pass in all other commands as parameters. | /run/server | +| Running parameters | Type: Optional
Meaning: Enter the parameters of the control container running command.
| port=8080 | + +### Post-start commands + +Suanova provides two processing types, command line script and HTTP request, to configure post-start commands. You can choose the configuration method that suits you according to the table below. + +**Command line script configuration** + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| Run Command | Type: Optional
Meaning: Enter an executable command, and separate multiple commands with spaces. If the command itself contains spaces, you need to add ("").
Meaning: When there are multiple commands, it is recommended to use /bin/sh or other shells to run the command, and pass in all other commands as parameters. | /run/server | +| Running parameters | Type: Optional
Meaning: Enter the parameters of the control container running command.
| port=8080 | + +### stop pre-command + +Suanova provides two processing types, command line script and HTTP request, to configure the pre-stop command. You can choose the configuration method that suits you according to the table below. + +**HTTP request configuration** + +| Parameter | Description | Example value | +| --------- | ----------- | ------------- | +| URL Path | Type: Optional
Meaning: Requested URL path.
Meaning: When there are multiple commands, it is recommended to use /bin/sh or other shells to run the command, and pass in all other commands as parameters. | /run/server | +| Port | Type: Required
Meaning: Requested port.
| port=8080 | +| Node Address | Type: Optional
Meaning: The requested IP address, the default is the node IP where the container is located.
| - | \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/workloads/pod-config/scheduling-policy.md b/docs/en/docs/kpanda/user-guide/workloads/pod-config/scheduling-policy.md new file mode 100644 index 0000000..8d85887 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/pod-config/scheduling-policy.md @@ -0,0 +1,98 @@ +# Scheduling Policy + +In a Kubernetes cluster, like many other Kubernetes objects, nodes have [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/). You can [manually add labels](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes/#add-a-label-to-a-node). Kubernetes also adds some standard labels to all nodes in the cluster. See [Common Labels, Annotations, and Taints](https://kubernetes.io/docs/reference/labels-annotations-taints/) for common node labels. By adding labels to nodes, you can have pods scheduled on specific nodes or groups of nodes. You can use this feature to ensure that specific Pods can only run on nodes with certain isolation, security or governance properties. + +__nodeSelector__ is the simplest recommended form of a node selection constraint. You can add a __nodeSelector__ field to the Pod's spec to set the [node label](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#built -in-node-labels). Kubernetes will only schedule pods on nodes with each label specified. __nodeSelector__ provides one of the easiest ways to constrain Pods to nodes with specific labels. Affinity and anti-affinity expand the types of constraints you can define. Some benefits of using affinity and anti-affinity are: + +- Affinity and anti-affinity languages are more expressive. __nodeSelector__ can only select nodes that have all the specified labels. Affinity, anti-affinity give you greater control over selection logic. + +- You can mark a rule as "soft demand" or "preference", so that the scheduler will still schedule the Pod if no matching node can be found. + +- You can use the labels of other Pods running on the node (or in other topological domains) to enforce scheduling constraints, instead of only using the labels of the node itself. This capability allows you to define rules which allow Pods to be placed together. + +You can choose which node the Pod will deploy to by setting affinity and anti-affinity. + +## Tolerance time + +When the node where the workload instance is located is unavailable, the period for the system to reschedule the instance to other available nodes. The default is 300 seconds. + +## Node affinity (nodeAffinity) + +Node affinity is conceptually similar to __nodeSelector__ , which allows you to constrain which nodes Pods can be scheduled on based on the labels on the nodes. There are two types of node affinity: + +- **Must be satisfied: ( __requiredDuringSchedulingIgnoredDuringExecution__ )** The scheduler can only run scheduling when the rules are satisfied. This functionality is similar to __nodeSelector__ , but with a more expressive syntax. You can define multiple hard constraint rules, but only one of them must be satisfied. + +- **Satisfy as much as possible: ( __preferredDuringSchedulingIgnoredDuringExecution__ )** The scheduler will try to find nodes that meet the corresponding rules. If no matching node is found, the scheduler will still schedule the Pod. You can also set weights for soft constraint rules. During specific scheduling, if there are multiple nodes that meet the conditions, the node with the highest weight will be scheduled first. At the same time, you can also define multiple hard constraint rules, but only one of them needs to be satisfied. + +#### Tag name + +The label corresponding to the node can use the default label or user-defined label. + +#### Operators + +- In: the label value needs to be in the list of values +- NotIn: the tag's value is not in a list +- Exists: To judge whether a certain label exists, no need to set the label value +- DoesNotExist: Determine if a tag does not exist, no need to set the tag value +- Gt: the value of the label is greater than a certain value (string comparison) +- Lt: the value of the label is less than a certain value (string comparison) + +#### Weights + +It can only be added in the "as far as possible" policy, which can be understood as the priority of scheduling, and those with the highest weight will be scheduled first. The value range is 1 to 100. + +## Workload Affinity + +Similar to node affinity, there are two types of workload affinity: + +- **Must be satisfied: (requiredDuringSchedulingIgnoredDuringExecution)** The scheduler can only run scheduling when the rules are satisfied. This functionality is similar to __nodeSelector__ , but with a more expressive syntax. You can define multiple hard constraint rules, but only one of them must be satisfied. +- **Satisfy as much as possible: (preferredDuringSchedulingIgnoredDuringExecution)** The scheduler will try to find nodes that meet the corresponding rules. If no matching node is found, the scheduler will still schedule the Pod. You can also set weights for soft constraint rules. During specific scheduling, if there are multiple nodes that meet the conditions, the node with the highest weight will be scheduled first. At the same time, you can also define multiple hard constraint rules, but only one of them needs to be satisfied. + +The affinity of the workload is mainly used to determine which Pods of the workload can be deployed in the same topology domain. For example, services that communicate with each other can be deployed in the same topology domain (such as the same availability zone) by applying affinity scheduling to reduce the network delay between them. + +#### Tag name + +The label corresponding to the node can use the default label or user-defined label. + +#### Namespaces + +Specifies the namespace in which the scheduling policy takes effect. + +#### Operators + +- In: the label value needs to be in the list of values +- NotIn: the tag's value is not in a list +- Exists: To judge whether a certain label exists, no need to set the label value +- DoesNotExist: Determine if a tag does not exist, no need to set the tag value + +#### Topology domain + +Specify the scope of influence during scheduling. If you specify kubernetes.io/Clustername, it will use the Node node as the distinguishing scope. + +## Workload Anti-Affinity + +Similar to node affinity, there are two types of anti-affinity for workloads: + +- **Must be satisfied: (requiredDuringSchedulingIgnoredDuringExecution)** The scheduler can only run scheduling when the rules are satisfied. This functionality is similar to __nodeSelector__ , but with a more expressive syntax. You can define multiple hard constraint rules, but only one of them must be satisfied. +- **Satisfy as much as possible: (preferredDuringSchedulingIgnoredDuringExecution)** The scheduler will try to find nodes that meet the corresponding rules. If no matching node is found, the scheduler will still schedule the Pod. You can also set weights for soft constraint rules. During specific scheduling, if there are multiple nodes that meet the conditions, the node with the highest weight will be scheduled first. At the same time, you can also define multiple hard constraint rules, but only one of them needs to be satisfied. + +The anti-affinity of the workload is mainly used to determine which Pods of the workload cannot be deployed in the same topology domain. For example, the same Pod of a load is distributed to different topological domains (such as different hosts) to improve the stability of the workload itself. + +#### Tag name + +The label corresponding to the node can use the default label or user-defined label. + +#### Namespaces + +Specifies the namespace in which the scheduling policy takes effect. + +#### Operators + +- In: the label value needs to be in the list of values +- NotIn: the tag's value is not in a list +- Exists: To judge whether a certain label exists, no need to set the label value +- DoesNotExist: Determine if a tag does not exist, no need to set the tag value + +#### Topology domain + +Specify the scope of influence when scheduling, such as specifying kubernetes.io/Clustername, it will use the Node node as the distinguishing scope. \ No newline at end of file diff --git a/docs/en/docs/kpanda/user-guide/workloads/pod-config/workload-status.md b/docs/en/docs/kpanda/user-guide/workloads/pod-config/workload-status.md new file mode 100644 index 0000000..d09f530 --- /dev/null +++ b/docs/en/docs/kpanda/user-guide/workloads/pod-config/workload-status.md @@ -0,0 +1,58 @@ +--- +MTPE: windsonsea +Date: 2024-07-19 +--- + +# Workload Status + +A workload is an application running on Kubernetes, and in Kubernetes, whether your application is composed of a single same component or composed of many different components, you can use a set of Pods to run it. Kubernetes provides five built-in workload resources to manage pods: + +- [Deployment](../create-deployment.md) +- [StatefulSet](../create-statefulset.md) +- [Daemonset](../create-daemonset.md) +- [Job](../create-job.md) +- [CronJob](../create-cronjob.md) + +You can also expand workload resources by setting [Custom Resource CRD](../../custom-resources/create.md). In the fifth-generation container management, it supports full lifecycle management of workloads such as creation, update, capacity expansion, monitoring, logging, deletion, and version management. + +## Pod Status + +Pod is the smallest computing unit created and managed in Kubernetes, that is, a collection of containers. These containers share storage, networking, and management policies that control how the containers run. +Pods are typically not created directly by users, but through workload resources. +Pods follow a predefined lifecycle, starting at __Pending__ [phase](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase), if at least one of the primary containers starts normally, it enters __Running__ , and then enters the __Succeeded__ or __Failed__ stage depending on whether any container in the Pod ends in a failed status. + +## Workload Status + +The fifth-generation container management module designs a built-in workload life cycle status set based on factors such as Pod status and number of replicas, so that users can more realistically perceive the running status of workloads. +Because different workload types (such as Deployment and Jobs) have inconsistent management mechanisms for Pods, different workloads will have different lifecycle status during operation, as shown in the following table. + +### Deployment, StatefulSet, DamemonSet Status + +| Status | Description | +| ------ | ----------- | +| Waiting | 1. A workload is in this status while its creation is in progress.
2. After an upgrade or rollback action is triggered, the workload is in this status.
3. Trigger operations such as pausing/scaling, and the workload is in this status. | +| Running | This status occurs when all instances under the workload are running and the number of replicas matches the user-defined number. | +| Deleting | When a delete operation is performed, the payload is in this status until the delete is complete. | +| Exception | Unable to get the status of the workload for some reason. This usually occurs because communication with the pod's host has failed. | +| Not Ready | When the container is in an abnormal, pending status, this status is displayed when the workload cannot be started due to an unknown error | + +### Job Status + +| Status | Description | +| ------ | ----------- | +| Waiting | The workload is in this status while Job creation is in progress. | +| Executing | The Job is in progress and the workload is in this status. | +| Execution Complete | The Job execution is complete and the workload is in this status. | +| Deleting | A delete operation is triggered and the workload is in this status. | +| Exception | Pod status could not be obtained for some reason. This usually occurs because communication with the pod's host has failed. | + +### CronJob status + +| Status | Description | +| ------ | ----------- | +| Waiting | The CronJob is in this status when it is being created. | +| Started | After the CronJob is successfully created, the CronJob is in this status when it is running normally or when the paused task is started. | +| Stopped | The CronJob is in this status when the stop task operation is performed. | +| Deleting | The deletion operation is triggered, and the CronJob is in this status. | + +When the workload is in an abnormal or unready status, you can move the mouse over the status value of the load, and the system will display more detailed error information through a prompt box. You can also view the [log](../../../../insight/user-guide/data-query/log.md) or events to obtain related running information of the workload. diff --git a/docs/en/docs/security/falco-exporter.md b/docs/en/docs/security/falco-exporter.md new file mode 100644 index 0000000..436de42 --- /dev/null +++ b/docs/en/docs/security/falco-exporter.md @@ -0,0 +1,65 @@ +--- +MTPE: Jeanine-tw +Revised: Jeanine-tw +Pics: Jeanine-tw +Date: 2022-12-27 +--- + +# What is Falco-exporter + +[Falco-exporter](https://github.com/falcosecurity/falco-exporter) is a Prometheus Metrics exporter for Falco output events. + +Falco-exporter is deployed as a DaemonSet on a Kubernetes cluster. If Prometheus is installed and running in the cluster, metrics provided by Falco-exporter will be automatically discovered. + +## Install Falco-exporter + +This section describes how to install Falco-exporter. + +!!! note + + Before installing and using Falco-exporter, you need to [install](falco-install.md) and run Falco with gRPC output enabled (enabled by via Unix sockets by default). For more information on enabling gRPC output in Falco Helm Chart, see [Enabling gRPC](https://github.com/falcosecurity/charts/tree/master/falco#enabling-grpc). + +Please confirm that your cluster has successfully connected to the `Container Management` platform, and then perform the following steps to install Falco-exporter. + +1. Click `Container Management`->`Clusters` in the left navigation bar, then find the cluster name where you want to install Falco-exporter. + + + +2. In the left navigation bar, select `Helm Releases` -> `Helm Charts`, and then find and click `falco-exporter`. + + + +3. Select the version you want to install in `Version` and click `Install`. + + +4. On the installation screen, fill in the required installation parameters. + + + + In the screen as above, fill in `application name`, `namespace`, `version`, etc. + + + + In the screen as above, fill in the following parameters: + + - `Falco Prometheus Exporter` -> `Image Settings` -> `Registry`: set the repository address of the falco-exporter image, which is already filled with the available online repositories by default. If it is a private environment, you can change it to a private repository address. + + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Repository`: set the falco-exporter image name. + + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Install ServiceMonitor`: install Prometheus Operator service monitor. It is enabled by default. + + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Scrape Interval`: user-defined interval; if not specified, the Prometheus default interval is used. + + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Scrape Timeout`: user-defined scrape timeout; if not specified, the Prometheus default scrape timeout is used. + + + + + + In the screen as above, fill in the following parameters: + + - `Falco Prometheus Exporter` -> `Prometheus prometheusRules` -> `Install prometheusRules`: create PrometheusRules to alert on priority events. It is enabled by default. + + - `Falco Prometheus Exporter` -> `Prometheus prometheusRules` -> `Alerts settings`: set whether alerts are enabled for different levels of log events, the interval between alerts, and the threshold for alerts. + +5. Click the `OK` button at the bottom right corner to complete the installation. diff --git a/docs/en/docs/security/falco-install.md b/docs/en/docs/security/falco-install.md new file mode 100644 index 0000000..4454faf --- /dev/null +++ b/docs/en/docs/security/falco-install.md @@ -0,0 +1,52 @@ +--- +MTPE: Jeanine-tw +Revised: Jeanine-tw +Pics: Jeanine-tw +Date: 2022-12-26 +--- + +# Install Falco + +Please confirm that your cluster has successfully connected to the `Container Management` platform, and then perform the following steps to install Falco. + +1. Click `Container Management`->`Clusters` in the left navigation bar, then find the cluster name where you want to install Falco. + + + +2. In the left navigation bar, select `Helm Releases` -> `Helm Charts`, and then find and click `Falco`. + + + +3. Select the version you want to install in `Version`, and click `Install`. + + + +4. On the installation page, fill in the required installation parameters. + + + + In the screen as above, fill in the `application name`, `namespace`, `version`, etc. + + + + In the screen as above, fill in the following parameters: + + - `Falco` -> `Image Settings` -> `Registry`: set the repository address of the Falco image, which is already filled with the available online repositories by default. If it is a private environment, you can change it to a private repository address. + + - `Falco` -> `Image Settings` -> `Repository`: set the Falco image name. + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Registry`: set the repository address of the Falco Driver image, which is already filled with available online repositories by default. If it is a private environment, you can change it to a private repository address. + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Repository`: set the Falco Driver image name. + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Driver Kind`: set the Driver Kind, providing the following two options. + + (1) ebpf: use ebpf to detect events, which requires the Linux kernel to support ebpf and enable CONFIG_BPF_JIT and sysctl net.core.bpf_jit_enable=1. + + (2) module: use kernel module detection with limited OS version support. Refer to module support [system version](https://download.falco.org/?prefix=driver). + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Log Level`: the minimum log level to be included in the log. + + Optional values include: `emergency`, `alert`, `critical`, `error`, `warning`, `notice`, `info`, `debug`. + +5. Click the `OK` button in the bottom right corner to complete the installation. diff --git a/docs/en/docs/security/falco.md b/docs/en/docs/security/falco.md new file mode 100644 index 0000000..4639384 --- /dev/null +++ b/docs/en/docs/security/falco.md @@ -0,0 +1,57 @@ +--- +MTPE: Jeanine-tw +Revised: Jeanine-tw +Pics: NA +Date: 2022-12-26 +--- + +# What is Falco + +[Falco](https://falco.org) is a `cloudnative runtime security` tool designed to detect anomalous activity in applications, and can be used to monitor the runtime security of Kubernetes applications and internal components. With only a set of rules, Falco can continuously monitor and watch for anomalous activity in containers, applications, hosts, and networks. + +## What does Falco detect? + +Falco can detect and alert on any behavior involving Linux system calls. Falco alerts can be triggered using specific system calls, parameters, and properties of the calling process. For example, Falco can easily detect events including but not limited to the following: + +- A shell is running inside a container or pod in Kubernetes. +- A container is running in privileged mode or mounting a sensitive path, such as /proc, from the host. +- A server process is spawning a child process of an unexpected type. +- A sensitive file, such as /etc/shadow, is being read unexpectedly. +- A non-device file is being written to /dev. +- A standard system binary, such as ls, is making an outbound network connection. +- A privileged pod is started in a Kubernetes cluster. + +For more information on the default rules that come with Falco, see the [Rules documentation](https://github.com/falcosecurity/falco/blob/master/rules_inventory/rules_overview.md). + +## What are Falco rules? + +Falco rules define the behavior and events that Falco should monitor. Rules can be written in the Falco rules file or in a generic configuration file. For more information on writing, managing and deploying rules, see Falco [Rules](https://falco.org/docs/rules/). + +## What are Falco Alerts? + +Alerts are configurable downstream operations that can be as simple as logging or as complex as STDOUT passing a gRPC call to a client. For more information on configuring, understanding, and developing alerts, see Falco [Alerts](https://falco.org/docs/alerts/). Falco can send alerts t: + +- Standard output +- A file +- A system log +- A spawned program +- An HTTP[s] endpoint +- A client via the gRPC API + +## What are the components of Falco? + +Falco consists of the following main components: + +- Userspace program: a CLI tool that can be used to interact with Falco. The userspace program handles signals, parses messages from a Falco driver, and sends alerts. + +- Configuration: define how Falco is run, what rules to assert, and how to perform alerts. For more information, see [Configuration](https://falco.org/docs/configuration). + +- Driver: a software that adheres to the Falco driver specification and sends a stream of system call information. You cannot run Falco without installing a driver. Currently, Falco supports the following drivers: + + - Kernel module built on libscap and libsinsp C++ libraries (default) + - BPF probe built from the same modules + - Userspace instrumentation + + For more information, see Falco [drivers](https://falco.org/docs/event-sources/drivers/). + +- Plugins: allow users to extend the functionality of falco libraries/falco executable by adding new event sources and new fields that can extract information from events. For more information, see [Plugins](https://falco.org/docs/plugins/). diff --git a/docs/en/docs/security/index.md b/docs/en/docs/security/index.md new file mode 100644 index 0000000..a6e39fa --- /dev/null +++ b/docs/en/docs/security/index.md @@ -0,0 +1,23 @@ +--- +MTPE: Jeanine-tw +Revised: NA +Pics: NA +Date: 2023-01-04 +--- + +# Cloud Native Security + +AI platform provides a fully automated security implementation for containers, Pods, images, runtimes, and microservices. +The following table lists some of the security features that have been implemented or are in the process of being implemented. + +| Security Features | Specific Items | Description | +| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | +| Image security | Trusted image Distribution | Key pairs and signature information are required to achieve secure transport of images. It's allowed to select a key for mirror signing during mirror transmission. | +| Runtime security | Event correlation analysis | Support correlation and risk analysis of security events detected at runtime to enhance attack traceability. Support converge alerts, reduce invalid alerts, and improve event response efficiency. | +| - | Container decoy repository | The container decoy repository is equipped with common decoys including but not limited to: unauthorized access vulnerabilities, code execution vulnerabilities, local file reading vulnerabilities, remote command execution RCE vulnerabilities, and other container decoys. | +| - | Container decoy deployment | Support custom decoy containers, including service names, service locations, etc. | +| - | Container decoy alerting | Support alerting on suspicious behavior in container decoys. | +| - | Offset detection | While scanning the image, learn all the binary information in the image and form a "whitelist" to allow only the binaries in the "whitelist" to run after the container is online, which ensures that the container can not run unauthorized (such as illegal download) executable files. | +| Micro-isolation | Intelligent recommendation of isolation policies | Support for recording historical access traffic to resources, and intelligent policy recommendation based on historical access traffic when configuring isolation policies for resources. | +| - | Tenant isolation | Support isolation control of tenants in Kubernetes clusters, with the ability to set different network security groups for different tenants, and supports tenant-level security policies to achieve inter-tenant network access and isolation. | +| Microservices security | Service and API security scanning |Supports automatic, manual and periodic scanning of services and APIs within a cluster. Support all traditional web scanning items including XSS vulnerabilities, SQL injection, command/code injection, directory enumeration, path traversal, XML entity injection, poc, file upload, weak password, jsonp, ssrf, arbitrary jump, CRLF injection and other risks. For vulnerabilities found in the container environment, support vulnerability type display, url display, parameter display, danger level display, test method display, etc.| diff --git a/docs/en/docs/stylesheets/tags.md b/docs/en/docs/stylesheets/tags.md new file mode 100644 index 0000000..422b139 --- /dev/null +++ b/docs/en/docs/stylesheets/tags.md @@ -0,0 +1,5 @@ +# Tags + +Following is a list of relevant tags: + +[TAGS] \ No newline at end of file diff --git a/docs/en/docs/virtnest/gpu/vm-gpu.md b/docs/en/docs/virtnest/gpu/vm-gpu.md new file mode 100644 index 0000000..5116be5 --- /dev/null +++ b/docs/en/docs/virtnest/gpu/vm-gpu.md @@ -0,0 +1,273 @@ +# Configure GPU Passthrough for Virtual Machines + +This page will explain the prerequisites for configuring GPU when creating a virtual machine. + +The key to configuring GPU for virtual machines is to configure the GPU Operator to deploy different +software components on the worker nodes, depending on the GPU workload configuration. Here are three example nodes: + +- The controller-node-1 node is configured to run containers. +- The work-node-1 node is configured to run virtual machines with GPU passthrough. +- The work-node-2 node is configured to run virtual machines with virtual vGPU. + +## Assumptions, Limitations, and Dependencies + +The worker nodes can run GPU-accelerated containers, virtual machines with GPU passthrough, or virtual machines with vGPU. However, a combination of any of these is not supported. + +1. The cluster administrator or developer needs to have prior knowledge of the cluster and correctly label the nodes to indicate the type of GPU workload they will run. +2. The worker node that runs a GPU-accelerated virtual machine with GPU passthrough or vGPU is assumed to + be a bare metal machine. If the worker node is a virtual machine, the GPU passthrough feature needs to + be enabled on the virtual machine platform. Please consult your virtual machine platform provider for guidance. +3. Nvidia MIG is not supported for vGPU. +4. The GPU Operator does not automatically install GPU drivers in the virtual machine. + +## Enable IOMMU + +To enable GPU passthrough, the cluster nodes need to have IOMMU enabled. Refer to +[How to Enable IOMMU](https://www.server-world.info/en/note?os=CentOS_7&p=kvm&f=10). +If your cluster is running on a virtual machine, please consult your virtual machine platform provider. + +## Label the Cluster Nodes + +Go to __Container Management__, select your worker cluster, click __Node Management__, and then click __Modify Labels__ in the action bar to add labels to the nodes. Each node can only have one label. + +You can assign the following values to the labels: container, vm-passthrough, and vm-vgpu. + +## Install Nvidia Operator + +1. Go to __Container Management__, select your worker cluster, click __Helm Apps__ -> __Helm Chart__ , + and choose and install gpu-operator. Modify the relevant fields in the yaml. + + ```yaml + gpu-operator.sandboxWorkloads.enabled=true + gpu-operator.vfioManager.enabled=true + gpu-operator.sandboxDevicePlugin.enabled=true + gpu-operator.sandboxDevicePlugin.version=v1.2.4 // version should be >= v1.2.4 + gpu-operator.toolkit.version=v1.14.3-ubuntu20.04 + ``` + +2. Wait for the installation to succeed, as shown in the following image: + +## Install virtnest-agent and Configure CR + +1. Install virtnest-agent, refer to [Install virtnest-agent](../install/virtnest-agent.md). + +2. Add vGPU and GPU passthrough to the Virtnest Kubevirt CR. + The following example shows the relevant yaml after adding vGPU and GPU passthrough: + + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com /GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com /GP104GL_TESLA_P4 + ``` + + 1. The following information needs to be filled in + 2. vGPU + 3. GPU passthrough + +3. In the kubevirt CR yaml, `permittedHostDevices` is used to import VM devices. + For vGPU, mediatedDevices needs to be added, with the following structure: + + ```yaml + mediatedDevices: + - mdevNameSelector: GRID P4-1Q # (1)! + resourceName: nvidia.com/GRID_P4-1Q # (2)! + ``` + + 1. Device name + 2. vGPU information registered by GPU Operator on the node + +4. For GPU passthrough, pciHostDevices needs to be added under `permittedHostDevices`, + with the following structure: + + ```yaml + pciHostDevices: + - externalResourceProvider: true # (1)! + pciVendorSelector: 10DE:1BB3 # (2)! + resourceName: nvidia.com/GP104GL_TESLA_P4 # (3)! + ``` + + 1. Do not change this by default + 2. Vendor ID of the current PCI device + 3. GPU information registered by GPU Operator on the node + +5. Example of obtaining vGPU information (only applicable to vGPU): + View the node information on the node marked as `nvidia.com/gpu.workload.config=vm-gpu`, + such as `work-node-2`, in the Capacity section, `nvidia.com/GRID_P4-1Q: 8` indicates the available vGPU: + + ```bash + kubectl describe node work-node-2 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GRID_P4-1Q : 8 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GRID_P4-1Q: 8 + pods: 110 + ``` + + In this case, the mdevNameSelector should be "GRID P4-1Q" and the resourceName should be "GRID_P4-1Q". + +6. Get GPU passthrough information: On the node marked as `nvidia.com/gpu.workload.config=vm-passthrough` + (work-node-1 in this example), view the node information. + In the Capacity section, `nvidia.com/GP104GL_TESLA_P4: 2` represents the available vGPU: + + ```bash + kubectl describe node work-node-1 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + ``` + + The resourceName should be "GRID_P4-1Q". How to obtain the pciVendorSelector? + Use SSH to log in to the target node work-node-1 and use the `lspci -nnk -d 10de:` command + to obtain the Nvidia GPU PCI information, as shown below: The red box indicates the pciVendorSelector information. + + +7. Edit the kubevirt CR note: If there are multiple GPUs of the same model, + you only need to write one in the CR, there is no need to list every GPU. + + ```bash + kubectl -n virtnest-system edit kubevirt kubevirt + ``` + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com/GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com/GP104GL_TESLA_P4 + ``` + + 1. The following information needs to be filled in + 2. vGPU + 3. GPU passthrough; in the example above, there are two GPUs for TEESLA P4, so only one needs to be registered here + +## Create VM Using YAML and Enable GPU Acceleration + +The only difference from a regular virtual machine is adding GPU-related information in the devices section. + +??? note "Click to view the complete YAML" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: testvm-gpu1 + namespace: default + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: systemdisk-testvm-gpu1 + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: www + source: + registry: + url: docker://release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 + runStrategy: Manual + template: + metadata: + creationTimestamp: null + spec: + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: systemdisk-testvm-gpu1 + - disk: + bus: virtio + name: cloudinitdisk + gpus: + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-0 + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-1 + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-testvm-gpu1 + name: systemdisk-testvm-gpu1 + - cloudInitNoCloud: + userDataBase64: I2Nsb3VkLWNvbmZpZwpzc2hfcHdhdXRoOiB0cnVlCmRpc2FibGVfcm9vdDogZmFsc2UKY2hwYXNzd2Q6IHsibGlzdCI6ICJyb290OmRhbmdlcm91cyIsIGV4cGlyZTogRmFsc2V9CgoKcnVuY21kOgogIC0gc2VkIC1pICIvI1w/UGVybWl0Um9vdExvZ2luL3MvXi4qJC9QZXJtaXRSb290TG9naW4geWVzL2ciIC9ldGMvc3NoL3NzaGRfY29uZmlnCiAgLSBzeXN0ZW1jdGwgcmVzdGFydCBzc2guc2VydmljZQ== + name: cloudinitdisk + ``` diff --git a/docs/en/docs/virtnest/gpu/vm-vgpu.md b/docs/en/docs/virtnest/gpu/vm-vgpu.md new file mode 100644 index 0000000..4e843aa --- /dev/null +++ b/docs/en/docs/virtnest/gpu/vm-vgpu.md @@ -0,0 +1,324 @@ +# Configure GPU (vGPU) for Virtual Machines + +This page will explain the prerequisites for configuring GPU when creating a virtual machine. + +The key to configuring GPU for virtual machines is to configure the GPU Operator to deploy different software components on the worker nodes, depending on the GPU workload configuration. Here are three example nodes: + +- The controller-node-1 node is configured to run containers. +- The work-node-1 node is configured to run virtual machines with GPU passthrough. +- The work-node-2 node is configured to run virtual machines with virtual vGPU. + +## Assumptions, Limitations, and Dependencies + +The worker nodes can run GPU-accelerated containers, virtual machines with GPU passthrough, or virtual machines with vGPU. However, a combination of any of these is not supported. + +1. The worker nodes can run GPU-accelerated containers, virtual machines with GPU passthrough, or virtual machines with vGPU individually, but not in any combination. +2. The cluster administrator or developer needs to have prior knowledge of the cluster and correctly label the nodes to indicate the type of GPU workload they will run. +3. The worker node that runs a GPU-accelerated virtual machine with GPU passthrough or vGPU is assumed to be a bare metal machine. If the worker node is a virtual machine, the GPU passthrough feature needs to be enabled on the virtual machine platform. Please consult your virtual machine platform provider for guidance. +4. Nvidia MIG is not supported for vGPU. +5. The GPU Operator does not automatically install GPU drivers in the virtual machine. + +## Enable IOMMU + +To enable GPU passthrough, the cluster nodes need to have IOMMU enabled. Please refer to [How to Enable IOMMU](https://www.server-world.info/en/note?os=CentOS_7&p=kvm&f=10). If your cluster is running on a virtual machine, please consult your virtual machine platform provider. + +## Build vGPU Manager Image + +Note: This step is only required when using NVIDIA vGPU. If you plan to use GPU passthrough only, skip this section. + +Follow these steps to build the vGPU Manager image and push it to the container registry: + +1. Download the vGPU software from the NVIDIA Licensing Portal. + + - Log in to the NVIDIA Licensing Portal and go to the **Software Downloads** page. + - The NVIDIA vGPU software is located in the **Driver downloads** tab on the **Software Downloads** page. + - Select **VGPU + Linux** in the filter criteria and click **Download** to get the Linux KVM package. + Unzip the downloaded file (`NVIDIA-Linux-x86_64--vgpu-kvm.run`). + + +2. Open a terminal and clone the container-images/driver repository. + + ```bash + git clone https://gitlab.com/nvidia/container-images/driver cd driver + ``` + +3. Switch to the vgpu-manager directory corresponding to your operating system. + + ```bash + cd vgpu-manager/ + ``` + +4. Copy the .run file extracted in step 1 to the current directory. + + ```bash + cp /*-vgpu-kvm.run ./ + ``` + +5. Set the environment variables. + + - PRIVATE_REGISTRY: The name of the private registry to store the driver image. + - VERSION: The version of the NVIDIA vGPU Manager, downloaded from the NVIDIA Software Portal. + - OS_TAG: Must match the operating system version of the cluster nodes. + - CUDA_VERSION: The base CUDA image version used to build the driver image. + + ```bash + export PRIVATE_REGISTRY=my/private/registry VERSION=510.73.06 OS_TAG=ubuntu22.04 CUDA_VERSION=12.2.0 + ``` + +6. Build the NVIDIA vGPU Manager Image. + + ```bash + docker build \ + --build-arg DRIVER_VERSION=${VERSION} \ + --build-arg CUDA_VERSION=${CUDA_VERSION} \ + -t ${PRIVATE_REGISTRY}``/vgpu-manager``:${VERSION}-${OS_TAG} . + ``` + +7. Push the NVIDIA vGPU Manager image to your container registry. + + ```bash + docker push ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} + ``` + +## Label the Cluster Nodes + +Go to __Container Management__, select your worker cluster, click __Node Management__, and then click __Modify Labels__ in the action bar to add labels to the nodes. Each node can only have one label. + +You can assign the following values to the labels: container, vm-passthrough, and vm-vgpu. + + + +## Install Nvidia Operator + +1. Go to __Container Management__, select your worker cluster, click __Helm Apps__ -> __Helm Chart__, and choose and install gpu-operator. Modify the relevant fields in the yaml. + + ```yaml + gpu-operator.sandboxWorkloads.enabled=true + gpu-operator.vgpuManager.enabled=true + gpu-operator.vgpuManager.repository= # (1)! + gpu-operator.vgpuManager.image=vgpu-manager + gpu-operator.vgpuManager.version= # (2)! + gpu-operator.vgpuDeviceManager.enabled=true + ``` + + 1. The container registry address from the "Build vGPU Manager Image" step. + 2. The VERSION from the "Build vGPU Manager Image" step. + +2. Wait for the installation to succeed, as shown in the following image: + + + +## Install virtnest-agent and Configure CR + +1. Install virtnest-agent, refer to [Install virtnest-agent](../install/virtnest-agent.md). + +2. Add vGPU and GPU passthrough to the Virtnest Kubevirt CR. The following example shows the relevant yaml after adding vGPU and GPU passthrough: + + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com /GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com /GP104GL_TESLA_P4 + ``` + + 1. The following information needs to be filled in + 2. vGPU + 3. GPU passthrough + +3. In the kubevirt CR yaml, `permittedHostDevices` is used to import VM devices. For vGPU, mediatedDevices needs to be added, with the following structure: + + ```yaml + mediatedDevices: + - mdevNameSelector: GRID P4-1Q # (1)! + resourceName: nvidia.com/GRID_P4-1Q # (2)! + ``` + + 1. Device name + 2. vGPU information registered by the GPU Operator on the node + +4. For GPU passthrough, pciHostDevices needs to be added under `permittedHostDevices`, with the following structure: + + ```yaml + pciHostDevices: + - externalResourceProvider: true # (1)! + pciVendorSelector: 10DE:1BB3 # (2)! + resourceName: nvidia.com/GP104GL_TESLA_P4 # (3)! + ``` + + 1. Do not change this by default + 2. Vendor ID of the current PCI device + 3. GPU information registered by the GPU Operator on the node + +5. Example of obtaining vGPU information (only applicable to vGPU): View the node information on the node marked as `nvidia.com/gpu.workload.config=vm-gpu`, such as `work-node-2`, in the Capacity section, `nvidia.com/GRID_P4-1Q: 8` indicates the available vGPU: + + ```bash + kubectl describe node work-node-2 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GRID_P4-1Q : 8 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GRID_P4-1Q: 8 + pods: 110 + ``` + + In this case, the mdevNameSelector should be "GRID P4-1Q" and the resourceName should be "GRID_P4-1Q". + +6. Get GPU passthrough information: On the node marked as `nvidia.com/gpu.workload.config=vm-passthrough` (work-node-1 in this example), view the node information. In the Capacity section, `nvidia.com/GP104GL_TESLA_P4: 2` represents the available vGPU: + + ```bash + kubectl describe node work-node-1 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + ``` + + The resourceName should be "GRID_P4-1Q". How to obtain the pciVendorSelector? SSH into the target node work-node-1 and use the `lspci -nnk -d 10de:` command to obtain the Nvidia GPU PCI information, as shown below: The red box indicates the pciVendorSelector information. + + +7. Edit the kubevirt CR note: If there are multiple GPUs of the same model, you only need to write one in the CR, there is no need to list every GPU. + + ```bash + kubectl -n virtnest-system edit kubevirt kubevirt + ``` + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com/GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com/GP104GL_TESLA_P4 + ``` + + 1. The following information needs to be filled in + 2. vGPU + 3. GPU passthrough; in the example above, there are two GPUs for TEESLA P4, so only one needs to be registered here + +## Create VM Using YAML and Enable GPU Acceleration + +The only difference from a regular virtual machine is adding the gpu-related information in the devices section. + +??? note "Click to view the complete YAML" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: testvm-gpu1 + namespace: default + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: systemdisk-testvm-gpu1 + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: www + source: + registry: + url: docker://release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 + runStrategy: Manual + template: + metadata: + creationTimestamp: null + spec: + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: systemdisk-testvm-gpu1 + - disk: + bus: virtio + name: cloudinitdisk + gpus: + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-0 + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-1 + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-testvm-gpu1 + name: systemdisk-testvm-gpu1 + - cloudInitNoCloud: + userDataBase64: I2Nsb3VkLWNvbmZpZwpzc2hfcHdhdXRoOiB0cnVlCmRpc2FibGVfcm9vdDogZmFsc2UKY2hwYXNzd2Q6IHsibGlzdCI6ICJyb290OmRhbmdlcm91cyIsIGV4cGlyZTogRmFsc2V9CgoKcnVuY21kOgogIC0gc2VkIC1pICIvI1w/UGVybWl0Um9vdExvZ2luL3MvXi4qJC9QZXJtaXRSb290TG9naW4geWVzL2ciIC9ldGMvc3NoL3NzaGRfY29uZmlnCiAgLSBzeXN0ZW1jdGwgcmVzdGFydCBzc2guc2VydmljZQ== + name: cloudinitdisk + ``` diff --git a/docs/en/docs/virtnest/images/VM-management.png b/docs/en/docs/virtnest/images/VM-management.png new file mode 100644 index 0000000..f2a4c1c Binary files /dev/null and b/docs/en/docs/virtnest/images/VM-management.png differ diff --git a/docs/en/docs/virtnest/images/basic-infor.png b/docs/en/docs/virtnest/images/basic-infor.png new file mode 100644 index 0000000..6ea5466 Binary files /dev/null and b/docs/en/docs/virtnest/images/basic-infor.png differ diff --git a/docs/en/docs/virtnest/images/container-registry01.png b/docs/en/docs/virtnest/images/container-registry01.png new file mode 100644 index 0000000..dbc9c24 Binary files /dev/null and b/docs/en/docs/virtnest/images/container-registry01.png differ diff --git a/docs/en/docs/virtnest/images/container-registry02.png b/docs/en/docs/virtnest/images/container-registry02.png new file mode 100644 index 0000000..626bbd0 Binary files /dev/null and b/docs/en/docs/virtnest/images/container-registry02.png differ diff --git a/docs/en/docs/virtnest/images/createvm-error02.png b/docs/en/docs/virtnest/images/createvm-error02.png new file mode 100644 index 0000000..8440d73 Binary files /dev/null and b/docs/en/docs/virtnest/images/createvm-error02.png differ diff --git a/docs/en/docs/virtnest/images/createvm-net01.png b/docs/en/docs/virtnest/images/createvm-net01.png new file mode 100644 index 0000000..48f30dc Binary files /dev/null and b/docs/en/docs/virtnest/images/createvm-net01.png differ diff --git a/docs/en/docs/virtnest/images/createvm-net02.png b/docs/en/docs/virtnest/images/createvm-net02.png new file mode 100644 index 0000000..a7c33cf Binary files /dev/null and b/docs/en/docs/virtnest/images/createvm-net02.png differ diff --git a/docs/en/docs/virtnest/images/createvm-net03.png b/docs/en/docs/virtnest/images/createvm-net03.png new file mode 100644 index 0000000..6a08652 Binary files /dev/null and b/docs/en/docs/virtnest/images/createvm-net03.png differ diff --git a/docs/en/docs/virtnest/images/createvm09.png b/docs/en/docs/virtnest/images/createvm09.png new file mode 100644 index 0000000..27cf454 Binary files /dev/null and b/docs/en/docs/virtnest/images/createvm09.png differ diff --git a/docs/en/docs/virtnest/images/createwithtemplate.png b/docs/en/docs/virtnest/images/createwithtemplate.png new file mode 100644 index 0000000..2471e67 Binary files /dev/null and b/docs/en/docs/virtnest/images/createwithtemplate.png differ diff --git a/docs/en/docs/virtnest/images/cronjob.jpg b/docs/en/docs/virtnest/images/cronjob.jpg new file mode 100644 index 0000000..9cd712b Binary files /dev/null and b/docs/en/docs/virtnest/images/cronjob.jpg differ diff --git a/docs/en/docs/virtnest/images/detail-event.png b/docs/en/docs/virtnest/images/detail-event.png new file mode 100644 index 0000000..5311893 Binary files /dev/null and b/docs/en/docs/virtnest/images/detail-event.png differ diff --git a/docs/en/docs/virtnest/images/detail-network.png b/docs/en/docs/virtnest/images/detail-network.png new file mode 100644 index 0000000..8ef8f5f Binary files /dev/null and b/docs/en/docs/virtnest/images/detail-network.png differ diff --git a/docs/en/docs/virtnest/images/detail-sc.png b/docs/en/docs/virtnest/images/detail-sc.png new file mode 100644 index 0000000..6a0397f Binary files /dev/null and b/docs/en/docs/virtnest/images/detail-sc.png differ diff --git a/docs/en/docs/virtnest/images/detail-snapshot.png b/docs/en/docs/virtnest/images/detail-snapshot.png new file mode 100644 index 0000000..f559a77 Binary files /dev/null and b/docs/en/docs/virtnest/images/detail-snapshot.png differ diff --git a/docs/en/docs/virtnest/images/detail01.png b/docs/en/docs/virtnest/images/detail01.png new file mode 100644 index 0000000..1067c8e Binary files /dev/null and b/docs/en/docs/virtnest/images/detail01.png differ diff --git a/docs/en/docs/virtnest/images/disk.png b/docs/en/docs/virtnest/images/disk.png new file mode 100644 index 0000000..ab51858 Binary files /dev/null and b/docs/en/docs/virtnest/images/disk.png differ diff --git a/docs/en/docs/virtnest/images/edit01.png b/docs/en/docs/virtnest/images/edit01.png new file mode 100644 index 0000000..5aa0aab Binary files /dev/null and b/docs/en/docs/virtnest/images/edit01.png differ diff --git a/docs/en/docs/virtnest/images/edit02.png b/docs/en/docs/virtnest/images/edit02.png new file mode 100644 index 0000000..5f8c078 Binary files /dev/null and b/docs/en/docs/virtnest/images/edit02.png differ diff --git a/docs/en/docs/virtnest/images/edit03.png b/docs/en/docs/virtnest/images/edit03.png new file mode 100644 index 0000000..bc94c60 Binary files /dev/null and b/docs/en/docs/virtnest/images/edit03.png differ diff --git a/docs/en/docs/virtnest/images/edit04.png b/docs/en/docs/virtnest/images/edit04.png new file mode 100644 index 0000000..783ef70 Binary files /dev/null and b/docs/en/docs/virtnest/images/edit04.png differ diff --git a/docs/en/docs/virtnest/images/edit05.png b/docs/en/docs/virtnest/images/edit05.png new file mode 100644 index 0000000..a701e35 Binary files /dev/null and b/docs/en/docs/virtnest/images/edit05.png differ diff --git a/docs/en/docs/virtnest/images/edit06.png b/docs/en/docs/virtnest/images/edit06.png new file mode 100644 index 0000000..585af2d Binary files /dev/null and b/docs/en/docs/virtnest/images/edit06.png differ diff --git a/docs/en/docs/virtnest/images/edit07.png b/docs/en/docs/virtnest/images/edit07.png new file mode 100644 index 0000000..5a4dd0e Binary files /dev/null and b/docs/en/docs/virtnest/images/edit07.png differ diff --git a/docs/en/docs/virtnest/images/edit08.png b/docs/en/docs/virtnest/images/edit08.png new file mode 100644 index 0000000..dca1d46 Binary files /dev/null and b/docs/en/docs/virtnest/images/edit08.png differ diff --git a/docs/en/docs/virtnest/images/gpu-01.png b/docs/en/docs/virtnest/images/gpu-01.png new file mode 100644 index 0000000..b04f33d Binary files /dev/null and b/docs/en/docs/virtnest/images/gpu-01.png differ diff --git a/docs/en/docs/virtnest/images/gpu-02.png b/docs/en/docs/virtnest/images/gpu-02.png new file mode 100644 index 0000000..3f7ad41 Binary files /dev/null and b/docs/en/docs/virtnest/images/gpu-02.png differ diff --git a/docs/en/docs/virtnest/images/gpu-03.png b/docs/en/docs/virtnest/images/gpu-03.png new file mode 100644 index 0000000..9dd94a6 Binary files /dev/null and b/docs/en/docs/virtnest/images/gpu-03.png differ diff --git a/docs/en/docs/virtnest/images/gpu-04.png b/docs/en/docs/virtnest/images/gpu-04.png new file mode 100644 index 0000000..532f6ee Binary files /dev/null and b/docs/en/docs/virtnest/images/gpu-04.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu01.png b/docs/en/docs/virtnest/images/import-ubuntu01.png new file mode 100644 index 0000000..a4d2d93 Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu01.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu02.png b/docs/en/docs/virtnest/images/import-ubuntu02.png new file mode 100644 index 0000000..5eed28c Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu02.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu03.png b/docs/en/docs/virtnest/images/import-ubuntu03.png new file mode 100644 index 0000000..dd9014d Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu03.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu04.png b/docs/en/docs/virtnest/images/import-ubuntu04.png new file mode 100644 index 0000000..56c4941 Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu04.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu05.png b/docs/en/docs/virtnest/images/import-ubuntu05.png new file mode 100644 index 0000000..0f8896a Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu05.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu06.png b/docs/en/docs/virtnest/images/import-ubuntu06.png new file mode 100644 index 0000000..56c0d68 Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu06.png differ diff --git a/docs/en/docs/virtnest/images/import-ubuntu07.png b/docs/en/docs/virtnest/images/import-ubuntu07.png new file mode 100644 index 0000000..923d8a6 Binary files /dev/null and b/docs/en/docs/virtnest/images/import-ubuntu07.png differ diff --git a/docs/en/docs/virtnest/images/install01.png b/docs/en/docs/virtnest/images/install01.png new file mode 100644 index 0000000..b37f4f4 Binary files /dev/null and b/docs/en/docs/virtnest/images/install01.png differ diff --git a/docs/en/docs/virtnest/images/install02.png b/docs/en/docs/virtnest/images/install02.png new file mode 100644 index 0000000..60be517 Binary files /dev/null and b/docs/en/docs/virtnest/images/install02.png differ diff --git a/docs/en/docs/virtnest/images/login-settings.png b/docs/en/docs/virtnest/images/login-settings.png new file mode 100644 index 0000000..545c327 Binary files /dev/null and b/docs/en/docs/virtnest/images/login-settings.png differ diff --git a/docs/en/docs/virtnest/images/monitor01.png b/docs/en/docs/virtnest/images/monitor01.png new file mode 100644 index 0000000..8e0684c Binary files /dev/null and b/docs/en/docs/virtnest/images/monitor01.png differ diff --git a/docs/en/docs/virtnest/images/monitor02.png b/docs/en/docs/virtnest/images/monitor02.png new file mode 100644 index 0000000..0a2bf71 Binary files /dev/null and b/docs/en/docs/virtnest/images/monitor02.png differ diff --git a/docs/en/docs/virtnest/images/monitor03.png b/docs/en/docs/virtnest/images/monitor03.png new file mode 100644 index 0000000..94b79ee Binary files /dev/null and b/docs/en/docs/virtnest/images/monitor03.png differ diff --git a/docs/en/docs/virtnest/images/monitor04.png b/docs/en/docs/virtnest/images/monitor04.png new file mode 100644 index 0000000..a7ec29e Binary files /dev/null and b/docs/en/docs/virtnest/images/monitor04.png differ diff --git a/docs/en/docs/virtnest/images/monitor05.png b/docs/en/docs/virtnest/images/monitor05.png new file mode 100644 index 0000000..5cdac87 Binary files /dev/null and b/docs/en/docs/virtnest/images/monitor05.png differ diff --git a/docs/en/docs/virtnest/images/pc.png b/docs/en/docs/virtnest/images/pc.png new file mode 100644 index 0000000..061dda4 Binary files /dev/null and b/docs/en/docs/virtnest/images/pc.png differ diff --git a/docs/en/docs/virtnest/images/snapshot.jpg b/docs/en/docs/virtnest/images/snapshot.jpg new file mode 100644 index 0000000..847c12c Binary files /dev/null and b/docs/en/docs/virtnest/images/snapshot.jpg differ diff --git a/docs/en/docs/virtnest/images/snapshot01.png b/docs/en/docs/virtnest/images/snapshot01.png new file mode 100644 index 0000000..d0af3bf Binary files /dev/null and b/docs/en/docs/virtnest/images/snapshot01.png differ diff --git a/docs/en/docs/virtnest/images/snapshot02.png b/docs/en/docs/virtnest/images/snapshot02.png new file mode 100644 index 0000000..1da1311 Binary files /dev/null and b/docs/en/docs/virtnest/images/snapshot02.png differ diff --git a/docs/en/docs/virtnest/images/snapshot03.png b/docs/en/docs/virtnest/images/snapshot03.png new file mode 100644 index 0000000..1c2d030 Binary files /dev/null and b/docs/en/docs/virtnest/images/snapshot03.png differ diff --git a/docs/en/docs/virtnest/images/snapshot04.png b/docs/en/docs/virtnest/images/snapshot04.png new file mode 100644 index 0000000..d4b574d Binary files /dev/null and b/docs/en/docs/virtnest/images/snapshot04.png differ diff --git a/docs/en/docs/virtnest/images/snapshot05.png b/docs/en/docs/virtnest/images/snapshot05.png new file mode 100644 index 0000000..5b36b89 Binary files /dev/null and b/docs/en/docs/virtnest/images/snapshot05.png differ diff --git a/docs/en/docs/virtnest/images/storage-network.png b/docs/en/docs/virtnest/images/storage-network.png new file mode 100644 index 0000000..057b7e5 Binary files /dev/null and b/docs/en/docs/virtnest/images/storage-network.png differ diff --git a/docs/en/docs/virtnest/images/tem-detail.png b/docs/en/docs/virtnest/images/tem-detail.png new file mode 100644 index 0000000..9b7f171 Binary files /dev/null and b/docs/en/docs/virtnest/images/tem-detail.png differ diff --git a/docs/en/docs/virtnest/images/tem-yaml.png b/docs/en/docs/virtnest/images/tem-yaml.png new file mode 100644 index 0000000..552ba52 Binary files /dev/null and b/docs/en/docs/virtnest/images/tem-yaml.png differ diff --git a/docs/en/docs/virtnest/images/tem01.png b/docs/en/docs/virtnest/images/tem01.png new file mode 100644 index 0000000..17daa31 Binary files /dev/null and b/docs/en/docs/virtnest/images/tem01.png differ diff --git a/docs/en/docs/virtnest/images/tem02.png b/docs/en/docs/virtnest/images/tem02.png new file mode 100644 index 0000000..436a7e9 Binary files /dev/null and b/docs/en/docs/virtnest/images/tem02.png differ diff --git a/docs/en/docs/virtnest/images/tem03.png b/docs/en/docs/virtnest/images/tem03.png new file mode 100644 index 0000000..bd9257e Binary files /dev/null and b/docs/en/docs/virtnest/images/tem03.png differ diff --git a/docs/en/docs/virtnest/images/template01.png b/docs/en/docs/virtnest/images/template01.png new file mode 100644 index 0000000..72d36d5 Binary files /dev/null and b/docs/en/docs/virtnest/images/template01.png differ diff --git a/docs/en/docs/virtnest/images/template02.png b/docs/en/docs/virtnest/images/template02.png new file mode 100644 index 0000000..e6f57fe Binary files /dev/null and b/docs/en/docs/virtnest/images/template02.png differ diff --git a/docs/en/docs/virtnest/images/turn-on.png b/docs/en/docs/virtnest/images/turn-on.png new file mode 100644 index 0000000..166d3eb Binary files /dev/null and b/docs/en/docs/virtnest/images/turn-on.png differ diff --git a/docs/en/docs/virtnest/images/vm-tem.png b/docs/en/docs/virtnest/images/vm-tem.png new file mode 100644 index 0000000..96a4c82 Binary files /dev/null and b/docs/en/docs/virtnest/images/vm-tem.png differ diff --git a/docs/en/docs/virtnest/images/vm01.png b/docs/en/docs/virtnest/images/vm01.png new file mode 100644 index 0000000..1dadafe Binary files /dev/null and b/docs/en/docs/virtnest/images/vm01.png differ diff --git a/docs/en/docs/virtnest/images/vm02.png b/docs/en/docs/virtnest/images/vm02.png new file mode 100644 index 0000000..19d2274 Binary files /dev/null and b/docs/en/docs/virtnest/images/vm02.png differ diff --git a/docs/en/docs/virtnest/images/vm03.png b/docs/en/docs/virtnest/images/vm03.png new file mode 100644 index 0000000..89b6dcc Binary files /dev/null and b/docs/en/docs/virtnest/images/vm03.png differ diff --git a/docs/en/docs/virtnest/images/window-uefi.png b/docs/en/docs/virtnest/images/window-uefi.png new file mode 100644 index 0000000..a783721 Binary files /dev/null and b/docs/en/docs/virtnest/images/window-uefi.png differ diff --git a/docs/en/docs/virtnest/quickstart/access.md b/docs/en/docs/virtnest/quickstart/access.md new file mode 100644 index 0000000..d9fde51 --- /dev/null +++ b/docs/en/docs/virtnest/quickstart/access.md @@ -0,0 +1,30 @@ +--- +hide: + - toc +MTPE: ModetaNiu +DATE: 2024-08-21 +--- + +# Connect to Virtual Machines + +This article will introduce two methods for connecting to virtual machines: Console Access (VNC) and Terminal Access. + +## Terminal Access + +Accessing virtual machines through the terminal provides more flexibility and lightweight access. However, +it does not directly display the graphical interface, has limited interactivity, and does not support +multiple concurrent terminal sessions. + +Click __Container Management__ in the left navigation bar, then click __Virtual Machines__ to access the list page. +Click the __┇__ button on the right side of the list to access the virtual machine via the terminal. + +## Console Access (VNC) + +Accessing virtual machines through VNC allows you to access and control the full graphical interface of the +remote computer. It provides a more interactive experience and allows intuitive operation of the remote device. +However, it may have some performance impact, and it does not support multiple concurrent terminal sessions. + +> Choose VNC for Windows systems. + +Click __Container Management__ in the left navigation bar, then click __Virtual Machines__ to access the list page. +Click the __┇__ button on the right side of the list to access the virtual machine via Console Access (VNC). diff --git a/docs/en/docs/virtnest/quickstart/detail.md b/docs/en/docs/virtnest/quickstart/detail.md new file mode 100644 index 0000000..2f131ab --- /dev/null +++ b/docs/en/docs/virtnest/quickstart/detail.md @@ -0,0 +1,68 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-26 +--- + +# Virtual Machine Details + +After successfully [creating a virtual machine](../quickstart/index.md), you can enter the VM Detail page to view +Basic Information, Settings, GPU Settings, Overview, Storage, Network, Snapshot and Event List. + +Click __Container Management__ in the left navigation bar, then click __Clusters__ to enter the page of the cluster +where the virtual machine is located. Click the VM Name to view the virtual machine details. + +### Basic Information + +The basic information of VM includes Status, Alias, Cluster, Namespace, IP, Label, Annotation, Node, Username, Password, and Create Time. + +- Status: The current running state of the virtual machine (Running / Processing / Power Off / Error). +- IP: The IP of the virtual machine. For virtual machines with multiple network interfaces, multiple IP will be assigned. + +### Settings & GPU Settings + +Settings includes: + +- Operating System: The operating system installed on the virtual machine to execute programs. +- Image Address: A link to a virtual hard disk file or operating system installation media, which is used to + load and install the operating system in the virtual machine software. +- Network Mode: The network mode configured for the virtual machine, including `Bridge` or `Masquerade(NAT)`. +- CPU & Memory: The resources allocated to the virtual machine. + +GPU Settings includes: GPU Type, GPU Model and GPU Counts + +![VM Detail](../images/detail01.png) + +### Other Information + +=== "Overview" + + It allows you to view its insight content. Please note that if insight-agent is not installed, + overview information cannot be obtained. + + ![Overview](../images/monitor02.png) + +=== "Storage" + + It displays the storage used by the virtual machine, including information about the system disk and data disk. + + ![Storage](../images/detail-sc.png) + +=== "Network" + + It displays the network settings of the virtual machine, including Multus CR, NIC Name, IP Address and so on. + + ![Network](../images/detail-network.png) + +=== "Snapshots" + + If you have [created snapshots](../vm/snapshot.md), this part will display relative information. + Restoring the virtual machine from snapshots is supported. + + ![Snapshots](../images/detail-snapshot.png) + +=== "Event List" + + The event list includes various state changes, operation records, and system messages during the lifecycle + of the virtual machine. + + ![Event List](../images/detail-event.png) diff --git a/docs/en/docs/virtnest/quickstart/index.md b/docs/en/docs/virtnest/quickstart/index.md new file mode 100644 index 0000000..cba0555 --- /dev/null +++ b/docs/en/docs/virtnest/quickstart/index.md @@ -0,0 +1,232 @@ +--- +MTPE: FanLin +Date: 2024-01-23 +--- + +# Create Virtual Machine + +This article will explain how to create a virtual machine using two methods: image and YAML file. + +Virtual machine, based on KubeVirt, manages virtual machines as cloud native applications, +seamlessly integrating with containers. This allows users to easily deploy virtual machine applications and +enjoy a smooth experience similar to containerized applications. + +## Prerequisites + +Before creating a virtual machine, make sure you meet the following prerequisites: + +- Expose hardware-assisted virtualization to the user operating system. +- [Install virtnest-agent](../install/index.md) on the specified cluster; the operating system kernel version must be 3.15 or higher. +- Create a [namespace](../../kpanda/user-guide/namespaces/createns.md) and [user](../../ghippo/user-guide/access-control/user.md). +- Prepare the image in advance. The platform comes with three built-in images (as shown below). If you need to + create your own image, refer to [creating from an image with KubeVirt](https://github.com/Tedezed/kubevirt-images-generator/tree/master). +- When configuring the network, if you choose to use the Passt network mode, you need to upgrade to Version 0.4.0 or higher. + +## Create image + +Follow the steps below to create a virtual machine using an image. + +1. Click __Container Management__ on the left navigation bar, then click __Virtual Machines__ to enter the __VM__ page. + + ![VM](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm01.png) + +2. On the virtual machine list page, click __Create VMs__ and select __Create with Image__. + + ![Create VM with Image](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm02.png) + +3. Fill the basic information, image settings, storage and network, login settings, and click __OK__ at the bottom right corner to complete the creation. + + The system will automatically return to the virtual machine list. By clicking the __┇__ button + on the right side of the list, you can perform operations such as power on/off, restart, + clone, update, create snapshots, console access (VNC), and delete virtual machines. + Cloning and snapshot capabilities depend on the selected StorageClass. + + ![VM Management](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm03.png) + +### Basic Information + +In the __Create VMs__ page, enter the information according to the table below and click __Next__. + +![Basic Information](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm04.png) + +- Name: Up to 63 characters, can only contain lowercase letters, numbers, and hyphens ( __-__ ), + and must start and end with a lowercase letter or number. The name must be unique within the + namespace, and cannot be changed once the virtual machine is created. +- Alias: Allows any characters, up to 60 characters. +- Cluster: Select the cluster to deploy the newly created virtual machine. +- Namespace: Select the namespace to deploy the newly created virtual machine. + If the desired namespace is not found, you can create a new namespace according to the prompts on the page. +- Label/Annotation: Select the desired labels/annotations to add to the virtual machine. + +### Image Settings + +Fill in the image-related information according to the table below, then click __Next__. + + ![container registry](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm05.png) + +1. Image Source: Supports three types of sources. + + - Registry: Images stored in the container registry. You can select images from the registry as needed. + - HTTP: Images stored in a file server using the HTTP protocol, supporting both + __HTTPS://__ and __HTTP://__ prefixes. + - Object Storage (S3): Virtual machine images obtained through the object storage protocol (S3). + For non-authenticated object storage files, please use the HTTP source. + +2. The following are the built-in images provided by the platform, including the operating system, version, + and the image URL. Custom virtual machine images are also supported. + + | Operating System | Version | Image Address | + | :--------------: | :------------------: | ------------- | + | CentOS | CentOS 7.9 | release-ci.daocloud.io/virtnest/system-images/centos-7.9-x86_64:v1 | + | Ubuntu | Ubuntu 22.04 | release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 | + | Debian | Debian 12 | release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 | + +- Image Secret: Only supports the default (Opaque) type of key, for specific operations you can refer to [Create Secret](../vm/create-secret.md). + + The built-in image storage in the bootstrap cluster, and the container registry of the bootstrap cluster is not encrypted, so when selecting the built-in image, there is no need to select a secret. + +!!! note + + The hot-plug configuration for CPU and memory requires virtnest v0.10.0 or higher, and virtnest-agent v0.7.0 or higher. + +1. Resource Config: For CPU, it is recommended to use whole numbers. If a decimal is entered, it will be rounded up. The hot-plug configuration for CPU and memory is supported. + +2. GPU Configuration: Enabling GPU functionality requires meeting certain prerequisites. For details, refer + to [Configuring GPU for Virtual Machines (Nvidia)](../gpu/vm-gpu.md). + Virtual machines support two types of Nvidia GPUs: Nvidia-GPU and Nvidia-vGPU. After selecting the desired type, + you will need to choose the corresponding GPU model and the number of cards. + +### Storage and Network + + ![Storage and Network](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm06.png) + +- Storage: + + - Storage is closely related to the function of the virtual machine. Mainly by using Kubernetes' persistent volumes and storage classes, it provides flexible and scalable virtual machine storage capabilities. For example, the virtual machine image is stored in the PVC, and it supports cloning, snapshotting, etc. with other data. + + - System Disk: The system automatically creates a VirtIO type rootfs system disk for storing the operating system and data. + + - Data Disk: The data disk is a storage device in the virtual machine used to store user data, application data, or other non-operating system related files. Compared with the system disk, the data disk is optional and can be dynamically added or removed as needed. The capacity of the data disk can also be flexibly configured according to demand. + + - Block storage is used by default. If you need to use the clone and snapshot functions, make sure that your storage pool has created the corresponding VolumeSnapshotClass, which you can refer to the following example. If you need to use the live migration function, make sure your storage supports and selects the ReadWriteMany access mode. + + In most cases, the storage will not automatically create such a VolumeSnapshotClass during the installation process, so you need to manually create a VolumeSnapshotClass. + The following is an example of HwameiStor creating a VolumeSnapshotClass: + + ```yaml + kind: VolumeSnapshotClass + apiVersion: snapshot.storage.k8s.io/v1 + metadata: + name: hwameistor-storage-lvm-snapshot + annotations: + snapshot.storage.kubernetes.io/is-default-class: "true" + parameters: + snapsize: "1073741824" + driver: lvm.hwameistor.io + deletionPolicy: Delete + ``` + + - Run the following command to check if the VolumeSnapshotClass was created successfully. + + ```sh + kubectl get VolumeSnapshotClass + ``` + + - View the created Snapshotclass and confirm that the provisioner property is consistent with the Driver property in the storage pool. + +- Network: + + - Network setting can be combined as needed according to the table information. + + | Network Mode | CNI | Install Spiderpool | Network Cards | Fixed IP | Live Migration | + | -------------------- | ------- | ------------------ | ----------------- | ----------- | -------------- | + | Masquerade (NAT) | Calico | ❌ | Single | ❌ | ✅ | + | | Cilium | ❌ | Single | ❌ | ✅ | + | | Flannel | ❌ | Single | ❌ | ✅ | + | Bridge | OVS | ✅ | Multiple | ✅ | ✅ | + + ![Network Configuration](../images/createvm-net01.png) + + - Network modes are divided into Masquerade (NAT) and Bridge, the latter mode need to be installed after the spiderpool component can be used. + + - The network mode of Masquerade (NAT) is selected by default, using the default network card eth0. + - If the spiderpool component is installed in the cluster, you can choose the Bridge mode, and the Bridge mode supports multiple NICs. + + ![Network Mode](../images/createvm-net02.png) + + - Add Network Card + + - Passthrough / Bridge mode supports manual addition of network cards. Click __Add NIC__ to configure the network card IP pool. Choose the Multus CR that matches the network mode, if not, you need to create it yourself. + - If you turn on the __Use Default IP Pool__ switch, use the default IP pool in the multus CR setting. If the switch is off, manually select the IP pool. + + ![Add Network Card](../images/createvm-net03.png) + +### Login Settings + +- Username/Password: Allows login to the virtual machine using a username and password. +- SSH: When selecting the SSH login method, you can bind an SSH key to the virtual machine for future login. + +![Login Settings](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm07.png) + +## Create with YAML + +In addition to creating virtual machines using images, you can also create them more quickly using YAML files. + +Go to the Virtual Machine list page and click the __Create with YAML__ button. + +![Create with YAML](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/createvm08.png) + +??? note "Click to view an example YAML for creating a virtual machine" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: example + namespace: default + spec: + dataVolumeTemplates: + - metadata: + name: systemdisk-example + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: rook-ceph-block + source: + registry: + url: >- + docker://release-ci.daocloud.io/virtnest/system-images/centos-7.9-x86_64:v1 + runStrategy: Always + template: + spec: + domain: + cpu: + cores: 1 + devices: + disks: + - disk: + bus: virtio + name: systemdisk-example + - disk: + bus: virtio + name: cloudinitdisk + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 1Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-example + name: systemdisk-example + ``` diff --git a/docs/en/docs/virtnest/quickstart/nodeport.md b/docs/en/docs/virtnest/quickstart/nodeport.md new file mode 100644 index 0000000..d524bf5 --- /dev/null +++ b/docs/en/docs/virtnest/quickstart/nodeport.md @@ -0,0 +1,51 @@ +# Accessing Virtual Machine via NodePort + +This page explains how to access a virtual machine using NodePort. + +## Limitations of Existing Access Methods + +1. Virtual machines support access via VNC or console, but both methods have a limitation: + they do not allow multiple terminals to be simultaneously online. + +2. Using a NodePort-formatted Service can help solve this problem. + +## Create a Service + +1. Using the Container Management Page + + - Select the cluster page where the target virtual machine is located and create a Service. + - Select the access type as NodePort. + - Choose the namespace (the namespace where the virtual machine resides). + - Fill in the label selector as `vm.kubevirt.io/name: your-vm-name`. + - Port Configuration: Choose TCP for the protocol, provide a custom port name, and set the service port and container port to 22. + +2. After successful creation, you can access the virtual machine by using `ssh username@nodeip -p port`. + +## Create the Service via kubectl + +1. Write the YAML file as follows: + + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: test-ssh + spec: + ports: + - name: tcp-ssh + nodePort: 32090 + protocol: TCP + port: 22 + targetPort: 22 + selector: + vm.kubevirt.io/name: test-image-s3 + type: NodePort + ``` + +2. Run the following command: + + ```sh + kubectl apply -f your-svc.yaml + ``` + +3. After successful creation, you can access the virtual machine by using `ssh username@nodeip -p 32090`. diff --git a/docs/en/docs/virtnest/quickstart/update.md b/docs/en/docs/virtnest/quickstart/update.md new file mode 100644 index 0000000..e7eb7d3 --- /dev/null +++ b/docs/en/docs/virtnest/quickstart/update.md @@ -0,0 +1,68 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-25 +--- + +# Update Virtual Machine + +This page is about how to update a virtual machine using both forms and YAML files. + +## Prerequisite + +Before updating the CPU, memory, and data disks of the VM while it is powered on, the following prerequisite must be met: + +- Live migration is supported. + +## Update Virtual Machine via Form + +On the virtual machine list page, click __Update__ to enter the Update VM page. + +![Update](../images/edit01.png) + +### Basic Information + +On this page, __Alias__ , __Label__ and __Annotation__ can be updated, while other information cannot. +After completing the updates, click __Next__ to proceed to the Image Settings page. + +![Basic Info](../images/edit02.png) + +### Image Settings + +On this page, parameters such as Image Address, Operating System, and Version cannot be changed once selected. +Users are allowed to update the __GPU Quota__, including enabling or disabling GPU support, selecting the GPU type, +specifying the required model, and configuring the number of GPU. A restart is required for taking effect. +After completing the updates, click __Next__ to proceed to the Storage and Network page. + +![Image Settings](../images/edit03.png) + +### Storage and Network + +On the Storage and Network page, the StorageClass and PVC Mode for the System Disk cannot be changed once selected. +You can increase Disk Capacity, but reducing it is not supported. And you can freely add or remove Data Disk. +Network updates are not supported. After completing the updates, click __Next__ to proceed to the Login Settings page. + +!!! note + + It is recommended to restart the virtual machine after modifying storage capacity or adding data disks to + ensure the configuration takes effect. + +![Storage](../images/edit04.png) + +![Network](../images/edit05.png) + +### Login Settings + +On the Login Settings page, Username, Password, and SSH cannot be changed once set. +After confirming your login information is correct, click __OK__ to complete the update process. + +![Login Settings](../images/edit06.png) + +## Edit YAML + +In addition to updating the virtual machine via forms, you can also quickly update it using a YAML file. + +Go to the virtual machine list page and click the __Edit YAML__ button. + +![YAML Edit](../images/edit07.png) + +![Edit YAML](../images/edit08.png) \ No newline at end of file diff --git a/docs/en/docs/virtnest/template/index.md b/docs/en/docs/virtnest/template/index.md new file mode 100644 index 0000000..8a41ad5 --- /dev/null +++ b/docs/en/docs/virtnest/template/index.md @@ -0,0 +1,87 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-23 +--- + +# Create Virtual Machines via Templates + +This guide explains how to create virtual machines using templates. + +With internal templates and custom templates, users can easily create new virtual machines. Additionally, we provide +the ability to convert existing virtual machines into templates, allowing users to manage and utilize resources more flexibly. + +## Create with Template + +Follow these steps to create a virtual machine using a template. + +1. Click __Container Management__ in the left navigation menu, then click __Virtual Machines__ to access + the __Virtual Machine Management__ page. On the virtual machine list page, click __Create Virtual Machine__ + and select __Create with Template__ . + + ![Create with Template](../images/createwithtemplate.png) + +2. On the template creation page, fill in the required information, including Basic Information, Template Config, + Storage and Network, and Login Settings. Then, click __OK__ in the bottom-right corner to complete the creation. + + The system will automatically return to the virtual machine list. By clicking __┇__ on the right side of the list, + you can perform operations such as power off/restart, clone, update, create snapshot, convert to template, + console access (VNC), and delete. + The ability to clone and create snapshots depends on the selected storage pool. + + ![VM Management](../images/VM-management.png) + +### Basic Information + +On the Create VMs page, enter the information according to the table below and click __Next__ . + +![Basic Information](../images/basic-infor.png) + +- Name: Can contain up to 63 characters and can only include lowercase letters, numbers, and hyphens ( __-__ ). The name must start and end with a lowercase letter or number. + Names must be unique within the same namespace, and the name cannot be changed after the virtual machine is created. +- Alias: Can include any characters, up to 60 characters in length. +- Cluster: Select the cluster where the new virtual machine will be deployed. +- Namespace: Select the namespace where the new virtual machine will be deployed. + If the desired namespace is not found, you can follow the instructions on the page to [create a new namespace](../../kpanda/user-guide/namespaces/createns.md). + +### Template Config + +The template list will appear, and you can choose either an internal template or a custom template based on your needs. + +- Select an Internal Template: AI platform Virtual Machine provides several standard templates that cannot be edited or deleted. When selecting an internal template, the image source, operating system, image address, and other information will be based on the template and cannot be modified. GPU quota will also be based on the template but can be modified. + + ![Template01](../images/template01.png) + + ![Template02](../images/template02.png) + +- Select a Custom Template: These templates are created from virtual machine configurations and can be edited or deleted. When using a custom template, you can modify the image source and other information based on your specific requirements. + + ![container registry01](../images/container-registry01.png) + + ![container registry02](../images/container-registry02.png) + +### Storage and Network + +![Storage and Network](../images/storage-network.png) + +- Storage: By default, the system creates a rootfs system disk of VirtIO type for storing the operating system and data. + Block storage is used by default. If you need to use clone and snapshot functionality, make sure your storage pool + supports the VolumeSnapshots feature and create it in the storage pool (SC). Please note that the storage pool (SC) + has additional prerequisites that need to be met. + + - Prerequisites: + + - KubeVirt utilizes the VolumeSnapshot feature of the Kubernetes CSI driver to capture the persistent state + of virtual machines. Therefore, you need to ensure that your virtual machine uses a StorageClass that + supports VolumeSnapshots and is configured with the correct VolumeSnapshotClass. + - Check the created SnapshotClass and confirm that the provisioner property matches the Driver property in the storage pool. + + - Supports adding one system disk and multiple data disks. + +- Network: If no configuration is made, the system will create a VirtIO type network by default. + +### Login Settings + +- Username/Password: You can log in to the virtual machine using a username and password. +- SSH: When selecting SSH login, you can bind an SSH key to the virtual machine for future login purposes. + +![Login Settings](../images/login-settings.png) diff --git a/docs/en/docs/virtnest/template/tep.md b/docs/en/docs/virtnest/template/tep.md new file mode 100644 index 0000000..2441368 --- /dev/null +++ b/docs/en/docs/virtnest/template/tep.md @@ -0,0 +1,58 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-11 +--- + +# VM Template + +This guide explains the usage of internal VM templates and custom VM templates. + +Using both internal and custom templates, users can easily create new VMs. +Additionally, we provide the ability to convert existing VMs into VM templates, +allowing users to manage and utilize resources more flexibly. + +## VM Templates + +1. Click __Container Management__ in the left navigation menu, then click __VM Template__ to access the __VM Template__ page. If the template is converted from a virtual machine configured with a GPU, the template will also include GPU information and will be displayed in the template list. + + ![VM templates](../images/tem01.png) + +2. Click the __┇__ on the right side of a template in the list. For internal templates, you can create VM and view YAML. + For custom templates, you can create VM, edit YAML and delete template. + + ![Internal template](../images/tem02.png) + + ![Custom template](../images/tem03.png) + + ![Edit custom template](../images/tem-yaml.png) + +### Internal Template + +- The platform provides CentOS and Ubuntu as templates. + + ![CentOS and Ubuntu](../images/vm-tem.png) + +### Custom Template + +Custom templates are created from VM configurations. The following steps explain how to convert a VM configuration +into a template. + +1. Click __Container Management__ in the left navigation menu, then click __Virtual Machines__ to access the list page. + Click the __┇__ on the right side of a VM in the list to convert the configuration into a template. Only running + or stopped VMs can be converted. + + ![Convert to Template](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/tep04.png) + +2. Provide a name for the new template. A notification will indicate that the original VM will be preserved and + remain available. After a successful conversion, a new entry will be added to the template list. + + ![Convert Confirmation](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/tep05.png) + +### Template Details + +After successfully creating a template, you can click the template name to view the details of the VM, +including Basic Information, GPU Settings, Storage, Network, and more. If you need to quickly deploy a +new VM based on that template, simply click the __Create VM__ button in the upper right corner of the +page for easy operation. + +![Details](../images/tem-detail.png) diff --git a/docs/en/docs/virtnest/vm-image/index.md b/docs/en/docs/virtnest/vm-image/index.md new file mode 100644 index 0000000..cce4e5d --- /dev/null +++ b/docs/en/docs/virtnest/vm-image/index.md @@ -0,0 +1,47 @@ +# Build Virtual Machine Images + +This document will explain how to build the required virtual machine images. + +A virtual machine image is essentially a replica file, which is a disk partition with an installed operating system. Common image file formats include raw, qcow2, vmdk, etc. + +## Build an Image + +Below are some detailed steps for building virtual machine images: + +1. Download System Images + + Before building virtual machine images, you need to download the required system images. We recommend using images in qcow2, raw, or vmdk formats. You can visit the following links to get CentOS and Fedora images: + + - [CentOS Cloud Images](https://cloud.centos.org/centos/7/images/?C=M;O=D): Obtain CentOS images from the official CentOS project or other sources. Make sure to choose a version compatible with your virtualization platform. + - [Fedora Cloud Images](https://fedoraproject.org/zh-Hans/cloud/download): Get images from the official Fedora project. Choose the appropriate version based on your requirements. + +2. Build a Docker Image and Push it to a Containe Registry + + In this step, we will use Docker to build an image and push it to a container registry for easy deployment and usage when needed. + + - Create a Dockerfile + + ```Dockerfile + FROM scratch + ADD --chown=107:107 CentOS-7-x86_64-GenericCloud.qcow2 /disk/ + ``` + + The Dockerfile above adds a file named `CentOS-7-x86_64-GenericCloud.qcow2` to the image being built from a scratch base image and places it in the __/disk/__ directory within the image. This operation includes the file in the image, allowing it to provide a CentOS 7 x86_64 operating system environment when used to create a virtual machine. + + - Build the Image + + ```shell + docker build -t release-ci.daocloud.io/ghippo/kubevirt-demo/centos7:v1 . + ``` + + The above command builds an image named `release-ci.daocloud.io/ghippo/kubevirt-demo/centos7:v1` using the instructions in the Dockerfile. You can modify the image name according to your project requirements. + + - Push the Image to the Container Registry + + Use the following command to push the built image to the `release-ci.daocloud.io` container registry. You can modify the repository name and address as needed. + + ```shell + docker push release-ci.daocloud.io/ghippo/kubevirt-demo/centos7:v1 + ``` + +These are the detailed steps and instructions for building virtual machine images. By following these steps, you will be able to successfully build and push images for virtual machines to meet your usage needs. diff --git a/docs/en/docs/virtnest/vm/auto-migrate.md b/docs/en/docs/virtnest/vm/auto-migrate.md new file mode 100644 index 0000000..c5151c3 --- /dev/null +++ b/docs/en/docs/virtnest/vm/auto-migrate.md @@ -0,0 +1,69 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-11 +--- + +# Automatic VM Drifting + +This article will explain how to seamlessly migrate running virtual machines to other nodes +when a node in the cluster becomes inaccessible due to power outages or network failures, +ensuring business continuity and data security. + +Compared to automatic drifting, live migration requires you to manually initiate +the migration process through the interface, rather than having the system automatically trigger it. + +## Prerequisites + +Before implementing automatic drifting, the following prerequisites must be met: + +- The virtual machine has not performed disk commit operations, or is using Rook-ceph or HwameiStor HA as the storage system. +- The node has been unreachable for more than five minutes. +- Ensure there are at least two available nodes in the cluster, and the virtual machine has not specified a scheduling node. +- The virtual machine's launcher pod has been deleted. + +## Steps + +1. Check the status of the virtual machine launcher pod: + + ```sh + kubectl get pod + ``` + + Check if the launcher pod is in a Terminating state. + +2. Force delete the launcher pod: + + If the launcher pod is in a Terminating state, you can force delete it with the following command: + + ```sh + kubectl delete --force + ``` + + Replace `` with the name of your launcher pod. + +3. Wait for recreation and check the status: + + After deletion, the system will automatically recreate the launcher pod. + Wait for its status to become running, then refresh the virtual machine list to see if the VM has successfully migrated to the new node. + +## Notes + +If using rook-ceph as storage, it needs to be configured in ReadWriteOnce mode: + +1. After force deleting the pod, you need to wait approximately six minutes for the launcher pod + to start, or you can immediately start the pod using the following commands: + + ```sh + kubectl get pv | grep + kubectl get VolumeAttachment | grep + ``` + + Replace `` and `` with your virtual machine name and persistent volume name. + +2. Then delete the corresponding VolumeAttachment with the following command: + + ```sh + kubectl delete VolumeAttachment + ``` + + Replace `` with your virtual machine name. \ No newline at end of file diff --git a/docs/en/docs/virtnest/vm/create-secret.md b/docs/en/docs/virtnest/vm/create-secret.md new file mode 100644 index 0000000..da4cdb2 --- /dev/null +++ b/docs/en/docs/virtnest/vm/create-secret.md @@ -0,0 +1,30 @@ +--- +hide: + - toc +MTPE: ModetaNiu +DATE: 2024-08-21 +--- + +# Create Secret + +When creating a virtual machine using Object Storage (S3) as the image source, sometimes you need to fill in a secret +to get through S3's verification. The following will introduce how to create a secret that meets the requirements +of the virtual machine. + +1. Click __Container Management__ in the left navigation bar, then click __Clusters__ , enter the details of the cluster + where the virtual machine is located, click __ConfigMaps & Secrets__ , select the __Secrets__ , + and click __Create Secret__ . + + ![Create Secret](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/secret01.png) + +2. Enter the creation page, fill in the secret name, select the namespace that is the same as the virtual machine, + and note that you need to select the default type __Opaque__ . The secret data needs to follow the following principles. + + - accessKeyId: Data represented in Base64 encoding + - secretKey: Data represented in Base64 encoding + + ![Requirements](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/secret02.png) + +3. After successful creation, you can use the required secret when creating a virtual machine. + + ![Use Secret](https://docs.daocloud.io/daocloud-docs-images/docs/en/docs/virtnest/images/secret03.png) diff --git a/docs/en/docs/virtnest/vm/cross-cluster-migrate.md b/docs/en/docs/virtnest/vm/cross-cluster-migrate.md new file mode 100644 index 0000000..018ff5d --- /dev/null +++ b/docs/en/docs/virtnest/vm/cross-cluster-migrate.md @@ -0,0 +1,172 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-27 +--- + +# Migrate VM across Clusters + +This feature currently does not have a UI, so you can follow the steps in the documentation. + +## Use Cases + +- A VM needs to be migrated to another cluster when the original cluster experiences a failure or performance degradation that makes the VM inaccessible. +- A VM needs to be migrated to another cluster when perform planned maintenance or upgrades on the cluster. +- A VM needs to be migrated to another cluster to match more appropriate resource configurations when the performance requirements of specific applications change and resource allocation needs to be adjusted. + +## Prerequisites + +Before performing migration of a VM across cluster, the following prerequisites must be met: + +- Cluster network connectivity: Ensure that the network between the original cluster and the target migration cluster is accessible. +- Same storage type: The target migration cluster must support the same storage type as the original cluster. For example, if the exporting cluster uses rook-ceph-block type StorageClass, the importing cluster must also support this type. +- Enable VMExport Feature Gate in KubeVirt of the original cluster. + +## Enable VMExport Feature Gate + +To activate the VMExport Feature Gate, run the following command in the original cluster. You can refer to [How to activate a feature gate](https://kubevirt.io/user-guide/cluster_admin/activating_feature_gates/#how-to-activate-a-feature-gate) + +```sh +kubectl edit kubevirt kubevirt -n virtnest-system +``` + +This command modifies the `featureGates` to include `VMExport`. + +```yaml +apiVersion: kubevirt.io/v1 +kind: KubeVirt +metadata: + name: kubevirt + namespace: virtnest-system +spec: + configuration: + developerConfiguration: + featureGates: + - DataVolumes + - LiveMigration + - VMExport +``` + +## Configure Ingress for the Original Cluster + +Using Nginx Ingress as an example, configure Ingress to point to the `virt-exportproxy` Service: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-vm-export + namespace: virtnest-system +spec: + tls: + - hosts: + - upgrade-test.com + secretName: nginx-tls + rules: + - host: upgrade-test.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: virt-exportproxy + port: + number: 8443 + ingressClassName: nginx +``` + +## Migration Steps + +1. Create a VirtualMachineExport CR. + + - If cold migration is performed while **the VM is powered off** : + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: example-token # Export Token used by the VM + namespace: default # Namespace where the VM resides + stringData: + token: 1234567890ab # Export the used Token (Modifiable) + + --- + apiVersion: export.kubevirt.io/v1alpha1 + kind: VirtualMachineExport + metadata: + name: example-export # Export name (Modifiable) + namespace: default # Namespace where the VM resides + spec: + tokenSecretRef: example-token # Must match the name of the token created above + source: + apiGroup: "kubevirt.io" + kind: VirtualMachine + name: testvm # VM name + ``` + + - If hot migration is performed using a VM snapshot while the **VM is powered on** : + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: example-token # Export Token used by VM + namespace: default # Namespace where the VM resides + stringData: + token: 1234567890ab # Export the used Token (Modifiable) + + --- + apiVersion: export.kubevirt.io/v1alpha1 + kind: VirtualMachineExport + metadata: + name: export-snapshot # Export name (Modifiable) + namespace: default # Namespace where the VM resides + spec: + tokenSecretRef: export-token # Must match the name of the token created above + source: + apiGroup: "snapshot.kubevirt.io" + kind: VirtualMachineSnapshot + name: export-snap-202407191524 # Name of the proper VM snapshot + ``` + +2. Check if the VirtualMachineExport is ready: + + ```sh + # Replace example-export with the name of the created VirtualMachineExport + kubectl get VirtualMachineExport example-export -n default + + NAME SOURCEKIND SOURCENAME PHASE + example-export VirtualMachine testvm Ready + ``` + +3. Once the VirtualMachineExport is ready, export the VM YAML. + + - If **virtctl** is installed, you can use the following command to export the VM YAML: + + ```sh + # Replace example-export with the name of the created VirtualMachineExport + # Specify the namespace with -n + virtctl vmexport download example-export --manifest --include-secret --output=manifest.yaml + ``` + + - If **virtctl** is not installed, you can use the following commands to export the VM YAML: + + ```sh + # Replace example-export with the name and namespace of the created VirtualMachineExport + manifesturl=$(kubectl get VirtualMachineExport example-export -n default -o=jsonpath='{.status.links.internal.manifests[0].url}') + secreturl=$(kubectl get VirtualMachineExport example-export -n default -o=jsonpath='{.status.links.internal.manifests[1].url}') + # Replace with the secret name and namespace + token=$(kubectl get secret example-token -n default -o=jsonpath='{.data.token}' | base64 -d) + + curl -H "Accept: application/yaml" -H "x-kubevirt-export-token: $token" --insecure $secreturl > manifest.yaml + curl -H "Accept: application/yaml" -H "x-kubevirt-export-token: $token" --insecure $manifesturl >> manifest.yaml + ``` + +4. Import VM. + + Copy the exported `manifest.yaml` to the target migration cluster and run the following command.(If the namespace does not exist, it need to be created in advance) : + + ```sh + kubectl apply -f manifest.yaml + ``` + After successfully creating a VM, you need to restart it. Once the VM is running successfully, the original VM need to be deleted in the original cluster (Do not delete the original VM if it has not started successfully). diff --git a/docs/en/docs/virtnest/vm/live-migration.md b/docs/en/docs/virtnest/vm/live-migration.md new file mode 100644 index 0000000..2b641ad --- /dev/null +++ b/docs/en/docs/virtnest/vm/live-migration.md @@ -0,0 +1,38 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-16 +--- + +# Live Migration + +This article will explain how to migrate a virtual machine from one node to another. + +When a node needs maintenance or upgrades, users can seamlessly migrate running virtual machines to other nodes +while ensuring business continuity and data security. + +## Prerequisites + +Before using live migration, the following prerequisites must be met: + +- Only running virtual machines can use the live migration feature. +- If you need to use live migration, make sure that your PVC access mode is ReadWriteMany. +- The current cluster must have at least 2 usable nodes. +- When using the feature of live migration, Masquerade or Bridge can be selected as the network mode. + +## Live Migration + +1. Click __Container Management__ on the left navigation bar, then click __Virtual Machines__ to enter the list page. + Click __┇__ on the right side of the list to migrate running virtual machines. Currently, + the virtual machine is on the node __controller-node-1__ . + + ![Live migration](../images/vm01.png) + +2. A pop-up box will appear, indicating that during live migration, the running virtual machine instances will be + migrated to another node, but the target node cannot be predetermined. Please ensure that other nodes + have sufficient resources. + + ![Pop-up box](../images/vm02.png) + +3. After a successful migration, you can view the node information in the virtual machine list. At this time, the node has been migrated to __controller-node-2__ . + + ![Successful](../images/vm03.png) diff --git a/docs/en/docs/virtnest/vm/monitor.md b/docs/en/docs/virtnest/vm/monitor.md new file mode 100644 index 0000000..466c0bb --- /dev/null +++ b/docs/en/docs/virtnest/vm/monitor.md @@ -0,0 +1,52 @@ +--- +MTPE: ModetaNiu +DATE: 2024-09-13 +--- + +# Virtual Machine Monitoring + +The virtual machine's monitoring is based on the Grafana Dashboard open-sourced by Kubevirt, +which generates monitoring dashboards for each virtual machine. + +Monitoring information of the virtual machine can provide better insights into the resource consumption +of the virtual machine, such as CPU, memory, storage, and network resource usage. These information can +help optimize and plan resources, improving overall resource utilization efficiency. + +## Prerequisites + +Before viewing the virtual machine monitoring information, the following prerequisites need to be met: + +- The insight-agent component needs to be installed in the same cluster where the virtual machine is located. + +## Virtual Machine Monitoring + +Navigate to the VM Detail page and click __Overview__ to view the monitoring content of the virtual machine. +Please note that without the insight-agent component installed, monitoring information cannot be obtained. +Below are the detailed information: + +- Total CPU, CPU Usage, Memory Total, Memory Usage. + + ![Monitoring](../images/monitor01.png) + +- CPU Utilisation: the percentage of CPU resources currently used by the virtual machine; +- Memory Utilisation: the percentage of memory resources currently used by the virtual machine out of + the total available memory. + + ![Utilisation](../images/monitor02.png) + +- Network Traffic by Virtual Machines: the amount of network data sent and received by the virtual machine + during a specific time period; +- Network Packet Loss Rate: the proportion of lost data packets during data transmission out of the total sent data packets. + + ![Traffic](../images/monitor03.png) + +- Network Packet Error Rate: the rate of errors that occur during network transmission; +- Storage Traffic: the speed and capacity at which the virtual machine system reads and writes to the disk + within a certain time period. + + ![Error rate](../images/monitor04.png) + +- Storage IOPS: the number of input/output operations the virtual machine system performs in one second. +- Storage Delay: the time delay experienced by the virtual machine system when performing disk read and write operations. + + ![Storage](../images/monitor05.png) diff --git a/docs/en/docs/virtnest/vm/scheduled-snapshot.md b/docs/en/docs/virtnest/vm/scheduled-snapshot.md new file mode 100644 index 0000000..cc9445f --- /dev/null +++ b/docs/en/docs/virtnest/vm/scheduled-snapshot.md @@ -0,0 +1,83 @@ +--- +MTPE: WANG0608GitHub +Date: 2024-09-27 +--- + +# Scheduled Snapshot + +This article introduces how to create snapshots for VMs on a schedule. + +You can create scheduled snapshots for VMs, providing continuous protection for data and ensuring +effective data recovery in case of data loss, corruption, or deletion. + +## Steps + +1. In the left navigation bar, click __Container Management__ -> __Clusters__ to select the proper + cluster where the target VM is located. + After entering the cluster, click __Workloads__ -> __CronJobs__, and choose __Create from YAML__ + to create a scheduled task. Refer to the following YAML example to create snapshots for the specified + VM on a schedule. + + ![create from yaml](../images/cronjob.jpg) + + ??? note "Click to view the YAML example for creating a scheduled task" + + ```yaml + apiVersion: batch/v1 + kind: CronJob + metadata: + name: xxxxx-xxxxx-cronjob # Scheduled task name (Customizable) + namespace: virtnest-system # Do not modify the namespace + spec: + schedule: "5 * * * *" # Modify the scheduled task execution interval as needed + concurrencyPolicy: Allow + suspend: false + successfulJobsHistoryLimit: 10 + failedJobsHistoryLimit: 3 + startingDeadlineSeconds: 60 + jobTemplate: + spec: + template: + metadata: + labels: + virtnest.io/vm: xxxx # Modify to the name of the VM that needs to be snapshotted + virtnest.io/namespace: xxxx # Modify to the namespace where the VM is located + spec: + serviceAccountName: kubevirt-operator + containers: + - name: snapshot-job + image: release.daocloud.io/virtnest/tools:v0.1.5 # For offline environments, modify the registry address to the proper registry address of the cluster + imagePullPolicy: IfNotPresent + env: + - name: NS + valueFrom: + fieldRef: + fieldPath: metadata.labels['virtnest.io/namespace'] + - name: VM + valueFrom: + fieldRef: + fieldPath: metadata.labels['virtnest.io/vm'] + command: + - /bin/sh + - -c + - | + export SUFFIX=$(date +"%Y%m%d-%H%M%S") + cat <-vgpu-kvm.run`). + + ![Download vGPU Software](../images/gpu-01.png) + +2. Clone the container-images/driver repository in the terminal + + ```bash + git clone https://gitlab.com/nvidia/container-images/driver cd driver + ``` + +3. Switch to the vgpu-manager directory for your operating system + + ```bash + cd vgpu-manager/ + ``` + +4. Copy the .run file extracted in step 1 to the current directory + + ```bash + cp /*-vgpu-kvm.run ./ + ``` + +5. Set environment variables + + - PRIVATE_REGISTRY: Name of the private registry to store the driver image. + - VERSION: Version of NVIDIA vGPU Manager, downloaded from the NVIDIA Software Portal. + - OS_TAG: Must match the operating system version of the cluster node. + - CUDA_VERSION: CUDA base image version used to build the driver image. + + ```bash + export PRIVATE_REGISTRY=my/private/registry VERSION=510.73.06 OS_TAG=ubuntu22.04 CUDA_VERSION=12.2.0 + ``` + +6. Build the NVIDIA vGPU Manager Image + + ```bash + docker build \ + --build-arg DRIVER_VERSION=${VERSION} \ + --build-arg CUDA_VERSION=${CUDA_VERSION} \ + -t ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} . + ``` + +7. Push the NVIDIA vGPU Manager image to your container registry + + ```bash + docker push ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} + ``` + +## Label Cluster Nodes + +Go to **Container Management** , select your worker cluster and click **Nodes**. On the right of the list, click __┇__ and select **Edit Labels** to add labels to the nodes. Each node can only have one label. + +You can assign the following values to the labels: container, vm-passthrough, and vm-vgpu. + +![Label](../images/gpu-02.png) + +## Install Nvidia Operator + +1. Go to **Container Management** , select your worker cluster, click **Helm Apps** -> **Helm Charts** , + choose and install gpu-operator. You need to modify some fields in the yaml. + + ```yaml + gpu-operator.sandboxWorkloads.enabled=true + gpu-operator.vgpuManager.enabled=true + gpu-operator.vgpuManager.repository= # (1)! + gpu-operator.vgpuManager.image=vgpu-manager + gpu-operator.vgpuManager.version= # (2)! + gpu-operator.vgpuDeviceManager.enabled=true + ``` + + 1. Fill in the container registry address refered in the step "Build vGPU Manager Image". + 2. Fill in the VERSION refered in the step "Build vGPU Manager Image". + +2. Wait for the installation to be successful, as shown in the image below: + + ![Installation Successful](../images/gpu-03.png) + +## Install virtnest-agent and Configure CR + +1. Install virtnest-agent, refer to [Install virtnest-agent](../install/virtnest-agent.md). + +2. Add vGPU and GPU direct pass-through to the Virtnest Kubevirt CR. + The following example shows the key yaml after adding vGPU and GPU direct pass-through: + + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + # Fill in the information below + permittedHostDevices: + mediatedDevices: # vGPU + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com /GRID_P4-1Q + pciHostDevices: # GPU direct pass-through + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com /GP104GL_TESLA_P4 + ``` + +3. In the kubevirt CR yaml, `permittedHostDevices` is used to import VM devices, + and vGPU should be added in `mediatedDevices` with the following structure: + + ```yaml + mediatedDevices: + - mdevNameSelector: GRID P4-1Q # Device Name + resourceName: nvidia.com/GRID_P4-1Q # vGPU information registered by GPU Operator to the node + ``` + +4. GPU direct pass-through should be added in `pciHostDevices` under `permittedHostDevices` with the following structure: + + ```yaml + pciHostDevices: + - externalResourceProvider: true # Do not change by default + pciVendorSelector: 10DE:1BB3 # Vendor id of the current pci device + resourceName: nvidia.com/GP104GL_TESLA_P4 # GPU information registered by GPU Operator to the node + ``` + +5. Example of obtaining vGPU information (only applicable to vGPU): View node information on a node marked as `nvidia.com/gpu.workload.config=vm-vgpu` (e.g., work-node-2), and the `nvidia.com/GRID_P4-1Q: 8` in Capacity indicates available vGPUs: + + ```bash + # kubectl describe node work-node-2 + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GRID_P4-1Q : 8 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GRID_P4-1Q: 8 + pods: 110 + ``` + + So the `mdevNameSelector` should be "GRID P4-1Q" and the `resourceName` should be "GRID_P4-1Q". + +6. Obtain GPU direct pass-through information: On a node marked as `nvidia.com/gpu.workload.config=vm-passthrough` (e.g., work-node-1), view the node information, and `nvidia.com/GP104GL_TESLA_P4: 2` in Capacity indicates available vGPUs: + + ```bash + # kubectl describe node work-node-1 + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + ``` + + So the `resourceName` should be "GRID_P4-1Q". How to obtain the `pciVendorSelector`? SSH into the target node work-node-1 and use the command "lspci -nnk -d 10de:" to get the Nvidia GPU PCI information, as shown in the image above. + +7. Editing kubevirt CR note: If there are multiple GPUs of the same model, only one needs to be written in the CR, listing each GPU is not necessary. + + ```bash + # kubectl -n virtnest-system edit kubevirt kubevirt + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + # Fill in the information below + permittedHostDevices: + mediatedDevices: # vGPU + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com/GRID_P4-1Q + pciHostDevices: # GPU direct pass-through, in the above example, TEESLA P4 has two GPUs, only register one here + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com/GP104GL_TESLA_P4 + ``` + +## Create VM YAML and Use GPU Acceleration + +The only difference from a regular virtual machine is adding GPU-related information in the devices section. + +??? note "Click to view complete YAML" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: testvm-gpu1 + namespace: default + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: systemdisk-testvm-gpu1 + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: www + source: + registry: + url: docker://release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 + runStrategy: Manual + template: + metadata: + creationTimestamp: null + spec: + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: systemdisk-testvm-gpu1 + - disk: + bus: virtio + name: cloudinitdisk + gpus: + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-0 + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-1 + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-testvm-gpu1 + name: systemdisk-testvm-gpu1 + - cloudInitNoCloud: + userDataBase64: I2Nsb3VkLWNvbmZpZwpzc2hfcHdhdXRoOiB0cnVlCmRpc2FibGVfcm9vdDogZmFsc2UKY2hwYXNzd2Q6IHsibGlzdCI6ICJyb290OmRhbmdlcm91cyIsIGV4cGlyZTogRmFsc2V9CgoKcnVuY21kOgogIC0gc2VkIC1pICIvI1w/UGVybWl0Um9vdExvZ2luL3MvXi4qJC9QZXJtaXRSb290TG9naW4geWVzL2ciIC9ldGMvc3NoL3NzaGRfY29uZmlnCiAgLSBzeXN0ZW1jdGwgcmVzdGFydCBzc2guc2VydmljZQ== + name: cloudinitdisk + ``` diff --git a/docs/en/docs/virtnest/vm/vm-network.md b/docs/en/docs/virtnest/vm/vm-network.md new file mode 100644 index 0000000..aea7776 --- /dev/null +++ b/docs/en/docs/virtnest/vm/vm-network.md @@ -0,0 +1,62 @@ +--- +MTPE: ModetaNiu +DATE: 2024-07-11 +--- + +# Virtual Machine Networking + +This article will introduce how to configure network information when creating virtual machines. + +In virtual machines, network management is a crucial part that allows us to manage and configure network connections +for virtual machines in a Kubernetes environment. It can be configured according to different needs and scenarios, +achieving a more flexible and diverse network architecture. + +1. Single NIC Scenario: For simple applications that only require basic network connectivity or when there are + resource constraints, using a single NIC can save network resources and prevent waste of resources. +2. Multiple NIC Scenario: When security isolation between different network environments needs to be achieved, + multiple NICs can be used to divide different network areas. It also allows for control and management of traffic. + +## Prerequisites + +1. When selecting the Bridge network mode, some information needs to be configured in advance: + + - Install and run Open vSwitch on the host nodes. See [Ovs-cni Quick Start](https://spidernet-io.github.io/spiderpool/v0.9/usage/install/underlay/get-started-ovs/#_1). + - Configure Open vSwitch bridge on the host nodes. See [vswitch](https://spidernet-io.github.io/spiderpool/v0.9/usage/install/underlay/get-started-ovs/#configure-open-vswitch-bridge-on-the-node) for instructions. + - Install Spiderpool. See [installing spiderpool](../../network/modules/spiderpool/install/install.md#how-to-install-spiderpool) for instructions. By default, Spiderpool will install both Multus CNI and Ovs CNI. + - Create a Multus CR of type `ovs`. You can [create a custom Multus CR](../../network/config/multus-cr.md#create-a-custom-multus-cr) or [use YAML for creation](https://spidernet-io.github.io/spiderpool/v0.9/usage/install/underlay/get-started-ovs-zh_CN/#spiderpool) + - Create a subnet and IP pool. See [creating subnets and IP pools](../../network/config/ippool/createpool.md) +. +## Network Configuration + +1. Network configuration can be combined according to the table information. + + | Network Mode | CNI | Spiderpool Installed | NIC Mode | Fixed IP | Live Migration | + | ------------------ | ------- | -------------------- | ----------- | ----------------- | -------------- | + | Masquerade (NAT) | Calico | ❌ | Single NIC | ❌ | ✅ | + | | Cilium | ❌ | Single NIC | ❌ | ✅ | + | | Flannel | ❌ | Single NIC | ❌ | ✅ | + | Bridge | OVS | ✅ | Multiple NIC| ✅ | ✅ | + + ![Network Config](../images/createvm-net01.png) + +2. Network Mode: There are two modes - Masquerade (NAT) and Bridge. Bridge mode requires the installation of + the spiderpool component. + + 1. The default selection is Masquerade (NAT) network mode using the eth0 default NIC. + + 2. If the cluster has the spiderpool component installed, then Bridge mode can be selected. The Bridge mode + supports multiple NICs. + + ![Network Mode](../images/createvm-net02.png) + + - Ensure all [prerequisites](#prerequisites) are met before selecting the Bridge mode. + +3. Adding NICs + + 1. Bridge modes support manually adding NICs. Click __Add NIC__ to configure the NIC IP pool. Choose a Multus CR + that matches the network mode, if not available, it needs to be created manually. + + 2. If the __Use Default IP Pool__ switch is turned on, it will use the default IP pool in the multus CR + configuration. If turned off, manually select the IP pool. + + ![Add NIC](../images/createvm-net03.png) diff --git a/docs/en/docs/virtnest/vm/vm-sc.md b/docs/en/docs/virtnest/vm/vm-sc.md new file mode 100644 index 0000000..87c65f4 --- /dev/null +++ b/docs/en/docs/virtnest/vm/vm-sc.md @@ -0,0 +1,181 @@ +# Storage for Virtual Machine + +This article will introduce how to configure storage when creating a virtual machine. + +Storage and virtual machine functionality are closely related, mainly providing flexible and scalable virtual machine storage capabilities through the use of Kubernetes persistent volumes and storage classes. +For example, virtual machine image storage in PVC supports cloning, snapshotting, and other operations with other data. + +## Deploying Different Storage + +Before using virtual machine storage functionality, different storage needs to be deployed according to requirements: + +1. Refer to [Deploying hwameistor](https://hwameistor.io/cn/docs/category/installation), + or install hwameistor-operator in the Helm template of the container management module. +2. Refer to [Deploying rook-ceph](https://rook.io/docs/rook/latest-release/Getting-Started/quickstart/) +3. Deploy localpath, use the command `kubectl apply -f` to create the following YAML: + +??? note "Click to view complete YAML" + + ```yaml + --- + apiVersion: v1 + kind: Namespace + metadata: + name: local-path-storage + + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: local-path-provisioner-service-account + namespace: local-path-storage + + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: local-path-provisioner-role + rules: + - apiGroups: [""] + resources: ["nodes", "persistentvolumeclaims", "configmaps"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["endpoints", "persistentvolumes", "pods"] + verbs: ["*"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: local-path-provisioner-bind + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: local-path-provisioner-role + subjects: + - kind: ServiceAccount + name: local-path-provisioner-service-account + namespace: local-path-storage + + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: local-path-provisioner + namespace: local-path-storage + spec: + replicas: 1 + selector: + matchLabels: + app: local-path-provisioner + template: + metadata: + labels: + app: local-path-provisioner + spec: + serviceAccountName: local-path-provisioner-service-account + containers: + - name: local-path-provisioner + image: rancher/local-path-provisioner:v0.0.22 + imagePullPolicy: IfNotPresent + command: + - local-path-provisioner + - --debug + - start + - --config + - /etc/config/config.json + volumeMounts: + - name: config-volume + mountPath: /etc/config/ + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumes: + - name: config-volume + configMap: + name: local-path-config + + --- + apiVersion: storage.k8s.io/v1 + kind: StorageClass + metadata: + name: local-path + provisioner: rancher.io/local-path + volumeBindingMode: WaitForFirstConsumer + reclaimPolicy: Delete + + --- + kind: ConfigMap + apiVersion: v1 + metadata: + name: local-path-config + namespace: local-path-storage + data: + config.json: |- + { + "nodePathMap": [ + { + "node": "DEFAULT_PATH_FOR_NON_LISTED_NODES", + "paths": ["/opt/local-path-provisioner"] + } + ] + } + setup: |- + #!/bin/sh + set -eu + mkdir -m 0777 -p "$VOL_DIR" + teardown: |- + #!/bin/sh + set -eu + rm -rf "$VOL_DIR" + helperPod.yaml: |- + apiVersion: v1 + kind: Pod + metadata: + name: helper-pod + spec: + containers: + - name: helper-pod + image: busybox + imagePullPolicy: IfNotPresent + ``` + +## Virtual Machine Storage + +1. System Disk: By default, a VirtIO type rootfs system disk is created for the system to store the operating system and data. + +2. Data Disk: The data disk is a storage device in the virtual machine used to store user data, application data, or other files unrelated to the operating system. Compared to the system disk, the data disk is optional and can be dynamically added or removed as needed. The capacity of the data disk can also be flexibly configured according to requirements. + + Block storage is used by default. If you need to use cloning and snapshot functions, make sure that your storage pool has created the corresponding VolumeSnapshotClass, as shown in the example below. If you need to use real-time migration, make sure that your storage supports and has selected the ReadWriteMany access mode. + + In most cases, such VolumeSnapshotClass is not automatically created during the installation process, so you need to manually create VolumeSnapshotClass. + Here is an example of creating a VolumeSnapshotClass in HwameiStor: + + ```yaml + kind: VolumeSnapshotClass + apiVersion: snapshot.storage.k8s.io/v1 + metadata: + name: hwameistor-storage-lvm-snapshot + annotations: + snapshot.storage.kubernetes.io/is-default-class: "true" + parameters: + snapsize: "1073741824" + driver: lvm.hwameistor.io + deletionPolicy: Delete + ``` + + - Execute the following command to check if the VolumeSnapshotClass has been successfully created. + + ```sh + kubectl get VolumeSnapshotClass + ``` + + - View the created Snapshotclass and confirm that the Provisioner property is consistent with the Driver property in the storage pool. diff --git a/docs/en/mkdocs.path.yaml b/docs/en/mkdocs.path.yaml new file mode 100644 index 0000000..66c8c32 --- /dev/null +++ b/docs/en/mkdocs.path.yaml @@ -0,0 +1,206 @@ +--- +# This file is used to split config and docs navigation +INHERIT: navigation.yml + +# Project information +site_name: DaoCloud Enterprise +site_url: https://docs.daocloud.io/ +site_author: DaoCloud +site_description: >- + DaoCloud Enterprise 5.0 is the next-generation PaaS platform, created with many leading cloud-native technologies, + to easily promote and boost your digital business. + +# copyright +copyright: Copyright © 2016 - 2024 DaoCloud + +# Repository +repo_name: DaoCloud/DaoCloud-docs + +repo_url: https://github.com/DaoCloud/DaoCloud-docs +edit_uri: edit/main/docs/en/docs/ + +use_directory_urls: true # disbale https://www.mkdocs.org/user-guide/configuration/#use_directory_urls +strict: false # enable strict mode, https://www.mkdocs.org/user-guide/configuration/#strict + +# Configuration +theme: + name: material + custom_dir: "theme" + # custom_dir: !ENV [THEME_DIR, "material"] + + # Don't include MkDocs' JavaScript + include_search_page: false + search_index_only: true + include_homepage_in_sidebar: false + + + # Static files + static_templates: + - 404.html + + language: "en" + features: + - content.code.annotate + - content.tooltips + # - navigation.indexes + - navigation.tabs + # - navigation.instant + # - navigation.prune + - navigation.sections + - navigation.tabs.sticky + - navigation.tracking + - navigation.top + - search.highlight + - search.suggest + - search.share + - toc.follow + # - toc.integrate + + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + font: + text: Roboto + code: Roboto Mono + favicon: images/favicon.ico + logo: images/DaoCloud.png + icon: + logo: logo + repo: fontawesome/brands/github + +# Plugins +plugins: + - search: + separator: '[\\s\\u200b\\-]' + - swagger-ui-tag + # - mermaid2 + - minify: + minify_html: true + minify_js: true + minify_css: true + htmlmin_opts: + remove_comments: true + + - redirects: + redirect_maps: + "en/install/install-dce.md": "install/index.md" + + # - git-revision-date: # Display the last update date on the bottom of each page, install with 'pip install mkdocs-git-revision-date-plugin' + # enabled_if_env: "CI" + # - git-revision-date-localized: # Add localized creation and update dates on the bottom of each page, install with 'pip install mkdocs-git-revision-date-localized-plugin' + # timezone: Asia/Shanghai + # type: timeago # Date format, valid values are 'date', 'datetime', 'iso_date', 'iso_datetime' and 'timeago' + # fallback_to_build_date: true # Default is false, enables fallback to time when mkdocs build was executed + # enable_creation_date: true # Show the file creation date next to the last update date + + # exclude: + # - index.md + # enabled: !ENV [ENABLED_GIT_REVISION_DATE, true] + + # auto desgin nav in dirs + # - awesome-pages: + # filename: .pages.yml + # collapse_single_pages: true + # strict: false + # - tags: + # tags_file: stylesheets/tags.md + +# Customization +extra: + homepage: / + + # comments + comments: + enabled: true + mode: giscus + type: Discussions + + # switch language + alternate: + - link: / + name: 简体中文 + lang: zh + - link: / + name: English + lang: en + generator: false + + status: + new: Recently added + +# Customization Javascript +extra_javascript: + - /stylesheets/zoom_image.js + # - https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js # disable fix mermaid not working + +# Customization css +extra_css: + - /stylesheets/custom.css + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - meta + - md_in_html + - tables + - toc: + permalink: true + title: nav + toc_depth: 5 + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + # emoji_index: !!python/name:materialx.emoji.twemoji + # emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + repo_url_shorthand: true + user: daocloud + repo: daocloud-docs + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + # - pymdownx.critic + + # - pymdownx.snippets: + # auto_append: + # - includes/glossary.md diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml new file mode 100644 index 0000000..3b3b7ea --- /dev/null +++ b/docs/en/mkdocs.yml @@ -0,0 +1,206 @@ +--- +# This file is used to split config and docs navigation +INHERIT: navigation.yml + +# Project information +site_name: Suanova Documentation +site_url: https://sophongo.github.io/sophdoc/ +site_author: Suanova +site_description: >- + Suanova documentation website. + +# copyright +copyright: Copyright © 2016 - 2024 Suanova + +# Repository +repo_name: sophongo/sophdoc + +repo_url: https://github.com/sophongo/sophdoc +edit_uri: edit/main/docs/en/docs/ + +use_directory_urls: false # disable https://www.mkdocs.org/user-guide/configuration/#use_directory_urls +strict: false # enable strict mode, https://www.mkdocs.org/user-guide/configuration/#strict + +# Configuration +theme: + name: material + custom_dir: "theme" + # custom_dir: !ENV [THEME_DIR, "material"] + + # Don't include MkDocs' JavaScript + include_search_page: false + search_index_only: true + include_homepage_in_sidebar: false + + + # Static files + static_templates: + - 404.html + + language: "en" + features: + - content.code.annotate + - content.code.copy + - content.tooltips + # - navigation.indexes + - navigation.tabs + # - navigation.instant + - navigation.prune + - navigation.sections + - navigation.tabs.sticky + - navigation.tracking + - navigation.top + - search.highlight + - search.suggest + - search.share + - toc.follow + - navigation.path + # - toc.integrate + + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + font: + text: Roboto + code: Roboto Mono + favicon: images/favicon.ico + logo: images/suanova.png + icon: + logo: logo + repo: fontawesome/brands/github + +# Plugins +plugins: + - search: + separator: '[\\s\\u200b\\-]' + - swagger-ui-tag + # - mermaid2 + - minify: + minify_html: true + minify_js: true + minify_css: true + htmlmin_opts: + remove_comments: true + + - redirects: + redirect_maps: + "en/install/install-dce.md": "install/index.md" + + # - git-revision-date: # Display the last update date on the bottom of each page, install with 'pip install mkdocs-git-revision-date-plugin' + # enabled_if_env: "CI" + # - git-revision-date-localized: # Add localized creation and update dates on the bottom of each page, install with 'pip install mkdocs-git-revision-date-localized-plugin' + # timezone: Asia/Shanghai + # type: timeago # Date format, valid values are 'date', 'datetime', 'iso_date', 'iso_datetime' and 'timeago' + # fallback_to_build_date: true # Default is false, enables fallback to time when mkdocs build was executed + # enable_creation_date: true # Show the file creation date next to the last update date + + # exclude: + # - index.md + # enabled: !ENV [ENABLED_GIT_REVISION_DATE, true] + + # auto desgin nav in dirs + # - awesome-pages: + # filename: .pages.yml + # collapse_single_pages: true + # strict: false + # - tags: + # tags_file: stylesheets/tags.md + +# Customization +extra: + homepage: / + + # comments + comments: + enabled: true + mode: giscus + type: Discussions + + # switch language + alternate: + - link: / + name: 简体中文 + lang: zh + - link: / + name: English + lang: en + generator: false + + status: + new: Recently added + +# Customization Javascript +extra_javascript: + - /stylesheets/zoom_image.js + # - https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js # disable fix mermaid not working + +# Customization css +extra_css: + - /stylesheets/custom.css + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - meta + - md_in_html + - tables + - toc: + permalink: true + title: nav + toc_depth: 5 + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + # emoji_index: !!python/name:materialx.emoji.twemoji + # emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + repo_url_shorthand: true + user: sophon + repo: sophondoc + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + - pymdownx.critic + - pymdownx.snippets + # auto_append: + # - includes/glossary.md diff --git a/docs/en/navigation.yml b/docs/en/navigation.yml new file mode 100644 index 0000000..f670a71 --- /dev/null +++ b/docs/en/navigation.yml @@ -0,0 +1,390 @@ +# Page Tree +nav: + - End User Manual: + - User Registration: index.md + - Global Management: + - Personal Center: + - Security Settings: ghippo/user-guide/personal-center/security-setting.md + - Access Keys: ghippo/user-guide/personal-center/accesstoken.md + - SSH Public Keys: ghippo/user-guide/personal-center/ssh-key.md + - Language Settings: ghippo/user-guide/personal-center/language.md + - Virtual Machines: + - Quick Start: + - Create Virtual Machine: virtnest/quickstart/index.md + - Update Virtual Machine: virtnest/quickstart/update.md + - Connect to Virtual Machine: virtnest/quickstart/access.md + - Access Virtual Machine via NodePort: virtnest/quickstart/nodeport.md + - Virtual Machine Details: virtnest/quickstart/detail.md + - Virtual Machine Management: + - Create Key: virtnest/vm/create-secret.md + - Clone Virtual Machine: virtnest/vm/clone.md + - Snapshot Management: virtnest/vm/snapshot.md + - Scheduled Snapshots: virtnest/vm/scheduled-snapshot.md + - Live Migration: virtnest/vm/live-migration.md + - Cold Migration within Cluster: virtnest/vm/migratiom.md + - Cross-Cluster Migration: virtnest/vm/cross-cluster-migrate.md + - Virtual Machine Monitoring: virtnest/vm/monitor.md + - Virtual Machine Network: virtnest/vm/vm-network.md + - Virtual Machine Storage: virtnest/vm/vm-sc.md + - Virtual Machine Drifting: virtnest/vm/auto-migrate.md + - Virtual Machine Health Check: virtnest/vm/health-check.md + - Container Management: + - Workloads: + - Create Deployment: kpanda/user-guide/workloads/create-deployment.md + - Create StatefulSet: kpanda/user-guide/workloads/create-statefulset.md + - Create DaemonSet: kpanda/user-guide/workloads/create-daemonset.md + - Create CronJob: kpanda/user-guide/workloads/create-cronjob.md + - Create Job: kpanda/user-guide/workloads/create-job.md + - Workload Parameter Configuration: + - Workload Status: kpanda/user-guide/workloads/pod-config/workload-status.md + - Job Parameters: kpanda/user-guide/workloads/pod-config/job-parameters.md + - Lifecycle: kpanda/user-guide/workloads/pod-config/lifecycle.md + - Environment Variables: kpanda/user-guide/workloads/pod-config/env-variables.md + - Health Check: kpanda/user-guide/workloads/pod-config/health-check.md + - Cluster Scheduling: kpanda/user-guide/workloads/pod-config/scheduling-policy.md + - Autoscaling: + - Install Metrics Server Plugin: kpanda/user-guide/scale/install-metrics-server.md + - Install Kubernetes CronHPA Controller: kpanda/user-guide/scale/install-cronhpa.md + - Install VPA Plugin: kpanda/user-guide/scale/install-vpa.md + - Create HPA Based on Built-in Metrics: kpanda/user-guide/scale/create-hpa.md + - Create HPA Based on Custom Metrics: kpanda/user-guide/scale/custom-hpa.md + - Create VPA Policy: kpanda/user-guide/scale/create-vpa.md + - HPA and CronHPA Compatibility Rules: kpanda/user-guide/scale/hpa-cronhpa-compatibility-rules.md + - Other Solutions: + - Introduction to Knative: kpanda/user-guide/scale/knative/knative.md + - Install Knative: kpanda/user-guide/scale/knative/install.md + - Knative Scenarios: kpanda/user-guide/scale/knative/scene.md + - Knative Practice: kpanda/user-guide/scale/knative/playground.md + - Helm Apps: + - Helm Template: kpanda/user-guide/helm/README.md + - Upload Helm Template: kpanda/user-guide/helm/upload-helm.md + - Manage Helm Apps: kpanda/user-guide/helm/helm-app.md + - Manage Helm Repository: kpanda/user-guide/helm/helm-repo.md + - Multi-Architecture Helm Apps: kpanda/user-guide/helm/multi-archi-helm.md + - Custom Helm App Import Addon: kpanda/user-guide/helm/Import-addon.md + - Operator Applications: kpanda/user-guide/olm/import-miniooperator.md + - Container Networking: + - Create Services: kpanda/user-guide/network/create-services.md + - Create Ingress: kpanda/user-guide/network/create-ingress.md + - Network Policies: kpanda/user-guide/network/network-policy.md + - Container Storage: + - Persistent Volume Claims: kpanda/user-guide/storage/pvc.md + - Persistent Volumes: kpanda/user-guide/storage/pv.md + - StorageClasses: kpanda/user-guide/storage/sc.md + - Shared StorageClasses: kpanda/user-guide/storage/sc-share.md + - AI Lab: + - Developer: + - Introduction: baize/developer/index.md + - Quick Start: baize/developer/quick-start.md + - Notebooks: + - Create Notebook: baize/developer/notebooks/create.md + - Start and Pause Notebook: baize/developer/notebooks/start-pause.md + - Notebook Workloads: baize/developer/notebooks/view.md + - Delete Notebook: baize/developer/notebooks/delete.md + - SSH Access to Notebook: baize/developer/notebooks/notebook-with-ssh.md + - Use Environments in Notebooks: baize/developer/notebooks/notebook-with-envs.md + - Baizectl Command-Line Tool: baize/developer/notebooks/baizectl.md + - Baizess Source Change Tool: baize/developer/notebooks/baizess.md + - Auto Shutdown for Idle Notebooks: baize/developer/notebooks/notebook-auto-close.md + - Job Center: + - Create Job: baize/developer/jobs/create.md + - Create Pytorch Job: baize/developer/jobs/pytorch.md + - Create Tensorflow Job: baize/developer/jobs/tensorflow.md + - Create MPI Job: baize/developer/jobs/mpi.md + - Create MXNet Job: baize/developer/jobs/mxnet.md + - Create PaddlePaddle Job: baize/developer/jobs/paddle.md + - Delete Job: baize/developer/jobs/delete.md + - View Job Load: baize/developer/jobs/view.md + - Job Analysis: baize/developer/jobs/tensorboard.md + - Data Management: + - Datasets: baize/developer/dataset/create-use-delete.md + - Environment: baize/developer/dataset/environments.md + - Inference Services: + - Model Support Status: baize/developer/inference/models.md + - Create Triton Inference Service: baize/developer/inference/triton-inference.md + - Create vLLM Inference Service: baize/developer/inference/vllm-inference.md + - Operator: + - Introduction: baize/oam/index.md + - Resource Management: baize/oam/resource.md + - Queue Management: + - Create Queue: baize/oam/queue/create.md + - Delete Queue: baize/oam/queue/delete.md + - Administrator Manual: + - User Registration: dce/license0.md + - Global Management: + - Access Control: + - What is Access Control: ghippo/user-guide/access-control/iam.md + - Users: ghippo/user-guide/access-control/user.md + - Groups: ghippo/user-guide/access-control/group.md + - Roles: + - ghippo/user-guide/access-control/role.md + - System Roles: ghippo/user-guide/access-control/global.md + - Custom Roles: ghippo/user-guide/access-control/custom-role.md + - Identity Providers: + - ghippo/user-guide/access-control/idprovider.md + - LDAP: ghippo/user-guide/access-control/ldap.md + - OIDC: ghippo/user-guide/access-control/oidc.md + - OAuth 2.0 for WeWork: ghippo/user-guide/access-control/oauth2.0.md + - Access Management: + - ghippo/user-guide/access-control/docking.md + - Webhook: ghippo/user-guide/access-control/webhook.md + - Workspaces and Folders: + - ghippo/user-guide/workspace/ws-folder.md + - Create and Delete Workspaces: ghippo/user-guide/workspace/workspace.md + - Workspace Permissions: ghippo/user-guide/workspace/ws-permission.md + - Create and Delete Folders: ghippo/user-guide/workspace/folders.md + - Folder Permissions: ghippo/user-guide/workspace/folder-permission.md + - Resource Quotas: ghippo/user-guide/workspace/quota.md + - Differences between Resource Groups and Shared Resources: ghippo/user-guide/workspace/res-gp-and-shared-res.md + - Resource Binding Permissions: ghippo/user-guide/workspace/wsbind-permission.md + - Audit Logs: + - Collect K8s Audit Logs: ghippo/user-guide/audit/open-audit.md + - Generate K8s Audit Logs: ghippo/user-guide/audit/open-k8s-audit.md + - Download and Export Audit Logs: ghippo/user-guide/audit/audit-log.md + - Get Source IP of Audit Logs: ghippo/user-guide/audit/source-ip.md + - Audit Item Summary: + - Container Management Audit Items: ghippo/user-guide/audit/gproduct-audit/kpanda.md + - Virtual Machine Audit Items: ghippo/user-guide/audit/gproduct-audit/virtnest.md + - Global Management Audit Items: ghippo/user-guide/audit/gproduct-audit/ghippo.md + - Operations Management: + - ghippo/user-guide/report-billing/index.md + - Report Management: ghippo/user-guide/report-billing/report.md + - Billing and Accounting: ghippo/user-guide/report-billing/billing.md + - Platform Settings: + - Security Policies: ghippo/user-guide/platform-setting/security.md + - Email Server Settings: ghippo/user-guide/platform-setting/mail-server.md + - Custom Appearance: ghippo/user-guide/platform-setting/appearance.md + - About Platform: ghippo/user-guide/platform-setting/about.md + - Reset Password: ghippo/user-guide/password.md + - Personal Center: + - Security Settings: ghippo/user-guide/personal-center/security-setting.md + - Access Keys: ghippo/user-guide/personal-center/accesstoken.md + - SSH Public Keys: ghippo/user-guide/personal-center/ssh-key.md + - Language Settings: ghippo/user-guide/personal-center/language.md + - Virtual Machines: + - Quick Start: + - Create Virtual Machine: virtnest/quickstart/index.md + - Update Virtual Machine: virtnest/quickstart/update.md + - Connect to Virtual Machine: virtnest/quickstart/access.md + - Access Virtual Machine via NodePort: virtnest/quickstart/nodeport.md + - Virtual Machine Details: virtnest/quickstart/detail.md + - Virtual Machine Management: + - Create Key: virtnest/vm/create-secret.md + - Clone Virtual Machine: virtnest/vm/clone.md + - Snapshot Management: virtnest/vm/snapshot.md + - Scheduled Snapshots: virtnest/vm/scheduled-snapshot.md + - Live Migration: virtnest/vm/live-migration.md + - Cold Migration within Cluster: virtnest/vm/migratiom.md + - Cross-Cluster Migration: virtnest/vm/cross-cluster-migrate.md + - Virtual Machine Monitoring: virtnest/vm/monitor.md + - Virtual Machine Network: virtnest/vm/vm-network.md + - Virtual Machine Storage: virtnest/vm/vm-sc.md + - Virtual Machine Drifting: virtnest/vm/auto-migrate.md + - Virtual Machine Health Check: virtnest/vm/health-check.md + - Virtual Machine GPU: + - Virtual Machine GPU: virtnest/gpu/vm-gpu.md + - Virtual Machine vGPU: virtnest/gpu/vm-vgpu.md + - Virtual Machine Templates: + - Create Virtual Machine via Template: virtnest/template/index.md + - Virtual Machine Templates: virtnest/template/tep.md + - Virtual Machine Images: virtnest/vm-image/index.md + - Container Management: + - Cluster Management: + - Create Cluster: kpanda/user-guide/clusters/create-cluster.md + - Integrate Cluster: kpanda/user-guide/clusters/integrate-cluster.md + - Access Cluster: kpanda/user-guide/clusters/access-cluster.md + - Upgrade Cluster: kpanda/user-guide/clusters/upgrade-cluster.md + - Uninstall/Detach Cluster: kpanda/user-guide/clusters/delete-cluster.md + - Cluster Roles: kpanda/user-guide/clusters/cluster-role.md + - Cluster Status: kpanda/user-guide/clusters/cluster-status.md + - How to Choose Runtime: kpanda/user-guide/clusters/runtime.md + - Cluster Version Support Range: kpanda/user-guide/clusters/cluster-version.md + - Integrate Rancher Cluster: kpanda/user-guide/clusters/integrate-rancher-cluster.md + - Deploy Second Scheduler in Cluster: kpanda/user-guide/clusters/cluster-scheduler-plugin.md + - Cluster Certificate Updates: kpanda/user-guide/clusters/k8s-cert.md + - Namespaces: + - Create Namespace: kpanda/user-guide/namespaces/createns.md + - Namespace Exclusive Nodes: kpanda/user-guide/namespaces/exclusive.md + - Pod Security Policies: kpanda/user-guide/namespaces/podsecurity.md + - Node Management: + - Node Availability Check: kpanda/user-guide/nodes/node-check.md + - Node Authentication: kpanda/user-guide/nodes/node-authentication.md + - Node Expansion: kpanda/user-guide/nodes/add-node.md + - Node Reduction: kpanda/user-guide/nodes/delete-node.md + - Taint Management: kpanda/user-guide/nodes/taints.md + - Node Scheduling: kpanda/user-guide/nodes/schedule.md + - Node Details: kpanda/user-guide/nodes/node-details.md + - Labels and Annotations: kpanda/user-guide/nodes/labels-annotations.md + - Workloads: + - Create Deployment: kpanda/user-guide/workloads/create-deployment.md + - Create StatefulSet: kpanda/user-guide/workloads/create-statefulset.md + - Create DaemonSet: kpanda/user-guide/workloads/create-daemonset.md + - Create CronJob: kpanda/user-guide/workloads/create-cronjob.md + - Create Job: kpanda/user-guide/workloads/create-job.md + - Workload Parameter Configuration: + - Workload Status: kpanda/user-guide/workloads/pod-config/workload-status.md + - Job Parameters: kpanda/user-guide/workloads/pod-config/job-parameters.md + - Lifecycle: kpanda/user-guide/workloads/pod-config/lifecycle.md + - Environment Variables: kpanda/user-guide/workloads/pod-config/env-variables.md + - Health Check: kpanda/user-guide/workloads/pod-config/health-check.md + - Cluster Scheduling: kpanda/user-guide/workloads/pod-config/scheduling-policy.md + - Autoscaling: + - Install Metrics Server Plugin: kpanda/user-guide/scale/install-metrics-server.md + - Install Kubernetes CronHPA Controller: kpanda/user-guide/scale/install-cronhpa.md + - Install VPA Plugin: kpanda/user-guide/scale/install-vpa.md + - Create HPA Based on Built-in Metrics: kpanda/user-guide/scale/create-hpa.md + - Create HPA Based on Custom Metrics: kpanda/user-guide/scale/custom-hpa.md + - Create VPA Policy: kpanda/user-guide/scale/create-vpa.md + - HPA and CronHPA Compatibility Rules: kpanda/user-guide/scale/hpa-cronhpa-compatibility-rules.md + - Other Solutions: + - Introduction to Knative: kpanda/user-guide/scale/knative/knative.md + - Install Knative: kpanda/user-guide/scale/knative/install.md + - Knative Scenarios: kpanda/user-guide/scale/knative/scene.md + - Knative Practice: kpanda/user-guide/scale/knative/playground.md + - Container Networking: + - Create Services: kpanda/user-guide/network/create-services.md + - Create Ingress: kpanda/user-guide/network/create-ingress.md + - Network Policies: kpanda/user-guide/network/network-policy.md + - Container Storage: + - Persistent Volume Claims: kpanda/user-guide/storage/pvc.md + - Persistent Volumes: kpanda/user-guide/storage/pv.md + - StorageClasses: kpanda/user-guide/storage/sc.md + - Shared StorageClasses: kpanda/user-guide/storage/sc-share.md + - ConfigMaps and Secrets: + - Create ConfigMap: kpanda/user-guide/configmaps-secrets/create-configmap.md + - Use ConfigMap: kpanda/user-guide/configmaps-secrets/use-configmap.md + - Create Secret: kpanda/user-guide/configmaps-secrets/create-secret.md + - Use Secret: kpanda/user-guide/configmaps-secrets/use-secret.md + - ConfigMap/Secret Hot Loading: kpanda/user-guide/configmaps-secrets/configmap-hot-loading.md + - Security Management: + - Security Scan Types: kpanda/user-guide/security/index.md + - Compliance Scanning: + - Scan Configuration: kpanda/user-guide/security/cis/config.md + - Scan Policy: kpanda/user-guide/security/cis/policy.md + - Scan Report: kpanda/user-guide/security/cis/report.md + - Permission Scanning: kpanda/user-guide/security/audit.md + - Vulnerability Scanning: kpanda/user-guide/security/hunter.md + - Integrate Falco Security Tool: + - Introduction: security/falco.md + - Installation: security/falco-install.md + - Falco Exporter: security/falco-exporter.md + - Permission Management: + - Introduction to Permission System: kpanda/user-guide/permissions/permission-brief.md + - Cluster and Namespace Authorization: kpanda/user-guide/permissions/cluster-ns-auth.md + - Add Built-in Permission Points for Container Management: kpanda/user-guide/permissions/custom-kpanda-role.md + - GPU Management: + - Overview of GPU Management: kpanda/user-guide/gpu/index.md + - GPU Support Matrix: kpanda/user-guide/gpu/gpu_matrix.md + - NVIDIA GPU Management: + - NVIDIA GPU Mode Description: kpanda/user-guide/gpu/nvidia/index.md + - GPU Operator: + - Offline Install GPU Operator: kpanda/user-guide/gpu/nvidia/install_nvidia_driver_of_operator.md + - Upload Red Hat GPU Operator Offline Image: kpanda/user-guide/gpu/nvidia/push_image_to_repo.md + - Build Red Hat 8.4 Offline Yum Source: kpanda/user-guide/gpu/nvidia/upgrade_yum_source_redhat8_4.md + - Build Red Hat 7.9 Offline Yum Source: kpanda/user-guide/gpu/nvidia/yum_source_redhat7_9.md + - Build Red Hat 9.2 Offline Yum Source: kpanda/user-guide/gpu/nvidia/rhel9.2_offline_install_driver.md + - Offline Install GPU Driver on Ubuntu 22.04: kpanda/user-guide/gpu/nvidia/ubuntu22.04_offline_install_driver.md + - NVIDIA Full GPU Mode: kpanda/user-guide/gpu/nvidia/full_gpu_userguide.md + - NVIDIA vGPU Mode: + - Install vGPU Addon: kpanda/user-guide/gpu/nvidia/vgpu/vgpu_addon.md + - Use NVIDIA vGPU: kpanda/user-guide/gpu/nvidia/vgpu/vgpu_user.md + - Build vGPU Memory Overcommit Image: kpanda/user-guide/gpu/nvidia/vgpu/hami.md + - NVIDIA MIG Mode: + - Overview of NVIDIA MIG: kpanda/user-guide/gpu/nvidia/mig/index.md + - Enable MIG Functionality: kpanda/user-guide/gpu/nvidia/mig/create_mig.md + - Use NVIDIA MIG: kpanda/user-guide/gpu/nvidia/mig/mig_usage.md + - MIG Related Commands: kpanda/user-guide/gpu/nvidia/mig/mig_command.md + - GPU Quota Management: kpanda/user-guide/gpu/vgpu_quota.md + - GPU Dynamic Regulation: kpanda/user-guide/gpu/dynamic-regulation.md + - GPU Monitoring and Alerts: + - GPU Monitoring Metrics: kpanda/user-guide/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md + - GPU Alert Rules: kpanda/user-guide/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md + - Using Volcano: + - Install Volcano: kpanda/user-guide/gpu/volcano/volcano_user_guide.md + - Use Volcano Gang Scheduler: kpanda/user-guide/gpu/volcano/volcano-gang-scheduler.md + - Use Volcano Priority Preemption Strategy: kpanda/user-guide/gpu/volcano/volcano_priority.md + - Use Volcano Binpack Strategy: kpanda/user-guide/gpu/volcano/volcano_binpack.md + - Use Volcano DRF Strategy: kpanda/user-guide/gpu/volcano/drf.md + - Use Volcano NUMA Affinity Scheduling: kpanda/user-guide/gpu/volcano/numa.md + - GPU Scheduling Configuration: kpanda/user-guide/gpu/gpu_scheduler_config.md + - Ascend NPUs: + - Install Ascend NPU Components: kpanda/user-guide/gpu/ascend/ascend_driver_install.md + - Use Ascend NPU: kpanda/user-guide/gpu/ascend/ascend_usage.md + - Enable Ascend VNPU: kpanda/user-guide/gpu/ascend/vnpu.md + - Iluvatar GPUs: kpanda/user-guide/gpu/Iluvatar_usage.md + - Muxi GPUs: kpanda/user-guide/gpu/metax/usemetax.md + - Cambricon GPUs: kpanda/user-guide/gpu/metax/use-mlu.md + - GPU FAQs: kpanda/user-guide/gpu/FAQ.md + - Insight: + - Dashboard: + - Overview: insight/user-guide/dashboard/overview.md + - Dashboard: insight/user-guide/dashboard/dashboard.md + - Log in to Grafana with Admin: insight/user-guide/dashboard/login-grafana.md + - Import Custom Dashboard: insight/user-guide/dashboard/import-dashboard.md + - Infrastructure: + - Clusters: insight/user-guide/infra/cluster.md + - Nodes: insight/user-guide/infra/node.md + - Namespaces: insight/user-guide/infra/namespace.md + - Workload: insight/user-guide/infra/container.md + - Events: insight/user-guide/infra/event.md + - Probes: insight/user-guide/infra/probe.md + - Metrics: insight/user-guide/data-query/metric.md + - Logging: insight/user-guide/data-query/log.md + - Traces: + - Service Topology: insight/user-guide/trace/topology.md + - Topology Helper: insight/user-guide/trace/topology-helper.md + - Service: insight/user-guide/trace/service.md + - Trace Query: insight/user-guide/trace/trace.md + - Alert Center: + - insight/user-guide/alert-center/index.md + - Alert Rules: insight/user-guide/alert-center/alert-policy.md + - Notification Config: insight/user-guide/alert-center/message.md + - Configure Notification Server: insight/user-guide/alert-center/sms-provider.md + - Message Template: insight/user-guide/alert-center/msg-template.md + - Alert Silence: insight/user-guide/alert-center/silent.md + - Alert Inhibition: insight/user-guide/alert-center/inhibition.md + - Data Collection: + - Collection Management: insight/user-guide/collection-manag/collection-manag.md + - Service Monitor: insight/user-guide/collection-manag/service-monitor.md + - insight-agent Status: insight/user-guide/collection-manag/agent-status.md + - System Config: + - System Components: insight/user-guide/system-config/system-component.md + - System Config: insight/user-guide/system-config/system-config.md + - Modify Config: insight/user-guide/system-config/modify-config.md + - AI Lab: + - Developer: + - Introduction: baize/developer/index.md + - Quick Start: baize/developer/quick-start.md + - Notebooks: + - Create Notebook: baize/developer/notebooks/create.md + - Start and Pause Notebook: baize/developer/notebooks/start-pause.md + - Notebook Workloads: baize/developer/notebooks/view.md + - Delete Notebook: baize/developer/notebooks/delete.md + - SSH Access to Notebook: baize/developer/notebooks/notebook-with-ssh.md + - Use Environments in Notebooks: baize/developer/notebooks/notebook-with-envs.md + - Baizectl Command-Line Tool: baize/developer/notebooks/baizectl.md + - Baizess Source Change Tool: baize/developer/notebooks/baizess.md + - Auto Shutdown for Idle Notebooks: baize/developer/notebooks/notebook-auto-close.md + - Job Center: + - Create Job: baize/developer/jobs/create.md + - Create Pytorch Job: baize/developer/jobs/pytorch.md + - Create Tensorflow Job: baize/developer/jobs/tensorflow.md + - Create MPI Job: baize/developer/jobs/mpi.md + - Create MXNet Job: baize/developer/jobs/mxnet.md + - Create PaddlePaddle Job: baize/developer/jobs/paddle.md + - Delete Job: baize/developer/jobs/delete.md + - View Job Load: baize/developer/jobs/view.md + - Job Analysis: baize/developer/jobs/tensorboard.md + - Data Management: + - Dataset List: baize/developer/dataset/create-use-delete.md + - Environment Management: baize/developer/dataset/environments.md + - Inference Services: + - Model Support Status: baize/developer/inference/models.md + - Create Triton Inference Service: baize/developer/inference/triton-inference.md + - Create vLLM Inference Service: baize/developer/inference/vllm-inference.md + - Operator: + - Introduction: baize/oam/index.md + - Resource Management: baize/oam/resource.md + - Queue Management: + - Create Queue: baize/oam/queue/create.md + - Delete Queue: baize/oam/queue/delete.md diff --git a/docs/en/theme/404.html b/docs/en/theme/404.html new file mode 100644 index 0000000..840baea --- /dev/null +++ b/docs/en/theme/404.html @@ -0,0 +1,91 @@ + + + + + DaoCloud Enterprise 5.0 + + + + + + +

+
+
+
+
+
+

你似乎来到了未知的空间!

+

You may come in an unknown space!

+
+
+

想要探索一下吗?试试回到起点,找到迷失的自我。

+

Want to explore? Try to go back to the beginning and find where you are lost.

+ 返回首页 + Go to Home +
+
+
+
+
+
+ + + + diff --git a/docs/en/theme/main.html b/docs/en/theme/main.html new file mode 100644 index 0000000..fed1500 --- /dev/null +++ b/docs/en/theme/main.html @@ -0,0 +1,33 @@ +{#- + This file was automatically generated - do not edit +-#} +{% extends "base.html" %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block announce %} + + New launch of DaoCloud Enterprise 5.0 Click to free try! + + +{% endblock %} +{% block content %} + {% include "overrides/partials/content.html" %} +{% endblock %} +{% block scripts %} + {{ super() }} + + + +{% endblock %} diff --git a/docs/en/theme/overrides/.icons/octoface.svg b/docs/en/theme/overrides/.icons/octoface.svg new file mode 100644 index 0000000..df0186e --- /dev/null +++ b/docs/en/theme/overrides/.icons/octoface.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape.avif b/docs/en/theme/overrides/assets/images/layers/1-landscape.avif new file mode 100644 index 0000000..227ad22 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape.png b/docs/en/theme/overrides/assets/images/layers/1-landscape.png new file mode 100644 index 0000000..4947122 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape.webp b/docs/en/theme/overrides/assets/images/layers/1-landscape.webp new file mode 100644 index 0000000..12a97b5 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.avif b/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.avif new file mode 100644 index 0000000..4cc450b Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.png b/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.png new file mode 100644 index 0000000..5ba3731 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.webp b/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.webp new file mode 100644 index 0000000..60c13e4 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@2x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.avif b/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.avif new file mode 100644 index 0000000..f5849e0 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.png b/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.png new file mode 100644 index 0000000..8308e69 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.webp b/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.webp new file mode 100644 index 0000000..b5f423e Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@3x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.avif b/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.avif new file mode 100644 index 0000000..055e9e8 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.png b/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.png new file mode 100644 index 0000000..b6513aa Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.webp b/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.webp new file mode 100644 index 0000000..a6f8ae4 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/1-landscape@4x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau.avif b/docs/en/theme/overrides/assets/images/layers/2-plateau.avif new file mode 100644 index 0000000..a840190 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau.png b/docs/en/theme/overrides/assets/images/layers/2-plateau.png new file mode 100644 index 0000000..a5311db Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau.webp b/docs/en/theme/overrides/assets/images/layers/2-plateau.webp new file mode 100644 index 0000000..299b41c Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.avif b/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.avif new file mode 100644 index 0000000..8f76503 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.png b/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.png new file mode 100644 index 0000000..e615102 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.webp b/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.webp new file mode 100644 index 0000000..9367d9c Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@2x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.avif b/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.avif new file mode 100644 index 0000000..9cb7281 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.png b/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.png new file mode 100644 index 0000000..6b2975f Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.webp b/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.webp new file mode 100644 index 0000000..1e6a788 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@3x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.avif b/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.avif new file mode 100644 index 0000000..4a4ffa6 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.png b/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.png new file mode 100644 index 0000000..66de822 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.webp b/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.webp new file mode 100644 index 0000000..af7c06d Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/2-plateau@4x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.avif b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.avif new file mode 100644 index 0000000..3a64dec Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.png b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.png new file mode 100644 index 0000000..024aff8 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.webp b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.webp new file mode 100644 index 0000000..4221d6f Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.avif b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.avif new file mode 100644 index 0000000..4cb8854 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.png b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.png new file mode 100644 index 0000000..d5feae1 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.webp b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.webp new file mode 100644 index 0000000..e1663eb Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@2x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.avif b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.avif new file mode 100644 index 0000000..ab7df5a Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.png b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.png new file mode 100644 index 0000000..37b39e9 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.webp b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.webp new file mode 100644 index 0000000..2b4f5ed Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@3x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.avif b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.avif new file mode 100644 index 0000000..c3323c4 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.png b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.png new file mode 100644 index 0000000..ffaa573 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.webp b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.webp new file mode 100644 index 0000000..e6d7b13 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/3-astronaut-1@4x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.avif b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.avif new file mode 100644 index 0000000..4c6d3f3 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.png b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.png new file mode 100644 index 0000000..905a0ae Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.webp b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.webp new file mode 100644 index 0000000..978fca9 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.avif b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.avif new file mode 100644 index 0000000..aae7473 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.png b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.png new file mode 100644 index 0000000..2026ee3 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.webp b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.webp new file mode 100644 index 0000000..1b77760 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@2x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.avif b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.avif new file mode 100644 index 0000000..ba33d05 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.png b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.png new file mode 100644 index 0000000..1bd811a Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.webp b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.webp new file mode 100644 index 0000000..b094e8a Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@3x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.avif b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.avif new file mode 100644 index 0000000..60c1787 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.png b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.png new file mode 100644 index 0000000..9520320 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.webp b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.webp new file mode 100644 index 0000000..c1ce5f9 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/4-astronaut-2@4x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1.avif b/docs/en/theme/overrides/assets/images/layers/5-plants-1.avif new file mode 100644 index 0000000..c2668e2 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1.png b/docs/en/theme/overrides/assets/images/layers/5-plants-1.png new file mode 100644 index 0000000..a4001be Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1.webp b/docs/en/theme/overrides/assets/images/layers/5-plants-1.webp new file mode 100644 index 0000000..771f236 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.avif b/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.avif new file mode 100644 index 0000000..7e39ea6 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.png b/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.png new file mode 100644 index 0000000..5e537b7 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.webp b/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.webp new file mode 100644 index 0000000..980ea24 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@2x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.avif b/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.avif new file mode 100644 index 0000000..9d7d1ab Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.png b/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.png new file mode 100644 index 0000000..1b3efb6 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.webp b/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.webp new file mode 100644 index 0000000..49688c6 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@3x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.avif b/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.avif new file mode 100644 index 0000000..ec34061 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.png b/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.png new file mode 100644 index 0000000..8af3b36 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.webp b/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.webp new file mode 100644 index 0000000..2d0da21 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/5-plants-1@4x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2.avif b/docs/en/theme/overrides/assets/images/layers/6-plants-2.avif new file mode 100644 index 0000000..ec17d51 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2.png b/docs/en/theme/overrides/assets/images/layers/6-plants-2.png new file mode 100644 index 0000000..eb2c9be Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2.webp b/docs/en/theme/overrides/assets/images/layers/6-plants-2.webp new file mode 100644 index 0000000..40dde22 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.avif b/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.avif new file mode 100644 index 0000000..c45980b Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.png b/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.png new file mode 100644 index 0000000..a6ecade Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.webp b/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.webp new file mode 100644 index 0000000..9b975bc Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@2x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.avif b/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.avif new file mode 100644 index 0000000..bd973f6 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.png b/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.png new file mode 100644 index 0000000..2416f96 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.webp b/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.webp new file mode 100644 index 0000000..5c37f8c Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@3x.webp differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.avif b/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.avif new file mode 100644 index 0000000..6e22986 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.avif differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.png b/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.png new file mode 100644 index 0000000..ff40efc Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.png differ diff --git a/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.webp b/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.webp new file mode 100644 index 0000000..fde5dcf Binary files /dev/null and b/docs/en/theme/overrides/assets/images/layers/6-plants-2@4x.webp differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/built-in-search.png b/docs/en/theme/overrides/assets/images/spotlight/built-in-search.png new file mode 100644 index 0000000..d28587d Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/built-in-search.png differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/ci-cd.png b/docs/en/theme/overrides/assets/images/spotlight/ci-cd.png new file mode 100644 index 0000000..2a44a3e Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/ci-cd.png differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/code-annotations.png b/docs/en/theme/overrides/assets/images/spotlight/code-annotations.png new file mode 100644 index 0000000..15047b7 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/code-annotations.png differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/easy-to-use.jpg b/docs/en/theme/overrides/assets/images/spotlight/easy-to-use.jpg new file mode 100644 index 0000000..3987105 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/easy-to-use.jpg differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/icons-emojis.png b/docs/en/theme/overrides/assets/images/spotlight/icons-emojis.png new file mode 100644 index 0000000..17cf992 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/icons-emojis.png differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/ready.jpg b/docs/en/theme/overrides/assets/images/spotlight/ready.jpg new file mode 100644 index 0000000..411aaab Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/ready.jpg differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/security.png b/docs/en/theme/overrides/assets/images/spotlight/security.png new file mode 100644 index 0000000..cc0d4ae Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/security.png differ diff --git a/docs/en/theme/overrides/assets/images/spotlight/social-cards.png b/docs/en/theme/overrides/assets/images/spotlight/social-cards.png new file mode 100644 index 0000000..25fb35a Binary files /dev/null and b/docs/en/theme/overrides/assets/images/spotlight/social-cards.png differ diff --git a/docs/en/theme/overrides/assets/images/users/john-maeda.jpg b/docs/en/theme/overrides/assets/images/users/john-maeda.jpg new file mode 100644 index 0000000..60f416e Binary files /dev/null and b/docs/en/theme/overrides/assets/images/users/john-maeda.jpg differ diff --git a/docs/en/theme/overrides/assets/images/users/michael-feng.jpg b/docs/en/theme/overrides/assets/images/users/michael-feng.jpg new file mode 100644 index 0000000..774a467 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/users/michael-feng.jpg differ diff --git a/docs/en/theme/overrides/assets/images/users/sebastian-ramirez.jpg b/docs/en/theme/overrides/assets/images/users/sebastian-ramirez.jpg new file mode 100644 index 0000000..e77e8e5 Binary files /dev/null and b/docs/en/theme/overrides/assets/images/users/sebastian-ramirez.jpg differ diff --git a/docs/en/theme/overrides/assets/images/wall.png b/docs/en/theme/overrides/assets/images/wall.png new file mode 100644 index 0000000..d3c21fb Binary files /dev/null and b/docs/en/theme/overrides/assets/images/wall.png differ diff --git a/docs/en/theme/overrides/assets/javascripts/bundle.b97a6647.min.js b/docs/en/theme/overrides/assets/javascripts/bundle.b97a6647.min.js new file mode 100644 index 0000000..e67e6bb --- /dev/null +++ b/docs/en/theme/overrides/assets/javascripts/bundle.b97a6647.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var To=Object.create;var nr=Object.defineProperty;var Oo=Object.getOwnPropertyDescriptor;var _o=Object.getOwnPropertyNames,Hr=Object.getOwnPropertySymbols,Mo=Object.getPrototypeOf,Rr=Object.prototype.hasOwnProperty,Lo=Object.prototype.propertyIsEnumerable;var Ir=(e,t,n)=>t in e?nr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Q=(e,t)=>{for(var n in t||(t={}))Rr.call(t,n)&&Ir(e,n,t[n]);if(Hr)for(var n of Hr(t))Lo.call(t,n)&&Ir(e,n,t[n]);return e};var Oe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Co=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of _o(t))!Rr.call(e,o)&&o!==n&&nr(e,o,{get:()=>t[o],enumerable:!(r=Oo(t,o))||r.enumerable});return e};var qe=(e,t,n)=>(n=e!=null?To(Mo(e)):{},Co(t||!e||!e.__esModule?nr(n,"default",{value:e,enumerable:!0}):n,e));var en=Oe((Yi,yt)=>{var kr,Pr,$r,Fr,Wr,Ur,jr,zr,Dr,gt,or,Vr,Nr,Qr,Ke,qr,Kr,Yr,Br,Gr,Jr,Xr,Zr,xt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(r){e(n(t,n(r)))}):typeof yt=="object"&&typeof yt.exports=="object"?e(n(t,n(yt.exports))):e(n(t));function n(r,o){return r!==t&&(typeof Object.create=="function"?Object.defineProperty(r,"__esModule",{value:!0}):r.__esModule=!0),function(i,a){return r[i]=o?o(i,a):a}}})(function(e){var t=Object.setPrototypeOf||{__proto__ :[]}instanceof Array&&function(r,o){r.__proto__=o}||function(r,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(r[i]=o[i])};kr=function(r,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(r,o);function i(){this.constructor=r}r.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},Pr=Object.assign||function(r){for(var o,i=1,a=arguments.length;i=0;u--)(p=r[u])&&(s=(c<3?p(s):c>3?p(o,i,s):p(o,i))||s);return c>3&&s&&Object.defineProperty(o,i,s),s},Wr=function(r,o){return function(i,a){o(i,a,r)}},Ur=function(r,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(r,o)},jr=function(r,o,i,a){function c(s){return s instanceof i?s:new i(function(p){p(s)})}return new(i||(i=Promise))(function(s,p){function u(d){try{f(a.next(d))}catch(l){p(l)}}function m(d){try{f(a.throw(d))}catch(l){p(l)}}function f(d){d.done?s(d.value):c(d.value).then(u,m)}f((a=a.apply(r,o||[])).next())})},zr=function(r,o){var i={label:0,sent:function(){if(s[0]&1)throw s[1];return s[1]},trys:[],ops:[]},a,c,s,p;return p={next:u(0),throw:u(1),return:u(2)},typeof Symbol=="function"&&(p[Symbol.iterator]=function(){return this}),p;function u(f){return function(d){return m([f,d])}}function m(f){if(a)throw new TypeError("Generator is already executing.");for(;i;)try{if(a=1,c&&(s=f[0]&2?c.return:f[0]?c.throw||((s=c.return)&&s.call(c),0):c.next)&&!(s=s.call(c,f[1])).done)return s;switch(c=0,s&&(f=[f[0]&2,s.value]),f[0]){case 0:case 1:s=f;break;case 4:return i.label++,{value:f[1],done:!1};case 5:i.label++,c=f[1],f=[0];continue;case 7:f=i.ops.pop(),i.trys.pop();continue;default:if(s=i.trys,!(s=s.length>0&&s[s.length-1])&&(f[0]===6||f[0]===2)){i=0;continue}if(f[0]===3&&(!s||f[1]>s[0]&&f[1]=r.length&&(r=void 0),{value:r&&r[a++],done:!r}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},or=function(r,o){var i=typeof Symbol=="function"&&r[Symbol.iterator];if(!i)return r;var a=i.call(r),c,s=[],p;try{for(;(o===void 0||o-- >0)&&!(c=a.next()).done;)s.push(c.value)}catch(u){p={error:u}}finally{try{c&&!c.done&&(i=a.return)&&i.call(a)}finally{if(p)throw p.error}}return s},Vr=function(){for(var r=[],o=0;o1||u(h,v)})})}function u(h,v){try{m(a[h](v))}catch(E){l(s[0][3],E)}}function m(h){h.value instanceof Ke?Promise.resolve(h.value.v).then(f,d):l(s[0][2],h)}function f(h){u("next",h)}function d(h){u("throw",h)}function l(h,v){h(v),s.shift(),s.length&&u(s[0][0],s[0][1])}},Kr=function(r){var o,i;return o={},a("next"),a("throw",function(c){throw c}),a("return"),o[Symbol.iterator]=function(){return this},o;function a(c,s){o[c]=r[c]?function(p){return(i=!i)?{value:Ke(r[c](p)),done:c==="return"}:s?s(p):p}:s}},Yr=function(r){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=r[Symbol.asyncIterator],i;return o?o.call(r):(r=typeof gt=="function"?gt(r):r[Symbol.iterator](),i={},a("next"),a("throw"),a("return"),i[Symbol.asyncIterator]=function(){return this},i);function a(s){i[s]=r[s]&&function(p){return new Promise(function(u,m){p=r[s](p),c(u,m,p.done,p.value)})}}function c(s,p,u,m){Promise.resolve(m).then(function(f){s({value:f,done:u})},p)}},Br=function(r,o){return Object.defineProperty?Object.defineProperty(r,"raw",{value:o}):r.raw=o,r};var n=Object.create?function(r,o){Object.defineProperty(r,"default",{enumerable:!0,value:o})}:function(r,o){r.default=o};Gr=function(r){if(r&&r.__esModule)return r;var o={};if(r!=null)for(var i in r)i!=="default"&&Object.prototype.hasOwnProperty.call(r,i)&&xt(o,r,i);return n(o,r),o},Jr=function(r){return r&&r.__esModule?r:{default:r}},Xr=function(r,o,i,a){if(i==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?r!==o||!a:!o.has(r))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?a:i==="a"?a.call(r):a?a.value:o.get(r)},Zr=function(r,o,i,a,c){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!c)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?r!==o||!c:!o.has(r))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?c.call(r,i):c?c.value=i:o.set(r,i),i},e("__extends",kr),e("__assign",Pr),e("__rest",$r),e("__decorate",Fr),e("__param",Wr),e("__metadata",Ur),e("__awaiter",jr),e("__generator",zr),e("__exportStar",Dr),e("__createBinding",xt),e("__values",gt),e("__read",or),e("__spread",Vr),e("__spreadArrays",Nr),e("__spreadArray",Qr),e("__await",Ke),e("__asyncGenerator",qr),e("__asyncDelegator",Kr),e("__asyncValues",Yr),e("__makeTemplateObject",Br),e("__importStar",Gr),e("__importDefault",Jr),e("__classPrivateFieldGet",Xr),e("__classPrivateFieldSet",Zr)})});var lt=Oe(pe=>{(function(){var e,t,n,r,o,i,a,c,s,p,u,m,f,d,l,h,v,E,O,F;F=150,p=20,O=150,s=.75,pe.score=function(b,x,T){var C,g,y,H;return g=T.preparedQuery,C=T.allowErrors,C||o(b,g.core_lw,g.core_up)?(H=b.toLowerCase(),y=t(b,H,g),Math.ceil(y)):0},pe.isMatch=o=function(b,x,T){var C,g,y,H,U,N,W;if(y=b.length,H=x.length,!y||H>y)return!1;for(C=-1,g=-1;++g-1)return l(b,x,w,S,L,X,J);for(te=new Array(X),U=new Array(X),rr=E(X,J),B=Math.ceil(s*X)+5,ue=B,W=!0,P=-1;++PM&&(M=Te),N=0,S[P]===vt)if(tr=c(V,b,x),N=H>0?H:f(b,x,w,S,V,P,tr),y=$+m(V,P,tr,g,N),y>M)M=y,ue=B;else{if(_&&--ue<=0)return Math.max(M,te[X-1])*rr;_=!1}$=Te,H=U[P],U[P]=N,te[P]=M}}return M=te[X-1],M*rr},pe.isWordStart=c=function(b,x,T){var C,g;return b===0?!0:(C=x[b],g=x[b-1],i(g)||C!==T[b]&&g===T[b-1])},pe.isWordEnd=a=function(b,x,T,C){var g,y;return b===C-1?!0:(g=x[b],y=x[b+1],i(y)||g===T[b]&&y!==T[b+1])},i=function(b){return b===" "||b==="."||b==="-"||b==="_"||b==="/"||b==="\\"},v=function(b){var x;return bg?C:g)+10):y+F*g},pe.scoreConsecutives=f=function(b,x,T,C,g,y,H){var U,N,W,V,P,J,B;for(N=b.length,V=T.length,W=N-g,P=V-y,U=W-1&&(P=c(W,b,x),P&&(g=W))),N=-1,V=0;++N1&&W>1))return n;for(g=0,B=0,ue=0,P=0,H=-1,U=-1;++U-1){B++;continue}else break;for(;++H12*U)return!1;for(y=-1;++yC)return!1;return!0}}).call(pe)});var Zt=Oe(mt=>{(function(){var e,t,n,r,o,i,a,c,s,p;p=lt(),i=p.isMatch,e=p.computeScore,c=p.scoreSize,s=20,n=2.5,mt.score=function(u,m,f){var d,l,h,v;return l=f.preparedQuery,d=f.allowErrors,d||i(u,l.core_lw,l.core_up)?(v=u.toLowerCase(),h=e(u,v,l),h=a(u,v,h,f),Math.ceil(h)):0},a=function(u,m,f,d){var l,h,v,E,O,F,b,x,T,C;if(f===0)return 0;for(T=d.preparedQuery,C=d.useExtensionBonus,x=d.pathSeparator,O=u.length-1;u[O]===x;)O--;if(v=u.lastIndexOf(x,O),b=O-v,F=1,C&&(F+=o(m,T.ext,v,O,2),f*=F),v===-1)return f;for(E=T.depth;v>-1&&E-- >0;)v=u.lastIndexOf(x,v-1);return h=v===-1?f:F*e(u.slice(v+1,O+1),m.slice(v+1,O+1),T),l=.5*s/(s+t(u,O+1,x)),l*h+(1-l)*f*c(0,n*b)},mt.countDir=t=function(u,m,f){var d,l;if(m<1)return 0;for(d=0,l=-1;++lf)))return 0;for(E=m.length,h=d-O,h0?.9*o(u,m,f,O-2,l-1):v/h}}).call(mt)});var Tr=Oe((eo,to)=>{(function(){var e,t,n,r,o,i,a,c;c=Zt(),n=c.countDir,o=c.getExtension,to.exports=e=function(){function s(p,u){var m,f,d;if(d=u!=null?u:{},m=d.optCharRegEx,f=d.pathSeparator,!(p&&p.length))return null;this.query=p,this.query_lw=p.toLowerCase(),this.core=t(p,m),this.core_lw=this.core.toLowerCase(),this.core_up=a(this.core),this.depth=n(p,p.length,f),this.ext=o(this.query_lw),this.charCodes=r(this.query_lw)}return s}(),i=/[ _\-:\/\\]/g,t=function(s,p){return p==null&&(p=i),s.replace(p,"")},a=function(s){var p,u,m,f;for(u="",m=0,f=s.length;m{(function(){var e,t,n,r,o;r=lt(),t=Zt(),e=Tr(),n=function(i){return i.candidate},o=function(i,a){return a.score-i.score},no.exports=function(i,a,c){var s,p,u,m,f,d,l,h,v,E,O,F,b;for(h=[],u=c.key,f=c.maxResults,m=c.maxInners,O=c.usePathScoring,v=m!=null&&m>0?m:i.length+1,s=u!=null,l=O?t:r,F=0,b=i.length;F0&&(h.push({candidate:p,score:d}),!--v))));F++);return h.sort(o),i=h.map(n),f!=null&&(i=i.slice(0,f)),i}}).call(ro)});var io=Oe(er=>{(function(){var e,t,n,r,o,i,a,c,s,p;p=lt(),n=p.isMatch,r=p.isWordStart,s=p.scoreConsecutives,c=p.scoreCharacter,a=p.scoreAcronyms,er.match=o=function(u,m,f){var d,l,h,v,E,O;return d=f.allowErrors,E=f.preparedQuery,v=f.pathSeparator,d||n(u,E.core_lw,E.core_up)?(O=u.toLowerCase(),h=t(u,O,E),h.length===0||u.indexOf(v)>-1&&(l=e(u,O,E,v),h=i(h,l)),h):[]},er.wrap=function(u,m,f){var d,l,h,v,E,O,F,b,x;if(f.wrap!=null&&(x=f.wrap,O=x.tagClass,b=x.tagOpen,F=x.tagClose),O==null&&(O="highlight"),b==null&&(b=''),F==null&&(F=""),u===m)return b+u+F;if(h=o(u,m,f),h.length===0)return u;for(v="",d=-1,E=0;++dE&&(v+=u.substring(E,l),E=l);++dE&&(v+=b,v+=u.substring(E,l),v+=F,E=l)}return E<=u.length-1&&(v+=u.substring(E)),v},e=function(u,m,f,d){var l,h,v;for(v=u.length-1;u[v]===d;)v--;if(l=u.lastIndexOf(d,v),l===-1)return[];for(h=f.depth;h-- >0;)if(l=u.lastIndexOf(d,l-1),l===-1)return[];return l++,v++,t(u.slice(l,v),m.slice(l,v),f,l)},i=function(u,m){var f,d,l,h,v,E,O;if(v=u.length,E=m.length,E===0)return u.slice();if(v===0)return m.slice();for(l=-1,h=0,d=m[h],O=[];++l0?x:s(u,m,P,J,g,y,S),F=ue+c(g,y,S,O,C)),L=X[y],x=T[y],B>L?N=h:(B=L,N=E),F>B?(B=F,N=l):C=0,X[y]=B,T[y]=C,_[++V]=B>0?N:v;for(g=H-1,y=W-1,V=g*W+y,b=!0,U=[];b&&g>=0&&y>=0;)switch(_[V]){case E:g--,V-=W;break;case h:y--,V--;break;case l:U.push(g+d),y--,g--,V-=W+1;break;default:b=!1}return U.reverse(),U}}).call(er)});var Or=Oe((ao,so)=>{(function(){var e,t,n,r,o,i,a,c;n=oo(),r=io(),c=lt(),i=Zt(),e=Tr(),a=null,t=(typeof process!="undefined"&&process!==null?process.platform:void 0)==="win32"?"\\":"/",so.exports={filter:function(s,p,u){return u==null&&(u={}),(p!=null?p.length:void 0)&&(s!=null?s.length:void 0)?(u=o(u,p),n(s,p,u)):[]},score:function(s,p,u){return u==null&&(u={}),(s!=null?s.length:void 0)&&(p!=null?p.length:void 0)?(u=o(u,p),u.usePathScoring?i.score(s,p,u):c.score(s,p,u)):0},match:function(s,p,u){var m,f,d;return u==null&&(u={}),s?p?s===p?function(){d=[];for(var l=0,h=s.length;0<=h?lh;0<=h?l++:l--)d.push(l);return d}.apply(this):(u=o(u,p),r.match(s,p,u)):[]:[]},wrap:function(s,p,u){return u==null&&(u={}),s?p?(u=o(u,p),r.wrap(s,p,u)):[]:[]},prepareQuery:function(s,p){return p==null&&(p={}),p=o(p,s),p.preparedQuery}},o=function(s,p){return s.allowErrors==null&&(s.allowErrors=!1),s.usePathScoring==null&&(s.usePathScoring=!0),s.useExtensionBonus==null&&(s.useExtensionBonus=!1),s.pathSeparator==null&&(s.pathSeparator=t),s.optCharRegEx==null&&(s.optCharRegEx=null),s.wrap==null&&(s.wrap=null),s.preparedQuery==null&&(s.preparedQuery=a&&a.query===p?a:a=new e(p,s)),s}}).call(ao)});var Cr=Oe((ht,Lr)=>{(function(t,n){typeof ht=="object"&&typeof Lr=="object"?Lr.exports=n():typeof define=="function"&&define.amd?define([],n):typeof ht=="object"?ht.ClipboardJS=n():t.ClipboardJS=n()})(ht,function(){return function(){var e={686:function(r,o,i){"use strict";i.d(o,{default:function(){return X}});var a=i(279),c=i.n(a),s=i(370),p=i.n(s),u=i(817),m=i.n(u);function f(L){try{return document.execCommand(L)}catch(w){return!1}}var d=function(w){var S=m()(w);return f("cut"),S},l=d;function h(L){var w=document.documentElement.getAttribute("dir")==="rtl",S=document.createElement("textarea");S.style.fontSize="12pt",S.style.border="0",S.style.padding="0",S.style.margin="0",S.style.position="absolute",S.style[w?"right":"left"]="-9999px";var _=window.pageYOffset||document.documentElement.scrollTop;return S.style.top="".concat(_,"px"),S.setAttribute("readonly",""),S.value=L,S}var v=function(w,S){var _=h(w);S.container.appendChild(_);var M=m()(_);return f("copy"),_.remove(),M},E=function(w){var S=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},_="";return typeof w=="string"?_=v(w,S):w instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(w==null?void 0:w.type)?_=v(w.value,S):(_=m()(w),f("copy")),_},O=E;function F(L){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?F=function(S){return typeof S}:F=function(S){return S&&typeof Symbol=="function"&&S.constructor===Symbol&&S!==Symbol.prototype?"symbol":typeof S},F(L)}var b=function(){var w=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},S=w.action,_=S===void 0?"copy":S,M=w.container,$=w.target,te=w.text;if(_!=="copy"&&_!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if($!==void 0)if($&&F($)==="object"&&$.nodeType===1){if(_==="copy"&&$.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(_==="cut"&&($.hasAttribute("readonly")||$.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(te)return O(te,{container:M});if($)return _==="cut"?l($):O($,{container:M})},x=b;function T(L){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?T=function(S){return typeof S}:T=function(S){return S&&typeof Symbol=="function"&&S.constructor===Symbol&&S!==Symbol.prototype?"symbol":typeof S},T(L)}function C(L,w){if(!(L instanceof w))throw new TypeError("Cannot call a class as a function")}function g(L,w){for(var S=0;S0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof M.action=="function"?M.action:this.defaultAction,this.target=typeof M.target=="function"?M.target:this.defaultTarget,this.text=typeof M.text=="function"?M.text:this.defaultText,this.container=T(M.container)==="object"?M.container:document.body}},{key:"listenClick",value:function(M){var $=this;this.listener=p()(M,"click",function(te){return $.onClick(te)})}},{key:"onClick",value:function(M){var $=M.delegateTarget||M.currentTarget,te=this.action($)||"copy",Te=x({action:te,container:this.container,target:this.target($),text:this.text($)});this.emit(Te?"success":"error",{action:te,text:Te,trigger:$,clearSelection:function(){$&&$.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(M){return B("action",M)}},{key:"defaultTarget",value:function(M){var $=B("target",M);if($)return document.querySelector($)}},{key:"defaultText",value:function(M){return B("text",M)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(M){var $=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return O(M,$)}},{key:"cut",value:function(M){return l(M)}},{key:"isSupported",value:function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],$=typeof M=="string"?[M]:M,te=!!document.queryCommandSupported;return $.forEach(function(Te){te=te&&!!document.queryCommandSupported(Te)}),te}}]),S}(c()),X=ue},828:function(r){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(c,s){for(;c&&c.nodeType!==o;){if(typeof c.matches=="function"&&c.matches(s))return c;c=c.parentNode}}r.exports=a},438:function(r,o,i){var a=i(828);function c(u,m,f,d,l){var h=p.apply(this,arguments);return u.addEventListener(f,h,l),{destroy:function(){u.removeEventListener(f,h,l)}}}function s(u,m,f,d,l){return typeof u.addEventListener=="function"?c.apply(null,arguments):typeof f=="function"?c.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(h){return c(h,m,f,d,l)}))}function p(u,m,f,d){return function(l){l.delegateTarget=a(l.target,m),l.delegateTarget&&d.call(u,l)}}r.exports=s},879:function(r,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(r,o,i){var a=i(879),c=i(438);function s(f,d,l){if(!f&&!d&&!l)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(l))throw new TypeError("Third argument must be a Function");if(a.node(f))return p(f,d,l);if(a.nodeList(f))return u(f,d,l);if(a.string(f))return m(f,d,l);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(f,d,l){return f.addEventListener(d,l),{destroy:function(){f.removeEventListener(d,l)}}}function u(f,d,l){return Array.prototype.forEach.call(f,function(h){h.addEventListener(d,l)}),{destroy:function(){Array.prototype.forEach.call(f,function(h){h.removeEventListener(d,l)})}}}function m(f,d,l){return c(document.body,f,d,l)}r.exports=s},817:function(r){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var c=i.hasAttribute("readonly");c||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),c||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var s=window.getSelection(),p=document.createRange();p.selectNodeContents(i),s.removeAllRanges(),s.addRange(p),a=s.toString()}return a}r.exports=o},279:function(r){function o(){}o.prototype={on:function(i,a,c){var s=this.e||(this.e={});return(s[i]||(s[i]=[])).push({fn:a,ctx:c}),this},once:function(i,a,c){var s=this;function p(){s.off(i,p),a.apply(c,arguments)}return p._=a,this.on(i,p,c)},emit:function(i){var a=[].slice.call(arguments,1),c=((this.e||(this.e={}))[i]||[]).slice(),s=0,p=c.length;for(s;s{"use strict";var ji=/["'&<>]/;go.exports=zi;function zi(e){var t=""+e,n=ji.exec(t);if(!n)return t;var r,o="",i=0,a=0;for(i=n.index;i0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(n){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,n)},t.prototype._subscribe=function(n){return this._throwIfClosed(),this._checkFinalizedStatuses(n),this._innerSubscribe(n)},t.prototype._innerSubscribe=function(n){var r=this,o=this,i=o.hasError,a=o.isStopped,c=o.observers;return i||a?ir:(this.currentObservers=null,c.push(n),new ye(function(){r.currentObservers=null,_e(c,n)}))},t.prototype._checkFinalizedStatuses=function(n){var r=this,o=r.hasError,i=r.thrownError,a=r.isStopped;o?n.error(i):a&&n.complete()},t.prototype.asObservable=function(){var n=new j;return n.source=this,n},t.create=function(n,r){return new dn(n,r)},t}(j);var dn=function(e){Z(t,e);function t(n,r){var o=e.call(this)||this;return o.destination=n,o.source=r,o}return t.prototype.next=function(n){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.next)===null||o===void 0||o.call(r,n)},t.prototype.error=function(n){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.error)===null||o===void 0||o.call(r,n)},t.prototype.complete=function(){var n,r;(r=(n=this.destination)===null||n===void 0?void 0:n.complete)===null||r===void 0||r.call(n)},t.prototype._subscribe=function(n){var r,o;return(o=(r=this.source)===null||r===void 0?void 0:r.subscribe(n))!==null&&o!==void 0?o:ir},t}(ne);var at={now:function(){return(at.delegate||Date).now()},delegate:void 0};var hn=function(e){Z(t,e);function t(n,r,o){n===void 0&&(n=1/0),r===void 0&&(r=1/0),o===void 0&&(o=at);var i=e.call(this)||this;return i._bufferSize=n,i._windowTime=r,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=r===1/0,i._bufferSize=Math.max(1,n),i._windowTime=Math.max(1,r),i}return t.prototype.next=function(n){var r=this,o=r.isStopped,i=r._buffer,a=r._infiniteTimeWindow,c=r._timestampProvider,s=r._windowTime;o||(i.push(n),!a&&i.push(c.now()+s)),this._trimBuffer(),e.prototype.next.call(this,n)},t.prototype._subscribe=function(n){this._throwIfClosed(),this._trimBuffer();for(var r=this._innerSubscribe(n),o=this,i=o._infiniteTimeWindow,a=o._buffer,c=a.slice(),s=0;s0?e.prototype.requestAsyncId.call(this,n,r,o):(n.actions.push(this),n._scheduled||(n._scheduled=Je.requestAnimationFrame(function(){return n.flush(void 0)})))},t.prototype.recycleAsyncId=function(n,r,o){if(o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0)return e.prototype.recycleAsyncId.call(this,n,r,o);n.actions.some(function(i){return i.id===r})||(Je.cancelAnimationFrame(r),n._scheduled=void 0)},t}(Lt);var gn=function(e){Z(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(n){this._active=!0;var r=this._scheduled;this._scheduled=void 0;var o=this.actions,i;n=n||o.shift();do if(i=n.execute(n.state,n.delay))break;while((n=o[0])&&n.id===r&&o.shift());if(this._active=!1,i){for(;(n=o[0])&&n.id===r&&o.shift();)n.unsubscribe();throw i}},t}(Ct);var ke=new gn(vn);var ve=new j(function(e){return e.complete()});function At(e){return e&&A(e.schedule)}function fr(e){return e[e.length-1]}function Xe(e){return A(fr(e))?e.pop():void 0}function Se(e){return At(fr(e))?e.pop():void 0}function xn(e,t){return typeof fr(e)=="number"?e.pop():t}var Ze=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Ht(e){return A(e==null?void 0:e.then)}function It(e){return A(e[Ge])}function Rt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Wo(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Pt=Wo();function $t(e){return A(e==null?void 0:e[Pt])}function Ft(e){return nn(this,arguments,function(){var n,r,o,i;return St(this,function(a){switch(a.label){case 0:n=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,wt(n.read())];case 3:return r=a.sent(),o=r.value,i=r.done,i?[4,wt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,wt(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return n.releaseLock(),[7];case 10:return[2]}})})}function Wt(e){return A(e==null?void 0:e.getReader)}function z(e){if(e instanceof j)return e;if(e!=null){if(It(e))return Uo(e);if(Ze(e))return jo(e);if(Ht(e))return zo(e);if(Rt(e))return yn(e);if($t(e))return Do(e);if(Wt(e))return Vo(e)}throw kt(e)}function Uo(e){return new j(function(t){var n=e[Ge]();if(A(n.subscribe))return n.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function jo(e){return new j(function(t){for(var n=0;n0&&(u=new Fe({next:function(T){return x.next(T)},error:function(T){h=!0,v(),m=br(E,o,T),x.error(T)},complete:function(){l=!0,v(),m=br(E,a),x.complete()}}),z(F).subscribe(u))})(p)}}function br(e,t){for(var n=[],r=2;rut()||document.body),Ce(1));function nt(e){return si.pipe(I(t=>e.contains(t)),ge())}function Dn(e,t){return Y(ee(e,"mouseenter").pipe(I(()=>!0)),ee(e,"mouseleave").pipe(I(()=>!1))).pipe(t?ze(t):re,de(!1))}function Ve(e){return{x:e.offsetLeft,y:e.offsetTop}}function yr(e){return Y(ee(window,"load"),ee(window,"resize")).pipe(je(0,ke),I(()=>Ve(e)),de(Ve(e)))}function Sr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ae(e){return Y(ee(e,"scroll"),ee(window,"resize")).pipe(je(0,ke),I(()=>Sr(e)),de(Sr(e)))}var Nn=function(){if(typeof Map!="undefined")return Map;function e(t,n){var r=-1;return t.some(function(o,i){return o[0]===n?(r=i,!0):!1}),r}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__ .length},enumerable:!0,configurable:!0}),t.prototype.get=function(n){var r=e(this.__entries__ ,n),o=this.__entries__[r];return o&&o[1]},t.prototype.set=function(n,r){var o=e(this.__entries__ ,n);~o?this.__entries__[o][1]=r:this.__entries__ .push([n,r])},t.prototype.delete=function(n){var r=this.__entries__ ,o=e(r,n);~o&&r.splice(o,1)},t.prototype.has=function(n){return!!~e(this.__entries__ ,n)},t.prototype.clear=function(){this.__entries__ .splice(0)},t.prototype.forEach=function(n,r){r===void 0&&(r=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!wr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),mi?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!wr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var n=t.propertyName,r=n===void 0?"":n,o=li.some(function(i){return!!~r.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Qn=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),Kn=typeof WeakMap!="undefined"?new WeakMap:new Nn,Yn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var n=di.getInstance(),r=new Ti(t,n,this);Kn.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Yn.prototype[e]=function(){var t;return(t=Kn.get(this))[e].apply(t,arguments)}});var Oi=function(){return typeof Qt.ResizeObserver!="undefined"?Qt.ResizeObserver:Yn}(),Bn=Oi;var _i=new ne,jm=Le(()=>se(new Bn(e=>{for(let t of e)_i.next(t)}))).pipe(oe(e=>Y(pt,se(e)).pipe(me(()=>e.disconnect()))),Ce(1));function Ee(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Yt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function Bt(e){let t=e.parentElement;for(;t&&e.scrollHeight<=t.scrollHeight;)t=(e=t).parentElement;return t?e:void 0}var Gn=new ne,Mi=Le(()=>se(new IntersectionObserver(e=>{for(let t of e)Gn.next(t)},{threshold:0}))).pipe(oe(e=>Y(pt,se(e)).pipe(me(()=>e.disconnect()))),Ce(1));function Gt(e){return Mi.pipe(xe(t=>t.observe(e)),oe(t=>Gn.pipe(ce(({target:n})=>n===e),me(()=>t.unobserve(e)),I(({isIntersecting:n})=>n))))}function Er(e,t=16){return Ae(e).pipe(I(({y:n})=>{let r=Ee(e),o=Yt(e);return n>=o.height-r.height-t}),ge())}var od={drawer:q("[data-md-toggle=drawer]"),search:q("[data-md-toggle=search]")};function Ne(){return new URL(location.href)}function Jn(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let n of t)Jn(e,n)}function D(e,t,...n){let r=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?r.setAttribute(o,t[o]):r.setAttribute(o,""));for(let o of n)Jn(r,o);return r}function Jt(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function Xn(e,t={credentials:"same-origin"}){return le(fetch(`${e}`,t)).pipe(Vt(()=>ve),oe(n=>n.status!==200?lr(()=>new Error(n.statusText)):se(n)))}function Qe(e,t){return Xn(e,t).pipe(oe(n=>n.json()),Ce(1))}function Pe(e,t=document){return q(`[data-mdx-component=${e}]`,t)}function Xt(e,t=document){return ie(`[data-mdx-component=${e}]`,t)}var Li=q("#__config"),ft=JSON.parse(Li.textContent);ft.base=`${new URL(ft.base,Ne())}`;function He(){return ft}function Ie(e,t){return typeof t!="undefined"?ft.translations[e].replace("#",t.toString()):ft.translations[e]}function Zn(e){let t=nt(e),n=Y(ee(e,"keyup"),ee(e,"focus").pipe(hr(1))).pipe(I(()=>e.value),de(e.value),ge());return t.pipe(ce(r=>!r),rt(n)).subscribe(([,r])=>{let o=document.location.pathname;typeof ga=="function"&&r.length&&ga("send","pageview",`${o}?q=[icon]+${r}`)}),we([n,t]).pipe(I(([r,o])=>({ref:e,value:r,focus:o})))}var _r=qe(Or());var po=qe(Or());function co(e,t){return(0,po.wrap)(e.shortcode,t,{wrap:{tagOpen:"",tagClose:""}})}function uo(e,t,n){return D("li",{class:"mdx-iconsearch-result__item"},D("span",{class:"twemoji"},D("img",{src:e.url})),D("button",{class:"md-clipboard--inline",title:Ie("clipboard.copy"),"data-clipboard-text":n?e.shortcode:`:${e.shortcode}:`},D("code",null,n?co(e,t):`:${co(e,t)}:`)))}function fo(e){let t=`@${e.name}`;return D("a",{href:e.url,title:t,class:"mdx-sponsorship__item"},D("img",{src:e.image}))}function lo(e){return D("a",{href:"https://github.com/sponsors/squidfunk",class:"mdx-sponsorship__item mdx-sponsorship__item--private"},"+",e)}function Ci(e,{index$:t,query$:n}){switch(e.getAttribute("data-mdx-mode")){case"file":return we([n.pipe(Nt("value")),t.pipe(I(({icons:r})=>Object.values(r.data).map(o=>o.replace(/\.svg$/,""))))]).pipe(I(([{value:r},o])=>(0,_r.filter)(o,r)),oe(r=>t.pipe(I(({icons:o})=>({data:r.map(i=>({shortcode:i,url:[o.base,i,".svg"].join("")}))})))));default:return we([n.pipe(Nt("value")),t.pipe(I(({icons:r,emojis:o})=>[...Object.keys(r.data),...Object.keys(o.data)]))]).pipe(I(([{value:r},o])=>(0,_r.filter)(o,r)),oe(r=>t.pipe(I(({icons:o,emojis:i})=>({data:r.map(a=>{let c=a in o.data?o:i;return{shortcode:a,url:[c.base,c.data[a]].join("")}})})))))}}function mo(e,{index$:t,query$:n}){let r=new ne,o=Er(e).pipe(ce(Boolean)),i=q(":scope > :first-child",e);r.pipe(rt(n)).subscribe(([{data:s},{value:p}])=>{if(p)switch(s.length){case 0:i.textContent="No matches";break;case 1:i.textContent="1 match";break;default:i.textContent=`${Jt(s.length)} matches`}else i.textContent="Type to start searching"});let a=e.getAttribute("data-mdx-mode")==="file",c=q(":scope > :last-child",e);return r.pipe(xe(()=>c.innerHTML=""),oe(({data:s})=>Y(se(...s.slice(0,10)),se(...s.slice(10)).pipe(mr(10),xr(o),oe(([p])=>p)))),rt(n)).subscribe(([s,{value:p}])=>c.appendChild(uo(s,p,a))),Ci(e,{query$:n,index$:t}).pipe(xe(s=>r.next(s)),me(()=>r.complete()),I(s=>Q({ref:e},s)))}function ho(e){let t=He(),n=Qe(new URL("overrides/assets/javascripts/iconsearch_index.json",t.base)),r=Pe("iconsearch-query",e),o=Pe("iconsearch-result",e),i=Zn(r),a=mo(o,{index$:n,query$:i});return Y(i,a)}function Ai(e){return Y(...ie(":scope [hidden]",e).map(t=>Gt(t).pipe(ce(n=>n),tt(1),I(()=>({active:t})))))}function bo(e){return Le(()=>{let t=new ne;t.subscribe(({active:r})=>{r.hidden=!1}),navigator.userAgent.includes("Gecko/")&&Ae(e).pipe(I(({y:r})=>r>1),ge()).subscribe(r=>{let o=Pe("hero");o.hidden=r});let n=q(":scope > :nth-child(2)",e);return we([Ae(e),yr(n)]).subscribe(([{y:r},o])=>{q("header").classList.toggle("md-header--shadow",r>o.y)}),Ai(e).pipe(xe(r=>t.next(r)),me(()=>t.complete()),I(r=>Q({ref:e},r)))})}function Mr(e,t){return t==="inline"?D("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},D("div",{class:"md-tooltip__inner md-typeset"})):D("div",{class:"md-tooltip",id:e,role:"tooltip"},D("div",{class:"md-tooltip__inner md-typeset"}))}var Hi=0;function Ii(e,t){document.body.append(e);let{width:n}=Ee(e);e.style.setProperty("--md-tooltip-width",`${n}px`),e.remove();let r=Bt(t),o=typeof r!="undefined"?Ae(r):se({x:0,y:0}),i=Y(nt(t),Dn(t));return we([i,o]).pipe(I(([a,c])=>{let{x:s,y:p}=Ve(t),u=Ee(t);return{active:a,offset:{x:s-c.x+u.width/2-n/2,y:p-c.y+u.height+8}}}))}function dt(e){let t=e.title;if(!t.length||e.closest("table"))return ve;let n=`__tooltip_${Hi++}`,r=Mr(n,"inline"),o=q(".md-typeset",r);return o.innerHTML=t,Le(()=>{let i=new ne;return i.subscribe({next({offset:a}){r.style.setProperty("--md-tooltip-x",`${a.x}px`),r.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){r.style.removeProperty("--md-tooltip-x"),r.style.removeProperty("--md-tooltip-y")}}),Y(i.pipe(ce(({active:a})=>a)),i.pipe(ze(250),ce(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",r),e.setAttribute("aria-describedby",n),e.removeAttribute("title")):(r.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){r.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(je(16,ke)).subscribe(({active:a})=>{r.classList.toggle("md-tooltip--active",a)}),i.pipe(gr(125,ke),ce(()=>!!e.offsetParent),I(()=>e.offsetParent.getBoundingClientRect()),I(({x:a})=>a)).subscribe({next(a){a?r.style.setProperty("--md-tooltip-0",`${-a}px`):r.style.removeProperty("--md-tooltip-0")},complete(){r.style.removeProperty("--md-tooltip-0")}}),Ii(r,e).pipe(xe(a=>i.next(a)),me(()=>i.complete()),I(a=>Q({ref:e},a)))}).pipe(We(fe))}var ki=qe(Cr());var yv=D("table");var $i=qe(Cr());var Di=qe(xo());function wo(e){let t=Qe("https://3if8u9o552.execute-api.us-east-1.amazonaws.com/_/"),n=Pe("sponsorship-count"),r=Pe("sponsorship-total");return t.subscribe(o=>{e.removeAttribute("hidden");let i=q(":scope > :first-child",e);for(let a of o.sponsors)if(a.type==="public"){let c=fo(a.user);i.appendChild(c),dt(c).subscribe()}i.appendChild(lo(o.sponsors.filter(({type:a})=>a==="private").length)),n.innerText=`${o.sponsors.length}`,r.innerText=`$ ${o.total.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")} a month`}),t.pipe(I(o=>Q({ref:e},o)))}function Eo(){let{origin:e}=new URL(location.href);typeof ga!="undefined"&&ee(document.body,"click").subscribe(t=>{if(t.target instanceof HTMLElement){let n=t.target.closest("a");n&&n.origin!==e&&ga("send","event","outbound","click",n.href)}})}Eo();var qi=document$.pipe(oe(()=>Y(...Xt("iconsearch").map(e=>ho(e)),...Xt("parallax").map(e=>bo(e)),...Xt("sponsorship").map(e=>wo(e)))));qi.subscribe();})(); diff --git a/docs/en/theme/overrides/assets/javascripts/iconsearch_index.json b/docs/en/theme/overrides/assets/javascripts/iconsearch_index.json new file mode 100644 index 0000000..dc78e81 --- /dev/null +++ b/docs/en/theme/overrides/assets/javascripts/iconsearch_index.json @@ -0,0 +1 @@ +{"icons":{"base":"https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/material/.icons/","data":{"fontawesome-brands-42-group":"fontawesome/brands/42-group.svg","fontawesome-brands-500px":"fontawesome/brands/500px.svg","fontawesome-brands-accessible-icon":"fontawesome/brands/accessible-icon.svg","fontawesome-brands-accusoft":"fontawesome/brands/accusoft.svg","fontawesome-brands-adn":"fontawesome/brands/adn.svg","fontawesome-brands-adversal":"fontawesome/brands/adversal.svg","fontawesome-brands-affiliatetheme":"fontawesome/brands/affiliatetheme.svg","fontawesome-brands-airbnb":"fontawesome/brands/airbnb.svg","fontawesome-brands-algolia":"fontawesome/brands/algolia.svg","fontawesome-brands-alipay":"fontawesome/brands/alipay.svg","fontawesome-brands-amazon-pay":"fontawesome/brands/amazon-pay.svg","fontawesome-brands-amazon":"fontawesome/brands/amazon.svg","fontawesome-brands-amilia":"fontawesome/brands/amilia.svg","fontawesome-brands-android":"fontawesome/brands/android.svg","fontawesome-brands-angellist":"fontawesome/brands/angellist.svg","fontawesome-brands-angrycreative":"fontawesome/brands/angrycreative.svg","fontawesome-brands-angular":"fontawesome/brands/angular.svg","fontawesome-brands-app-store-ios":"fontawesome/brands/app-store-ios.svg","fontawesome-brands-app-store":"fontawesome/brands/app-store.svg","fontawesome-brands-apper":"fontawesome/brands/apper.svg","fontawesome-brands-apple-pay":"fontawesome/brands/apple-pay.svg","fontawesome-brands-apple":"fontawesome/brands/apple.svg","fontawesome-brands-artstation":"fontawesome/brands/artstation.svg","fontawesome-brands-asymmetrik":"fontawesome/brands/asymmetrik.svg","fontawesome-brands-atlassian":"fontawesome/brands/atlassian.svg","fontawesome-brands-audible":"fontawesome/brands/audible.svg","fontawesome-brands-autoprefixer":"fontawesome/brands/autoprefixer.svg","fontawesome-brands-avianex":"fontawesome/brands/avianex.svg","fontawesome-brands-aviato":"fontawesome/brands/aviato.svg","fontawesome-brands-aws":"fontawesome/brands/aws.svg","fontawesome-brands-bandcamp":"fontawesome/brands/bandcamp.svg","fontawesome-brands-battle-net":"fontawesome/brands/battle-net.svg","fontawesome-brands-behance":"fontawesome/brands/behance.svg","fontawesome-brands-bilibili":"fontawesome/brands/bilibili.svg","fontawesome-brands-bimobject":"fontawesome/brands/bimobject.svg","fontawesome-brands-bitbucket":"fontawesome/brands/bitbucket.svg","fontawesome-brands-bitcoin":"fontawesome/brands/bitcoin.svg","fontawesome-brands-bity":"fontawesome/brands/bity.svg","fontawesome-brands-black-tie":"fontawesome/brands/black-tie.svg","fontawesome-brands-blackberry":"fontawesome/brands/blackberry.svg","fontawesome-brands-blogger-b":"fontawesome/brands/blogger-b.svg","fontawesome-brands-blogger":"fontawesome/brands/blogger.svg","fontawesome-brands-bluetooth-b":"fontawesome/brands/bluetooth-b.svg","fontawesome-brands-bluetooth":"fontawesome/brands/bluetooth.svg","fontawesome-brands-bootstrap":"fontawesome/brands/bootstrap.svg","fontawesome-brands-bots":"fontawesome/brands/bots.svg","fontawesome-brands-btc":"fontawesome/brands/btc.svg","fontawesome-brands-buffer":"fontawesome/brands/buffer.svg","fontawesome-brands-buromobelexperte":"fontawesome/brands/buromobelexperte.svg","fontawesome-brands-buy-n-large":"fontawesome/brands/buy-n-large.svg","fontawesome-brands-buysellads":"fontawesome/brands/buysellads.svg","fontawesome-brands-canadian-maple-leaf":"fontawesome/brands/canadian-maple-leaf.svg","fontawesome-brands-cc-amazon-pay":"fontawesome/brands/cc-amazon-pay.svg","fontawesome-brands-cc-amex":"fontawesome/brands/cc-amex.svg","fontawesome-brands-cc-apple-pay":"fontawesome/brands/cc-apple-pay.svg","fontawesome-brands-cc-diners-club":"fontawesome/brands/cc-diners-club.svg","fontawesome-brands-cc-discover":"fontawesome/brands/cc-discover.svg","fontawesome-brands-cc-jcb":"fontawesome/brands/cc-jcb.svg","fontawesome-brands-cc-mastercard":"fontawesome/brands/cc-mastercard.svg","fontawesome-brands-cc-paypal":"fontawesome/brands/cc-paypal.svg","fontawesome-brands-cc-stripe":"fontawesome/brands/cc-stripe.svg","fontawesome-brands-cc-visa":"fontawesome/brands/cc-visa.svg","fontawesome-brands-centercode":"fontawesome/brands/centercode.svg","fontawesome-brands-centos":"fontawesome/brands/centos.svg","fontawesome-brands-chrome":"fontawesome/brands/chrome.svg","fontawesome-brands-chromecast":"fontawesome/brands/chromecast.svg","fontawesome-brands-cloudflare":"fontawesome/brands/cloudflare.svg","fontawesome-brands-cloudscale":"fontawesome/brands/cloudscale.svg","fontawesome-brands-cloudsmith":"fontawesome/brands/cloudsmith.svg","fontawesome-brands-cloudversify":"fontawesome/brands/cloudversify.svg","fontawesome-brands-cmplid":"fontawesome/brands/cmplid.svg","fontawesome-brands-codepen":"fontawesome/brands/codepen.svg","fontawesome-brands-codiepie":"fontawesome/brands/codiepie.svg","fontawesome-brands-confluence":"fontawesome/brands/confluence.svg","fontawesome-brands-connectdevelop":"fontawesome/brands/connectdevelop.svg","fontawesome-brands-contao":"fontawesome/brands/contao.svg","fontawesome-brands-cotton-bureau":"fontawesome/brands/cotton-bureau.svg","fontawesome-brands-cpanel":"fontawesome/brands/cpanel.svg","fontawesome-brands-creative-commons-by":"fontawesome/brands/creative-commons-by.svg","fontawesome-brands-creative-commons-nc-eu":"fontawesome/brands/creative-commons-nc-eu.svg","fontawesome-brands-creative-commons-nc-jp":"fontawesome/brands/creative-commons-nc-jp.svg","fontawesome-brands-creative-commons-nc":"fontawesome/brands/creative-commons-nc.svg","fontawesome-brands-creative-commons-nd":"fontawesome/brands/creative-commons-nd.svg","fontawesome-brands-creative-commons-pd-alt":"fontawesome/brands/creative-commons-pd-alt.svg","fontawesome-brands-creative-commons-pd":"fontawesome/brands/creative-commons-pd.svg","fontawesome-brands-creative-commons-remix":"fontawesome/brands/creative-commons-remix.svg","fontawesome-brands-creative-commons-sa":"fontawesome/brands/creative-commons-sa.svg","fontawesome-brands-creative-commons-sampling-plus":"fontawesome/brands/creative-commons-sampling-plus.svg","fontawesome-brands-creative-commons-sampling":"fontawesome/brands/creative-commons-sampling.svg","fontawesome-brands-creative-commons-share":"fontawesome/brands/creative-commons-share.svg","fontawesome-brands-creative-commons-zero":"fontawesome/brands/creative-commons-zero.svg","fontawesome-brands-creative-commons":"fontawesome/brands/creative-commons.svg","fontawesome-brands-critical-role":"fontawesome/brands/critical-role.svg","fontawesome-brands-css3-alt":"fontawesome/brands/css3-alt.svg","fontawesome-brands-css3":"fontawesome/brands/css3.svg","fontawesome-brands-cuttlefish":"fontawesome/brands/cuttlefish.svg","fontawesome-brands-d-and-d-beyond":"fontawesome/brands/d-and-d-beyond.svg","fontawesome-brands-d-and-d":"fontawesome/brands/d-and-d.svg","fontawesome-brands-dailymotion":"fontawesome/brands/dailymotion.svg","fontawesome-brands-dashcube":"fontawesome/brands/dashcube.svg","fontawesome-brands-deezer":"fontawesome/brands/deezer.svg","fontawesome-brands-delicious":"fontawesome/brands/delicious.svg","fontawesome-brands-deploydog":"fontawesome/brands/deploydog.svg","fontawesome-brands-deskpro":"fontawesome/brands/deskpro.svg","fontawesome-brands-dev":"fontawesome/brands/dev.svg","fontawesome-brands-deviantart":"fontawesome/brands/deviantart.svg","fontawesome-brands-dhl":"fontawesome/brands/dhl.svg","fontawesome-brands-diaspora":"fontawesome/brands/diaspora.svg","fontawesome-brands-digg":"fontawesome/brands/digg.svg","fontawesome-brands-digital-ocean":"fontawesome/brands/digital-ocean.svg","fontawesome-brands-discord":"fontawesome/brands/discord.svg","fontawesome-brands-discourse":"fontawesome/brands/discourse.svg","fontawesome-brands-dochub":"fontawesome/brands/dochub.svg","fontawesome-brands-docker":"fontawesome/brands/docker.svg","fontawesome-brands-draft2digital":"fontawesome/brands/draft2digital.svg","fontawesome-brands-dribbble":"fontawesome/brands/dribbble.svg","fontawesome-brands-dropbox":"fontawesome/brands/dropbox.svg","fontawesome-brands-drupal":"fontawesome/brands/drupal.svg","fontawesome-brands-dyalog":"fontawesome/brands/dyalog.svg","fontawesome-brands-earlybirds":"fontawesome/brands/earlybirds.svg","fontawesome-brands-ebay":"fontawesome/brands/ebay.svg","fontawesome-brands-edge-legacy":"fontawesome/brands/edge-legacy.svg","fontawesome-brands-edge":"fontawesome/brands/edge.svg","fontawesome-brands-elementor":"fontawesome/brands/elementor.svg","fontawesome-brands-ello":"fontawesome/brands/ello.svg","fontawesome-brands-ember":"fontawesome/brands/ember.svg","fontawesome-brands-empire":"fontawesome/brands/empire.svg","fontawesome-brands-envira":"fontawesome/brands/envira.svg","fontawesome-brands-erlang":"fontawesome/brands/erlang.svg","fontawesome-brands-ethereum":"fontawesome/brands/ethereum.svg","fontawesome-brands-etsy":"fontawesome/brands/etsy.svg","fontawesome-brands-evernote":"fontawesome/brands/evernote.svg","fontawesome-brands-expeditedssl":"fontawesome/brands/expeditedssl.svg","fontawesome-brands-facebook-f":"fontawesome/brands/facebook-f.svg","fontawesome-brands-facebook-messenger":"fontawesome/brands/facebook-messenger.svg","fontawesome-brands-facebook":"fontawesome/brands/facebook.svg","fontawesome-brands-fantasy-flight-games":"fontawesome/brands/fantasy-flight-games.svg","fontawesome-brands-fedex":"fontawesome/brands/fedex.svg","fontawesome-brands-fedora":"fontawesome/brands/fedora.svg","fontawesome-brands-figma":"fontawesome/brands/figma.svg","fontawesome-brands-firefox-browser":"fontawesome/brands/firefox-browser.svg","fontawesome-brands-firefox":"fontawesome/brands/firefox.svg","fontawesome-brands-first-order-alt":"fontawesome/brands/first-order-alt.svg","fontawesome-brands-first-order":"fontawesome/brands/first-order.svg","fontawesome-brands-firstdraft":"fontawesome/brands/firstdraft.svg","fontawesome-brands-flickr":"fontawesome/brands/flickr.svg","fontawesome-brands-flipboard":"fontawesome/brands/flipboard.svg","fontawesome-brands-fly":"fontawesome/brands/fly.svg","fontawesome-brands-font-awesome":"fontawesome/brands/font-awesome.svg","fontawesome-brands-fonticons-fi":"fontawesome/brands/fonticons-fi.svg","fontawesome-brands-fonticons":"fontawesome/brands/fonticons.svg","fontawesome-brands-fort-awesome-alt":"fontawesome/brands/fort-awesome-alt.svg","fontawesome-brands-fort-awesome":"fontawesome/brands/fort-awesome.svg","fontawesome-brands-forumbee":"fontawesome/brands/forumbee.svg","fontawesome-brands-foursquare":"fontawesome/brands/foursquare.svg","fontawesome-brands-free-code-camp":"fontawesome/brands/free-code-camp.svg","fontawesome-brands-freebsd":"fontawesome/brands/freebsd.svg","fontawesome-brands-fulcrum":"fontawesome/brands/fulcrum.svg","fontawesome-brands-galactic-republic":"fontawesome/brands/galactic-republic.svg","fontawesome-brands-galactic-senate":"fontawesome/brands/galactic-senate.svg","fontawesome-brands-get-pocket":"fontawesome/brands/get-pocket.svg","fontawesome-brands-gg-circle":"fontawesome/brands/gg-circle.svg","fontawesome-brands-gg":"fontawesome/brands/gg.svg","fontawesome-brands-git-alt":"fontawesome/brands/git-alt.svg","fontawesome-brands-git":"fontawesome/brands/git.svg","fontawesome-brands-github-alt":"fontawesome/brands/github-alt.svg","fontawesome-brands-github":"fontawesome/brands/github.svg","fontawesome-brands-gitkraken":"fontawesome/brands/gitkraken.svg","fontawesome-brands-gitlab":"fontawesome/brands/gitlab.svg","fontawesome-brands-gitter":"fontawesome/brands/gitter.svg","fontawesome-brands-glide-g":"fontawesome/brands/glide-g.svg","fontawesome-brands-glide":"fontawesome/brands/glide.svg","fontawesome-brands-gofore":"fontawesome/brands/gofore.svg","fontawesome-brands-golang":"fontawesome/brands/golang.svg","fontawesome-brands-goodreads-g":"fontawesome/brands/goodreads-g.svg","fontawesome-brands-goodreads":"fontawesome/brands/goodreads.svg","fontawesome-brands-google-drive":"fontawesome/brands/google-drive.svg","fontawesome-brands-google-pay":"fontawesome/brands/google-pay.svg","fontawesome-brands-google-play":"fontawesome/brands/google-play.svg","fontawesome-brands-google-plus-g":"fontawesome/brands/google-plus-g.svg","fontawesome-brands-google-plus":"fontawesome/brands/google-plus.svg","fontawesome-brands-google-wallet":"fontawesome/brands/google-wallet.svg","fontawesome-brands-google":"fontawesome/brands/google.svg","fontawesome-brands-gratipay":"fontawesome/brands/gratipay.svg","fontawesome-brands-grav":"fontawesome/brands/grav.svg","fontawesome-brands-gripfire":"fontawesome/brands/gripfire.svg","fontawesome-brands-grunt":"fontawesome/brands/grunt.svg","fontawesome-brands-guilded":"fontawesome/brands/guilded.svg","fontawesome-brands-gulp":"fontawesome/brands/gulp.svg","fontawesome-brands-hacker-news":"fontawesome/brands/hacker-news.svg","fontawesome-brands-hackerrank":"fontawesome/brands/hackerrank.svg","fontawesome-brands-hashnode":"fontawesome/brands/hashnode.svg","fontawesome-brands-hips":"fontawesome/brands/hips.svg","fontawesome-brands-hire-a-helper":"fontawesome/brands/hire-a-helper.svg","fontawesome-brands-hive":"fontawesome/brands/hive.svg","fontawesome-brands-hooli":"fontawesome/brands/hooli.svg","fontawesome-brands-hornbill":"fontawesome/brands/hornbill.svg","fontawesome-brands-hotjar":"fontawesome/brands/hotjar.svg","fontawesome-brands-houzz":"fontawesome/brands/houzz.svg","fontawesome-brands-html5":"fontawesome/brands/html5.svg","fontawesome-brands-hubspot":"fontawesome/brands/hubspot.svg","fontawesome-brands-ideal":"fontawesome/brands/ideal.svg","fontawesome-brands-imdb":"fontawesome/brands/imdb.svg","fontawesome-brands-instagram":"fontawesome/brands/instagram.svg","fontawesome-brands-instalod":"fontawesome/brands/instalod.svg","fontawesome-brands-intercom":"fontawesome/brands/intercom.svg","fontawesome-brands-internet-explorer":"fontawesome/brands/internet-explorer.svg","fontawesome-brands-invision":"fontawesome/brands/invision.svg","fontawesome-brands-ioxhost":"fontawesome/brands/ioxhost.svg","fontawesome-brands-itch-io":"fontawesome/brands/itch-io.svg","fontawesome-brands-itunes-note":"fontawesome/brands/itunes-note.svg","fontawesome-brands-itunes":"fontawesome/brands/itunes.svg","fontawesome-brands-java":"fontawesome/brands/java.svg","fontawesome-brands-jedi-order":"fontawesome/brands/jedi-order.svg","fontawesome-brands-jenkins":"fontawesome/brands/jenkins.svg","fontawesome-brands-jira":"fontawesome/brands/jira.svg","fontawesome-brands-joget":"fontawesome/brands/joget.svg","fontawesome-brands-joomla":"fontawesome/brands/joomla.svg","fontawesome-brands-js":"fontawesome/brands/js.svg","fontawesome-brands-jsfiddle":"fontawesome/brands/jsfiddle.svg","fontawesome-brands-kaggle":"fontawesome/brands/kaggle.svg","fontawesome-brands-keybase":"fontawesome/brands/keybase.svg","fontawesome-brands-keycdn":"fontawesome/brands/keycdn.svg","fontawesome-brands-kickstarter-k":"fontawesome/brands/kickstarter-k.svg","fontawesome-brands-kickstarter":"fontawesome/brands/kickstarter.svg","fontawesome-brands-korvue":"fontawesome/brands/korvue.svg","fontawesome-brands-laravel":"fontawesome/brands/laravel.svg","fontawesome-brands-lastfm":"fontawesome/brands/lastfm.svg","fontawesome-brands-leanpub":"fontawesome/brands/leanpub.svg","fontawesome-brands-less":"fontawesome/brands/less.svg","fontawesome-brands-line":"fontawesome/brands/line.svg","fontawesome-brands-linkedin-in":"fontawesome/brands/linkedin-in.svg","fontawesome-brands-linkedin":"fontawesome/brands/linkedin.svg","fontawesome-brands-linode":"fontawesome/brands/linode.svg","fontawesome-brands-linux":"fontawesome/brands/linux.svg","fontawesome-brands-lyft":"fontawesome/brands/lyft.svg","fontawesome-brands-magento":"fontawesome/brands/magento.svg","fontawesome-brands-mailchimp":"fontawesome/brands/mailchimp.svg","fontawesome-brands-mandalorian":"fontawesome/brands/mandalorian.svg","fontawesome-brands-markdown":"fontawesome/brands/markdown.svg","fontawesome-brands-mastodon":"fontawesome/brands/mastodon.svg","fontawesome-brands-maxcdn":"fontawesome/brands/maxcdn.svg","fontawesome-brands-mdb":"fontawesome/brands/mdb.svg","fontawesome-brands-medapps":"fontawesome/brands/medapps.svg","fontawesome-brands-medium":"fontawesome/brands/medium.svg","fontawesome-brands-medrt":"fontawesome/brands/medrt.svg","fontawesome-brands-meetup":"fontawesome/brands/meetup.svg","fontawesome-brands-megaport":"fontawesome/brands/megaport.svg","fontawesome-brands-mendeley":"fontawesome/brands/mendeley.svg","fontawesome-brands-meta":"fontawesome/brands/meta.svg","fontawesome-brands-microblog":"fontawesome/brands/microblog.svg","fontawesome-brands-microsoft":"fontawesome/brands/microsoft.svg","fontawesome-brands-mix":"fontawesome/brands/mix.svg","fontawesome-brands-mixcloud":"fontawesome/brands/mixcloud.svg","fontawesome-brands-mixer":"fontawesome/brands/mixer.svg","fontawesome-brands-mizuni":"fontawesome/brands/mizuni.svg","fontawesome-brands-modx":"fontawesome/brands/modx.svg","fontawesome-brands-monero":"fontawesome/brands/monero.svg","fontawesome-brands-napster":"fontawesome/brands/napster.svg","fontawesome-brands-neos":"fontawesome/brands/neos.svg","fontawesome-brands-nfc-directional":"fontawesome/brands/nfc-directional.svg","fontawesome-brands-nfc-symbol":"fontawesome/brands/nfc-symbol.svg","fontawesome-brands-nimblr":"fontawesome/brands/nimblr.svg","fontawesome-brands-node-js":"fontawesome/brands/node-js.svg","fontawesome-brands-node":"fontawesome/brands/node.svg","fontawesome-brands-npm":"fontawesome/brands/npm.svg","fontawesome-brands-ns8":"fontawesome/brands/ns8.svg","fontawesome-brands-nutritionix":"fontawesome/brands/nutritionix.svg","fontawesome-brands-octopus-deploy":"fontawesome/brands/octopus-deploy.svg","fontawesome-brands-odnoklassniki":"fontawesome/brands/odnoklassniki.svg","fontawesome-brands-old-republic":"fontawesome/brands/old-republic.svg","fontawesome-brands-opencart":"fontawesome/brands/opencart.svg","fontawesome-brands-openid":"fontawesome/brands/openid.svg","fontawesome-brands-opera":"fontawesome/brands/opera.svg","fontawesome-brands-optin-monster":"fontawesome/brands/optin-monster.svg","fontawesome-brands-orcid":"fontawesome/brands/orcid.svg","fontawesome-brands-osi":"fontawesome/brands/osi.svg","fontawesome-brands-padlet":"fontawesome/brands/padlet.svg","fontawesome-brands-page4":"fontawesome/brands/page4.svg","fontawesome-brands-pagelines":"fontawesome/brands/pagelines.svg","fontawesome-brands-palfed":"fontawesome/brands/palfed.svg","fontawesome-brands-patreon":"fontawesome/brands/patreon.svg","fontawesome-brands-paypal":"fontawesome/brands/paypal.svg","fontawesome-brands-perbyte":"fontawesome/brands/perbyte.svg","fontawesome-brands-periscope":"fontawesome/brands/periscope.svg","fontawesome-brands-phabricator":"fontawesome/brands/phabricator.svg","fontawesome-brands-phoenix-framework":"fontawesome/brands/phoenix-framework.svg","fontawesome-brands-phoenix-squadron":"fontawesome/brands/phoenix-squadron.svg","fontawesome-brands-php":"fontawesome/brands/php.svg","fontawesome-brands-pied-piper-alt":"fontawesome/brands/pied-piper-alt.svg","fontawesome-brands-pied-piper-hat":"fontawesome/brands/pied-piper-hat.svg","fontawesome-brands-pied-piper-pp":"fontawesome/brands/pied-piper-pp.svg","fontawesome-brands-pied-piper":"fontawesome/brands/pied-piper.svg","fontawesome-brands-pinterest-p":"fontawesome/brands/pinterest-p.svg","fontawesome-brands-pinterest":"fontawesome/brands/pinterest.svg","fontawesome-brands-pix":"fontawesome/brands/pix.svg","fontawesome-brands-playstation":"fontawesome/brands/playstation.svg","fontawesome-brands-product-hunt":"fontawesome/brands/product-hunt.svg","fontawesome-brands-pushed":"fontawesome/brands/pushed.svg","fontawesome-brands-python":"fontawesome/brands/python.svg","fontawesome-brands-qq":"fontawesome/brands/qq.svg","fontawesome-brands-quinscape":"fontawesome/brands/quinscape.svg","fontawesome-brands-quora":"fontawesome/brands/quora.svg","fontawesome-brands-r-project":"fontawesome/brands/r-project.svg","fontawesome-brands-raspberry-pi":"fontawesome/brands/raspberry-pi.svg","fontawesome-brands-ravelry":"fontawesome/brands/ravelry.svg","fontawesome-brands-react":"fontawesome/brands/react.svg","fontawesome-brands-reacteurope":"fontawesome/brands/reacteurope.svg","fontawesome-brands-readme":"fontawesome/brands/readme.svg","fontawesome-brands-rebel":"fontawesome/brands/rebel.svg","fontawesome-brands-red-river":"fontawesome/brands/red-river.svg","fontawesome-brands-reddit-alien":"fontawesome/brands/reddit-alien.svg","fontawesome-brands-reddit":"fontawesome/brands/reddit.svg","fontawesome-brands-redhat":"fontawesome/brands/redhat.svg","fontawesome-brands-renren":"fontawesome/brands/renren.svg","fontawesome-brands-replyd":"fontawesome/brands/replyd.svg","fontawesome-brands-researchgate":"fontawesome/brands/researchgate.svg","fontawesome-brands-resolving":"fontawesome/brands/resolving.svg","fontawesome-brands-rev":"fontawesome/brands/rev.svg","fontawesome-brands-rocketchat":"fontawesome/brands/rocketchat.svg","fontawesome-brands-rockrms":"fontawesome/brands/rockrms.svg","fontawesome-brands-rust":"fontawesome/brands/rust.svg","fontawesome-brands-safari":"fontawesome/brands/safari.svg","fontawesome-brands-salesforce":"fontawesome/brands/salesforce.svg","fontawesome-brands-sass":"fontawesome/brands/sass.svg","fontawesome-brands-schlix":"fontawesome/brands/schlix.svg","fontawesome-brands-screenpal":"fontawesome/brands/screenpal.svg","fontawesome-brands-scribd":"fontawesome/brands/scribd.svg","fontawesome-brands-searchengin":"fontawesome/brands/searchengin.svg","fontawesome-brands-sellcast":"fontawesome/brands/sellcast.svg","fontawesome-brands-sellsy":"fontawesome/brands/sellsy.svg","fontawesome-brands-servicestack":"fontawesome/brands/servicestack.svg","fontawesome-brands-shirtsinbulk":"fontawesome/brands/shirtsinbulk.svg","fontawesome-brands-shopify":"fontawesome/brands/shopify.svg","fontawesome-brands-shopware":"fontawesome/brands/shopware.svg","fontawesome-brands-simplybuilt":"fontawesome/brands/simplybuilt.svg","fontawesome-brands-sistrix":"fontawesome/brands/sistrix.svg","fontawesome-brands-sith":"fontawesome/brands/sith.svg","fontawesome-brands-sitrox":"fontawesome/brands/sitrox.svg","fontawesome-brands-sketch":"fontawesome/brands/sketch.svg","fontawesome-brands-skyatlas":"fontawesome/brands/skyatlas.svg","fontawesome-brands-skype":"fontawesome/brands/skype.svg","fontawesome-brands-slack":"fontawesome/brands/slack.svg","fontawesome-brands-slideshare":"fontawesome/brands/slideshare.svg","fontawesome-brands-snapchat":"fontawesome/brands/snapchat.svg","fontawesome-brands-soundcloud":"fontawesome/brands/soundcloud.svg","fontawesome-brands-sourcetree":"fontawesome/brands/sourcetree.svg","fontawesome-brands-space-awesome":"fontawesome/brands/space-awesome.svg","fontawesome-brands-speakap":"fontawesome/brands/speakap.svg","fontawesome-brands-speaker-deck":"fontawesome/brands/speaker-deck.svg","fontawesome-brands-spotify":"fontawesome/brands/spotify.svg","fontawesome-brands-square-behance":"fontawesome/brands/square-behance.svg","fontawesome-brands-square-dribbble":"fontawesome/brands/square-dribbble.svg","fontawesome-brands-square-facebook":"fontawesome/brands/square-facebook.svg","fontawesome-brands-square-font-awesome-stroke":"fontawesome/brands/square-font-awesome-stroke.svg","fontawesome-brands-square-font-awesome":"fontawesome/brands/square-font-awesome.svg","fontawesome-brands-square-git":"fontawesome/brands/square-git.svg","fontawesome-brands-square-github":"fontawesome/brands/square-github.svg","fontawesome-brands-square-gitlab":"fontawesome/brands/square-gitlab.svg","fontawesome-brands-square-google-plus":"fontawesome/brands/square-google-plus.svg","fontawesome-brands-square-hacker-news":"fontawesome/brands/square-hacker-news.svg","fontawesome-brands-square-instagram":"fontawesome/brands/square-instagram.svg","fontawesome-brands-square-js":"fontawesome/brands/square-js.svg","fontawesome-brands-square-lastfm":"fontawesome/brands/square-lastfm.svg","fontawesome-brands-square-odnoklassniki":"fontawesome/brands/square-odnoklassniki.svg","fontawesome-brands-square-pied-piper":"fontawesome/brands/square-pied-piper.svg","fontawesome-brands-square-pinterest":"fontawesome/brands/square-pinterest.svg","fontawesome-brands-square-reddit":"fontawesome/brands/square-reddit.svg","fontawesome-brands-square-snapchat":"fontawesome/brands/square-snapchat.svg","fontawesome-brands-square-steam":"fontawesome/brands/square-steam.svg","fontawesome-brands-square-tumblr":"fontawesome/brands/square-tumblr.svg","fontawesome-brands-square-twitter":"fontawesome/brands/square-twitter.svg","fontawesome-brands-square-viadeo":"fontawesome/brands/square-viadeo.svg","fontawesome-brands-square-vimeo":"fontawesome/brands/square-vimeo.svg","fontawesome-brands-square-whatsapp":"fontawesome/brands/square-whatsapp.svg","fontawesome-brands-square-xing":"fontawesome/brands/square-xing.svg","fontawesome-brands-square-youtube":"fontawesome/brands/square-youtube.svg","fontawesome-brands-squarespace":"fontawesome/brands/squarespace.svg","fontawesome-brands-stack-exchange":"fontawesome/brands/stack-exchange.svg","fontawesome-brands-stack-overflow":"fontawesome/brands/stack-overflow.svg","fontawesome-brands-stackpath":"fontawesome/brands/stackpath.svg","fontawesome-brands-staylinked":"fontawesome/brands/staylinked.svg","fontawesome-brands-steam-symbol":"fontawesome/brands/steam-symbol.svg","fontawesome-brands-steam":"fontawesome/brands/steam.svg","fontawesome-brands-sticker-mule":"fontawesome/brands/sticker-mule.svg","fontawesome-brands-strava":"fontawesome/brands/strava.svg","fontawesome-brands-stripe-s":"fontawesome/brands/stripe-s.svg","fontawesome-brands-stripe":"fontawesome/brands/stripe.svg","fontawesome-brands-studiovinari":"fontawesome/brands/studiovinari.svg","fontawesome-brands-stumbleupon-circle":"fontawesome/brands/stumbleupon-circle.svg","fontawesome-brands-stumbleupon":"fontawesome/brands/stumbleupon.svg","fontawesome-brands-superpowers":"fontawesome/brands/superpowers.svg","fontawesome-brands-supple":"fontawesome/brands/supple.svg","fontawesome-brands-suse":"fontawesome/brands/suse.svg","fontawesome-brands-swift":"fontawesome/brands/swift.svg","fontawesome-brands-symfony":"fontawesome/brands/symfony.svg","fontawesome-brands-teamspeak":"fontawesome/brands/teamspeak.svg","fontawesome-brands-telegram":"fontawesome/brands/telegram.svg","fontawesome-brands-tencent-weibo":"fontawesome/brands/tencent-weibo.svg","fontawesome-brands-the-red-yeti":"fontawesome/brands/the-red-yeti.svg","fontawesome-brands-themeco":"fontawesome/brands/themeco.svg","fontawesome-brands-themeisle":"fontawesome/brands/themeisle.svg","fontawesome-brands-think-peaks":"fontawesome/brands/think-peaks.svg","fontawesome-brands-tiktok":"fontawesome/brands/tiktok.svg","fontawesome-brands-trade-federation":"fontawesome/brands/trade-federation.svg","fontawesome-brands-trello":"fontawesome/brands/trello.svg","fontawesome-brands-tumblr":"fontawesome/brands/tumblr.svg","fontawesome-brands-twitch":"fontawesome/brands/twitch.svg","fontawesome-brands-twitter":"fontawesome/brands/twitter.svg","fontawesome-brands-typo3":"fontawesome/brands/typo3.svg","fontawesome-brands-uber":"fontawesome/brands/uber.svg","fontawesome-brands-ubuntu":"fontawesome/brands/ubuntu.svg","fontawesome-brands-uikit":"fontawesome/brands/uikit.svg","fontawesome-brands-umbraco":"fontawesome/brands/umbraco.svg","fontawesome-brands-uncharted":"fontawesome/brands/uncharted.svg","fontawesome-brands-uniregistry":"fontawesome/brands/uniregistry.svg","fontawesome-brands-unity":"fontawesome/brands/unity.svg","fontawesome-brands-unsplash":"fontawesome/brands/unsplash.svg","fontawesome-brands-untappd":"fontawesome/brands/untappd.svg","fontawesome-brands-ups":"fontawesome/brands/ups.svg","fontawesome-brands-usb":"fontawesome/brands/usb.svg","fontawesome-brands-usps":"fontawesome/brands/usps.svg","fontawesome-brands-ussunnah":"fontawesome/brands/ussunnah.svg","fontawesome-brands-vaadin":"fontawesome/brands/vaadin.svg","fontawesome-brands-viacoin":"fontawesome/brands/viacoin.svg","fontawesome-brands-viadeo":"fontawesome/brands/viadeo.svg","fontawesome-brands-viber":"fontawesome/brands/viber.svg","fontawesome-brands-vimeo-v":"fontawesome/brands/vimeo-v.svg","fontawesome-brands-vimeo":"fontawesome/brands/vimeo.svg","fontawesome-brands-vine":"fontawesome/brands/vine.svg","fontawesome-brands-vk":"fontawesome/brands/vk.svg","fontawesome-brands-vnv":"fontawesome/brands/vnv.svg","fontawesome-brands-vuejs":"fontawesome/brands/vuejs.svg","fontawesome-brands-watchman-monitoring":"fontawesome/brands/watchman-monitoring.svg","fontawesome-brands-waze":"fontawesome/brands/waze.svg","fontawesome-brands-weebly":"fontawesome/brands/weebly.svg","fontawesome-brands-weibo":"fontawesome/brands/weibo.svg","fontawesome-brands-weixin":"fontawesome/brands/weixin.svg","fontawesome-brands-whatsapp":"fontawesome/brands/whatsapp.svg","fontawesome-brands-whmcs":"fontawesome/brands/whmcs.svg","fontawesome-brands-wikipedia-w":"fontawesome/brands/wikipedia-w.svg","fontawesome-brands-windows":"fontawesome/brands/windows.svg","fontawesome-brands-wirsindhandwerk":"fontawesome/brands/wirsindhandwerk.svg","fontawesome-brands-wix":"fontawesome/brands/wix.svg","fontawesome-brands-wizards-of-the-coast":"fontawesome/brands/wizards-of-the-coast.svg","fontawesome-brands-wodu":"fontawesome/brands/wodu.svg","fontawesome-brands-wolf-pack-battalion":"fontawesome/brands/wolf-pack-battalion.svg","fontawesome-brands-wordpress-simple":"fontawesome/brands/wordpress-simple.svg","fontawesome-brands-wordpress":"fontawesome/brands/wordpress.svg","fontawesome-brands-wpbeginner":"fontawesome/brands/wpbeginner.svg","fontawesome-brands-wpexplorer":"fontawesome/brands/wpexplorer.svg","fontawesome-brands-wpforms":"fontawesome/brands/wpforms.svg","fontawesome-brands-wpressr":"fontawesome/brands/wpressr.svg","fontawesome-brands-xbox":"fontawesome/brands/xbox.svg","fontawesome-brands-xing":"fontawesome/brands/xing.svg","fontawesome-brands-y-combinator":"fontawesome/brands/y-combinator.svg","fontawesome-brands-yahoo":"fontawesome/brands/yahoo.svg","fontawesome-brands-yammer":"fontawesome/brands/yammer.svg","fontawesome-brands-yandex-international":"fontawesome/brands/yandex-international.svg","fontawesome-brands-yandex":"fontawesome/brands/yandex.svg","fontawesome-brands-yarn":"fontawesome/brands/yarn.svg","fontawesome-brands-yelp":"fontawesome/brands/yelp.svg","fontawesome-brands-yoast":"fontawesome/brands/yoast.svg","fontawesome-brands-youtube":"fontawesome/brands/youtube.svg","fontawesome-brands-zhihu":"fontawesome/brands/zhihu.svg","fontawesome-regular-address-book":"fontawesome/regular/address-book.svg","fontawesome-regular-address-card":"fontawesome/regular/address-card.svg","fontawesome-regular-bell-slash":"fontawesome/regular/bell-slash.svg","fontawesome-regular-bell":"fontawesome/regular/bell.svg","fontawesome-regular-bookmark":"fontawesome/regular/bookmark.svg","fontawesome-regular-building":"fontawesome/regular/building.svg","fontawesome-regular-calendar-check":"fontawesome/regular/calendar-check.svg","fontawesome-regular-calendar-days":"fontawesome/regular/calendar-days.svg","fontawesome-regular-calendar-minus":"fontawesome/regular/calendar-minus.svg","fontawesome-regular-calendar-plus":"fontawesome/regular/calendar-plus.svg","fontawesome-regular-calendar-xmark":"fontawesome/regular/calendar-xmark.svg","fontawesome-regular-calendar":"fontawesome/regular/calendar.svg","fontawesome-regular-chart-bar":"fontawesome/regular/chart-bar.svg","fontawesome-regular-chess-bishop":"fontawesome/regular/chess-bishop.svg","fontawesome-regular-chess-king":"fontawesome/regular/chess-king.svg","fontawesome-regular-chess-knight":"fontawesome/regular/chess-knight.svg","fontawesome-regular-chess-pawn":"fontawesome/regular/chess-pawn.svg","fontawesome-regular-chess-queen":"fontawesome/regular/chess-queen.svg","fontawesome-regular-chess-rook":"fontawesome/regular/chess-rook.svg","fontawesome-regular-circle-check":"fontawesome/regular/circle-check.svg","fontawesome-regular-circle-dot":"fontawesome/regular/circle-dot.svg","fontawesome-regular-circle-down":"fontawesome/regular/circle-down.svg","fontawesome-regular-circle-left":"fontawesome/regular/circle-left.svg","fontawesome-regular-circle-pause":"fontawesome/regular/circle-pause.svg","fontawesome-regular-circle-play":"fontawesome/regular/circle-play.svg","fontawesome-regular-circle-question":"fontawesome/regular/circle-question.svg","fontawesome-regular-circle-right":"fontawesome/regular/circle-right.svg","fontawesome-regular-circle-stop":"fontawesome/regular/circle-stop.svg","fontawesome-regular-circle-up":"fontawesome/regular/circle-up.svg","fontawesome-regular-circle-user":"fontawesome/regular/circle-user.svg","fontawesome-regular-circle-xmark":"fontawesome/regular/circle-xmark.svg","fontawesome-regular-circle":"fontawesome/regular/circle.svg","fontawesome-regular-clipboard":"fontawesome/regular/clipboard.svg","fontawesome-regular-clock":"fontawesome/regular/clock.svg","fontawesome-regular-clone":"fontawesome/regular/clone.svg","fontawesome-regular-closed-captioning":"fontawesome/regular/closed-captioning.svg","fontawesome-regular-comment-dots":"fontawesome/regular/comment-dots.svg","fontawesome-regular-comment":"fontawesome/regular/comment.svg","fontawesome-regular-comments":"fontawesome/regular/comments.svg","fontawesome-regular-compass":"fontawesome/regular/compass.svg","fontawesome-regular-copy":"fontawesome/regular/copy.svg","fontawesome-regular-copyright":"fontawesome/regular/copyright.svg","fontawesome-regular-credit-card":"fontawesome/regular/credit-card.svg","fontawesome-regular-envelope-open":"fontawesome/regular/envelope-open.svg","fontawesome-regular-envelope":"fontawesome/regular/envelope.svg","fontawesome-regular-eye-slash":"fontawesome/regular/eye-slash.svg","fontawesome-regular-eye":"fontawesome/regular/eye.svg","fontawesome-regular-face-angry":"fontawesome/regular/face-angry.svg","fontawesome-regular-face-dizzy":"fontawesome/regular/face-dizzy.svg","fontawesome-regular-face-flushed":"fontawesome/regular/face-flushed.svg","fontawesome-regular-face-frown-open":"fontawesome/regular/face-frown-open.svg","fontawesome-regular-face-frown":"fontawesome/regular/face-frown.svg","fontawesome-regular-face-grimace":"fontawesome/regular/face-grimace.svg","fontawesome-regular-face-grin-beam-sweat":"fontawesome/regular/face-grin-beam-sweat.svg","fontawesome-regular-face-grin-beam":"fontawesome/regular/face-grin-beam.svg","fontawesome-regular-face-grin-hearts":"fontawesome/regular/face-grin-hearts.svg","fontawesome-regular-face-grin-squint-tears":"fontawesome/regular/face-grin-squint-tears.svg","fontawesome-regular-face-grin-squint":"fontawesome/regular/face-grin-squint.svg","fontawesome-regular-face-grin-stars":"fontawesome/regular/face-grin-stars.svg","fontawesome-regular-face-grin-tears":"fontawesome/regular/face-grin-tears.svg","fontawesome-regular-face-grin-tongue-squint":"fontawesome/regular/face-grin-tongue-squint.svg","fontawesome-regular-face-grin-tongue-wink":"fontawesome/regular/face-grin-tongue-wink.svg","fontawesome-regular-face-grin-tongue":"fontawesome/regular/face-grin-tongue.svg","fontawesome-regular-face-grin-wide":"fontawesome/regular/face-grin-wide.svg","fontawesome-regular-face-grin-wink":"fontawesome/regular/face-grin-wink.svg","fontawesome-regular-face-grin":"fontawesome/regular/face-grin.svg","fontawesome-regular-face-kiss-beam":"fontawesome/regular/face-kiss-beam.svg","fontawesome-regular-face-kiss-wink-heart":"fontawesome/regular/face-kiss-wink-heart.svg","fontawesome-regular-face-kiss":"fontawesome/regular/face-kiss.svg","fontawesome-regular-face-laugh-beam":"fontawesome/regular/face-laugh-beam.svg","fontawesome-regular-face-laugh-squint":"fontawesome/regular/face-laugh-squint.svg","fontawesome-regular-face-laugh-wink":"fontawesome/regular/face-laugh-wink.svg","fontawesome-regular-face-laugh":"fontawesome/regular/face-laugh.svg","fontawesome-regular-face-meh-blank":"fontawesome/regular/face-meh-blank.svg","fontawesome-regular-face-meh":"fontawesome/regular/face-meh.svg","fontawesome-regular-face-rolling-eyes":"fontawesome/regular/face-rolling-eyes.svg","fontawesome-regular-face-sad-cry":"fontawesome/regular/face-sad-cry.svg","fontawesome-regular-face-sad-tear":"fontawesome/regular/face-sad-tear.svg","fontawesome-regular-face-smile-beam":"fontawesome/regular/face-smile-beam.svg","fontawesome-regular-face-smile-wink":"fontawesome/regular/face-smile-wink.svg","fontawesome-regular-face-smile":"fontawesome/regular/face-smile.svg","fontawesome-regular-face-surprise":"fontawesome/regular/face-surprise.svg","fontawesome-regular-face-tired":"fontawesome/regular/face-tired.svg","fontawesome-regular-file-audio":"fontawesome/regular/file-audio.svg","fontawesome-regular-file-code":"fontawesome/regular/file-code.svg","fontawesome-regular-file-excel":"fontawesome/regular/file-excel.svg","fontawesome-regular-file-image":"fontawesome/regular/file-image.svg","fontawesome-regular-file-lines":"fontawesome/regular/file-lines.svg","fontawesome-regular-file-pdf":"fontawesome/regular/file-pdf.svg","fontawesome-regular-file-powerpoint":"fontawesome/regular/file-powerpoint.svg","fontawesome-regular-file-video":"fontawesome/regular/file-video.svg","fontawesome-regular-file-word":"fontawesome/regular/file-word.svg","fontawesome-regular-file-zipper":"fontawesome/regular/file-zipper.svg","fontawesome-regular-file":"fontawesome/regular/file.svg","fontawesome-regular-flag":"fontawesome/regular/flag.svg","fontawesome-regular-floppy-disk":"fontawesome/regular/floppy-disk.svg","fontawesome-regular-folder-closed":"fontawesome/regular/folder-closed.svg","fontawesome-regular-folder-open":"fontawesome/regular/folder-open.svg","fontawesome-regular-folder":"fontawesome/regular/folder.svg","fontawesome-regular-font-awesome":"fontawesome/regular/font-awesome.svg","fontawesome-regular-futbol":"fontawesome/regular/futbol.svg","fontawesome-regular-gem":"fontawesome/regular/gem.svg","fontawesome-regular-hand-back-fist":"fontawesome/regular/hand-back-fist.svg","fontawesome-regular-hand-lizard":"fontawesome/regular/hand-lizard.svg","fontawesome-regular-hand-peace":"fontawesome/regular/hand-peace.svg","fontawesome-regular-hand-point-down":"fontawesome/regular/hand-point-down.svg","fontawesome-regular-hand-point-left":"fontawesome/regular/hand-point-left.svg","fontawesome-regular-hand-point-right":"fontawesome/regular/hand-point-right.svg","fontawesome-regular-hand-point-up":"fontawesome/regular/hand-point-up.svg","fontawesome-regular-hand-pointer":"fontawesome/regular/hand-pointer.svg","fontawesome-regular-hand-scissors":"fontawesome/regular/hand-scissors.svg","fontawesome-regular-hand-spock":"fontawesome/regular/hand-spock.svg","fontawesome-regular-hand":"fontawesome/regular/hand.svg","fontawesome-regular-handshake":"fontawesome/regular/handshake.svg","fontawesome-regular-hard-drive":"fontawesome/regular/hard-drive.svg","fontawesome-regular-heart":"fontawesome/regular/heart.svg","fontawesome-regular-hospital":"fontawesome/regular/hospital.svg","fontawesome-regular-hourglass-half":"fontawesome/regular/hourglass-half.svg","fontawesome-regular-hourglass":"fontawesome/regular/hourglass.svg","fontawesome-regular-id-badge":"fontawesome/regular/id-badge.svg","fontawesome-regular-id-card":"fontawesome/regular/id-card.svg","fontawesome-regular-image":"fontawesome/regular/image.svg","fontawesome-regular-images":"fontawesome/regular/images.svg","fontawesome-regular-keyboard":"fontawesome/regular/keyboard.svg","fontawesome-regular-lemon":"fontawesome/regular/lemon.svg","fontawesome-regular-life-ring":"fontawesome/regular/life-ring.svg","fontawesome-regular-lightbulb":"fontawesome/regular/lightbulb.svg","fontawesome-regular-map":"fontawesome/regular/map.svg","fontawesome-regular-message":"fontawesome/regular/message.svg","fontawesome-regular-money-bill-1":"fontawesome/regular/money-bill-1.svg","fontawesome-regular-moon":"fontawesome/regular/moon.svg","fontawesome-regular-newspaper":"fontawesome/regular/newspaper.svg","fontawesome-regular-notdef":"fontawesome/regular/notdef.svg","fontawesome-regular-note-sticky":"fontawesome/regular/note-sticky.svg","fontawesome-regular-object-group":"fontawesome/regular/object-group.svg","fontawesome-regular-object-ungroup":"fontawesome/regular/object-ungroup.svg","fontawesome-regular-paper-plane":"fontawesome/regular/paper-plane.svg","fontawesome-regular-paste":"fontawesome/regular/paste.svg","fontawesome-regular-pen-to-square":"fontawesome/regular/pen-to-square.svg","fontawesome-regular-rectangle-list":"fontawesome/regular/rectangle-list.svg","fontawesome-regular-rectangle-xmark":"fontawesome/regular/rectangle-xmark.svg","fontawesome-regular-registered":"fontawesome/regular/registered.svg","fontawesome-regular-share-from-square":"fontawesome/regular/share-from-square.svg","fontawesome-regular-snowflake":"fontawesome/regular/snowflake.svg","fontawesome-regular-square-caret-down":"fontawesome/regular/square-caret-down.svg","fontawesome-regular-square-caret-left":"fontawesome/regular/square-caret-left.svg","fontawesome-regular-square-caret-right":"fontawesome/regular/square-caret-right.svg","fontawesome-regular-square-caret-up":"fontawesome/regular/square-caret-up.svg","fontawesome-regular-square-check":"fontawesome/regular/square-check.svg","fontawesome-regular-square-full":"fontawesome/regular/square-full.svg","fontawesome-regular-square-minus":"fontawesome/regular/square-minus.svg","fontawesome-regular-square-plus":"fontawesome/regular/square-plus.svg","fontawesome-regular-square":"fontawesome/regular/square.svg","fontawesome-regular-star-half-stroke":"fontawesome/regular/star-half-stroke.svg","fontawesome-regular-star-half":"fontawesome/regular/star-half.svg","fontawesome-regular-star":"fontawesome/regular/star.svg","fontawesome-regular-sun":"fontawesome/regular/sun.svg","fontawesome-regular-thumbs-down":"fontawesome/regular/thumbs-down.svg","fontawesome-regular-thumbs-up":"fontawesome/regular/thumbs-up.svg","fontawesome-regular-trash-can":"fontawesome/regular/trash-can.svg","fontawesome-regular-user":"fontawesome/regular/user.svg","fontawesome-regular-window-maximize":"fontawesome/regular/window-maximize.svg","fontawesome-regular-window-minimize":"fontawesome/regular/window-minimize.svg","fontawesome-regular-window-restore":"fontawesome/regular/window-restore.svg","fontawesome-solid-0":"fontawesome/solid/0.svg","fontawesome-solid-1":"fontawesome/solid/1.svg","fontawesome-solid-2":"fontawesome/solid/2.svg","fontawesome-solid-3":"fontawesome/solid/3.svg","fontawesome-solid-4":"fontawesome/solid/4.svg","fontawesome-solid-5":"fontawesome/solid/5.svg","fontawesome-solid-6":"fontawesome/solid/6.svg","fontawesome-solid-7":"fontawesome/solid/7.svg","fontawesome-solid-8":"fontawesome/solid/8.svg","fontawesome-solid-9":"fontawesome/solid/9.svg","fontawesome-solid-a":"fontawesome/solid/a.svg","fontawesome-solid-address-book":"fontawesome/solid/address-book.svg","fontawesome-solid-address-card":"fontawesome/solid/address-card.svg","fontawesome-solid-align-center":"fontawesome/solid/align-center.svg","fontawesome-solid-align-justify":"fontawesome/solid/align-justify.svg","fontawesome-solid-align-left":"fontawesome/solid/align-left.svg","fontawesome-solid-align-right":"fontawesome/solid/align-right.svg","fontawesome-solid-anchor-circle-check":"fontawesome/solid/anchor-circle-check.svg","fontawesome-solid-anchor-circle-exclamation":"fontawesome/solid/anchor-circle-exclamation.svg","fontawesome-solid-anchor-circle-xmark":"fontawesome/solid/anchor-circle-xmark.svg","fontawesome-solid-anchor-lock":"fontawesome/solid/anchor-lock.svg","fontawesome-solid-anchor":"fontawesome/solid/anchor.svg","fontawesome-solid-angle-down":"fontawesome/solid/angle-down.svg","fontawesome-solid-angle-left":"fontawesome/solid/angle-left.svg","fontawesome-solid-angle-right":"fontawesome/solid/angle-right.svg","fontawesome-solid-angle-up":"fontawesome/solid/angle-up.svg","fontawesome-solid-angles-down":"fontawesome/solid/angles-down.svg","fontawesome-solid-angles-left":"fontawesome/solid/angles-left.svg","fontawesome-solid-angles-right":"fontawesome/solid/angles-right.svg","fontawesome-solid-angles-up":"fontawesome/solid/angles-up.svg","fontawesome-solid-ankh":"fontawesome/solid/ankh.svg","fontawesome-solid-apple-whole":"fontawesome/solid/apple-whole.svg","fontawesome-solid-archway":"fontawesome/solid/archway.svg","fontawesome-solid-arrow-down-1-9":"fontawesome/solid/arrow-down-1-9.svg","fontawesome-solid-arrow-down-9-1":"fontawesome/solid/arrow-down-9-1.svg","fontawesome-solid-arrow-down-a-z":"fontawesome/solid/arrow-down-a-z.svg","fontawesome-solid-arrow-down-long":"fontawesome/solid/arrow-down-long.svg","fontawesome-solid-arrow-down-short-wide":"fontawesome/solid/arrow-down-short-wide.svg","fontawesome-solid-arrow-down-up-across-line":"fontawesome/solid/arrow-down-up-across-line.svg","fontawesome-solid-arrow-down-up-lock":"fontawesome/solid/arrow-down-up-lock.svg","fontawesome-solid-arrow-down-wide-short":"fontawesome/solid/arrow-down-wide-short.svg","fontawesome-solid-arrow-down-z-a":"fontawesome/solid/arrow-down-z-a.svg","fontawesome-solid-arrow-down":"fontawesome/solid/arrow-down.svg","fontawesome-solid-arrow-left-long":"fontawesome/solid/arrow-left-long.svg","fontawesome-solid-arrow-left":"fontawesome/solid/arrow-left.svg","fontawesome-solid-arrow-pointer":"fontawesome/solid/arrow-pointer.svg","fontawesome-solid-arrow-right-arrow-left":"fontawesome/solid/arrow-right-arrow-left.svg","fontawesome-solid-arrow-right-from-bracket":"fontawesome/solid/arrow-right-from-bracket.svg","fontawesome-solid-arrow-right-long":"fontawesome/solid/arrow-right-long.svg","fontawesome-solid-arrow-right-to-bracket":"fontawesome/solid/arrow-right-to-bracket.svg","fontawesome-solid-arrow-right-to-city":"fontawesome/solid/arrow-right-to-city.svg","fontawesome-solid-arrow-right":"fontawesome/solid/arrow-right.svg","fontawesome-solid-arrow-rotate-left":"fontawesome/solid/arrow-rotate-left.svg","fontawesome-solid-arrow-rotate-right":"fontawesome/solid/arrow-rotate-right.svg","fontawesome-solid-arrow-trend-down":"fontawesome/solid/arrow-trend-down.svg","fontawesome-solid-arrow-trend-up":"fontawesome/solid/arrow-trend-up.svg","fontawesome-solid-arrow-turn-down":"fontawesome/solid/arrow-turn-down.svg","fontawesome-solid-arrow-turn-up":"fontawesome/solid/arrow-turn-up.svg","fontawesome-solid-arrow-up-1-9":"fontawesome/solid/arrow-up-1-9.svg","fontawesome-solid-arrow-up-9-1":"fontawesome/solid/arrow-up-9-1.svg","fontawesome-solid-arrow-up-a-z":"fontawesome/solid/arrow-up-a-z.svg","fontawesome-solid-arrow-up-from-bracket":"fontawesome/solid/arrow-up-from-bracket.svg","fontawesome-solid-arrow-up-from-ground-water":"fontawesome/solid/arrow-up-from-ground-water.svg","fontawesome-solid-arrow-up-from-water-pump":"fontawesome/solid/arrow-up-from-water-pump.svg","fontawesome-solid-arrow-up-long":"fontawesome/solid/arrow-up-long.svg","fontawesome-solid-arrow-up-right-dots":"fontawesome/solid/arrow-up-right-dots.svg","fontawesome-solid-arrow-up-right-from-square":"fontawesome/solid/arrow-up-right-from-square.svg","fontawesome-solid-arrow-up-short-wide":"fontawesome/solid/arrow-up-short-wide.svg","fontawesome-solid-arrow-up-wide-short":"fontawesome/solid/arrow-up-wide-short.svg","fontawesome-solid-arrow-up-z-a":"fontawesome/solid/arrow-up-z-a.svg","fontawesome-solid-arrow-up":"fontawesome/solid/arrow-up.svg","fontawesome-solid-arrows-down-to-line":"fontawesome/solid/arrows-down-to-line.svg","fontawesome-solid-arrows-down-to-people":"fontawesome/solid/arrows-down-to-people.svg","fontawesome-solid-arrows-left-right-to-line":"fontawesome/solid/arrows-left-right-to-line.svg","fontawesome-solid-arrows-left-right":"fontawesome/solid/arrows-left-right.svg","fontawesome-solid-arrows-rotate":"fontawesome/solid/arrows-rotate.svg","fontawesome-solid-arrows-spin":"fontawesome/solid/arrows-spin.svg","fontawesome-solid-arrows-split-up-and-left":"fontawesome/solid/arrows-split-up-and-left.svg","fontawesome-solid-arrows-to-circle":"fontawesome/solid/arrows-to-circle.svg","fontawesome-solid-arrows-to-dot":"fontawesome/solid/arrows-to-dot.svg","fontawesome-solid-arrows-to-eye":"fontawesome/solid/arrows-to-eye.svg","fontawesome-solid-arrows-turn-right":"fontawesome/solid/arrows-turn-right.svg","fontawesome-solid-arrows-turn-to-dots":"fontawesome/solid/arrows-turn-to-dots.svg","fontawesome-solid-arrows-up-down-left-right":"fontawesome/solid/arrows-up-down-left-right.svg","fontawesome-solid-arrows-up-down":"fontawesome/solid/arrows-up-down.svg","fontawesome-solid-arrows-up-to-line":"fontawesome/solid/arrows-up-to-line.svg","fontawesome-solid-asterisk":"fontawesome/solid/asterisk.svg","fontawesome-solid-at":"fontawesome/solid/at.svg","fontawesome-solid-atom":"fontawesome/solid/atom.svg","fontawesome-solid-audio-description":"fontawesome/solid/audio-description.svg","fontawesome-solid-austral-sign":"fontawesome/solid/austral-sign.svg","fontawesome-solid-award":"fontawesome/solid/award.svg","fontawesome-solid-b":"fontawesome/solid/b.svg","fontawesome-solid-baby-carriage":"fontawesome/solid/baby-carriage.svg","fontawesome-solid-baby":"fontawesome/solid/baby.svg","fontawesome-solid-backward-fast":"fontawesome/solid/backward-fast.svg","fontawesome-solid-backward-step":"fontawesome/solid/backward-step.svg","fontawesome-solid-backward":"fontawesome/solid/backward.svg","fontawesome-solid-bacon":"fontawesome/solid/bacon.svg","fontawesome-solid-bacteria":"fontawesome/solid/bacteria.svg","fontawesome-solid-bacterium":"fontawesome/solid/bacterium.svg","fontawesome-solid-bag-shopping":"fontawesome/solid/bag-shopping.svg","fontawesome-solid-bahai":"fontawesome/solid/bahai.svg","fontawesome-solid-baht-sign":"fontawesome/solid/baht-sign.svg","fontawesome-solid-ban-smoking":"fontawesome/solid/ban-smoking.svg","fontawesome-solid-ban":"fontawesome/solid/ban.svg","fontawesome-solid-bandage":"fontawesome/solid/bandage.svg","fontawesome-solid-barcode":"fontawesome/solid/barcode.svg","fontawesome-solid-bars-progress":"fontawesome/solid/bars-progress.svg","fontawesome-solid-bars-staggered":"fontawesome/solid/bars-staggered.svg","fontawesome-solid-bars":"fontawesome/solid/bars.svg","fontawesome-solid-baseball-bat-ball":"fontawesome/solid/baseball-bat-ball.svg","fontawesome-solid-baseball":"fontawesome/solid/baseball.svg","fontawesome-solid-basket-shopping":"fontawesome/solid/basket-shopping.svg","fontawesome-solid-basketball":"fontawesome/solid/basketball.svg","fontawesome-solid-bath":"fontawesome/solid/bath.svg","fontawesome-solid-battery-empty":"fontawesome/solid/battery-empty.svg","fontawesome-solid-battery-full":"fontawesome/solid/battery-full.svg","fontawesome-solid-battery-half":"fontawesome/solid/battery-half.svg","fontawesome-solid-battery-quarter":"fontawesome/solid/battery-quarter.svg","fontawesome-solid-battery-three-quarters":"fontawesome/solid/battery-three-quarters.svg","fontawesome-solid-bed-pulse":"fontawesome/solid/bed-pulse.svg","fontawesome-solid-bed":"fontawesome/solid/bed.svg","fontawesome-solid-beer-mug-empty":"fontawesome/solid/beer-mug-empty.svg","fontawesome-solid-bell-concierge":"fontawesome/solid/bell-concierge.svg","fontawesome-solid-bell-slash":"fontawesome/solid/bell-slash.svg","fontawesome-solid-bell":"fontawesome/solid/bell.svg","fontawesome-solid-bezier-curve":"fontawesome/solid/bezier-curve.svg","fontawesome-solid-bicycle":"fontawesome/solid/bicycle.svg","fontawesome-solid-binoculars":"fontawesome/solid/binoculars.svg","fontawesome-solid-biohazard":"fontawesome/solid/biohazard.svg","fontawesome-solid-bitcoin-sign":"fontawesome/solid/bitcoin-sign.svg","fontawesome-solid-blender-phone":"fontawesome/solid/blender-phone.svg","fontawesome-solid-blender":"fontawesome/solid/blender.svg","fontawesome-solid-blog":"fontawesome/solid/blog.svg","fontawesome-solid-bold":"fontawesome/solid/bold.svg","fontawesome-solid-bolt-lightning":"fontawesome/solid/bolt-lightning.svg","fontawesome-solid-bolt":"fontawesome/solid/bolt.svg","fontawesome-solid-bomb":"fontawesome/solid/bomb.svg","fontawesome-solid-bone":"fontawesome/solid/bone.svg","fontawesome-solid-bong":"fontawesome/solid/bong.svg","fontawesome-solid-book-atlas":"fontawesome/solid/book-atlas.svg","fontawesome-solid-book-bible":"fontawesome/solid/book-bible.svg","fontawesome-solid-book-bookmark":"fontawesome/solid/book-bookmark.svg","fontawesome-solid-book-journal-whills":"fontawesome/solid/book-journal-whills.svg","fontawesome-solid-book-medical":"fontawesome/solid/book-medical.svg","fontawesome-solid-book-open-reader":"fontawesome/solid/book-open-reader.svg","fontawesome-solid-book-open":"fontawesome/solid/book-open.svg","fontawesome-solid-book-quran":"fontawesome/solid/book-quran.svg","fontawesome-solid-book-skull":"fontawesome/solid/book-skull.svg","fontawesome-solid-book-tanakh":"fontawesome/solid/book-tanakh.svg","fontawesome-solid-book":"fontawesome/solid/book.svg","fontawesome-solid-bookmark":"fontawesome/solid/bookmark.svg","fontawesome-solid-border-all":"fontawesome/solid/border-all.svg","fontawesome-solid-border-none":"fontawesome/solid/border-none.svg","fontawesome-solid-border-top-left":"fontawesome/solid/border-top-left.svg","fontawesome-solid-bore-hole":"fontawesome/solid/bore-hole.svg","fontawesome-solid-bottle-droplet":"fontawesome/solid/bottle-droplet.svg","fontawesome-solid-bottle-water":"fontawesome/solid/bottle-water.svg","fontawesome-solid-bowl-food":"fontawesome/solid/bowl-food.svg","fontawesome-solid-bowl-rice":"fontawesome/solid/bowl-rice.svg","fontawesome-solid-bowling-ball":"fontawesome/solid/bowling-ball.svg","fontawesome-solid-box-archive":"fontawesome/solid/box-archive.svg","fontawesome-solid-box-open":"fontawesome/solid/box-open.svg","fontawesome-solid-box-tissue":"fontawesome/solid/box-tissue.svg","fontawesome-solid-box":"fontawesome/solid/box.svg","fontawesome-solid-boxes-packing":"fontawesome/solid/boxes-packing.svg","fontawesome-solid-boxes-stacked":"fontawesome/solid/boxes-stacked.svg","fontawesome-solid-braille":"fontawesome/solid/braille.svg","fontawesome-solid-brain":"fontawesome/solid/brain.svg","fontawesome-solid-brazilian-real-sign":"fontawesome/solid/brazilian-real-sign.svg","fontawesome-solid-bread-slice":"fontawesome/solid/bread-slice.svg","fontawesome-solid-bridge-circle-check":"fontawesome/solid/bridge-circle-check.svg","fontawesome-solid-bridge-circle-exclamation":"fontawesome/solid/bridge-circle-exclamation.svg","fontawesome-solid-bridge-circle-xmark":"fontawesome/solid/bridge-circle-xmark.svg","fontawesome-solid-bridge-lock":"fontawesome/solid/bridge-lock.svg","fontawesome-solid-bridge-water":"fontawesome/solid/bridge-water.svg","fontawesome-solid-bridge":"fontawesome/solid/bridge.svg","fontawesome-solid-briefcase-medical":"fontawesome/solid/briefcase-medical.svg","fontawesome-solid-briefcase":"fontawesome/solid/briefcase.svg","fontawesome-solid-broom-ball":"fontawesome/solid/broom-ball.svg","fontawesome-solid-broom":"fontawesome/solid/broom.svg","fontawesome-solid-brush":"fontawesome/solid/brush.svg","fontawesome-solid-bucket":"fontawesome/solid/bucket.svg","fontawesome-solid-bug-slash":"fontawesome/solid/bug-slash.svg","fontawesome-solid-bug":"fontawesome/solid/bug.svg","fontawesome-solid-bugs":"fontawesome/solid/bugs.svg","fontawesome-solid-building-circle-arrow-right":"fontawesome/solid/building-circle-arrow-right.svg","fontawesome-solid-building-circle-check":"fontawesome/solid/building-circle-check.svg","fontawesome-solid-building-circle-exclamation":"fontawesome/solid/building-circle-exclamation.svg","fontawesome-solid-building-circle-xmark":"fontawesome/solid/building-circle-xmark.svg","fontawesome-solid-building-columns":"fontawesome/solid/building-columns.svg","fontawesome-solid-building-flag":"fontawesome/solid/building-flag.svg","fontawesome-solid-building-lock":"fontawesome/solid/building-lock.svg","fontawesome-solid-building-ngo":"fontawesome/solid/building-ngo.svg","fontawesome-solid-building-shield":"fontawesome/solid/building-shield.svg","fontawesome-solid-building-un":"fontawesome/solid/building-un.svg","fontawesome-solid-building-user":"fontawesome/solid/building-user.svg","fontawesome-solid-building-wheat":"fontawesome/solid/building-wheat.svg","fontawesome-solid-building":"fontawesome/solid/building.svg","fontawesome-solid-bullhorn":"fontawesome/solid/bullhorn.svg","fontawesome-solid-bullseye":"fontawesome/solid/bullseye.svg","fontawesome-solid-burger":"fontawesome/solid/burger.svg","fontawesome-solid-burst":"fontawesome/solid/burst.svg","fontawesome-solid-bus-simple":"fontawesome/solid/bus-simple.svg","fontawesome-solid-bus":"fontawesome/solid/bus.svg","fontawesome-solid-business-time":"fontawesome/solid/business-time.svg","fontawesome-solid-c":"fontawesome/solid/c.svg","fontawesome-solid-cable-car":"fontawesome/solid/cable-car.svg","fontawesome-solid-cake-candles":"fontawesome/solid/cake-candles.svg","fontawesome-solid-calculator":"fontawesome/solid/calculator.svg","fontawesome-solid-calendar-check":"fontawesome/solid/calendar-check.svg","fontawesome-solid-calendar-day":"fontawesome/solid/calendar-day.svg","fontawesome-solid-calendar-days":"fontawesome/solid/calendar-days.svg","fontawesome-solid-calendar-minus":"fontawesome/solid/calendar-minus.svg","fontawesome-solid-calendar-plus":"fontawesome/solid/calendar-plus.svg","fontawesome-solid-calendar-week":"fontawesome/solid/calendar-week.svg","fontawesome-solid-calendar-xmark":"fontawesome/solid/calendar-xmark.svg","fontawesome-solid-calendar":"fontawesome/solid/calendar.svg","fontawesome-solid-camera-retro":"fontawesome/solid/camera-retro.svg","fontawesome-solid-camera-rotate":"fontawesome/solid/camera-rotate.svg","fontawesome-solid-camera":"fontawesome/solid/camera.svg","fontawesome-solid-campground":"fontawesome/solid/campground.svg","fontawesome-solid-candy-cane":"fontawesome/solid/candy-cane.svg","fontawesome-solid-cannabis":"fontawesome/solid/cannabis.svg","fontawesome-solid-capsules":"fontawesome/solid/capsules.svg","fontawesome-solid-car-battery":"fontawesome/solid/car-battery.svg","fontawesome-solid-car-burst":"fontawesome/solid/car-burst.svg","fontawesome-solid-car-on":"fontawesome/solid/car-on.svg","fontawesome-solid-car-rear":"fontawesome/solid/car-rear.svg","fontawesome-solid-car-side":"fontawesome/solid/car-side.svg","fontawesome-solid-car-tunnel":"fontawesome/solid/car-tunnel.svg","fontawesome-solid-car":"fontawesome/solid/car.svg","fontawesome-solid-caravan":"fontawesome/solid/caravan.svg","fontawesome-solid-caret-down":"fontawesome/solid/caret-down.svg","fontawesome-solid-caret-left":"fontawesome/solid/caret-left.svg","fontawesome-solid-caret-right":"fontawesome/solid/caret-right.svg","fontawesome-solid-caret-up":"fontawesome/solid/caret-up.svg","fontawesome-solid-carrot":"fontawesome/solid/carrot.svg","fontawesome-solid-cart-arrow-down":"fontawesome/solid/cart-arrow-down.svg","fontawesome-solid-cart-flatbed-suitcase":"fontawesome/solid/cart-flatbed-suitcase.svg","fontawesome-solid-cart-flatbed":"fontawesome/solid/cart-flatbed.svg","fontawesome-solid-cart-plus":"fontawesome/solid/cart-plus.svg","fontawesome-solid-cart-shopping":"fontawesome/solid/cart-shopping.svg","fontawesome-solid-cash-register":"fontawesome/solid/cash-register.svg","fontawesome-solid-cat":"fontawesome/solid/cat.svg","fontawesome-solid-cedi-sign":"fontawesome/solid/cedi-sign.svg","fontawesome-solid-cent-sign":"fontawesome/solid/cent-sign.svg","fontawesome-solid-certificate":"fontawesome/solid/certificate.svg","fontawesome-solid-chair":"fontawesome/solid/chair.svg","fontawesome-solid-chalkboard-user":"fontawesome/solid/chalkboard-user.svg","fontawesome-solid-chalkboard":"fontawesome/solid/chalkboard.svg","fontawesome-solid-champagne-glasses":"fontawesome/solid/champagne-glasses.svg","fontawesome-solid-charging-station":"fontawesome/solid/charging-station.svg","fontawesome-solid-chart-area":"fontawesome/solid/chart-area.svg","fontawesome-solid-chart-bar":"fontawesome/solid/chart-bar.svg","fontawesome-solid-chart-column":"fontawesome/solid/chart-column.svg","fontawesome-solid-chart-gantt":"fontawesome/solid/chart-gantt.svg","fontawesome-solid-chart-line":"fontawesome/solid/chart-line.svg","fontawesome-solid-chart-pie":"fontawesome/solid/chart-pie.svg","fontawesome-solid-chart-simple":"fontawesome/solid/chart-simple.svg","fontawesome-solid-check-double":"fontawesome/solid/check-double.svg","fontawesome-solid-check-to-slot":"fontawesome/solid/check-to-slot.svg","fontawesome-solid-check":"fontawesome/solid/check.svg","fontawesome-solid-cheese":"fontawesome/solid/cheese.svg","fontawesome-solid-chess-bishop":"fontawesome/solid/chess-bishop.svg","fontawesome-solid-chess-board":"fontawesome/solid/chess-board.svg","fontawesome-solid-chess-king":"fontawesome/solid/chess-king.svg","fontawesome-solid-chess-knight":"fontawesome/solid/chess-knight.svg","fontawesome-solid-chess-pawn":"fontawesome/solid/chess-pawn.svg","fontawesome-solid-chess-queen":"fontawesome/solid/chess-queen.svg","fontawesome-solid-chess-rook":"fontawesome/solid/chess-rook.svg","fontawesome-solid-chess":"fontawesome/solid/chess.svg","fontawesome-solid-chevron-down":"fontawesome/solid/chevron-down.svg","fontawesome-solid-chevron-left":"fontawesome/solid/chevron-left.svg","fontawesome-solid-chevron-right":"fontawesome/solid/chevron-right.svg","fontawesome-solid-chevron-up":"fontawesome/solid/chevron-up.svg","fontawesome-solid-child-dress":"fontawesome/solid/child-dress.svg","fontawesome-solid-child-reaching":"fontawesome/solid/child-reaching.svg","fontawesome-solid-child-rifle":"fontawesome/solid/child-rifle.svg","fontawesome-solid-child":"fontawesome/solid/child.svg","fontawesome-solid-children":"fontawesome/solid/children.svg","fontawesome-solid-church":"fontawesome/solid/church.svg","fontawesome-solid-circle-arrow-down":"fontawesome/solid/circle-arrow-down.svg","fontawesome-solid-circle-arrow-left":"fontawesome/solid/circle-arrow-left.svg","fontawesome-solid-circle-arrow-right":"fontawesome/solid/circle-arrow-right.svg","fontawesome-solid-circle-arrow-up":"fontawesome/solid/circle-arrow-up.svg","fontawesome-solid-circle-check":"fontawesome/solid/circle-check.svg","fontawesome-solid-circle-chevron-down":"fontawesome/solid/circle-chevron-down.svg","fontawesome-solid-circle-chevron-left":"fontawesome/solid/circle-chevron-left.svg","fontawesome-solid-circle-chevron-right":"fontawesome/solid/circle-chevron-right.svg","fontawesome-solid-circle-chevron-up":"fontawesome/solid/circle-chevron-up.svg","fontawesome-solid-circle-dollar-to-slot":"fontawesome/solid/circle-dollar-to-slot.svg","fontawesome-solid-circle-dot":"fontawesome/solid/circle-dot.svg","fontawesome-solid-circle-down":"fontawesome/solid/circle-down.svg","fontawesome-solid-circle-exclamation":"fontawesome/solid/circle-exclamation.svg","fontawesome-solid-circle-h":"fontawesome/solid/circle-h.svg","fontawesome-solid-circle-half-stroke":"fontawesome/solid/circle-half-stroke.svg","fontawesome-solid-circle-info":"fontawesome/solid/circle-info.svg","fontawesome-solid-circle-left":"fontawesome/solid/circle-left.svg","fontawesome-solid-circle-minus":"fontawesome/solid/circle-minus.svg","fontawesome-solid-circle-nodes":"fontawesome/solid/circle-nodes.svg","fontawesome-solid-circle-notch":"fontawesome/solid/circle-notch.svg","fontawesome-solid-circle-pause":"fontawesome/solid/circle-pause.svg","fontawesome-solid-circle-play":"fontawesome/solid/circle-play.svg","fontawesome-solid-circle-plus":"fontawesome/solid/circle-plus.svg","fontawesome-solid-circle-question":"fontawesome/solid/circle-question.svg","fontawesome-solid-circle-radiation":"fontawesome/solid/circle-radiation.svg","fontawesome-solid-circle-right":"fontawesome/solid/circle-right.svg","fontawesome-solid-circle-stop":"fontawesome/solid/circle-stop.svg","fontawesome-solid-circle-up":"fontawesome/solid/circle-up.svg","fontawesome-solid-circle-user":"fontawesome/solid/circle-user.svg","fontawesome-solid-circle-xmark":"fontawesome/solid/circle-xmark.svg","fontawesome-solid-circle":"fontawesome/solid/circle.svg","fontawesome-solid-city":"fontawesome/solid/city.svg","fontawesome-solid-clapperboard":"fontawesome/solid/clapperboard.svg","fontawesome-solid-clipboard-check":"fontawesome/solid/clipboard-check.svg","fontawesome-solid-clipboard-list":"fontawesome/solid/clipboard-list.svg","fontawesome-solid-clipboard-question":"fontawesome/solid/clipboard-question.svg","fontawesome-solid-clipboard-user":"fontawesome/solid/clipboard-user.svg","fontawesome-solid-clipboard":"fontawesome/solid/clipboard.svg","fontawesome-solid-clock-rotate-left":"fontawesome/solid/clock-rotate-left.svg","fontawesome-solid-clock":"fontawesome/solid/clock.svg","fontawesome-solid-clone":"fontawesome/solid/clone.svg","fontawesome-solid-closed-captioning":"fontawesome/solid/closed-captioning.svg","fontawesome-solid-cloud-arrow-down":"fontawesome/solid/cloud-arrow-down.svg","fontawesome-solid-cloud-arrow-up":"fontawesome/solid/cloud-arrow-up.svg","fontawesome-solid-cloud-bolt":"fontawesome/solid/cloud-bolt.svg","fontawesome-solid-cloud-meatball":"fontawesome/solid/cloud-meatball.svg","fontawesome-solid-cloud-moon-rain":"fontawesome/solid/cloud-moon-rain.svg","fontawesome-solid-cloud-moon":"fontawesome/solid/cloud-moon.svg","fontawesome-solid-cloud-rain":"fontawesome/solid/cloud-rain.svg","fontawesome-solid-cloud-showers-heavy":"fontawesome/solid/cloud-showers-heavy.svg","fontawesome-solid-cloud-showers-water":"fontawesome/solid/cloud-showers-water.svg","fontawesome-solid-cloud-sun-rain":"fontawesome/solid/cloud-sun-rain.svg","fontawesome-solid-cloud-sun":"fontawesome/solid/cloud-sun.svg","fontawesome-solid-cloud":"fontawesome/solid/cloud.svg","fontawesome-solid-clover":"fontawesome/solid/clover.svg","fontawesome-solid-code-branch":"fontawesome/solid/code-branch.svg","fontawesome-solid-code-commit":"fontawesome/solid/code-commit.svg","fontawesome-solid-code-compare":"fontawesome/solid/code-compare.svg","fontawesome-solid-code-fork":"fontawesome/solid/code-fork.svg","fontawesome-solid-code-merge":"fontawesome/solid/code-merge.svg","fontawesome-solid-code-pull-request":"fontawesome/solid/code-pull-request.svg","fontawesome-solid-code":"fontawesome/solid/code.svg","fontawesome-solid-coins":"fontawesome/solid/coins.svg","fontawesome-solid-colon-sign":"fontawesome/solid/colon-sign.svg","fontawesome-solid-comment-dollar":"fontawesome/solid/comment-dollar.svg","fontawesome-solid-comment-dots":"fontawesome/solid/comment-dots.svg","fontawesome-solid-comment-medical":"fontawesome/solid/comment-medical.svg","fontawesome-solid-comment-slash":"fontawesome/solid/comment-slash.svg","fontawesome-solid-comment-sms":"fontawesome/solid/comment-sms.svg","fontawesome-solid-comment":"fontawesome/solid/comment.svg","fontawesome-solid-comments-dollar":"fontawesome/solid/comments-dollar.svg","fontawesome-solid-comments":"fontawesome/solid/comments.svg","fontawesome-solid-compact-disc":"fontawesome/solid/compact-disc.svg","fontawesome-solid-compass-drafting":"fontawesome/solid/compass-drafting.svg","fontawesome-solid-compass":"fontawesome/solid/compass.svg","fontawesome-solid-compress":"fontawesome/solid/compress.svg","fontawesome-solid-computer-mouse":"fontawesome/solid/computer-mouse.svg","fontawesome-solid-computer":"fontawesome/solid/computer.svg","fontawesome-solid-cookie-bite":"fontawesome/solid/cookie-bite.svg","fontawesome-solid-cookie":"fontawesome/solid/cookie.svg","fontawesome-solid-copy":"fontawesome/solid/copy.svg","fontawesome-solid-copyright":"fontawesome/solid/copyright.svg","fontawesome-solid-couch":"fontawesome/solid/couch.svg","fontawesome-solid-cow":"fontawesome/solid/cow.svg","fontawesome-solid-credit-card":"fontawesome/solid/credit-card.svg","fontawesome-solid-crop-simple":"fontawesome/solid/crop-simple.svg","fontawesome-solid-crop":"fontawesome/solid/crop.svg","fontawesome-solid-cross":"fontawesome/solid/cross.svg","fontawesome-solid-crosshairs":"fontawesome/solid/crosshairs.svg","fontawesome-solid-crow":"fontawesome/solid/crow.svg","fontawesome-solid-crown":"fontawesome/solid/crown.svg","fontawesome-solid-crutch":"fontawesome/solid/crutch.svg","fontawesome-solid-cruzeiro-sign":"fontawesome/solid/cruzeiro-sign.svg","fontawesome-solid-cube":"fontawesome/solid/cube.svg","fontawesome-solid-cubes-stacked":"fontawesome/solid/cubes-stacked.svg","fontawesome-solid-cubes":"fontawesome/solid/cubes.svg","fontawesome-solid-d":"fontawesome/solid/d.svg","fontawesome-solid-database":"fontawesome/solid/database.svg","fontawesome-solid-delete-left":"fontawesome/solid/delete-left.svg","fontawesome-solid-democrat":"fontawesome/solid/democrat.svg","fontawesome-solid-desktop":"fontawesome/solid/desktop.svg","fontawesome-solid-dharmachakra":"fontawesome/solid/dharmachakra.svg","fontawesome-solid-diagram-next":"fontawesome/solid/diagram-next.svg","fontawesome-solid-diagram-predecessor":"fontawesome/solid/diagram-predecessor.svg","fontawesome-solid-diagram-project":"fontawesome/solid/diagram-project.svg","fontawesome-solid-diagram-successor":"fontawesome/solid/diagram-successor.svg","fontawesome-solid-diamond-turn-right":"fontawesome/solid/diamond-turn-right.svg","fontawesome-solid-diamond":"fontawesome/solid/diamond.svg","fontawesome-solid-dice-d20":"fontawesome/solid/dice-d20.svg","fontawesome-solid-dice-d6":"fontawesome/solid/dice-d6.svg","fontawesome-solid-dice-five":"fontawesome/solid/dice-five.svg","fontawesome-solid-dice-four":"fontawesome/solid/dice-four.svg","fontawesome-solid-dice-one":"fontawesome/solid/dice-one.svg","fontawesome-solid-dice-six":"fontawesome/solid/dice-six.svg","fontawesome-solid-dice-three":"fontawesome/solid/dice-three.svg","fontawesome-solid-dice-two":"fontawesome/solid/dice-two.svg","fontawesome-solid-dice":"fontawesome/solid/dice.svg","fontawesome-solid-disease":"fontawesome/solid/disease.svg","fontawesome-solid-display":"fontawesome/solid/display.svg","fontawesome-solid-divide":"fontawesome/solid/divide.svg","fontawesome-solid-dna":"fontawesome/solid/dna.svg","fontawesome-solid-dog":"fontawesome/solid/dog.svg","fontawesome-solid-dollar-sign":"fontawesome/solid/dollar-sign.svg","fontawesome-solid-dolly":"fontawesome/solid/dolly.svg","fontawesome-solid-dong-sign":"fontawesome/solid/dong-sign.svg","fontawesome-solid-door-closed":"fontawesome/solid/door-closed.svg","fontawesome-solid-door-open":"fontawesome/solid/door-open.svg","fontawesome-solid-dove":"fontawesome/solid/dove.svg","fontawesome-solid-down-left-and-up-right-to-center":"fontawesome/solid/down-left-and-up-right-to-center.svg","fontawesome-solid-down-long":"fontawesome/solid/down-long.svg","fontawesome-solid-download":"fontawesome/solid/download.svg","fontawesome-solid-dragon":"fontawesome/solid/dragon.svg","fontawesome-solid-draw-polygon":"fontawesome/solid/draw-polygon.svg","fontawesome-solid-droplet-slash":"fontawesome/solid/droplet-slash.svg","fontawesome-solid-droplet":"fontawesome/solid/droplet.svg","fontawesome-solid-drum-steelpan":"fontawesome/solid/drum-steelpan.svg","fontawesome-solid-drum":"fontawesome/solid/drum.svg","fontawesome-solid-drumstick-bite":"fontawesome/solid/drumstick-bite.svg","fontawesome-solid-dumbbell":"fontawesome/solid/dumbbell.svg","fontawesome-solid-dumpster-fire":"fontawesome/solid/dumpster-fire.svg","fontawesome-solid-dumpster":"fontawesome/solid/dumpster.svg","fontawesome-solid-dungeon":"fontawesome/solid/dungeon.svg","fontawesome-solid-e":"fontawesome/solid/e.svg","fontawesome-solid-ear-deaf":"fontawesome/solid/ear-deaf.svg","fontawesome-solid-ear-listen":"fontawesome/solid/ear-listen.svg","fontawesome-solid-earth-africa":"fontawesome/solid/earth-africa.svg","fontawesome-solid-earth-americas":"fontawesome/solid/earth-americas.svg","fontawesome-solid-earth-asia":"fontawesome/solid/earth-asia.svg","fontawesome-solid-earth-europe":"fontawesome/solid/earth-europe.svg","fontawesome-solid-earth-oceania":"fontawesome/solid/earth-oceania.svg","fontawesome-solid-egg":"fontawesome/solid/egg.svg","fontawesome-solid-eject":"fontawesome/solid/eject.svg","fontawesome-solid-elevator":"fontawesome/solid/elevator.svg","fontawesome-solid-ellipsis-vertical":"fontawesome/solid/ellipsis-vertical.svg","fontawesome-solid-ellipsis":"fontawesome/solid/ellipsis.svg","fontawesome-solid-envelope-circle-check":"fontawesome/solid/envelope-circle-check.svg","fontawesome-solid-envelope-open-text":"fontawesome/solid/envelope-open-text.svg","fontawesome-solid-envelope-open":"fontawesome/solid/envelope-open.svg","fontawesome-solid-envelope":"fontawesome/solid/envelope.svg","fontawesome-solid-envelopes-bulk":"fontawesome/solid/envelopes-bulk.svg","fontawesome-solid-equals":"fontawesome/solid/equals.svg","fontawesome-solid-eraser":"fontawesome/solid/eraser.svg","fontawesome-solid-ethernet":"fontawesome/solid/ethernet.svg","fontawesome-solid-euro-sign":"fontawesome/solid/euro-sign.svg","fontawesome-solid-exclamation":"fontawesome/solid/exclamation.svg","fontawesome-solid-expand":"fontawesome/solid/expand.svg","fontawesome-solid-explosion":"fontawesome/solid/explosion.svg","fontawesome-solid-eye-dropper":"fontawesome/solid/eye-dropper.svg","fontawesome-solid-eye-low-vision":"fontawesome/solid/eye-low-vision.svg","fontawesome-solid-eye-slash":"fontawesome/solid/eye-slash.svg","fontawesome-solid-eye":"fontawesome/solid/eye.svg","fontawesome-solid-f":"fontawesome/solid/f.svg","fontawesome-solid-face-angry":"fontawesome/solid/face-angry.svg","fontawesome-solid-face-dizzy":"fontawesome/solid/face-dizzy.svg","fontawesome-solid-face-flushed":"fontawesome/solid/face-flushed.svg","fontawesome-solid-face-frown-open":"fontawesome/solid/face-frown-open.svg","fontawesome-solid-face-frown":"fontawesome/solid/face-frown.svg","fontawesome-solid-face-grimace":"fontawesome/solid/face-grimace.svg","fontawesome-solid-face-grin-beam-sweat":"fontawesome/solid/face-grin-beam-sweat.svg","fontawesome-solid-face-grin-beam":"fontawesome/solid/face-grin-beam.svg","fontawesome-solid-face-grin-hearts":"fontawesome/solid/face-grin-hearts.svg","fontawesome-solid-face-grin-squint-tears":"fontawesome/solid/face-grin-squint-tears.svg","fontawesome-solid-face-grin-squint":"fontawesome/solid/face-grin-squint.svg","fontawesome-solid-face-grin-stars":"fontawesome/solid/face-grin-stars.svg","fontawesome-solid-face-grin-tears":"fontawesome/solid/face-grin-tears.svg","fontawesome-solid-face-grin-tongue-squint":"fontawesome/solid/face-grin-tongue-squint.svg","fontawesome-solid-face-grin-tongue-wink":"fontawesome/solid/face-grin-tongue-wink.svg","fontawesome-solid-face-grin-tongue":"fontawesome/solid/face-grin-tongue.svg","fontawesome-solid-face-grin-wide":"fontawesome/solid/face-grin-wide.svg","fontawesome-solid-face-grin-wink":"fontawesome/solid/face-grin-wink.svg","fontawesome-solid-face-grin":"fontawesome/solid/face-grin.svg","fontawesome-solid-face-kiss-beam":"fontawesome/solid/face-kiss-beam.svg","fontawesome-solid-face-kiss-wink-heart":"fontawesome/solid/face-kiss-wink-heart.svg","fontawesome-solid-face-kiss":"fontawesome/solid/face-kiss.svg","fontawesome-solid-face-laugh-beam":"fontawesome/solid/face-laugh-beam.svg","fontawesome-solid-face-laugh-squint":"fontawesome/solid/face-laugh-squint.svg","fontawesome-solid-face-laugh-wink":"fontawesome/solid/face-laugh-wink.svg","fontawesome-solid-face-laugh":"fontawesome/solid/face-laugh.svg","fontawesome-solid-face-meh-blank":"fontawesome/solid/face-meh-blank.svg","fontawesome-solid-face-meh":"fontawesome/solid/face-meh.svg","fontawesome-solid-face-rolling-eyes":"fontawesome/solid/face-rolling-eyes.svg","fontawesome-solid-face-sad-cry":"fontawesome/solid/face-sad-cry.svg","fontawesome-solid-face-sad-tear":"fontawesome/solid/face-sad-tear.svg","fontawesome-solid-face-smile-beam":"fontawesome/solid/face-smile-beam.svg","fontawesome-solid-face-smile-wink":"fontawesome/solid/face-smile-wink.svg","fontawesome-solid-face-smile":"fontawesome/solid/face-smile.svg","fontawesome-solid-face-surprise":"fontawesome/solid/face-surprise.svg","fontawesome-solid-face-tired":"fontawesome/solid/face-tired.svg","fontawesome-solid-fan":"fontawesome/solid/fan.svg","fontawesome-solid-faucet-drip":"fontawesome/solid/faucet-drip.svg","fontawesome-solid-faucet":"fontawesome/solid/faucet.svg","fontawesome-solid-fax":"fontawesome/solid/fax.svg","fontawesome-solid-feather-pointed":"fontawesome/solid/feather-pointed.svg","fontawesome-solid-feather":"fontawesome/solid/feather.svg","fontawesome-solid-ferry":"fontawesome/solid/ferry.svg","fontawesome-solid-file-arrow-down":"fontawesome/solid/file-arrow-down.svg","fontawesome-solid-file-arrow-up":"fontawesome/solid/file-arrow-up.svg","fontawesome-solid-file-audio":"fontawesome/solid/file-audio.svg","fontawesome-solid-file-circle-check":"fontawesome/solid/file-circle-check.svg","fontawesome-solid-file-circle-exclamation":"fontawesome/solid/file-circle-exclamation.svg","fontawesome-solid-file-circle-minus":"fontawesome/solid/file-circle-minus.svg","fontawesome-solid-file-circle-plus":"fontawesome/solid/file-circle-plus.svg","fontawesome-solid-file-circle-question":"fontawesome/solid/file-circle-question.svg","fontawesome-solid-file-circle-xmark":"fontawesome/solid/file-circle-xmark.svg","fontawesome-solid-file-code":"fontawesome/solid/file-code.svg","fontawesome-solid-file-contract":"fontawesome/solid/file-contract.svg","fontawesome-solid-file-csv":"fontawesome/solid/file-csv.svg","fontawesome-solid-file-excel":"fontawesome/solid/file-excel.svg","fontawesome-solid-file-export":"fontawesome/solid/file-export.svg","fontawesome-solid-file-image":"fontawesome/solid/file-image.svg","fontawesome-solid-file-import":"fontawesome/solid/file-import.svg","fontawesome-solid-file-invoice-dollar":"fontawesome/solid/file-invoice-dollar.svg","fontawesome-solid-file-invoice":"fontawesome/solid/file-invoice.svg","fontawesome-solid-file-lines":"fontawesome/solid/file-lines.svg","fontawesome-solid-file-medical":"fontawesome/solid/file-medical.svg","fontawesome-solid-file-pdf":"fontawesome/solid/file-pdf.svg","fontawesome-solid-file-pen":"fontawesome/solid/file-pen.svg","fontawesome-solid-file-powerpoint":"fontawesome/solid/file-powerpoint.svg","fontawesome-solid-file-prescription":"fontawesome/solid/file-prescription.svg","fontawesome-solid-file-shield":"fontawesome/solid/file-shield.svg","fontawesome-solid-file-signature":"fontawesome/solid/file-signature.svg","fontawesome-solid-file-video":"fontawesome/solid/file-video.svg","fontawesome-solid-file-waveform":"fontawesome/solid/file-waveform.svg","fontawesome-solid-file-word":"fontawesome/solid/file-word.svg","fontawesome-solid-file-zipper":"fontawesome/solid/file-zipper.svg","fontawesome-solid-file":"fontawesome/solid/file.svg","fontawesome-solid-fill-drip":"fontawesome/solid/fill-drip.svg","fontawesome-solid-fill":"fontawesome/solid/fill.svg","fontawesome-solid-film":"fontawesome/solid/film.svg","fontawesome-solid-filter-circle-dollar":"fontawesome/solid/filter-circle-dollar.svg","fontawesome-solid-filter-circle-xmark":"fontawesome/solid/filter-circle-xmark.svg","fontawesome-solid-filter":"fontawesome/solid/filter.svg","fontawesome-solid-fingerprint":"fontawesome/solid/fingerprint.svg","fontawesome-solid-fire-burner":"fontawesome/solid/fire-burner.svg","fontawesome-solid-fire-extinguisher":"fontawesome/solid/fire-extinguisher.svg","fontawesome-solid-fire-flame-curved":"fontawesome/solid/fire-flame-curved.svg","fontawesome-solid-fire-flame-simple":"fontawesome/solid/fire-flame-simple.svg","fontawesome-solid-fire":"fontawesome/solid/fire.svg","fontawesome-solid-fish-fins":"fontawesome/solid/fish-fins.svg","fontawesome-solid-fish":"fontawesome/solid/fish.svg","fontawesome-solid-flag-checkered":"fontawesome/solid/flag-checkered.svg","fontawesome-solid-flag-usa":"fontawesome/solid/flag-usa.svg","fontawesome-solid-flag":"fontawesome/solid/flag.svg","fontawesome-solid-flask-vial":"fontawesome/solid/flask-vial.svg","fontawesome-solid-flask":"fontawesome/solid/flask.svg","fontawesome-solid-floppy-disk":"fontawesome/solid/floppy-disk.svg","fontawesome-solid-florin-sign":"fontawesome/solid/florin-sign.svg","fontawesome-solid-folder-closed":"fontawesome/solid/folder-closed.svg","fontawesome-solid-folder-minus":"fontawesome/solid/folder-minus.svg","fontawesome-solid-folder-open":"fontawesome/solid/folder-open.svg","fontawesome-solid-folder-plus":"fontawesome/solid/folder-plus.svg","fontawesome-solid-folder-tree":"fontawesome/solid/folder-tree.svg","fontawesome-solid-folder":"fontawesome/solid/folder.svg","fontawesome-solid-font-awesome":"fontawesome/solid/font-awesome.svg","fontawesome-solid-font":"fontawesome/solid/font.svg","fontawesome-solid-football":"fontawesome/solid/football.svg","fontawesome-solid-forward-fast":"fontawesome/solid/forward-fast.svg","fontawesome-solid-forward-step":"fontawesome/solid/forward-step.svg","fontawesome-solid-forward":"fontawesome/solid/forward.svg","fontawesome-solid-franc-sign":"fontawesome/solid/franc-sign.svg","fontawesome-solid-frog":"fontawesome/solid/frog.svg","fontawesome-solid-futbol":"fontawesome/solid/futbol.svg","fontawesome-solid-g":"fontawesome/solid/g.svg","fontawesome-solid-gamepad":"fontawesome/solid/gamepad.svg","fontawesome-solid-gas-pump":"fontawesome/solid/gas-pump.svg","fontawesome-solid-gauge-high":"fontawesome/solid/gauge-high.svg","fontawesome-solid-gauge-simple-high":"fontawesome/solid/gauge-simple-high.svg","fontawesome-solid-gauge-simple":"fontawesome/solid/gauge-simple.svg","fontawesome-solid-gauge":"fontawesome/solid/gauge.svg","fontawesome-solid-gavel":"fontawesome/solid/gavel.svg","fontawesome-solid-gear":"fontawesome/solid/gear.svg","fontawesome-solid-gears":"fontawesome/solid/gears.svg","fontawesome-solid-gem":"fontawesome/solid/gem.svg","fontawesome-solid-genderless":"fontawesome/solid/genderless.svg","fontawesome-solid-ghost":"fontawesome/solid/ghost.svg","fontawesome-solid-gift":"fontawesome/solid/gift.svg","fontawesome-solid-gifts":"fontawesome/solid/gifts.svg","fontawesome-solid-glass-water-droplet":"fontawesome/solid/glass-water-droplet.svg","fontawesome-solid-glass-water":"fontawesome/solid/glass-water.svg","fontawesome-solid-glasses":"fontawesome/solid/glasses.svg","fontawesome-solid-globe":"fontawesome/solid/globe.svg","fontawesome-solid-golf-ball-tee":"fontawesome/solid/golf-ball-tee.svg","fontawesome-solid-gopuram":"fontawesome/solid/gopuram.svg","fontawesome-solid-graduation-cap":"fontawesome/solid/graduation-cap.svg","fontawesome-solid-greater-than-equal":"fontawesome/solid/greater-than-equal.svg","fontawesome-solid-greater-than":"fontawesome/solid/greater-than.svg","fontawesome-solid-grip-lines-vertical":"fontawesome/solid/grip-lines-vertical.svg","fontawesome-solid-grip-lines":"fontawesome/solid/grip-lines.svg","fontawesome-solid-grip-vertical":"fontawesome/solid/grip-vertical.svg","fontawesome-solid-grip":"fontawesome/solid/grip.svg","fontawesome-solid-group-arrows-rotate":"fontawesome/solid/group-arrows-rotate.svg","fontawesome-solid-guarani-sign":"fontawesome/solid/guarani-sign.svg","fontawesome-solid-guitar":"fontawesome/solid/guitar.svg","fontawesome-solid-gun":"fontawesome/solid/gun.svg","fontawesome-solid-h":"fontawesome/solid/h.svg","fontawesome-solid-hammer":"fontawesome/solid/hammer.svg","fontawesome-solid-hamsa":"fontawesome/solid/hamsa.svg","fontawesome-solid-hand-back-fist":"fontawesome/solid/hand-back-fist.svg","fontawesome-solid-hand-dots":"fontawesome/solid/hand-dots.svg","fontawesome-solid-hand-fist":"fontawesome/solid/hand-fist.svg","fontawesome-solid-hand-holding-dollar":"fontawesome/solid/hand-holding-dollar.svg","fontawesome-solid-hand-holding-droplet":"fontawesome/solid/hand-holding-droplet.svg","fontawesome-solid-hand-holding-hand":"fontawesome/solid/hand-holding-hand.svg","fontawesome-solid-hand-holding-heart":"fontawesome/solid/hand-holding-heart.svg","fontawesome-solid-hand-holding-medical":"fontawesome/solid/hand-holding-medical.svg","fontawesome-solid-hand-holding":"fontawesome/solid/hand-holding.svg","fontawesome-solid-hand-lizard":"fontawesome/solid/hand-lizard.svg","fontawesome-solid-hand-middle-finger":"fontawesome/solid/hand-middle-finger.svg","fontawesome-solid-hand-peace":"fontawesome/solid/hand-peace.svg","fontawesome-solid-hand-point-down":"fontawesome/solid/hand-point-down.svg","fontawesome-solid-hand-point-left":"fontawesome/solid/hand-point-left.svg","fontawesome-solid-hand-point-right":"fontawesome/solid/hand-point-right.svg","fontawesome-solid-hand-point-up":"fontawesome/solid/hand-point-up.svg","fontawesome-solid-hand-pointer":"fontawesome/solid/hand-pointer.svg","fontawesome-solid-hand-scissors":"fontawesome/solid/hand-scissors.svg","fontawesome-solid-hand-sparkles":"fontawesome/solid/hand-sparkles.svg","fontawesome-solid-hand-spock":"fontawesome/solid/hand-spock.svg","fontawesome-solid-hand":"fontawesome/solid/hand.svg","fontawesome-solid-handcuffs":"fontawesome/solid/handcuffs.svg","fontawesome-solid-hands-asl-interpreting":"fontawesome/solid/hands-asl-interpreting.svg","fontawesome-solid-hands-bound":"fontawesome/solid/hands-bound.svg","fontawesome-solid-hands-bubbles":"fontawesome/solid/hands-bubbles.svg","fontawesome-solid-hands-clapping":"fontawesome/solid/hands-clapping.svg","fontawesome-solid-hands-holding-child":"fontawesome/solid/hands-holding-child.svg","fontawesome-solid-hands-holding-circle":"fontawesome/solid/hands-holding-circle.svg","fontawesome-solid-hands-holding":"fontawesome/solid/hands-holding.svg","fontawesome-solid-hands-praying":"fontawesome/solid/hands-praying.svg","fontawesome-solid-hands":"fontawesome/solid/hands.svg","fontawesome-solid-handshake-angle":"fontawesome/solid/handshake-angle.svg","fontawesome-solid-handshake-simple-slash":"fontawesome/solid/handshake-simple-slash.svg","fontawesome-solid-handshake-simple":"fontawesome/solid/handshake-simple.svg","fontawesome-solid-handshake-slash":"fontawesome/solid/handshake-slash.svg","fontawesome-solid-handshake":"fontawesome/solid/handshake.svg","fontawesome-solid-hanukiah":"fontawesome/solid/hanukiah.svg","fontawesome-solid-hard-drive":"fontawesome/solid/hard-drive.svg","fontawesome-solid-hashtag":"fontawesome/solid/hashtag.svg","fontawesome-solid-hat-cowboy-side":"fontawesome/solid/hat-cowboy-side.svg","fontawesome-solid-hat-cowboy":"fontawesome/solid/hat-cowboy.svg","fontawesome-solid-hat-wizard":"fontawesome/solid/hat-wizard.svg","fontawesome-solid-head-side-cough-slash":"fontawesome/solid/head-side-cough-slash.svg","fontawesome-solid-head-side-cough":"fontawesome/solid/head-side-cough.svg","fontawesome-solid-head-side-mask":"fontawesome/solid/head-side-mask.svg","fontawesome-solid-head-side-virus":"fontawesome/solid/head-side-virus.svg","fontawesome-solid-heading":"fontawesome/solid/heading.svg","fontawesome-solid-headphones-simple":"fontawesome/solid/headphones-simple.svg","fontawesome-solid-headphones":"fontawesome/solid/headphones.svg","fontawesome-solid-headset":"fontawesome/solid/headset.svg","fontawesome-solid-heart-circle-bolt":"fontawesome/solid/heart-circle-bolt.svg","fontawesome-solid-heart-circle-check":"fontawesome/solid/heart-circle-check.svg","fontawesome-solid-heart-circle-exclamation":"fontawesome/solid/heart-circle-exclamation.svg","fontawesome-solid-heart-circle-minus":"fontawesome/solid/heart-circle-minus.svg","fontawesome-solid-heart-circle-plus":"fontawesome/solid/heart-circle-plus.svg","fontawesome-solid-heart-circle-xmark":"fontawesome/solid/heart-circle-xmark.svg","fontawesome-solid-heart-crack":"fontawesome/solid/heart-crack.svg","fontawesome-solid-heart-pulse":"fontawesome/solid/heart-pulse.svg","fontawesome-solid-heart":"fontawesome/solid/heart.svg","fontawesome-solid-helicopter-symbol":"fontawesome/solid/helicopter-symbol.svg","fontawesome-solid-helicopter":"fontawesome/solid/helicopter.svg","fontawesome-solid-helmet-safety":"fontawesome/solid/helmet-safety.svg","fontawesome-solid-helmet-un":"fontawesome/solid/helmet-un.svg","fontawesome-solid-highlighter":"fontawesome/solid/highlighter.svg","fontawesome-solid-hill-avalanche":"fontawesome/solid/hill-avalanche.svg","fontawesome-solid-hill-rockslide":"fontawesome/solid/hill-rockslide.svg","fontawesome-solid-hippo":"fontawesome/solid/hippo.svg","fontawesome-solid-hockey-puck":"fontawesome/solid/hockey-puck.svg","fontawesome-solid-holly-berry":"fontawesome/solid/holly-berry.svg","fontawesome-solid-horse-head":"fontawesome/solid/horse-head.svg","fontawesome-solid-horse":"fontawesome/solid/horse.svg","fontawesome-solid-hospital-user":"fontawesome/solid/hospital-user.svg","fontawesome-solid-hospital":"fontawesome/solid/hospital.svg","fontawesome-solid-hot-tub-person":"fontawesome/solid/hot-tub-person.svg","fontawesome-solid-hotdog":"fontawesome/solid/hotdog.svg","fontawesome-solid-hotel":"fontawesome/solid/hotel.svg","fontawesome-solid-hourglass-end":"fontawesome/solid/hourglass-end.svg","fontawesome-solid-hourglass-half":"fontawesome/solid/hourglass-half.svg","fontawesome-solid-hourglass-start":"fontawesome/solid/hourglass-start.svg","fontawesome-solid-hourglass":"fontawesome/solid/hourglass.svg","fontawesome-solid-house-chimney-crack":"fontawesome/solid/house-chimney-crack.svg","fontawesome-solid-house-chimney-medical":"fontawesome/solid/house-chimney-medical.svg","fontawesome-solid-house-chimney-user":"fontawesome/solid/house-chimney-user.svg","fontawesome-solid-house-chimney-window":"fontawesome/solid/house-chimney-window.svg","fontawesome-solid-house-chimney":"fontawesome/solid/house-chimney.svg","fontawesome-solid-house-circle-check":"fontawesome/solid/house-circle-check.svg","fontawesome-solid-house-circle-exclamation":"fontawesome/solid/house-circle-exclamation.svg","fontawesome-solid-house-circle-xmark":"fontawesome/solid/house-circle-xmark.svg","fontawesome-solid-house-crack":"fontawesome/solid/house-crack.svg","fontawesome-solid-house-fire":"fontawesome/solid/house-fire.svg","fontawesome-solid-house-flag":"fontawesome/solid/house-flag.svg","fontawesome-solid-house-flood-water-circle-arrow-right":"fontawesome/solid/house-flood-water-circle-arrow-right.svg","fontawesome-solid-house-flood-water":"fontawesome/solid/house-flood-water.svg","fontawesome-solid-house-laptop":"fontawesome/solid/house-laptop.svg","fontawesome-solid-house-lock":"fontawesome/solid/house-lock.svg","fontawesome-solid-house-medical-circle-check":"fontawesome/solid/house-medical-circle-check.svg","fontawesome-solid-house-medical-circle-exclamation":"fontawesome/solid/house-medical-circle-exclamation.svg","fontawesome-solid-house-medical-circle-xmark":"fontawesome/solid/house-medical-circle-xmark.svg","fontawesome-solid-house-medical-flag":"fontawesome/solid/house-medical-flag.svg","fontawesome-solid-house-medical":"fontawesome/solid/house-medical.svg","fontawesome-solid-house-signal":"fontawesome/solid/house-signal.svg","fontawesome-solid-house-tsunami":"fontawesome/solid/house-tsunami.svg","fontawesome-solid-house-user":"fontawesome/solid/house-user.svg","fontawesome-solid-house":"fontawesome/solid/house.svg","fontawesome-solid-hryvnia-sign":"fontawesome/solid/hryvnia-sign.svg","fontawesome-solid-hurricane":"fontawesome/solid/hurricane.svg","fontawesome-solid-i-cursor":"fontawesome/solid/i-cursor.svg","fontawesome-solid-i":"fontawesome/solid/i.svg","fontawesome-solid-ice-cream":"fontawesome/solid/ice-cream.svg","fontawesome-solid-icicles":"fontawesome/solid/icicles.svg","fontawesome-solid-icons":"fontawesome/solid/icons.svg","fontawesome-solid-id-badge":"fontawesome/solid/id-badge.svg","fontawesome-solid-id-card-clip":"fontawesome/solid/id-card-clip.svg","fontawesome-solid-id-card":"fontawesome/solid/id-card.svg","fontawesome-solid-igloo":"fontawesome/solid/igloo.svg","fontawesome-solid-image-portrait":"fontawesome/solid/image-portrait.svg","fontawesome-solid-image":"fontawesome/solid/image.svg","fontawesome-solid-images":"fontawesome/solid/images.svg","fontawesome-solid-inbox":"fontawesome/solid/inbox.svg","fontawesome-solid-indent":"fontawesome/solid/indent.svg","fontawesome-solid-indian-rupee-sign":"fontawesome/solid/indian-rupee-sign.svg","fontawesome-solid-industry":"fontawesome/solid/industry.svg","fontawesome-solid-infinity":"fontawesome/solid/infinity.svg","fontawesome-solid-info":"fontawesome/solid/info.svg","fontawesome-solid-italic":"fontawesome/solid/italic.svg","fontawesome-solid-j":"fontawesome/solid/j.svg","fontawesome-solid-jar-wheat":"fontawesome/solid/jar-wheat.svg","fontawesome-solid-jar":"fontawesome/solid/jar.svg","fontawesome-solid-jedi":"fontawesome/solid/jedi.svg","fontawesome-solid-jet-fighter-up":"fontawesome/solid/jet-fighter-up.svg","fontawesome-solid-jet-fighter":"fontawesome/solid/jet-fighter.svg","fontawesome-solid-joint":"fontawesome/solid/joint.svg","fontawesome-solid-jug-detergent":"fontawesome/solid/jug-detergent.svg","fontawesome-solid-k":"fontawesome/solid/k.svg","fontawesome-solid-kaaba":"fontawesome/solid/kaaba.svg","fontawesome-solid-key":"fontawesome/solid/key.svg","fontawesome-solid-keyboard":"fontawesome/solid/keyboard.svg","fontawesome-solid-khanda":"fontawesome/solid/khanda.svg","fontawesome-solid-kip-sign":"fontawesome/solid/kip-sign.svg","fontawesome-solid-kit-medical":"fontawesome/solid/kit-medical.svg","fontawesome-solid-kitchen-set":"fontawesome/solid/kitchen-set.svg","fontawesome-solid-kiwi-bird":"fontawesome/solid/kiwi-bird.svg","fontawesome-solid-l":"fontawesome/solid/l.svg","fontawesome-solid-land-mine-on":"fontawesome/solid/land-mine-on.svg","fontawesome-solid-landmark-dome":"fontawesome/solid/landmark-dome.svg","fontawesome-solid-landmark-flag":"fontawesome/solid/landmark-flag.svg","fontawesome-solid-landmark":"fontawesome/solid/landmark.svg","fontawesome-solid-language":"fontawesome/solid/language.svg","fontawesome-solid-laptop-code":"fontawesome/solid/laptop-code.svg","fontawesome-solid-laptop-file":"fontawesome/solid/laptop-file.svg","fontawesome-solid-laptop-medical":"fontawesome/solid/laptop-medical.svg","fontawesome-solid-laptop":"fontawesome/solid/laptop.svg","fontawesome-solid-lari-sign":"fontawesome/solid/lari-sign.svg","fontawesome-solid-layer-group":"fontawesome/solid/layer-group.svg","fontawesome-solid-leaf":"fontawesome/solid/leaf.svg","fontawesome-solid-left-long":"fontawesome/solid/left-long.svg","fontawesome-solid-left-right":"fontawesome/solid/left-right.svg","fontawesome-solid-lemon":"fontawesome/solid/lemon.svg","fontawesome-solid-less-than-equal":"fontawesome/solid/less-than-equal.svg","fontawesome-solid-less-than":"fontawesome/solid/less-than.svg","fontawesome-solid-life-ring":"fontawesome/solid/life-ring.svg","fontawesome-solid-lightbulb":"fontawesome/solid/lightbulb.svg","fontawesome-solid-lines-leaning":"fontawesome/solid/lines-leaning.svg","fontawesome-solid-link-slash":"fontawesome/solid/link-slash.svg","fontawesome-solid-link":"fontawesome/solid/link.svg","fontawesome-solid-lira-sign":"fontawesome/solid/lira-sign.svg","fontawesome-solid-list-check":"fontawesome/solid/list-check.svg","fontawesome-solid-list-ol":"fontawesome/solid/list-ol.svg","fontawesome-solid-list-ul":"fontawesome/solid/list-ul.svg","fontawesome-solid-list":"fontawesome/solid/list.svg","fontawesome-solid-litecoin-sign":"fontawesome/solid/litecoin-sign.svg","fontawesome-solid-location-arrow":"fontawesome/solid/location-arrow.svg","fontawesome-solid-location-crosshairs":"fontawesome/solid/location-crosshairs.svg","fontawesome-solid-location-dot":"fontawesome/solid/location-dot.svg","fontawesome-solid-location-pin-lock":"fontawesome/solid/location-pin-lock.svg","fontawesome-solid-location-pin":"fontawesome/solid/location-pin.svg","fontawesome-solid-lock-open":"fontawesome/solid/lock-open.svg","fontawesome-solid-lock":"fontawesome/solid/lock.svg","fontawesome-solid-locust":"fontawesome/solid/locust.svg","fontawesome-solid-lungs-virus":"fontawesome/solid/lungs-virus.svg","fontawesome-solid-lungs":"fontawesome/solid/lungs.svg","fontawesome-solid-m":"fontawesome/solid/m.svg","fontawesome-solid-magnet":"fontawesome/solid/magnet.svg","fontawesome-solid-magnifying-glass-arrow-right":"fontawesome/solid/magnifying-glass-arrow-right.svg","fontawesome-solid-magnifying-glass-chart":"fontawesome/solid/magnifying-glass-chart.svg","fontawesome-solid-magnifying-glass-dollar":"fontawesome/solid/magnifying-glass-dollar.svg","fontawesome-solid-magnifying-glass-location":"fontawesome/solid/magnifying-glass-location.svg","fontawesome-solid-magnifying-glass-minus":"fontawesome/solid/magnifying-glass-minus.svg","fontawesome-solid-magnifying-glass-plus":"fontawesome/solid/magnifying-glass-plus.svg","fontawesome-solid-magnifying-glass":"fontawesome/solid/magnifying-glass.svg","fontawesome-solid-manat-sign":"fontawesome/solid/manat-sign.svg","fontawesome-solid-map-location-dot":"fontawesome/solid/map-location-dot.svg","fontawesome-solid-map-location":"fontawesome/solid/map-location.svg","fontawesome-solid-map-pin":"fontawesome/solid/map-pin.svg","fontawesome-solid-map":"fontawesome/solid/map.svg","fontawesome-solid-marker":"fontawesome/solid/marker.svg","fontawesome-solid-mars-and-venus-burst":"fontawesome/solid/mars-and-venus-burst.svg","fontawesome-solid-mars-and-venus":"fontawesome/solid/mars-and-venus.svg","fontawesome-solid-mars-double":"fontawesome/solid/mars-double.svg","fontawesome-solid-mars-stroke-right":"fontawesome/solid/mars-stroke-right.svg","fontawesome-solid-mars-stroke-up":"fontawesome/solid/mars-stroke-up.svg","fontawesome-solid-mars-stroke":"fontawesome/solid/mars-stroke.svg","fontawesome-solid-mars":"fontawesome/solid/mars.svg","fontawesome-solid-martini-glass-citrus":"fontawesome/solid/martini-glass-citrus.svg","fontawesome-solid-martini-glass-empty":"fontawesome/solid/martini-glass-empty.svg","fontawesome-solid-martini-glass":"fontawesome/solid/martini-glass.svg","fontawesome-solid-mask-face":"fontawesome/solid/mask-face.svg","fontawesome-solid-mask-ventilator":"fontawesome/solid/mask-ventilator.svg","fontawesome-solid-mask":"fontawesome/solid/mask.svg","fontawesome-solid-masks-theater":"fontawesome/solid/masks-theater.svg","fontawesome-solid-mattress-pillow":"fontawesome/solid/mattress-pillow.svg","fontawesome-solid-maximize":"fontawesome/solid/maximize.svg","fontawesome-solid-medal":"fontawesome/solid/medal.svg","fontawesome-solid-memory":"fontawesome/solid/memory.svg","fontawesome-solid-menorah":"fontawesome/solid/menorah.svg","fontawesome-solid-mercury":"fontawesome/solid/mercury.svg","fontawesome-solid-message":"fontawesome/solid/message.svg","fontawesome-solid-meteor":"fontawesome/solid/meteor.svg","fontawesome-solid-microchip":"fontawesome/solid/microchip.svg","fontawesome-solid-microphone-lines-slash":"fontawesome/solid/microphone-lines-slash.svg","fontawesome-solid-microphone-lines":"fontawesome/solid/microphone-lines.svg","fontawesome-solid-microphone-slash":"fontawesome/solid/microphone-slash.svg","fontawesome-solid-microphone":"fontawesome/solid/microphone.svg","fontawesome-solid-microscope":"fontawesome/solid/microscope.svg","fontawesome-solid-mill-sign":"fontawesome/solid/mill-sign.svg","fontawesome-solid-minimize":"fontawesome/solid/minimize.svg","fontawesome-solid-minus":"fontawesome/solid/minus.svg","fontawesome-solid-mitten":"fontawesome/solid/mitten.svg","fontawesome-solid-mobile-button":"fontawesome/solid/mobile-button.svg","fontawesome-solid-mobile-retro":"fontawesome/solid/mobile-retro.svg","fontawesome-solid-mobile-screen-button":"fontawesome/solid/mobile-screen-button.svg","fontawesome-solid-mobile-screen":"fontawesome/solid/mobile-screen.svg","fontawesome-solid-mobile":"fontawesome/solid/mobile.svg","fontawesome-solid-money-bill-1-wave":"fontawesome/solid/money-bill-1-wave.svg","fontawesome-solid-money-bill-1":"fontawesome/solid/money-bill-1.svg","fontawesome-solid-money-bill-transfer":"fontawesome/solid/money-bill-transfer.svg","fontawesome-solid-money-bill-trend-up":"fontawesome/solid/money-bill-trend-up.svg","fontawesome-solid-money-bill-wave":"fontawesome/solid/money-bill-wave.svg","fontawesome-solid-money-bill-wheat":"fontawesome/solid/money-bill-wheat.svg","fontawesome-solid-money-bill":"fontawesome/solid/money-bill.svg","fontawesome-solid-money-bills":"fontawesome/solid/money-bills.svg","fontawesome-solid-money-check-dollar":"fontawesome/solid/money-check-dollar.svg","fontawesome-solid-money-check":"fontawesome/solid/money-check.svg","fontawesome-solid-monument":"fontawesome/solid/monument.svg","fontawesome-solid-moon":"fontawesome/solid/moon.svg","fontawesome-solid-mortar-pestle":"fontawesome/solid/mortar-pestle.svg","fontawesome-solid-mosque":"fontawesome/solid/mosque.svg","fontawesome-solid-mosquito-net":"fontawesome/solid/mosquito-net.svg","fontawesome-solid-mosquito":"fontawesome/solid/mosquito.svg","fontawesome-solid-motorcycle":"fontawesome/solid/motorcycle.svg","fontawesome-solid-mound":"fontawesome/solid/mound.svg","fontawesome-solid-mountain-city":"fontawesome/solid/mountain-city.svg","fontawesome-solid-mountain-sun":"fontawesome/solid/mountain-sun.svg","fontawesome-solid-mountain":"fontawesome/solid/mountain.svg","fontawesome-solid-mug-hot":"fontawesome/solid/mug-hot.svg","fontawesome-solid-mug-saucer":"fontawesome/solid/mug-saucer.svg","fontawesome-solid-music":"fontawesome/solid/music.svg","fontawesome-solid-n":"fontawesome/solid/n.svg","fontawesome-solid-naira-sign":"fontawesome/solid/naira-sign.svg","fontawesome-solid-network-wired":"fontawesome/solid/network-wired.svg","fontawesome-solid-neuter":"fontawesome/solid/neuter.svg","fontawesome-solid-newspaper":"fontawesome/solid/newspaper.svg","fontawesome-solid-not-equal":"fontawesome/solid/not-equal.svg","fontawesome-solid-notdef":"fontawesome/solid/notdef.svg","fontawesome-solid-note-sticky":"fontawesome/solid/note-sticky.svg","fontawesome-solid-notes-medical":"fontawesome/solid/notes-medical.svg","fontawesome-solid-o":"fontawesome/solid/o.svg","fontawesome-solid-object-group":"fontawesome/solid/object-group.svg","fontawesome-solid-object-ungroup":"fontawesome/solid/object-ungroup.svg","fontawesome-solid-oil-can":"fontawesome/solid/oil-can.svg","fontawesome-solid-oil-well":"fontawesome/solid/oil-well.svg","fontawesome-solid-om":"fontawesome/solid/om.svg","fontawesome-solid-otter":"fontawesome/solid/otter.svg","fontawesome-solid-outdent":"fontawesome/solid/outdent.svg","fontawesome-solid-p":"fontawesome/solid/p.svg","fontawesome-solid-pager":"fontawesome/solid/pager.svg","fontawesome-solid-paint-roller":"fontawesome/solid/paint-roller.svg","fontawesome-solid-paintbrush":"fontawesome/solid/paintbrush.svg","fontawesome-solid-palette":"fontawesome/solid/palette.svg","fontawesome-solid-pallet":"fontawesome/solid/pallet.svg","fontawesome-solid-panorama":"fontawesome/solid/panorama.svg","fontawesome-solid-paper-plane":"fontawesome/solid/paper-plane.svg","fontawesome-solid-paperclip":"fontawesome/solid/paperclip.svg","fontawesome-solid-parachute-box":"fontawesome/solid/parachute-box.svg","fontawesome-solid-paragraph":"fontawesome/solid/paragraph.svg","fontawesome-solid-passport":"fontawesome/solid/passport.svg","fontawesome-solid-paste":"fontawesome/solid/paste.svg","fontawesome-solid-pause":"fontawesome/solid/pause.svg","fontawesome-solid-paw":"fontawesome/solid/paw.svg","fontawesome-solid-peace":"fontawesome/solid/peace.svg","fontawesome-solid-pen-clip":"fontawesome/solid/pen-clip.svg","fontawesome-solid-pen-fancy":"fontawesome/solid/pen-fancy.svg","fontawesome-solid-pen-nib":"fontawesome/solid/pen-nib.svg","fontawesome-solid-pen-ruler":"fontawesome/solid/pen-ruler.svg","fontawesome-solid-pen-to-square":"fontawesome/solid/pen-to-square.svg","fontawesome-solid-pen":"fontawesome/solid/pen.svg","fontawesome-solid-pencil":"fontawesome/solid/pencil.svg","fontawesome-solid-people-arrows":"fontawesome/solid/people-arrows.svg","fontawesome-solid-people-carry-box":"fontawesome/solid/people-carry-box.svg","fontawesome-solid-people-group":"fontawesome/solid/people-group.svg","fontawesome-solid-people-line":"fontawesome/solid/people-line.svg","fontawesome-solid-people-pulling":"fontawesome/solid/people-pulling.svg","fontawesome-solid-people-robbery":"fontawesome/solid/people-robbery.svg","fontawesome-solid-people-roof":"fontawesome/solid/people-roof.svg","fontawesome-solid-pepper-hot":"fontawesome/solid/pepper-hot.svg","fontawesome-solid-percent":"fontawesome/solid/percent.svg","fontawesome-solid-person-arrow-down-to-line":"fontawesome/solid/person-arrow-down-to-line.svg","fontawesome-solid-person-arrow-up-from-line":"fontawesome/solid/person-arrow-up-from-line.svg","fontawesome-solid-person-biking":"fontawesome/solid/person-biking.svg","fontawesome-solid-person-booth":"fontawesome/solid/person-booth.svg","fontawesome-solid-person-breastfeeding":"fontawesome/solid/person-breastfeeding.svg","fontawesome-solid-person-burst":"fontawesome/solid/person-burst.svg","fontawesome-solid-person-cane":"fontawesome/solid/person-cane.svg","fontawesome-solid-person-chalkboard":"fontawesome/solid/person-chalkboard.svg","fontawesome-solid-person-circle-check":"fontawesome/solid/person-circle-check.svg","fontawesome-solid-person-circle-exclamation":"fontawesome/solid/person-circle-exclamation.svg","fontawesome-solid-person-circle-minus":"fontawesome/solid/person-circle-minus.svg","fontawesome-solid-person-circle-plus":"fontawesome/solid/person-circle-plus.svg","fontawesome-solid-person-circle-question":"fontawesome/solid/person-circle-question.svg","fontawesome-solid-person-circle-xmark":"fontawesome/solid/person-circle-xmark.svg","fontawesome-solid-person-digging":"fontawesome/solid/person-digging.svg","fontawesome-solid-person-dots-from-line":"fontawesome/solid/person-dots-from-line.svg","fontawesome-solid-person-dress-burst":"fontawesome/solid/person-dress-burst.svg","fontawesome-solid-person-dress":"fontawesome/solid/person-dress.svg","fontawesome-solid-person-drowning":"fontawesome/solid/person-drowning.svg","fontawesome-solid-person-falling-burst":"fontawesome/solid/person-falling-burst.svg","fontawesome-solid-person-falling":"fontawesome/solid/person-falling.svg","fontawesome-solid-person-half-dress":"fontawesome/solid/person-half-dress.svg","fontawesome-solid-person-harassing":"fontawesome/solid/person-harassing.svg","fontawesome-solid-person-hiking":"fontawesome/solid/person-hiking.svg","fontawesome-solid-person-military-pointing":"fontawesome/solid/person-military-pointing.svg","fontawesome-solid-person-military-rifle":"fontawesome/solid/person-military-rifle.svg","fontawesome-solid-person-military-to-person":"fontawesome/solid/person-military-to-person.svg","fontawesome-solid-person-praying":"fontawesome/solid/person-praying.svg","fontawesome-solid-person-pregnant":"fontawesome/solid/person-pregnant.svg","fontawesome-solid-person-rays":"fontawesome/solid/person-rays.svg","fontawesome-solid-person-rifle":"fontawesome/solid/person-rifle.svg","fontawesome-solid-person-running":"fontawesome/solid/person-running.svg","fontawesome-solid-person-shelter":"fontawesome/solid/person-shelter.svg","fontawesome-solid-person-skating":"fontawesome/solid/person-skating.svg","fontawesome-solid-person-skiing-nordic":"fontawesome/solid/person-skiing-nordic.svg","fontawesome-solid-person-skiing":"fontawesome/solid/person-skiing.svg","fontawesome-solid-person-snowboarding":"fontawesome/solid/person-snowboarding.svg","fontawesome-solid-person-swimming":"fontawesome/solid/person-swimming.svg","fontawesome-solid-person-through-window":"fontawesome/solid/person-through-window.svg","fontawesome-solid-person-walking-arrow-loop-left":"fontawesome/solid/person-walking-arrow-loop-left.svg","fontawesome-solid-person-walking-arrow-right":"fontawesome/solid/person-walking-arrow-right.svg","fontawesome-solid-person-walking-dashed-line-arrow-right":"fontawesome/solid/person-walking-dashed-line-arrow-right.svg","fontawesome-solid-person-walking-luggage":"fontawesome/solid/person-walking-luggage.svg","fontawesome-solid-person-walking-with-cane":"fontawesome/solid/person-walking-with-cane.svg","fontawesome-solid-person-walking":"fontawesome/solid/person-walking.svg","fontawesome-solid-person":"fontawesome/solid/person.svg","fontawesome-solid-peseta-sign":"fontawesome/solid/peseta-sign.svg","fontawesome-solid-peso-sign":"fontawesome/solid/peso-sign.svg","fontawesome-solid-phone-flip":"fontawesome/solid/phone-flip.svg","fontawesome-solid-phone-slash":"fontawesome/solid/phone-slash.svg","fontawesome-solid-phone-volume":"fontawesome/solid/phone-volume.svg","fontawesome-solid-phone":"fontawesome/solid/phone.svg","fontawesome-solid-photo-film":"fontawesome/solid/photo-film.svg","fontawesome-solid-piggy-bank":"fontawesome/solid/piggy-bank.svg","fontawesome-solid-pills":"fontawesome/solid/pills.svg","fontawesome-solid-pizza-slice":"fontawesome/solid/pizza-slice.svg","fontawesome-solid-place-of-worship":"fontawesome/solid/place-of-worship.svg","fontawesome-solid-plane-arrival":"fontawesome/solid/plane-arrival.svg","fontawesome-solid-plane-circle-check":"fontawesome/solid/plane-circle-check.svg","fontawesome-solid-plane-circle-exclamation":"fontawesome/solid/plane-circle-exclamation.svg","fontawesome-solid-plane-circle-xmark":"fontawesome/solid/plane-circle-xmark.svg","fontawesome-solid-plane-departure":"fontawesome/solid/plane-departure.svg","fontawesome-solid-plane-lock":"fontawesome/solid/plane-lock.svg","fontawesome-solid-plane-slash":"fontawesome/solid/plane-slash.svg","fontawesome-solid-plane-up":"fontawesome/solid/plane-up.svg","fontawesome-solid-plane":"fontawesome/solid/plane.svg","fontawesome-solid-plant-wilt":"fontawesome/solid/plant-wilt.svg","fontawesome-solid-plate-wheat":"fontawesome/solid/plate-wheat.svg","fontawesome-solid-play":"fontawesome/solid/play.svg","fontawesome-solid-plug-circle-bolt":"fontawesome/solid/plug-circle-bolt.svg","fontawesome-solid-plug-circle-check":"fontawesome/solid/plug-circle-check.svg","fontawesome-solid-plug-circle-exclamation":"fontawesome/solid/plug-circle-exclamation.svg","fontawesome-solid-plug-circle-minus":"fontawesome/solid/plug-circle-minus.svg","fontawesome-solid-plug-circle-plus":"fontawesome/solid/plug-circle-plus.svg","fontawesome-solid-plug-circle-xmark":"fontawesome/solid/plug-circle-xmark.svg","fontawesome-solid-plug":"fontawesome/solid/plug.svg","fontawesome-solid-plus-minus":"fontawesome/solid/plus-minus.svg","fontawesome-solid-plus":"fontawesome/solid/plus.svg","fontawesome-solid-podcast":"fontawesome/solid/podcast.svg","fontawesome-solid-poo-storm":"fontawesome/solid/poo-storm.svg","fontawesome-solid-poo":"fontawesome/solid/poo.svg","fontawesome-solid-poop":"fontawesome/solid/poop.svg","fontawesome-solid-power-off":"fontawesome/solid/power-off.svg","fontawesome-solid-prescription-bottle-medical":"fontawesome/solid/prescription-bottle-medical.svg","fontawesome-solid-prescription-bottle":"fontawesome/solid/prescription-bottle.svg","fontawesome-solid-prescription":"fontawesome/solid/prescription.svg","fontawesome-solid-print":"fontawesome/solid/print.svg","fontawesome-solid-pump-medical":"fontawesome/solid/pump-medical.svg","fontawesome-solid-pump-soap":"fontawesome/solid/pump-soap.svg","fontawesome-solid-puzzle-piece":"fontawesome/solid/puzzle-piece.svg","fontawesome-solid-q":"fontawesome/solid/q.svg","fontawesome-solid-qrcode":"fontawesome/solid/qrcode.svg","fontawesome-solid-question":"fontawesome/solid/question.svg","fontawesome-solid-quote-left":"fontawesome/solid/quote-left.svg","fontawesome-solid-quote-right":"fontawesome/solid/quote-right.svg","fontawesome-solid-r":"fontawesome/solid/r.svg","fontawesome-solid-radiation":"fontawesome/solid/radiation.svg","fontawesome-solid-radio":"fontawesome/solid/radio.svg","fontawesome-solid-rainbow":"fontawesome/solid/rainbow.svg","fontawesome-solid-ranking-star":"fontawesome/solid/ranking-star.svg","fontawesome-solid-receipt":"fontawesome/solid/receipt.svg","fontawesome-solid-record-vinyl":"fontawesome/solid/record-vinyl.svg","fontawesome-solid-rectangle-ad":"fontawesome/solid/rectangle-ad.svg","fontawesome-solid-rectangle-list":"fontawesome/solid/rectangle-list.svg","fontawesome-solid-rectangle-xmark":"fontawesome/solid/rectangle-xmark.svg","fontawesome-solid-recycle":"fontawesome/solid/recycle.svg","fontawesome-solid-registered":"fontawesome/solid/registered.svg","fontawesome-solid-repeat":"fontawesome/solid/repeat.svg","fontawesome-solid-reply-all":"fontawesome/solid/reply-all.svg","fontawesome-solid-reply":"fontawesome/solid/reply.svg","fontawesome-solid-republican":"fontawesome/solid/republican.svg","fontawesome-solid-restroom":"fontawesome/solid/restroom.svg","fontawesome-solid-retweet":"fontawesome/solid/retweet.svg","fontawesome-solid-ribbon":"fontawesome/solid/ribbon.svg","fontawesome-solid-right-from-bracket":"fontawesome/solid/right-from-bracket.svg","fontawesome-solid-right-left":"fontawesome/solid/right-left.svg","fontawesome-solid-right-long":"fontawesome/solid/right-long.svg","fontawesome-solid-right-to-bracket":"fontawesome/solid/right-to-bracket.svg","fontawesome-solid-ring":"fontawesome/solid/ring.svg","fontawesome-solid-road-barrier":"fontawesome/solid/road-barrier.svg","fontawesome-solid-road-bridge":"fontawesome/solid/road-bridge.svg","fontawesome-solid-road-circle-check":"fontawesome/solid/road-circle-check.svg","fontawesome-solid-road-circle-exclamation":"fontawesome/solid/road-circle-exclamation.svg","fontawesome-solid-road-circle-xmark":"fontawesome/solid/road-circle-xmark.svg","fontawesome-solid-road-lock":"fontawesome/solid/road-lock.svg","fontawesome-solid-road-spikes":"fontawesome/solid/road-spikes.svg","fontawesome-solid-road":"fontawesome/solid/road.svg","fontawesome-solid-robot":"fontawesome/solid/robot.svg","fontawesome-solid-rocket":"fontawesome/solid/rocket.svg","fontawesome-solid-rotate-left":"fontawesome/solid/rotate-left.svg","fontawesome-solid-rotate-right":"fontawesome/solid/rotate-right.svg","fontawesome-solid-rotate":"fontawesome/solid/rotate.svg","fontawesome-solid-route":"fontawesome/solid/route.svg","fontawesome-solid-rss":"fontawesome/solid/rss.svg","fontawesome-solid-ruble-sign":"fontawesome/solid/ruble-sign.svg","fontawesome-solid-rug":"fontawesome/solid/rug.svg","fontawesome-solid-ruler-combined":"fontawesome/solid/ruler-combined.svg","fontawesome-solid-ruler-horizontal":"fontawesome/solid/ruler-horizontal.svg","fontawesome-solid-ruler-vertical":"fontawesome/solid/ruler-vertical.svg","fontawesome-solid-ruler":"fontawesome/solid/ruler.svg","fontawesome-solid-rupee-sign":"fontawesome/solid/rupee-sign.svg","fontawesome-solid-rupiah-sign":"fontawesome/solid/rupiah-sign.svg","fontawesome-solid-s":"fontawesome/solid/s.svg","fontawesome-solid-sack-dollar":"fontawesome/solid/sack-dollar.svg","fontawesome-solid-sack-xmark":"fontawesome/solid/sack-xmark.svg","fontawesome-solid-sailboat":"fontawesome/solid/sailboat.svg","fontawesome-solid-satellite-dish":"fontawesome/solid/satellite-dish.svg","fontawesome-solid-satellite":"fontawesome/solid/satellite.svg","fontawesome-solid-scale-balanced":"fontawesome/solid/scale-balanced.svg","fontawesome-solid-scale-unbalanced-flip":"fontawesome/solid/scale-unbalanced-flip.svg","fontawesome-solid-scale-unbalanced":"fontawesome/solid/scale-unbalanced.svg","fontawesome-solid-school-circle-check":"fontawesome/solid/school-circle-check.svg","fontawesome-solid-school-circle-exclamation":"fontawesome/solid/school-circle-exclamation.svg","fontawesome-solid-school-circle-xmark":"fontawesome/solid/school-circle-xmark.svg","fontawesome-solid-school-flag":"fontawesome/solid/school-flag.svg","fontawesome-solid-school-lock":"fontawesome/solid/school-lock.svg","fontawesome-solid-school":"fontawesome/solid/school.svg","fontawesome-solid-scissors":"fontawesome/solid/scissors.svg","fontawesome-solid-screwdriver-wrench":"fontawesome/solid/screwdriver-wrench.svg","fontawesome-solid-screwdriver":"fontawesome/solid/screwdriver.svg","fontawesome-solid-scroll-torah":"fontawesome/solid/scroll-torah.svg","fontawesome-solid-scroll":"fontawesome/solid/scroll.svg","fontawesome-solid-sd-card":"fontawesome/solid/sd-card.svg","fontawesome-solid-section":"fontawesome/solid/section.svg","fontawesome-solid-seedling":"fontawesome/solid/seedling.svg","fontawesome-solid-server":"fontawesome/solid/server.svg","fontawesome-solid-shapes":"fontawesome/solid/shapes.svg","fontawesome-solid-share-from-square":"fontawesome/solid/share-from-square.svg","fontawesome-solid-share-nodes":"fontawesome/solid/share-nodes.svg","fontawesome-solid-share":"fontawesome/solid/share.svg","fontawesome-solid-sheet-plastic":"fontawesome/solid/sheet-plastic.svg","fontawesome-solid-shekel-sign":"fontawesome/solid/shekel-sign.svg","fontawesome-solid-shield-cat":"fontawesome/solid/shield-cat.svg","fontawesome-solid-shield-dog":"fontawesome/solid/shield-dog.svg","fontawesome-solid-shield-halved":"fontawesome/solid/shield-halved.svg","fontawesome-solid-shield-heart":"fontawesome/solid/shield-heart.svg","fontawesome-solid-shield-virus":"fontawesome/solid/shield-virus.svg","fontawesome-solid-shield":"fontawesome/solid/shield.svg","fontawesome-solid-ship":"fontawesome/solid/ship.svg","fontawesome-solid-shirt":"fontawesome/solid/shirt.svg","fontawesome-solid-shoe-prints":"fontawesome/solid/shoe-prints.svg","fontawesome-solid-shop-lock":"fontawesome/solid/shop-lock.svg","fontawesome-solid-shop-slash":"fontawesome/solid/shop-slash.svg","fontawesome-solid-shop":"fontawesome/solid/shop.svg","fontawesome-solid-shower":"fontawesome/solid/shower.svg","fontawesome-solid-shrimp":"fontawesome/solid/shrimp.svg","fontawesome-solid-shuffle":"fontawesome/solid/shuffle.svg","fontawesome-solid-shuttle-space":"fontawesome/solid/shuttle-space.svg","fontawesome-solid-sign-hanging":"fontawesome/solid/sign-hanging.svg","fontawesome-solid-signal":"fontawesome/solid/signal.svg","fontawesome-solid-signature":"fontawesome/solid/signature.svg","fontawesome-solid-signs-post":"fontawesome/solid/signs-post.svg","fontawesome-solid-sim-card":"fontawesome/solid/sim-card.svg","fontawesome-solid-sink":"fontawesome/solid/sink.svg","fontawesome-solid-sitemap":"fontawesome/solid/sitemap.svg","fontawesome-solid-skull-crossbones":"fontawesome/solid/skull-crossbones.svg","fontawesome-solid-skull":"fontawesome/solid/skull.svg","fontawesome-solid-slash":"fontawesome/solid/slash.svg","fontawesome-solid-sleigh":"fontawesome/solid/sleigh.svg","fontawesome-solid-sliders":"fontawesome/solid/sliders.svg","fontawesome-solid-smog":"fontawesome/solid/smog.svg","fontawesome-solid-smoking":"fontawesome/solid/smoking.svg","fontawesome-solid-snowflake":"fontawesome/solid/snowflake.svg","fontawesome-solid-snowman":"fontawesome/solid/snowman.svg","fontawesome-solid-snowplow":"fontawesome/solid/snowplow.svg","fontawesome-solid-soap":"fontawesome/solid/soap.svg","fontawesome-solid-socks":"fontawesome/solid/socks.svg","fontawesome-solid-solar-panel":"fontawesome/solid/solar-panel.svg","fontawesome-solid-sort-down":"fontawesome/solid/sort-down.svg","fontawesome-solid-sort-up":"fontawesome/solid/sort-up.svg","fontawesome-solid-sort":"fontawesome/solid/sort.svg","fontawesome-solid-spa":"fontawesome/solid/spa.svg","fontawesome-solid-spaghetti-monster-flying":"fontawesome/solid/spaghetti-monster-flying.svg","fontawesome-solid-spell-check":"fontawesome/solid/spell-check.svg","fontawesome-solid-spider":"fontawesome/solid/spider.svg","fontawesome-solid-spinner":"fontawesome/solid/spinner.svg","fontawesome-solid-splotch":"fontawesome/solid/splotch.svg","fontawesome-solid-spoon":"fontawesome/solid/spoon.svg","fontawesome-solid-spray-can-sparkles":"fontawesome/solid/spray-can-sparkles.svg","fontawesome-solid-spray-can":"fontawesome/solid/spray-can.svg","fontawesome-solid-square-arrow-up-right":"fontawesome/solid/square-arrow-up-right.svg","fontawesome-solid-square-caret-down":"fontawesome/solid/square-caret-down.svg","fontawesome-solid-square-caret-left":"fontawesome/solid/square-caret-left.svg","fontawesome-solid-square-caret-right":"fontawesome/solid/square-caret-right.svg","fontawesome-solid-square-caret-up":"fontawesome/solid/square-caret-up.svg","fontawesome-solid-square-check":"fontawesome/solid/square-check.svg","fontawesome-solid-square-envelope":"fontawesome/solid/square-envelope.svg","fontawesome-solid-square-full":"fontawesome/solid/square-full.svg","fontawesome-solid-square-h":"fontawesome/solid/square-h.svg","fontawesome-solid-square-minus":"fontawesome/solid/square-minus.svg","fontawesome-solid-square-nfi":"fontawesome/solid/square-nfi.svg","fontawesome-solid-square-parking":"fontawesome/solid/square-parking.svg","fontawesome-solid-square-pen":"fontawesome/solid/square-pen.svg","fontawesome-solid-square-person-confined":"fontawesome/solid/square-person-confined.svg","fontawesome-solid-square-phone-flip":"fontawesome/solid/square-phone-flip.svg","fontawesome-solid-square-phone":"fontawesome/solid/square-phone.svg","fontawesome-solid-square-plus":"fontawesome/solid/square-plus.svg","fontawesome-solid-square-poll-horizontal":"fontawesome/solid/square-poll-horizontal.svg","fontawesome-solid-square-poll-vertical":"fontawesome/solid/square-poll-vertical.svg","fontawesome-solid-square-root-variable":"fontawesome/solid/square-root-variable.svg","fontawesome-solid-square-rss":"fontawesome/solid/square-rss.svg","fontawesome-solid-square-share-nodes":"fontawesome/solid/square-share-nodes.svg","fontawesome-solid-square-up-right":"fontawesome/solid/square-up-right.svg","fontawesome-solid-square-virus":"fontawesome/solid/square-virus.svg","fontawesome-solid-square-xmark":"fontawesome/solid/square-xmark.svg","fontawesome-solid-square":"fontawesome/solid/square.svg","fontawesome-solid-staff-snake":"fontawesome/solid/staff-snake.svg","fontawesome-solid-stairs":"fontawesome/solid/stairs.svg","fontawesome-solid-stamp":"fontawesome/solid/stamp.svg","fontawesome-solid-stapler":"fontawesome/solid/stapler.svg","fontawesome-solid-star-and-crescent":"fontawesome/solid/star-and-crescent.svg","fontawesome-solid-star-half-stroke":"fontawesome/solid/star-half-stroke.svg","fontawesome-solid-star-half":"fontawesome/solid/star-half.svg","fontawesome-solid-star-of-david":"fontawesome/solid/star-of-david.svg","fontawesome-solid-star-of-life":"fontawesome/solid/star-of-life.svg","fontawesome-solid-star":"fontawesome/solid/star.svg","fontawesome-solid-sterling-sign":"fontawesome/solid/sterling-sign.svg","fontawesome-solid-stethoscope":"fontawesome/solid/stethoscope.svg","fontawesome-solid-stop":"fontawesome/solid/stop.svg","fontawesome-solid-stopwatch-20":"fontawesome/solid/stopwatch-20.svg","fontawesome-solid-stopwatch":"fontawesome/solid/stopwatch.svg","fontawesome-solid-store-slash":"fontawesome/solid/store-slash.svg","fontawesome-solid-store":"fontawesome/solid/store.svg","fontawesome-solid-street-view":"fontawesome/solid/street-view.svg","fontawesome-solid-strikethrough":"fontawesome/solid/strikethrough.svg","fontawesome-solid-stroopwafel":"fontawesome/solid/stroopwafel.svg","fontawesome-solid-subscript":"fontawesome/solid/subscript.svg","fontawesome-solid-suitcase-medical":"fontawesome/solid/suitcase-medical.svg","fontawesome-solid-suitcase-rolling":"fontawesome/solid/suitcase-rolling.svg","fontawesome-solid-suitcase":"fontawesome/solid/suitcase.svg","fontawesome-solid-sun-plant-wilt":"fontawesome/solid/sun-plant-wilt.svg","fontawesome-solid-sun":"fontawesome/solid/sun.svg","fontawesome-solid-superscript":"fontawesome/solid/superscript.svg","fontawesome-solid-swatchbook":"fontawesome/solid/swatchbook.svg","fontawesome-solid-synagogue":"fontawesome/solid/synagogue.svg","fontawesome-solid-syringe":"fontawesome/solid/syringe.svg","fontawesome-solid-t":"fontawesome/solid/t.svg","fontawesome-solid-table-cells-large":"fontawesome/solid/table-cells-large.svg","fontawesome-solid-table-cells":"fontawesome/solid/table-cells.svg","fontawesome-solid-table-columns":"fontawesome/solid/table-columns.svg","fontawesome-solid-table-list":"fontawesome/solid/table-list.svg","fontawesome-solid-table-tennis-paddle-ball":"fontawesome/solid/table-tennis-paddle-ball.svg","fontawesome-solid-table":"fontawesome/solid/table.svg","fontawesome-solid-tablet-button":"fontawesome/solid/tablet-button.svg","fontawesome-solid-tablet-screen-button":"fontawesome/solid/tablet-screen-button.svg","fontawesome-solid-tablet":"fontawesome/solid/tablet.svg","fontawesome-solid-tablets":"fontawesome/solid/tablets.svg","fontawesome-solid-tachograph-digital":"fontawesome/solid/tachograph-digital.svg","fontawesome-solid-tag":"fontawesome/solid/tag.svg","fontawesome-solid-tags":"fontawesome/solid/tags.svg","fontawesome-solid-tape":"fontawesome/solid/tape.svg","fontawesome-solid-tarp-droplet":"fontawesome/solid/tarp-droplet.svg","fontawesome-solid-tarp":"fontawesome/solid/tarp.svg","fontawesome-solid-taxi":"fontawesome/solid/taxi.svg","fontawesome-solid-teeth-open":"fontawesome/solid/teeth-open.svg","fontawesome-solid-teeth":"fontawesome/solid/teeth.svg","fontawesome-solid-temperature-arrow-down":"fontawesome/solid/temperature-arrow-down.svg","fontawesome-solid-temperature-arrow-up":"fontawesome/solid/temperature-arrow-up.svg","fontawesome-solid-temperature-empty":"fontawesome/solid/temperature-empty.svg","fontawesome-solid-temperature-full":"fontawesome/solid/temperature-full.svg","fontawesome-solid-temperature-half":"fontawesome/solid/temperature-half.svg","fontawesome-solid-temperature-high":"fontawesome/solid/temperature-high.svg","fontawesome-solid-temperature-low":"fontawesome/solid/temperature-low.svg","fontawesome-solid-temperature-quarter":"fontawesome/solid/temperature-quarter.svg","fontawesome-solid-temperature-three-quarters":"fontawesome/solid/temperature-three-quarters.svg","fontawesome-solid-tenge-sign":"fontawesome/solid/tenge-sign.svg","fontawesome-solid-tent-arrow-down-to-line":"fontawesome/solid/tent-arrow-down-to-line.svg","fontawesome-solid-tent-arrow-left-right":"fontawesome/solid/tent-arrow-left-right.svg","fontawesome-solid-tent-arrow-turn-left":"fontawesome/solid/tent-arrow-turn-left.svg","fontawesome-solid-tent-arrows-down":"fontawesome/solid/tent-arrows-down.svg","fontawesome-solid-tent":"fontawesome/solid/tent.svg","fontawesome-solid-tents":"fontawesome/solid/tents.svg","fontawesome-solid-terminal":"fontawesome/solid/terminal.svg","fontawesome-solid-text-height":"fontawesome/solid/text-height.svg","fontawesome-solid-text-slash":"fontawesome/solid/text-slash.svg","fontawesome-solid-text-width":"fontawesome/solid/text-width.svg","fontawesome-solid-thermometer":"fontawesome/solid/thermometer.svg","fontawesome-solid-thumbs-down":"fontawesome/solid/thumbs-down.svg","fontawesome-solid-thumbs-up":"fontawesome/solid/thumbs-up.svg","fontawesome-solid-thumbtack":"fontawesome/solid/thumbtack.svg","fontawesome-solid-ticket-simple":"fontawesome/solid/ticket-simple.svg","fontawesome-solid-ticket":"fontawesome/solid/ticket.svg","fontawesome-solid-timeline":"fontawesome/solid/timeline.svg","fontawesome-solid-toggle-off":"fontawesome/solid/toggle-off.svg","fontawesome-solid-toggle-on":"fontawesome/solid/toggle-on.svg","fontawesome-solid-toilet-paper-slash":"fontawesome/solid/toilet-paper-slash.svg","fontawesome-solid-toilet-paper":"fontawesome/solid/toilet-paper.svg","fontawesome-solid-toilet-portable":"fontawesome/solid/toilet-portable.svg","fontawesome-solid-toilet":"fontawesome/solid/toilet.svg","fontawesome-solid-toilets-portable":"fontawesome/solid/toilets-portable.svg","fontawesome-solid-toolbox":"fontawesome/solid/toolbox.svg","fontawesome-solid-tooth":"fontawesome/solid/tooth.svg","fontawesome-solid-torii-gate":"fontawesome/solid/torii-gate.svg","fontawesome-solid-tornado":"fontawesome/solid/tornado.svg","fontawesome-solid-tower-broadcast":"fontawesome/solid/tower-broadcast.svg","fontawesome-solid-tower-cell":"fontawesome/solid/tower-cell.svg","fontawesome-solid-tower-observation":"fontawesome/solid/tower-observation.svg","fontawesome-solid-tractor":"fontawesome/solid/tractor.svg","fontawesome-solid-trademark":"fontawesome/solid/trademark.svg","fontawesome-solid-traffic-light":"fontawesome/solid/traffic-light.svg","fontawesome-solid-trailer":"fontawesome/solid/trailer.svg","fontawesome-solid-train-subway":"fontawesome/solid/train-subway.svg","fontawesome-solid-train-tram":"fontawesome/solid/train-tram.svg","fontawesome-solid-train":"fontawesome/solid/train.svg","fontawesome-solid-transgender":"fontawesome/solid/transgender.svg","fontawesome-solid-trash-arrow-up":"fontawesome/solid/trash-arrow-up.svg","fontawesome-solid-trash-can-arrow-up":"fontawesome/solid/trash-can-arrow-up.svg","fontawesome-solid-trash-can":"fontawesome/solid/trash-can.svg","fontawesome-solid-trash":"fontawesome/solid/trash.svg","fontawesome-solid-tree-city":"fontawesome/solid/tree-city.svg","fontawesome-solid-tree":"fontawesome/solid/tree.svg","fontawesome-solid-triangle-exclamation":"fontawesome/solid/triangle-exclamation.svg","fontawesome-solid-trophy":"fontawesome/solid/trophy.svg","fontawesome-solid-trowel-bricks":"fontawesome/solid/trowel-bricks.svg","fontawesome-solid-trowel":"fontawesome/solid/trowel.svg","fontawesome-solid-truck-arrow-right":"fontawesome/solid/truck-arrow-right.svg","fontawesome-solid-truck-droplet":"fontawesome/solid/truck-droplet.svg","fontawesome-solid-truck-fast":"fontawesome/solid/truck-fast.svg","fontawesome-solid-truck-field-un":"fontawesome/solid/truck-field-un.svg","fontawesome-solid-truck-field":"fontawesome/solid/truck-field.svg","fontawesome-solid-truck-front":"fontawesome/solid/truck-front.svg","fontawesome-solid-truck-medical":"fontawesome/solid/truck-medical.svg","fontawesome-solid-truck-monster":"fontawesome/solid/truck-monster.svg","fontawesome-solid-truck-moving":"fontawesome/solid/truck-moving.svg","fontawesome-solid-truck-pickup":"fontawesome/solid/truck-pickup.svg","fontawesome-solid-truck-plane":"fontawesome/solid/truck-plane.svg","fontawesome-solid-truck-ramp-box":"fontawesome/solid/truck-ramp-box.svg","fontawesome-solid-truck":"fontawesome/solid/truck.svg","fontawesome-solid-tty":"fontawesome/solid/tty.svg","fontawesome-solid-turkish-lira-sign":"fontawesome/solid/turkish-lira-sign.svg","fontawesome-solid-turn-down":"fontawesome/solid/turn-down.svg","fontawesome-solid-turn-up":"fontawesome/solid/turn-up.svg","fontawesome-solid-tv":"fontawesome/solid/tv.svg","fontawesome-solid-u":"fontawesome/solid/u.svg","fontawesome-solid-umbrella-beach":"fontawesome/solid/umbrella-beach.svg","fontawesome-solid-umbrella":"fontawesome/solid/umbrella.svg","fontawesome-solid-underline":"fontawesome/solid/underline.svg","fontawesome-solid-universal-access":"fontawesome/solid/universal-access.svg","fontawesome-solid-unlock-keyhole":"fontawesome/solid/unlock-keyhole.svg","fontawesome-solid-unlock":"fontawesome/solid/unlock.svg","fontawesome-solid-up-down-left-right":"fontawesome/solid/up-down-left-right.svg","fontawesome-solid-up-down":"fontawesome/solid/up-down.svg","fontawesome-solid-up-long":"fontawesome/solid/up-long.svg","fontawesome-solid-up-right-and-down-left-from-center":"fontawesome/solid/up-right-and-down-left-from-center.svg","fontawesome-solid-up-right-from-square":"fontawesome/solid/up-right-from-square.svg","fontawesome-solid-upload":"fontawesome/solid/upload.svg","fontawesome-solid-user-astronaut":"fontawesome/solid/user-astronaut.svg","fontawesome-solid-user-check":"fontawesome/solid/user-check.svg","fontawesome-solid-user-clock":"fontawesome/solid/user-clock.svg","fontawesome-solid-user-doctor":"fontawesome/solid/user-doctor.svg","fontawesome-solid-user-gear":"fontawesome/solid/user-gear.svg","fontawesome-solid-user-graduate":"fontawesome/solid/user-graduate.svg","fontawesome-solid-user-group":"fontawesome/solid/user-group.svg","fontawesome-solid-user-injured":"fontawesome/solid/user-injured.svg","fontawesome-solid-user-large-slash":"fontawesome/solid/user-large-slash.svg","fontawesome-solid-user-large":"fontawesome/solid/user-large.svg","fontawesome-solid-user-lock":"fontawesome/solid/user-lock.svg","fontawesome-solid-user-minus":"fontawesome/solid/user-minus.svg","fontawesome-solid-user-ninja":"fontawesome/solid/user-ninja.svg","fontawesome-solid-user-nurse":"fontawesome/solid/user-nurse.svg","fontawesome-solid-user-pen":"fontawesome/solid/user-pen.svg","fontawesome-solid-user-plus":"fontawesome/solid/user-plus.svg","fontawesome-solid-user-secret":"fontawesome/solid/user-secret.svg","fontawesome-solid-user-shield":"fontawesome/solid/user-shield.svg","fontawesome-solid-user-slash":"fontawesome/solid/user-slash.svg","fontawesome-solid-user-tag":"fontawesome/solid/user-tag.svg","fontawesome-solid-user-tie":"fontawesome/solid/user-tie.svg","fontawesome-solid-user-xmark":"fontawesome/solid/user-xmark.svg","fontawesome-solid-user":"fontawesome/solid/user.svg","fontawesome-solid-users-between-lines":"fontawesome/solid/users-between-lines.svg","fontawesome-solid-users-gear":"fontawesome/solid/users-gear.svg","fontawesome-solid-users-line":"fontawesome/solid/users-line.svg","fontawesome-solid-users-rays":"fontawesome/solid/users-rays.svg","fontawesome-solid-users-rectangle":"fontawesome/solid/users-rectangle.svg","fontawesome-solid-users-slash":"fontawesome/solid/users-slash.svg","fontawesome-solid-users-viewfinder":"fontawesome/solid/users-viewfinder.svg","fontawesome-solid-users":"fontawesome/solid/users.svg","fontawesome-solid-utensils":"fontawesome/solid/utensils.svg","fontawesome-solid-v":"fontawesome/solid/v.svg","fontawesome-solid-van-shuttle":"fontawesome/solid/van-shuttle.svg","fontawesome-solid-vault":"fontawesome/solid/vault.svg","fontawesome-solid-vector-square":"fontawesome/solid/vector-square.svg","fontawesome-solid-venus-double":"fontawesome/solid/venus-double.svg","fontawesome-solid-venus-mars":"fontawesome/solid/venus-mars.svg","fontawesome-solid-venus":"fontawesome/solid/venus.svg","fontawesome-solid-vest-patches":"fontawesome/solid/vest-patches.svg","fontawesome-solid-vest":"fontawesome/solid/vest.svg","fontawesome-solid-vial-circle-check":"fontawesome/solid/vial-circle-check.svg","fontawesome-solid-vial-virus":"fontawesome/solid/vial-virus.svg","fontawesome-solid-vial":"fontawesome/solid/vial.svg","fontawesome-solid-vials":"fontawesome/solid/vials.svg","fontawesome-solid-video-slash":"fontawesome/solid/video-slash.svg","fontawesome-solid-video":"fontawesome/solid/video.svg","fontawesome-solid-vihara":"fontawesome/solid/vihara.svg","fontawesome-solid-virus-covid-slash":"fontawesome/solid/virus-covid-slash.svg","fontawesome-solid-virus-covid":"fontawesome/solid/virus-covid.svg","fontawesome-solid-virus-slash":"fontawesome/solid/virus-slash.svg","fontawesome-solid-virus":"fontawesome/solid/virus.svg","fontawesome-solid-viruses":"fontawesome/solid/viruses.svg","fontawesome-solid-voicemail":"fontawesome/solid/voicemail.svg","fontawesome-solid-volcano":"fontawesome/solid/volcano.svg","fontawesome-solid-volleyball":"fontawesome/solid/volleyball.svg","fontawesome-solid-volume-high":"fontawesome/solid/volume-high.svg","fontawesome-solid-volume-low":"fontawesome/solid/volume-low.svg","fontawesome-solid-volume-off":"fontawesome/solid/volume-off.svg","fontawesome-solid-volume-xmark":"fontawesome/solid/volume-xmark.svg","fontawesome-solid-vr-cardboard":"fontawesome/solid/vr-cardboard.svg","fontawesome-solid-w":"fontawesome/solid/w.svg","fontawesome-solid-walkie-talkie":"fontawesome/solid/walkie-talkie.svg","fontawesome-solid-wallet":"fontawesome/solid/wallet.svg","fontawesome-solid-wand-magic-sparkles":"fontawesome/solid/wand-magic-sparkles.svg","fontawesome-solid-wand-magic":"fontawesome/solid/wand-magic.svg","fontawesome-solid-wand-sparkles":"fontawesome/solid/wand-sparkles.svg","fontawesome-solid-registry":"fontawesome/solid/registry.svg","fontawesome-solid-water-ladder":"fontawesome/solid/water-ladder.svg","fontawesome-solid-water":"fontawesome/solid/water.svg","fontawesome-solid-wave-square":"fontawesome/solid/wave-square.svg","fontawesome-solid-weight-hanging":"fontawesome/solid/weight-hanging.svg","fontawesome-solid-weight-scale":"fontawesome/solid/weight-scale.svg","fontawesome-solid-wheat-awn-circle-exclamation":"fontawesome/solid/wheat-awn-circle-exclamation.svg","fontawesome-solid-wheat-awn":"fontawesome/solid/wheat-awn.svg","fontawesome-solid-wheelchair-move":"fontawesome/solid/wheelchair-move.svg","fontawesome-solid-wheelchair":"fontawesome/solid/wheelchair.svg","fontawesome-solid-whiskey-glass":"fontawesome/solid/whiskey-glass.svg","fontawesome-solid-wifi":"fontawesome/solid/wifi.svg","fontawesome-solid-wind":"fontawesome/solid/wind.svg","fontawesome-solid-window-maximize":"fontawesome/solid/window-maximize.svg","fontawesome-solid-window-minimize":"fontawesome/solid/window-minimize.svg","fontawesome-solid-window-restore":"fontawesome/solid/window-restore.svg","fontawesome-solid-wine-bottle":"fontawesome/solid/wine-bottle.svg","fontawesome-solid-wine-glass-empty":"fontawesome/solid/wine-glass-empty.svg","fontawesome-solid-wine-glass":"fontawesome/solid/wine-glass.svg","fontawesome-solid-won-sign":"fontawesome/solid/won-sign.svg","fontawesome-solid-worm":"fontawesome/solid/worm.svg","fontawesome-solid-wrench":"fontawesome/solid/wrench.svg","fontawesome-solid-x-ray":"fontawesome/solid/x-ray.svg","fontawesome-solid-x":"fontawesome/solid/x.svg","fontawesome-solid-xmark":"fontawesome/solid/xmark.svg","fontawesome-solid-xmarks-lines":"fontawesome/solid/xmarks-lines.svg","fontawesome-solid-y":"fontawesome/solid/y.svg","fontawesome-solid-yen-sign":"fontawesome/solid/yen-sign.svg","fontawesome-solid-yin-yang":"fontawesome/solid/yin-yang.svg","fontawesome-solid-z":"fontawesome/solid/z.svg","logo":"logo.svg","material-ab-testing":"material/ab-testing.svg","material-abacus":"material/abacus.svg","material-abjad-arabic":"material/abjad-arabic.svg","material-abjad-hebrew":"material/abjad-hebrew.svg","material-abugida-devanagari":"material/abugida-devanagari.svg","material-abugida-thai":"material/abugida-thai.svg","material-access-point-check":"material/access-point-check.svg","material-access-point-minus":"material/access-point-minus.svg","material-access-point-network-off":"material/access-point-network-off.svg","material-access-point-network":"material/access-point-network.svg","material-access-point-off":"material/access-point-off.svg","material-access-point-plus":"material/access-point-plus.svg","material-access-point-remove":"material/access-point-remove.svg","material-access-point":"material/access-point.svg","material-account-alert-outline":"material/account-alert-outline.svg","material-account-alert":"material/account-alert.svg","material-account-arrow-down-outline":"material/account-arrow-down-outline.svg","material-account-arrow-down":"material/account-arrow-down.svg","material-account-arrow-left-outline":"material/account-arrow-left-outline.svg","material-account-arrow-left":"material/account-arrow-left.svg","material-account-arrow-right-outline":"material/account-arrow-right-outline.svg","material-account-arrow-right":"material/account-arrow-right.svg","material-account-arrow-up-outline":"material/account-arrow-up-outline.svg","material-account-arrow-up":"material/account-arrow-up.svg","material-account-badge-outline":"material/account-badge-outline.svg","material-account-badge":"material/account-badge.svg","material-account-box-multiple-outline":"material/account-box-multiple-outline.svg","material-account-box-multiple":"material/account-box-multiple.svg","material-account-box-outline":"material/account-box-outline.svg","material-account-box":"material/account-box.svg","material-account-cancel-outline":"material/account-cancel-outline.svg","material-account-cancel":"material/account-cancel.svg","material-account-card-outline":"material/account-card-outline.svg","material-account-card":"material/account-card.svg","material-account-cash-outline":"material/account-cash-outline.svg","material-account-cash":"material/account-cash.svg","material-account-check-outline":"material/account-check-outline.svg","material-account-check":"material/account-check.svg","material-account-child-circle":"material/account-child-circle.svg","material-account-child-outline":"material/account-child-outline.svg","material-account-child":"material/account-child.svg","material-account-circle-outline":"material/account-circle-outline.svg","material-account-circle":"material/account-circle.svg","material-account-clock-outline":"material/account-clock-outline.svg","material-account-clock":"material/account-clock.svg","material-account-cog-outline":"material/account-cog-outline.svg","material-account-cog":"material/account-cog.svg","material-account-convert-outline":"material/account-convert-outline.svg","material-account-convert":"material/account-convert.svg","material-account-cowboy-hat-outline":"material/account-cowboy-hat-outline.svg","material-account-cowboy-hat":"material/account-cowboy-hat.svg","material-account-credit-card-outline":"material/account-credit-card-outline.svg","material-account-credit-card":"material/account-credit-card.svg","material-account-details-outline":"material/account-details-outline.svg","material-account-details":"material/account-details.svg","material-account-edit-outline":"material/account-edit-outline.svg","material-account-edit":"material/account-edit.svg","material-account-eye-outline":"material/account-eye-outline.svg","material-account-eye":"material/account-eye.svg","material-account-filter-outline":"material/account-filter-outline.svg","material-account-filter":"material/account-filter.svg","material-account-group-outline":"material/account-group-outline.svg","material-account-group":"material/account-group.svg","material-account-hard-hat-outline":"material/account-hard-hat-outline.svg","material-account-hard-hat":"material/account-hard-hat.svg","material-account-heart-outline":"material/account-heart-outline.svg","material-account-heart":"material/account-heart.svg","material-account-injury-outline":"material/account-injury-outline.svg","material-account-injury":"material/account-injury.svg","material-account-key-outline":"material/account-key-outline.svg","material-account-key":"material/account-key.svg","material-account-lock-open-outline":"material/account-lock-open-outline.svg","material-account-lock-open":"material/account-lock-open.svg","material-account-lock-outline":"material/account-lock-outline.svg","material-account-lock":"material/account-lock.svg","material-account-minus-outline":"material/account-minus-outline.svg","material-account-minus":"material/account-minus.svg","material-account-multiple-check-outline":"material/account-multiple-check-outline.svg","material-account-multiple-check":"material/account-multiple-check.svg","material-account-multiple-minus-outline":"material/account-multiple-minus-outline.svg","material-account-multiple-minus":"material/account-multiple-minus.svg","material-account-multiple-outline":"material/account-multiple-outline.svg","material-account-multiple-plus-outline":"material/account-multiple-plus-outline.svg","material-account-multiple-plus":"material/account-multiple-plus.svg","material-account-multiple-remove-outline":"material/account-multiple-remove-outline.svg","material-account-multiple-remove":"material/account-multiple-remove.svg","material-account-multiple":"material/account-multiple.svg","material-account-music-outline":"material/account-music-outline.svg","material-account-music":"material/account-music.svg","material-account-network-off-outline":"material/account-network-off-outline.svg","material-account-network-off":"material/account-network-off.svg","material-account-network-outline":"material/account-network-outline.svg","material-account-network":"material/account-network.svg","material-account-off-outline":"material/account-off-outline.svg","material-account-off":"material/account-off.svg","material-account-outline":"material/account-outline.svg","material-account-plus-outline":"material/account-plus-outline.svg","material-account-plus":"material/account-plus.svg","material-account-question-outline":"material/account-question-outline.svg","material-account-question":"material/account-question.svg","material-account-reactivate-outline":"material/account-reactivate-outline.svg","material-account-reactivate":"material/account-reactivate.svg","material-account-remove-outline":"material/account-remove-outline.svg","material-account-remove":"material/account-remove.svg","material-account-school-outline":"material/account-school-outline.svg","material-account-school":"material/account-school.svg","material-account-search-outline":"material/account-search-outline.svg","material-account-search":"material/account-search.svg","material-account-settings-outline":"material/account-settings-outline.svg","material-account-settings":"material/account-settings.svg","material-account-star-outline":"material/account-star-outline.svg","material-account-star":"material/account-star.svg","material-account-supervisor-circle-outline":"material/account-supervisor-circle-outline.svg","material-account-supervisor-circle":"material/account-supervisor-circle.svg","material-account-supervisor-outline":"material/account-supervisor-outline.svg","material-account-supervisor":"material/account-supervisor.svg","material-account-switch-outline":"material/account-switch-outline.svg","material-account-switch":"material/account-switch.svg","material-account-sync-outline":"material/account-sync-outline.svg","material-account-sync":"material/account-sync.svg","material-account-tie-hat-outline":"material/account-tie-hat-outline.svg","material-account-tie-hat":"material/account-tie-hat.svg","material-account-tie-outline":"material/account-tie-outline.svg","material-account-tie-voice-off-outline":"material/account-tie-voice-off-outline.svg","material-account-tie-voice-off":"material/account-tie-voice-off.svg","material-account-tie-voice-outline":"material/account-tie-voice-outline.svg","material-account-tie-voice":"material/account-tie-voice.svg","material-account-tie-woman":"material/account-tie-woman.svg","material-account-tie":"material/account-tie.svg","material-account-voice-off":"material/account-voice-off.svg","material-account-voice":"material/account-voice.svg","material-account-wrench-outline":"material/account-wrench-outline.svg","material-account-wrench":"material/account-wrench.svg","material-account":"material/account.svg","material-adjust":"material/adjust.svg","material-advertisements-off":"material/advertisements-off.svg","material-advertisements":"material/advertisements.svg","material-air-conditioner":"material/air-conditioner.svg","material-air-filter":"material/air-filter.svg","material-air-horn":"material/air-horn.svg","material-air-humidifier-off":"material/air-humidifier-off.svg","material-air-humidifier":"material/air-humidifier.svg","material-air-purifier-off":"material/air-purifier-off.svg","material-air-purifier":"material/air-purifier.svg","material-airbag":"material/airbag.svg","material-airballoon-outline":"material/airballoon-outline.svg","material-airballoon":"material/airballoon.svg","material-airplane-alert":"material/airplane-alert.svg","material-airplane-check":"material/airplane-check.svg","material-airplane-clock":"material/airplane-clock.svg","material-airplane-cog":"material/airplane-cog.svg","material-airplane-edit":"material/airplane-edit.svg","material-airplane-landing":"material/airplane-landing.svg","material-airplane-marker":"material/airplane-marker.svg","material-airplane-minus":"material/airplane-minus.svg","material-airplane-off":"material/airplane-off.svg","material-airplane-plus":"material/airplane-plus.svg","material-airplane-remove":"material/airplane-remove.svg","material-airplane-search":"material/airplane-search.svg","material-airplane-settings":"material/airplane-settings.svg","material-airplane-takeoff":"material/airplane-takeoff.svg","material-airplane":"material/airplane.svg","material-airport":"material/airport.svg","material-alarm-bell":"material/alarm-bell.svg","material-alarm-check":"material/alarm-check.svg","material-alarm-light-off-outline":"material/alarm-light-off-outline.svg","material-alarm-light-off":"material/alarm-light-off.svg","material-alarm-light-outline":"material/alarm-light-outline.svg","material-alarm-light":"material/alarm-light.svg","material-alarm-multiple":"material/alarm-multiple.svg","material-alarm-note-off":"material/alarm-note-off.svg","material-alarm-note":"material/alarm-note.svg","material-alarm-off":"material/alarm-off.svg","material-alarm-panel-outline":"material/alarm-panel-outline.svg","material-alarm-panel":"material/alarm-panel.svg","material-alarm-plus":"material/alarm-plus.svg","material-alarm-snooze":"material/alarm-snooze.svg","material-alarm":"material/alarm.svg","material-album":"material/album.svg","material-alert-box-outline":"material/alert-box-outline.svg","material-alert-box":"material/alert-box.svg","material-alert-circle-check-outline":"material/alert-circle-check-outline.svg","material-alert-circle-check":"material/alert-circle-check.svg","material-alert-circle-outline":"material/alert-circle-outline.svg","material-alert-circle":"material/alert-circle.svg","material-alert-decagram-outline":"material/alert-decagram-outline.svg","material-alert-decagram":"material/alert-decagram.svg","material-alert-minus-outline":"material/alert-minus-outline.svg","material-alert-minus":"material/alert-minus.svg","material-alert-octagon-outline":"material/alert-octagon-outline.svg","material-alert-octagon":"material/alert-octagon.svg","material-alert-octagram-outline":"material/alert-octagram-outline.svg","material-alert-octagram":"material/alert-octagram.svg","material-alert-outline":"material/alert-outline.svg","material-alert-plus-outline":"material/alert-plus-outline.svg","material-alert-plus":"material/alert-plus.svg","material-alert-remove-outline":"material/alert-remove-outline.svg","material-alert-remove":"material/alert-remove.svg","material-alert-rhombus-outline":"material/alert-rhombus-outline.svg","material-alert-rhombus":"material/alert-rhombus.svg","material-alert":"material/alert.svg","material-alien-outline":"material/alien-outline.svg","material-alien":"material/alien.svg","material-align-horizontal-center":"material/align-horizontal-center.svg","material-align-horizontal-distribute":"material/align-horizontal-distribute.svg","material-align-horizontal-left":"material/align-horizontal-left.svg","material-align-horizontal-right":"material/align-horizontal-right.svg","material-align-vertical-bottom":"material/align-vertical-bottom.svg","material-align-vertical-center":"material/align-vertical-center.svg","material-align-vertical-distribute":"material/align-vertical-distribute.svg","material-align-vertical-top":"material/align-vertical-top.svg","material-all-inclusive-box-outline":"material/all-inclusive-box-outline.svg","material-all-inclusive-box":"material/all-inclusive-box.svg","material-all-inclusive":"material/all-inclusive.svg","material-allergy":"material/allergy.svg","material-alpha-a-box-outline":"material/alpha-a-box-outline.svg","material-alpha-a-box":"material/alpha-a-box.svg","material-alpha-a-circle-outline":"material/alpha-a-circle-outline.svg","material-alpha-a-circle":"material/alpha-a-circle.svg","material-alpha-a":"material/alpha-a.svg","material-alpha-b-box-outline":"material/alpha-b-box-outline.svg","material-alpha-b-box":"material/alpha-b-box.svg","material-alpha-b-circle-outline":"material/alpha-b-circle-outline.svg","material-alpha-b-circle":"material/alpha-b-circle.svg","material-alpha-b":"material/alpha-b.svg","material-alpha-c-box-outline":"material/alpha-c-box-outline.svg","material-alpha-c-box":"material/alpha-c-box.svg","material-alpha-c-circle-outline":"material/alpha-c-circle-outline.svg","material-alpha-c-circle":"material/alpha-c-circle.svg","material-alpha-c":"material/alpha-c.svg","material-alpha-d-box-outline":"material/alpha-d-box-outline.svg","material-alpha-d-box":"material/alpha-d-box.svg","material-alpha-d-circle-outline":"material/alpha-d-circle-outline.svg","material-alpha-d-circle":"material/alpha-d-circle.svg","material-alpha-d":"material/alpha-d.svg","material-alpha-e-box-outline":"material/alpha-e-box-outline.svg","material-alpha-e-box":"material/alpha-e-box.svg","material-alpha-e-circle-outline":"material/alpha-e-circle-outline.svg","material-alpha-e-circle":"material/alpha-e-circle.svg","material-alpha-e":"material/alpha-e.svg","material-alpha-f-box-outline":"material/alpha-f-box-outline.svg","material-alpha-f-box":"material/alpha-f-box.svg","material-alpha-f-circle-outline":"material/alpha-f-circle-outline.svg","material-alpha-f-circle":"material/alpha-f-circle.svg","material-alpha-f":"material/alpha-f.svg","material-alpha-g-box-outline":"material/alpha-g-box-outline.svg","material-alpha-g-box":"material/alpha-g-box.svg","material-alpha-g-circle-outline":"material/alpha-g-circle-outline.svg","material-alpha-g-circle":"material/alpha-g-circle.svg","material-alpha-g":"material/alpha-g.svg","material-alpha-h-box-outline":"material/alpha-h-box-outline.svg","material-alpha-h-box":"material/alpha-h-box.svg","material-alpha-h-circle-outline":"material/alpha-h-circle-outline.svg","material-alpha-h-circle":"material/alpha-h-circle.svg","material-alpha-h":"material/alpha-h.svg","material-alpha-i-box-outline":"material/alpha-i-box-outline.svg","material-alpha-i-box":"material/alpha-i-box.svg","material-alpha-i-circle-outline":"material/alpha-i-circle-outline.svg","material-alpha-i-circle":"material/alpha-i-circle.svg","material-alpha-i":"material/alpha-i.svg","material-alpha-j-box-outline":"material/alpha-j-box-outline.svg","material-alpha-j-box":"material/alpha-j-box.svg","material-alpha-j-circle-outline":"material/alpha-j-circle-outline.svg","material-alpha-j-circle":"material/alpha-j-circle.svg","material-alpha-j":"material/alpha-j.svg","material-alpha-k-box-outline":"material/alpha-k-box-outline.svg","material-alpha-k-box":"material/alpha-k-box.svg","material-alpha-k-circle-outline":"material/alpha-k-circle-outline.svg","material-alpha-k-circle":"material/alpha-k-circle.svg","material-alpha-k":"material/alpha-k.svg","material-alpha-l-box-outline":"material/alpha-l-box-outline.svg","material-alpha-l-box":"material/alpha-l-box.svg","material-alpha-l-circle-outline":"material/alpha-l-circle-outline.svg","material-alpha-l-circle":"material/alpha-l-circle.svg","material-alpha-l":"material/alpha-l.svg","material-alpha-m-box-outline":"material/alpha-m-box-outline.svg","material-alpha-m-box":"material/alpha-m-box.svg","material-alpha-m-circle-outline":"material/alpha-m-circle-outline.svg","material-alpha-m-circle":"material/alpha-m-circle.svg","material-alpha-m":"material/alpha-m.svg","material-alpha-n-box-outline":"material/alpha-n-box-outline.svg","material-alpha-n-box":"material/alpha-n-box.svg","material-alpha-n-circle-outline":"material/alpha-n-circle-outline.svg","material-alpha-n-circle":"material/alpha-n-circle.svg","material-alpha-n":"material/alpha-n.svg","material-alpha-o-box-outline":"material/alpha-o-box-outline.svg","material-alpha-o-box":"material/alpha-o-box.svg","material-alpha-o-circle-outline":"material/alpha-o-circle-outline.svg","material-alpha-o-circle":"material/alpha-o-circle.svg","material-alpha-o":"material/alpha-o.svg","material-alpha-p-box-outline":"material/alpha-p-box-outline.svg","material-alpha-p-box":"material/alpha-p-box.svg","material-alpha-p-circle-outline":"material/alpha-p-circle-outline.svg","material-alpha-p-circle":"material/alpha-p-circle.svg","material-alpha-p":"material/alpha-p.svg","material-alpha-q-box-outline":"material/alpha-q-box-outline.svg","material-alpha-q-box":"material/alpha-q-box.svg","material-alpha-q-circle-outline":"material/alpha-q-circle-outline.svg","material-alpha-q-circle":"material/alpha-q-circle.svg","material-alpha-q":"material/alpha-q.svg","material-alpha-r-box-outline":"material/alpha-r-box-outline.svg","material-alpha-r-box":"material/alpha-r-box.svg","material-alpha-r-circle-outline":"material/alpha-r-circle-outline.svg","material-alpha-r-circle":"material/alpha-r-circle.svg","material-alpha-r":"material/alpha-r.svg","material-alpha-s-box-outline":"material/alpha-s-box-outline.svg","material-alpha-s-box":"material/alpha-s-box.svg","material-alpha-s-circle-outline":"material/alpha-s-circle-outline.svg","material-alpha-s-circle":"material/alpha-s-circle.svg","material-alpha-s":"material/alpha-s.svg","material-alpha-t-box-outline":"material/alpha-t-box-outline.svg","material-alpha-t-box":"material/alpha-t-box.svg","material-alpha-t-circle-outline":"material/alpha-t-circle-outline.svg","material-alpha-t-circle":"material/alpha-t-circle.svg","material-alpha-t":"material/alpha-t.svg","material-alpha-u-box-outline":"material/alpha-u-box-outline.svg","material-alpha-u-box":"material/alpha-u-box.svg","material-alpha-u-circle-outline":"material/alpha-u-circle-outline.svg","material-alpha-u-circle":"material/alpha-u-circle.svg","material-alpha-u":"material/alpha-u.svg","material-alpha-v-box-outline":"material/alpha-v-box-outline.svg","material-alpha-v-box":"material/alpha-v-box.svg","material-alpha-v-circle-outline":"material/alpha-v-circle-outline.svg","material-alpha-v-circle":"material/alpha-v-circle.svg","material-alpha-v":"material/alpha-v.svg","material-alpha-w-box-outline":"material/alpha-w-box-outline.svg","material-alpha-w-box":"material/alpha-w-box.svg","material-alpha-w-circle-outline":"material/alpha-w-circle-outline.svg","material-alpha-w-circle":"material/alpha-w-circle.svg","material-alpha-w":"material/alpha-w.svg","material-alpha-x-box-outline":"material/alpha-x-box-outline.svg","material-alpha-x-box":"material/alpha-x-box.svg","material-alpha-x-circle-outline":"material/alpha-x-circle-outline.svg","material-alpha-x-circle":"material/alpha-x-circle.svg","material-alpha-x":"material/alpha-x.svg","material-alpha-y-box-outline":"material/alpha-y-box-outline.svg","material-alpha-y-box":"material/alpha-y-box.svg","material-alpha-y-circle-outline":"material/alpha-y-circle-outline.svg","material-alpha-y-circle":"material/alpha-y-circle.svg","material-alpha-y":"material/alpha-y.svg","material-alpha-z-box-outline":"material/alpha-z-box-outline.svg","material-alpha-z-box":"material/alpha-z-box.svg","material-alpha-z-circle-outline":"material/alpha-z-circle-outline.svg","material-alpha-z-circle":"material/alpha-z-circle.svg","material-alpha-z":"material/alpha-z.svg","material-alpha":"material/alpha.svg","material-alphabet-aurebesh":"material/alphabet-aurebesh.svg","material-alphabet-cyrillic":"material/alphabet-cyrillic.svg","material-alphabet-greek":"material/alphabet-greek.svg","material-alphabet-latin":"material/alphabet-latin.svg","material-alphabet-piqad":"material/alphabet-piqad.svg","material-alphabet-tengwar":"material/alphabet-tengwar.svg","material-alphabetical-off":"material/alphabetical-off.svg","material-alphabetical-variant-off":"material/alphabetical-variant-off.svg","material-alphabetical-variant":"material/alphabetical-variant.svg","material-alphabetical":"material/alphabetical.svg","material-altimeter":"material/altimeter.svg","material-ambulance":"material/ambulance.svg","material-ammunition":"material/ammunition.svg","material-ampersand":"material/ampersand.svg","material-amplifier-off":"material/amplifier-off.svg","material-amplifier":"material/amplifier.svg","material-anchor":"material/anchor.svg","material-android-studio":"material/android-studio.svg","material-android":"material/android.svg","material-angle-acute":"material/angle-acute.svg","material-angle-obtuse":"material/angle-obtuse.svg","material-angle-right":"material/angle-right.svg","material-angular":"material/angular.svg","material-angularjs":"material/angularjs.svg","material-animation-outline":"material/animation-outline.svg","material-animation-play-outline":"material/animation-play-outline.svg","material-animation-play":"material/animation-play.svg","material-animation":"material/animation.svg","material-ansible":"material/ansible.svg","material-antenna":"material/antenna.svg","material-anvil":"material/anvil.svg","material-apache-kafka":"material/apache-kafka.svg","material-api-off":"material/api-off.svg","material-api":"material/api.svg","material-apple-finder":"material/apple-finder.svg","material-apple-icloud":"material/apple-icloud.svg","material-apple-ios":"material/apple-ios.svg","material-apple-keyboard-caps":"material/apple-keyboard-caps.svg","material-apple-keyboard-command":"material/apple-keyboard-command.svg","material-apple-keyboard-control":"material/apple-keyboard-control.svg","material-apple-keyboard-option":"material/apple-keyboard-option.svg","material-apple-keyboard-shift":"material/apple-keyboard-shift.svg","material-apple-safari":"material/apple-safari.svg","material-apple":"material/apple.svg","material-application-array-outline":"material/application-array-outline.svg","material-application-array":"material/application-array.svg","material-application-braces-outline":"material/application-braces-outline.svg","material-application-braces":"material/application-braces.svg","material-application-brackets-outline":"material/application-brackets-outline.svg","material-application-brackets":"material/application-brackets.svg","material-application-cog-outline":"material/application-cog-outline.svg","material-application-cog":"material/application-cog.svg","material-application-edit-outline":"material/application-edit-outline.svg","material-application-edit":"material/application-edit.svg","material-application-export":"material/application-export.svg","material-application-import":"material/application-import.svg","material-application-outline":"material/application-outline.svg","material-application-parentheses-outline":"material/application-parentheses-outline.svg","material-application-parentheses":"material/application-parentheses.svg","material-application-settings-outline":"material/application-settings-outline.svg","material-application-settings":"material/application-settings.svg","material-application-variable-outline":"material/application-variable-outline.svg","material-application-variable":"material/application-variable.svg","material-application":"material/application.svg","material-approximately-equal-box":"material/approximately-equal-box.svg","material-approximately-equal":"material/approximately-equal.svg","material-apps-box":"material/apps-box.svg","material-apps":"material/apps.svg","material-arch":"material/arch.svg","material-archive-alert-outline":"material/archive-alert-outline.svg","material-archive-alert":"material/archive-alert.svg","material-archive-arrow-down-outline":"material/archive-arrow-down-outline.svg","material-archive-arrow-down":"material/archive-arrow-down.svg","material-archive-arrow-up-outline":"material/archive-arrow-up-outline.svg","material-archive-arrow-up":"material/archive-arrow-up.svg","material-archive-cancel-outline":"material/archive-cancel-outline.svg","material-archive-cancel":"material/archive-cancel.svg","material-archive-check-outline":"material/archive-check-outline.svg","material-archive-check":"material/archive-check.svg","material-archive-clock-outline":"material/archive-clock-outline.svg","material-archive-clock":"material/archive-clock.svg","material-archive-cog-outline":"material/archive-cog-outline.svg","material-archive-cog":"material/archive-cog.svg","material-archive-edit-outline":"material/archive-edit-outline.svg","material-archive-edit":"material/archive-edit.svg","material-archive-eye-outline":"material/archive-eye-outline.svg","material-archive-eye":"material/archive-eye.svg","material-archive-lock-open-outline":"material/archive-lock-open-outline.svg","material-archive-lock-open":"material/archive-lock-open.svg","material-archive-lock-outline":"material/archive-lock-outline.svg","material-archive-lock":"material/archive-lock.svg","material-archive-marker-outline":"material/archive-marker-outline.svg","material-archive-marker":"material/archive-marker.svg","material-archive-minus-outline":"material/archive-minus-outline.svg","material-archive-minus":"material/archive-minus.svg","material-archive-music-outline":"material/archive-music-outline.svg","material-archive-music":"material/archive-music.svg","material-archive-off-outline":"material/archive-off-outline.svg","material-archive-off":"material/archive-off.svg","material-archive-outline":"material/archive-outline.svg","material-archive-plus-outline":"material/archive-plus-outline.svg","material-archive-plus":"material/archive-plus.svg","material-archive-refresh-outline":"material/archive-refresh-outline.svg","material-archive-refresh":"material/archive-refresh.svg","material-archive-remove-outline":"material/archive-remove-outline.svg","material-archive-remove":"material/archive-remove.svg","material-archive-search-outline":"material/archive-search-outline.svg","material-archive-search":"material/archive-search.svg","material-archive-settings-outline":"material/archive-settings-outline.svg","material-archive-settings":"material/archive-settings.svg","material-archive-star-outline":"material/archive-star-outline.svg","material-archive-star":"material/archive-star.svg","material-archive-sync-outline":"material/archive-sync-outline.svg","material-archive-sync":"material/archive-sync.svg","material-archive":"material/archive.svg","material-arm-flex-outline":"material/arm-flex-outline.svg","material-arm-flex":"material/arm-flex.svg","material-arrange-bring-forward":"material/arrange-bring-forward.svg","material-arrange-bring-to-front":"material/arrange-bring-to-front.svg","material-arrange-send-backward":"material/arrange-send-backward.svg","material-arrange-send-to-back":"material/arrange-send-to-back.svg","material-arrow-all":"material/arrow-all.svg","material-arrow-bottom-left-bold-box-outline":"material/arrow-bottom-left-bold-box-outline.svg","material-arrow-bottom-left-bold-box":"material/arrow-bottom-left-bold-box.svg","material-arrow-bottom-left-bold-outline":"material/arrow-bottom-left-bold-outline.svg","material-arrow-bottom-left-thick":"material/arrow-bottom-left-thick.svg","material-arrow-bottom-left-thin-circle-outline":"material/arrow-bottom-left-thin-circle-outline.svg","material-arrow-bottom-left-thin":"material/arrow-bottom-left-thin.svg","material-arrow-bottom-left":"material/arrow-bottom-left.svg","material-arrow-bottom-right-bold-box-outline":"material/arrow-bottom-right-bold-box-outline.svg","material-arrow-bottom-right-bold-box":"material/arrow-bottom-right-bold-box.svg","material-arrow-bottom-right-bold-outline":"material/arrow-bottom-right-bold-outline.svg","material-arrow-bottom-right-thick":"material/arrow-bottom-right-thick.svg","material-arrow-bottom-right-thin-circle-outline":"material/arrow-bottom-right-thin-circle-outline.svg","material-arrow-bottom-right-thin":"material/arrow-bottom-right-thin.svg","material-arrow-bottom-right":"material/arrow-bottom-right.svg","material-arrow-collapse-all":"material/arrow-collapse-all.svg","material-arrow-collapse-down":"material/arrow-collapse-down.svg","material-arrow-collapse-horizontal":"material/arrow-collapse-horizontal.svg","material-arrow-collapse-left":"material/arrow-collapse-left.svg","material-arrow-collapse-right":"material/arrow-collapse-right.svg","material-arrow-collapse-up":"material/arrow-collapse-up.svg","material-arrow-collapse-vertical":"material/arrow-collapse-vertical.svg","material-arrow-collapse":"material/arrow-collapse.svg","material-arrow-decision-auto-outline":"material/arrow-decision-auto-outline.svg","material-arrow-decision-auto":"material/arrow-decision-auto.svg","material-arrow-decision-outline":"material/arrow-decision-outline.svg","material-arrow-decision":"material/arrow-decision.svg","material-arrow-down-bold-box-outline":"material/arrow-down-bold-box-outline.svg","material-arrow-down-bold-box":"material/arrow-down-bold-box.svg","material-arrow-down-bold-circle-outline":"material/arrow-down-bold-circle-outline.svg","material-arrow-down-bold-circle":"material/arrow-down-bold-circle.svg","material-arrow-down-bold-hexagon-outline":"material/arrow-down-bold-hexagon-outline.svg","material-arrow-down-bold-outline":"material/arrow-down-bold-outline.svg","material-arrow-down-bold":"material/arrow-down-bold.svg","material-arrow-down-box":"material/arrow-down-box.svg","material-arrow-down-circle-outline":"material/arrow-down-circle-outline.svg","material-arrow-down-circle":"material/arrow-down-circle.svg","material-arrow-down-drop-circle-outline":"material/arrow-down-drop-circle-outline.svg","material-arrow-down-drop-circle":"material/arrow-down-drop-circle.svg","material-arrow-down-left-bold":"material/arrow-down-left-bold.svg","material-arrow-down-left":"material/arrow-down-left.svg","material-arrow-down-right-bold":"material/arrow-down-right-bold.svg","material-arrow-down-right":"material/arrow-down-right.svg","material-arrow-down-thick":"material/arrow-down-thick.svg","material-arrow-down-thin-circle-outline":"material/arrow-down-thin-circle-outline.svg","material-arrow-down-thin":"material/arrow-down-thin.svg","material-arrow-down":"material/arrow-down.svg","material-arrow-expand-all":"material/arrow-expand-all.svg","material-arrow-expand-down":"material/arrow-expand-down.svg","material-arrow-expand-horizontal":"material/arrow-expand-horizontal.svg","material-arrow-expand-left":"material/arrow-expand-left.svg","material-arrow-expand-right":"material/arrow-expand-right.svg","material-arrow-expand-up":"material/arrow-expand-up.svg","material-arrow-expand-vertical":"material/arrow-expand-vertical.svg","material-arrow-expand":"material/arrow-expand.svg","material-arrow-horizontal-lock":"material/arrow-horizontal-lock.svg","material-arrow-left-bold-box-outline":"material/arrow-left-bold-box-outline.svg","material-arrow-left-bold-box":"material/arrow-left-bold-box.svg","material-arrow-left-bold-circle-outline":"material/arrow-left-bold-circle-outline.svg","material-arrow-left-bold-circle":"material/arrow-left-bold-circle.svg","material-arrow-left-bold-hexagon-outline":"material/arrow-left-bold-hexagon-outline.svg","material-arrow-left-bold-outline":"material/arrow-left-bold-outline.svg","material-arrow-left-bold":"material/arrow-left-bold.svg","material-arrow-left-bottom-bold":"material/arrow-left-bottom-bold.svg","material-arrow-left-bottom":"material/arrow-left-bottom.svg","material-arrow-left-box":"material/arrow-left-box.svg","material-arrow-left-circle-outline":"material/arrow-left-circle-outline.svg","material-arrow-left-circle":"material/arrow-left-circle.svg","material-arrow-left-drop-circle-outline":"material/arrow-left-drop-circle-outline.svg","material-arrow-left-drop-circle":"material/arrow-left-drop-circle.svg","material-arrow-left-right-bold-outline":"material/arrow-left-right-bold-outline.svg","material-arrow-left-right-bold":"material/arrow-left-right-bold.svg","material-arrow-left-right":"material/arrow-left-right.svg","material-arrow-left-thick":"material/arrow-left-thick.svg","material-arrow-left-thin-circle-outline":"material/arrow-left-thin-circle-outline.svg","material-arrow-left-thin":"material/arrow-left-thin.svg","material-arrow-left-top-bold":"material/arrow-left-top-bold.svg","material-arrow-left-top":"material/arrow-left-top.svg","material-arrow-left":"material/arrow-left.svg","material-arrow-projectile-multiple":"material/arrow-projectile-multiple.svg","material-arrow-projectile":"material/arrow-projectile.svg","material-arrow-right-bold-box-outline":"material/arrow-right-bold-box-outline.svg","material-arrow-right-bold-box":"material/arrow-right-bold-box.svg","material-arrow-right-bold-circle-outline":"material/arrow-right-bold-circle-outline.svg","material-arrow-right-bold-circle":"material/arrow-right-bold-circle.svg","material-arrow-right-bold-hexagon-outline":"material/arrow-right-bold-hexagon-outline.svg","material-arrow-right-bold-outline":"material/arrow-right-bold-outline.svg","material-arrow-right-bold":"material/arrow-right-bold.svg","material-arrow-right-bottom-bold":"material/arrow-right-bottom-bold.svg","material-arrow-right-bottom":"material/arrow-right-bottom.svg","material-arrow-right-box":"material/arrow-right-box.svg","material-arrow-right-circle-outline":"material/arrow-right-circle-outline.svg","material-arrow-right-circle":"material/arrow-right-circle.svg","material-arrow-right-drop-circle-outline":"material/arrow-right-drop-circle-outline.svg","material-arrow-right-drop-circle":"material/arrow-right-drop-circle.svg","material-arrow-right-thick":"material/arrow-right-thick.svg","material-arrow-right-thin-circle-outline":"material/arrow-right-thin-circle-outline.svg","material-arrow-right-thin":"material/arrow-right-thin.svg","material-arrow-right-top-bold":"material/arrow-right-top-bold.svg","material-arrow-right-top":"material/arrow-right-top.svg","material-arrow-right":"material/arrow-right.svg","material-arrow-split-horizontal":"material/arrow-split-horizontal.svg","material-arrow-split-vertical":"material/arrow-split-vertical.svg","material-arrow-top-left-bold-box-outline":"material/arrow-top-left-bold-box-outline.svg","material-arrow-top-left-bold-box":"material/arrow-top-left-bold-box.svg","material-arrow-top-left-bold-outline":"material/arrow-top-left-bold-outline.svg","material-arrow-top-left-bottom-right-bold":"material/arrow-top-left-bottom-right-bold.svg","material-arrow-top-left-bottom-right":"material/arrow-top-left-bottom-right.svg","material-arrow-top-left-thick":"material/arrow-top-left-thick.svg","material-arrow-top-left-thin-circle-outline":"material/arrow-top-left-thin-circle-outline.svg","material-arrow-top-left-thin":"material/arrow-top-left-thin.svg","material-arrow-top-left":"material/arrow-top-left.svg","material-arrow-top-right-bold-box-outline":"material/arrow-top-right-bold-box-outline.svg","material-arrow-top-right-bold-box":"material/arrow-top-right-bold-box.svg","material-arrow-top-right-bold-outline":"material/arrow-top-right-bold-outline.svg","material-arrow-top-right-bottom-left-bold":"material/arrow-top-right-bottom-left-bold.svg","material-arrow-top-right-bottom-left":"material/arrow-top-right-bottom-left.svg","material-arrow-top-right-thick":"material/arrow-top-right-thick.svg","material-arrow-top-right-thin-circle-outline":"material/arrow-top-right-thin-circle-outline.svg","material-arrow-top-right-thin":"material/arrow-top-right-thin.svg","material-arrow-top-right":"material/arrow-top-right.svg","material-arrow-u-down-left-bold":"material/arrow-u-down-left-bold.svg","material-arrow-u-down-left":"material/arrow-u-down-left.svg","material-arrow-u-down-right-bold":"material/arrow-u-down-right-bold.svg","material-arrow-u-down-right":"material/arrow-u-down-right.svg","material-arrow-u-left-bottom-bold":"material/arrow-u-left-bottom-bold.svg","material-arrow-u-left-bottom":"material/arrow-u-left-bottom.svg","material-arrow-u-left-top-bold":"material/arrow-u-left-top-bold.svg","material-arrow-u-left-top":"material/arrow-u-left-top.svg","material-arrow-u-right-bottom-bold":"material/arrow-u-right-bottom-bold.svg","material-arrow-u-right-bottom":"material/arrow-u-right-bottom.svg","material-arrow-u-right-top-bold":"material/arrow-u-right-top-bold.svg","material-arrow-u-right-top":"material/arrow-u-right-top.svg","material-arrow-u-up-left-bold":"material/arrow-u-up-left-bold.svg","material-arrow-u-up-left":"material/arrow-u-up-left.svg","material-arrow-u-up-right-bold":"material/arrow-u-up-right-bold.svg","material-arrow-u-up-right":"material/arrow-u-up-right.svg","material-arrow-up-bold-box-outline":"material/arrow-up-bold-box-outline.svg","material-arrow-up-bold-box":"material/arrow-up-bold-box.svg","material-arrow-up-bold-circle-outline":"material/arrow-up-bold-circle-outline.svg","material-arrow-up-bold-circle":"material/arrow-up-bold-circle.svg","material-arrow-up-bold-hexagon-outline":"material/arrow-up-bold-hexagon-outline.svg","material-arrow-up-bold-outline":"material/arrow-up-bold-outline.svg","material-arrow-up-bold":"material/arrow-up-bold.svg","material-arrow-up-box":"material/arrow-up-box.svg","material-arrow-up-circle-outline":"material/arrow-up-circle-outline.svg","material-arrow-up-circle":"material/arrow-up-circle.svg","material-arrow-up-down-bold-outline":"material/arrow-up-down-bold-outline.svg","material-arrow-up-down-bold":"material/arrow-up-down-bold.svg","material-arrow-up-down":"material/arrow-up-down.svg","material-arrow-up-drop-circle-outline":"material/arrow-up-drop-circle-outline.svg","material-arrow-up-drop-circle":"material/arrow-up-drop-circle.svg","material-arrow-up-left-bold":"material/arrow-up-left-bold.svg","material-arrow-up-left":"material/arrow-up-left.svg","material-arrow-up-right-bold":"material/arrow-up-right-bold.svg","material-arrow-up-right":"material/arrow-up-right.svg","material-arrow-up-thick":"material/arrow-up-thick.svg","material-arrow-up-thin-circle-outline":"material/arrow-up-thin-circle-outline.svg","material-arrow-up-thin":"material/arrow-up-thin.svg","material-arrow-up":"material/arrow-up.svg","material-arrow-vertical-lock":"material/arrow-vertical-lock.svg","material-artboard":"material/artboard.svg","material-artstation":"material/artstation.svg","material-aspect-ratio":"material/aspect-ratio.svg","material-assistant":"material/assistant.svg","material-asterisk-circle-outline":"material/asterisk-circle-outline.svg","material-asterisk":"material/asterisk.svg","material-at":"material/at.svg","material-atlassian":"material/atlassian.svg","material-atm":"material/atm.svg","material-atom-variant":"material/atom-variant.svg","material-atom":"material/atom.svg","material-attachment-check":"material/attachment-check.svg","material-attachment-lock":"material/attachment-lock.svg","material-attachment-minus":"material/attachment-minus.svg","material-attachment-off":"material/attachment-off.svg","material-attachment-plus":"material/attachment-plus.svg","material-attachment-remove":"material/attachment-remove.svg","material-attachment":"material/attachment.svg","material-atv":"material/atv.svg","material-audio-input-rca":"material/audio-input-rca.svg","material-audio-input-stereo-minijack":"material/audio-input-stereo-minijack.svg","material-audio-input-xlr":"material/audio-input-xlr.svg","material-audio-video-off":"material/audio-video-off.svg","material-audio-video":"material/audio-video.svg","material-augmented-reality":"material/augmented-reality.svg","material-auto-download":"material/auto-download.svg","material-auto-fix":"material/auto-fix.svg","material-auto-upload":"material/auto-upload.svg","material-autorenew-off":"material/autorenew-off.svg","material-autorenew":"material/autorenew.svg","material-av-timer":"material/av-timer.svg","material-awning-outline":"material/awning-outline.svg","material-awning":"material/awning.svg","material-aws":"material/aws.svg","material-axe-battle":"material/axe-battle.svg","material-axe":"material/axe.svg","material-axis-arrow-info":"material/axis-arrow-info.svg","material-axis-arrow-lock":"material/axis-arrow-lock.svg","material-axis-arrow":"material/axis-arrow.svg","material-axis-lock":"material/axis-lock.svg","material-axis-x-arrow-lock":"material/axis-x-arrow-lock.svg","material-axis-x-arrow":"material/axis-x-arrow.svg","material-axis-x-rotate-clockwise":"material/axis-x-rotate-clockwise.svg","material-axis-x-rotate-counterclockwise":"material/axis-x-rotate-counterclockwise.svg","material-axis-x-y-arrow-lock":"material/axis-x-y-arrow-lock.svg","material-axis-y-arrow-lock":"material/axis-y-arrow-lock.svg","material-axis-y-arrow":"material/axis-y-arrow.svg","material-axis-y-rotate-clockwise":"material/axis-y-rotate-clockwise.svg","material-axis-y-rotate-counterclockwise":"material/axis-y-rotate-counterclockwise.svg","material-axis-z-arrow-lock":"material/axis-z-arrow-lock.svg","material-axis-z-arrow":"material/axis-z-arrow.svg","material-axis-z-rotate-clockwise":"material/axis-z-rotate-clockwise.svg","material-axis-z-rotate-counterclockwise":"material/axis-z-rotate-counterclockwise.svg","material-axis":"material/axis.svg","material-babel":"material/babel.svg","material-baby-bottle-outline":"material/baby-bottle-outline.svg","material-baby-bottle":"material/baby-bottle.svg","material-baby-buggy-off":"material/baby-buggy-off.svg","material-baby-buggy":"material/baby-buggy.svg","material-baby-carriage-off":"material/baby-carriage-off.svg","material-baby-carriage":"material/baby-carriage.svg","material-baby-face-outline":"material/baby-face-outline.svg","material-baby-face":"material/baby-face.svg","material-baby":"material/baby.svg","material-backburger":"material/backburger.svg","material-backspace-outline":"material/backspace-outline.svg","material-backspace-reverse-outline":"material/backspace-reverse-outline.svg","material-backspace-reverse":"material/backspace-reverse.svg","material-backspace":"material/backspace.svg","material-backup-restore":"material/backup-restore.svg","material-bacteria-outline":"material/bacteria-outline.svg","material-bacteria":"material/bacteria.svg","material-badge-account-alert-outline":"material/badge-account-alert-outline.svg","material-badge-account-alert":"material/badge-account-alert.svg","material-badge-account-horizontal-outline":"material/badge-account-horizontal-outline.svg","material-badge-account-horizontal":"material/badge-account-horizontal.svg","material-badge-account-outline":"material/badge-account-outline.svg","material-badge-account":"material/badge-account.svg","material-badminton":"material/badminton.svg","material-bag-carry-on-check":"material/bag-carry-on-check.svg","material-bag-carry-on-off":"material/bag-carry-on-off.svg","material-bag-carry-on":"material/bag-carry-on.svg","material-bag-checked":"material/bag-checked.svg","material-bag-personal-off-outline":"material/bag-personal-off-outline.svg","material-bag-personal-off":"material/bag-personal-off.svg","material-bag-personal-outline":"material/bag-personal-outline.svg","material-bag-personal-tag-outline":"material/bag-personal-tag-outline.svg","material-bag-personal-tag":"material/bag-personal-tag.svg","material-bag-personal":"material/bag-personal.svg","material-bag-suitcase-off-outline":"material/bag-suitcase-off-outline.svg","material-bag-suitcase-off":"material/bag-suitcase-off.svg","material-bag-suitcase-outline":"material/bag-suitcase-outline.svg","material-bag-suitcase":"material/bag-suitcase.svg","material-baguette":"material/baguette.svg","material-balcony":"material/balcony.svg","material-balloon":"material/balloon.svg","material-ballot-outline":"material/ballot-outline.svg","material-ballot-recount-outline":"material/ballot-recount-outline.svg","material-ballot-recount":"material/ballot-recount.svg","material-ballot":"material/ballot.svg","material-bandage":"material/bandage.svg","material-bank-check":"material/bank-check.svg","material-bank-minus":"material/bank-minus.svg","material-bank-off-outline":"material/bank-off-outline.svg","material-bank-off":"material/bank-off.svg","material-bank-outline":"material/bank-outline.svg","material-bank-plus":"material/bank-plus.svg","material-bank-remove":"material/bank-remove.svg","material-bank-transfer-in":"material/bank-transfer-in.svg","material-bank-transfer-out":"material/bank-transfer-out.svg","material-bank-transfer":"material/bank-transfer.svg","material-bank":"material/bank.svg","material-barcode-off":"material/barcode-off.svg","material-barcode-scan":"material/barcode-scan.svg","material-barcode":"material/barcode.svg","material-barley-off":"material/barley-off.svg","material-barley":"material/barley.svg","material-barn":"material/barn.svg","material-barrel-outline":"material/barrel-outline.svg","material-barrel":"material/barrel.svg","material-baseball-bat":"material/baseball-bat.svg","material-baseball-diamond-outline":"material/baseball-diamond-outline.svg","material-baseball-diamond":"material/baseball-diamond.svg","material-baseball":"material/baseball.svg","material-bash":"material/bash.svg","material-basket-check-outline":"material/basket-check-outline.svg","material-basket-check":"material/basket-check.svg","material-basket-fill":"material/basket-fill.svg","material-basket-minus-outline":"material/basket-minus-outline.svg","material-basket-minus":"material/basket-minus.svg","material-basket-off-outline":"material/basket-off-outline.svg","material-basket-off":"material/basket-off.svg","material-basket-outline":"material/basket-outline.svg","material-basket-plus-outline":"material/basket-plus-outline.svg","material-basket-plus":"material/basket-plus.svg","material-basket-remove-outline":"material/basket-remove-outline.svg","material-basket-remove":"material/basket-remove.svg","material-basket-unfill":"material/basket-unfill.svg","material-basket":"material/basket.svg","material-basketball-hoop-outline":"material/basketball-hoop-outline.svg","material-basketball-hoop":"material/basketball-hoop.svg","material-basketball":"material/basketball.svg","material-bat":"material/bat.svg","material-bathtub-outline":"material/bathtub-outline.svg","material-bathtub":"material/bathtub.svg","material-battery-10-bluetooth":"material/battery-10-bluetooth.svg","material-battery-10":"material/battery-10.svg","material-battery-20-bluetooth":"material/battery-20-bluetooth.svg","material-battery-20":"material/battery-20.svg","material-battery-30-bluetooth":"material/battery-30-bluetooth.svg","material-battery-30":"material/battery-30.svg","material-battery-40-bluetooth":"material/battery-40-bluetooth.svg","material-battery-40":"material/battery-40.svg","material-battery-50-bluetooth":"material/battery-50-bluetooth.svg","material-battery-50":"material/battery-50.svg","material-battery-60-bluetooth":"material/battery-60-bluetooth.svg","material-battery-60":"material/battery-60.svg","material-battery-70-bluetooth":"material/battery-70-bluetooth.svg","material-battery-70":"material/battery-70.svg","material-battery-80-bluetooth":"material/battery-80-bluetooth.svg","material-battery-80":"material/battery-80.svg","material-battery-90-bluetooth":"material/battery-90-bluetooth.svg","material-battery-90":"material/battery-90.svg","material-battery-alert-bluetooth":"material/battery-alert-bluetooth.svg","material-battery-alert-variant-outline":"material/battery-alert-variant-outline.svg","material-battery-alert-variant":"material/battery-alert-variant.svg","material-battery-alert":"material/battery-alert.svg","material-battery-arrow-down-outline":"material/battery-arrow-down-outline.svg","material-battery-arrow-down":"material/battery-arrow-down.svg","material-battery-arrow-up-outline":"material/battery-arrow-up-outline.svg","material-battery-arrow-up":"material/battery-arrow-up.svg","material-battery-bluetooth-variant":"material/battery-bluetooth-variant.svg","material-battery-bluetooth":"material/battery-bluetooth.svg","material-battery-charging-10":"material/battery-charging-10.svg","material-battery-charging-100":"material/battery-charging-100.svg","material-battery-charging-20":"material/battery-charging-20.svg","material-battery-charging-30":"material/battery-charging-30.svg","material-battery-charging-40":"material/battery-charging-40.svg","material-battery-charging-50":"material/battery-charging-50.svg","material-battery-charging-60":"material/battery-charging-60.svg","material-battery-charging-70":"material/battery-charging-70.svg","material-battery-charging-80":"material/battery-charging-80.svg","material-battery-charging-90":"material/battery-charging-90.svg","material-battery-charging-high":"material/battery-charging-high.svg","material-battery-charging-low":"material/battery-charging-low.svg","material-battery-charging-medium":"material/battery-charging-medium.svg","material-battery-charging-outline":"material/battery-charging-outline.svg","material-battery-charging-wireless-10":"material/battery-charging-wireless-10.svg","material-battery-charging-wireless-20":"material/battery-charging-wireless-20.svg","material-battery-charging-wireless-30":"material/battery-charging-wireless-30.svg","material-battery-charging-wireless-40":"material/battery-charging-wireless-40.svg","material-battery-charging-wireless-50":"material/battery-charging-wireless-50.svg","material-battery-charging-wireless-60":"material/battery-charging-wireless-60.svg","material-battery-charging-wireless-70":"material/battery-charging-wireless-70.svg","material-battery-charging-wireless-80":"material/battery-charging-wireless-80.svg","material-battery-charging-wireless-90":"material/battery-charging-wireless-90.svg","material-battery-charging-wireless-alert":"material/battery-charging-wireless-alert.svg","material-battery-charging-wireless-outline":"material/battery-charging-wireless-outline.svg","material-battery-charging-wireless":"material/battery-charging-wireless.svg","material-battery-charging":"material/battery-charging.svg","material-battery-check-outline":"material/battery-check-outline.svg","material-battery-check":"material/battery-check.svg","material-battery-clock-outline":"material/battery-clock-outline.svg","material-battery-clock":"material/battery-clock.svg","material-battery-heart-outline":"material/battery-heart-outline.svg","material-battery-heart-variant":"material/battery-heart-variant.svg","material-battery-heart":"material/battery-heart.svg","material-battery-high":"material/battery-high.svg","material-battery-lock-open":"material/battery-lock-open.svg","material-battery-lock":"material/battery-lock.svg","material-battery-low":"material/battery-low.svg","material-battery-medium":"material/battery-medium.svg","material-battery-minus-outline":"material/battery-minus-outline.svg","material-battery-minus-variant":"material/battery-minus-variant.svg","material-battery-minus":"material/battery-minus.svg","material-battery-negative":"material/battery-negative.svg","material-battery-off-outline":"material/battery-off-outline.svg","material-battery-off":"material/battery-off.svg","material-battery-outline":"material/battery-outline.svg","material-battery-plus-outline":"material/battery-plus-outline.svg","material-battery-plus-variant":"material/battery-plus-variant.svg","material-battery-plus":"material/battery-plus.svg","material-battery-positive":"material/battery-positive.svg","material-battery-remove-outline":"material/battery-remove-outline.svg","material-battery-remove":"material/battery-remove.svg","material-battery-sync-outline":"material/battery-sync-outline.svg","material-battery-sync":"material/battery-sync.svg","material-battery-unknown-bluetooth":"material/battery-unknown-bluetooth.svg","material-battery-unknown":"material/battery-unknown.svg","material-battery":"material/battery.svg","material-beach":"material/beach.svg","material-beaker-alert-outline":"material/beaker-alert-outline.svg","material-beaker-alert":"material/beaker-alert.svg","material-beaker-check-outline":"material/beaker-check-outline.svg","material-beaker-check":"material/beaker-check.svg","material-beaker-minus-outline":"material/beaker-minus-outline.svg","material-beaker-minus":"material/beaker-minus.svg","material-beaker-outline":"material/beaker-outline.svg","material-beaker-plus-outline":"material/beaker-plus-outline.svg","material-beaker-plus":"material/beaker-plus.svg","material-beaker-question-outline":"material/beaker-question-outline.svg","material-beaker-question":"material/beaker-question.svg","material-beaker-remove-outline":"material/beaker-remove-outline.svg","material-beaker-remove":"material/beaker-remove.svg","material-beaker":"material/beaker.svg","material-bed-clock":"material/bed-clock.svg","material-bed-double-outline":"material/bed-double-outline.svg","material-bed-double":"material/bed-double.svg","material-bed-empty":"material/bed-empty.svg","material-bed-king-outline":"material/bed-king-outline.svg","material-bed-king":"material/bed-king.svg","material-bed-outline":"material/bed-outline.svg","material-bed-queen-outline":"material/bed-queen-outline.svg","material-bed-queen":"material/bed-queen.svg","material-bed-single-outline":"material/bed-single-outline.svg","material-bed-single":"material/bed-single.svg","material-bed":"material/bed.svg","material-bee-flower":"material/bee-flower.svg","material-bee":"material/bee.svg","material-beehive-off-outline":"material/beehive-off-outline.svg","material-beehive-outline":"material/beehive-outline.svg","material-beekeeper":"material/beekeeper.svg","material-beer-outline":"material/beer-outline.svg","material-beer":"material/beer.svg","material-bell-alert-outline":"material/bell-alert-outline.svg","material-bell-alert":"material/bell-alert.svg","material-bell-badge-outline":"material/bell-badge-outline.svg","material-bell-badge":"material/bell-badge.svg","material-bell-cancel-outline":"material/bell-cancel-outline.svg","material-bell-cancel":"material/bell-cancel.svg","material-bell-check-outline":"material/bell-check-outline.svg","material-bell-check":"material/bell-check.svg","material-bell-circle-outline":"material/bell-circle-outline.svg","material-bell-circle":"material/bell-circle.svg","material-bell-cog-outline":"material/bell-cog-outline.svg","material-bell-cog":"material/bell-cog.svg","material-bell-minus-outline":"material/bell-minus-outline.svg","material-bell-minus":"material/bell-minus.svg","material-bell-off-outline":"material/bell-off-outline.svg","material-bell-off":"material/bell-off.svg","material-bell-outline":"material/bell-outline.svg","material-bell-plus-outline":"material/bell-plus-outline.svg","material-bell-plus":"material/bell-plus.svg","material-bell-remove-outline":"material/bell-remove-outline.svg","material-bell-remove":"material/bell-remove.svg","material-bell-ring-outline":"material/bell-ring-outline.svg","material-bell-ring":"material/bell-ring.svg","material-bell-sleep-outline":"material/bell-sleep-outline.svg","material-bell-sleep":"material/bell-sleep.svg","material-bell":"material/bell.svg","material-beta":"material/beta.svg","material-betamax":"material/betamax.svg","material-biathlon":"material/biathlon.svg","material-bicycle-basket":"material/bicycle-basket.svg","material-bicycle-cargo":"material/bicycle-cargo.svg","material-bicycle-electric":"material/bicycle-electric.svg","material-bicycle-penny-farthing":"material/bicycle-penny-farthing.svg","material-bicycle":"material/bicycle.svg","material-bike-fast":"material/bike-fast.svg","material-bike":"material/bike.svg","material-billboard":"material/billboard.svg","material-billiards-rack":"material/billiards-rack.svg","material-billiards":"material/billiards.svg","material-binoculars":"material/binoculars.svg","material-bio":"material/bio.svg","material-biohazard":"material/biohazard.svg","material-bird":"material/bird.svg","material-bitbucket":"material/bitbucket.svg","material-bitcoin":"material/bitcoin.svg","material-black-mesa":"material/black-mesa.svg","material-blender-outline":"material/blender-outline.svg","material-blender-software":"material/blender-software.svg","material-blender":"material/blender.svg","material-blinds-horizontal-closed":"material/blinds-horizontal-closed.svg","material-blinds-horizontal":"material/blinds-horizontal.svg","material-blinds-open":"material/blinds-open.svg","material-blinds-vertical-closed":"material/blinds-vertical-closed.svg","material-blinds-vertical":"material/blinds-vertical.svg","material-blinds":"material/blinds.svg","material-block-helper":"material/block-helper.svg","material-blood-bag":"material/blood-bag.svg","material-bluetooth-audio":"material/bluetooth-audio.svg","material-bluetooth-connect":"material/bluetooth-connect.svg","material-bluetooth-off":"material/bluetooth-off.svg","material-bluetooth-settings":"material/bluetooth-settings.svg","material-bluetooth-transfer":"material/bluetooth-transfer.svg","material-bluetooth":"material/bluetooth.svg","material-blur-linear":"material/blur-linear.svg","material-blur-off":"material/blur-off.svg","material-blur-radial":"material/blur-radial.svg","material-blur":"material/blur.svg","material-bolt":"material/bolt.svg","material-bomb-off":"material/bomb-off.svg","material-bomb":"material/bomb.svg","material-bone-off":"material/bone-off.svg","material-bone":"material/bone.svg","material-book-account-outline":"material/book-account-outline.svg","material-book-account":"material/book-account.svg","material-book-alert-outline":"material/book-alert-outline.svg","material-book-alert":"material/book-alert.svg","material-book-alphabet":"material/book-alphabet.svg","material-book-arrow-down-outline":"material/book-arrow-down-outline.svg","material-book-arrow-down":"material/book-arrow-down.svg","material-book-arrow-left-outline":"material/book-arrow-left-outline.svg","material-book-arrow-left":"material/book-arrow-left.svg","material-book-arrow-right-outline":"material/book-arrow-right-outline.svg","material-book-arrow-right":"material/book-arrow-right.svg","material-book-arrow-up-outline":"material/book-arrow-up-outline.svg","material-book-arrow-up":"material/book-arrow-up.svg","material-book-cancel-outline":"material/book-cancel-outline.svg","material-book-cancel":"material/book-cancel.svg","material-book-check-outline":"material/book-check-outline.svg","material-book-check":"material/book-check.svg","material-book-clock-outline":"material/book-clock-outline.svg","material-book-clock":"material/book-clock.svg","material-book-cog-outline":"material/book-cog-outline.svg","material-book-cog":"material/book-cog.svg","material-book-cross":"material/book-cross.svg","material-book-edit-outline":"material/book-edit-outline.svg","material-book-edit":"material/book-edit.svg","material-book-education-outline":"material/book-education-outline.svg","material-book-education":"material/book-education.svg","material-book-heart-outline":"material/book-heart-outline.svg","material-book-heart":"material/book-heart.svg","material-book-information-variant":"material/book-information-variant.svg","material-book-lock-open-outline":"material/book-lock-open-outline.svg","material-book-lock-open":"material/book-lock-open.svg","material-book-lock-outline":"material/book-lock-outline.svg","material-book-lock":"material/book-lock.svg","material-book-marker-outline":"material/book-marker-outline.svg","material-book-marker":"material/book-marker.svg","material-book-minus-multiple-outline":"material/book-minus-multiple-outline.svg","material-book-minus-multiple":"material/book-minus-multiple.svg","material-book-minus-outline":"material/book-minus-outline.svg","material-book-minus":"material/book-minus.svg","material-book-multiple-outline":"material/book-multiple-outline.svg","material-book-multiple":"material/book-multiple.svg","material-book-music-outline":"material/book-music-outline.svg","material-book-music":"material/book-music.svg","material-book-off-outline":"material/book-off-outline.svg","material-book-off":"material/book-off.svg","material-book-open-blank-variant":"material/book-open-blank-variant.svg","material-book-open-outline":"material/book-open-outline.svg","material-book-open-page-variant-outline":"material/book-open-page-variant-outline.svg","material-book-open-page-variant":"material/book-open-page-variant.svg","material-book-open-variant":"material/book-open-variant.svg","material-book-open":"material/book-open.svg","material-book-outline":"material/book-outline.svg","material-book-play-outline":"material/book-play-outline.svg","material-book-play":"material/book-play.svg","material-book-plus-multiple-outline":"material/book-plus-multiple-outline.svg","material-book-plus-multiple":"material/book-plus-multiple.svg","material-book-plus-outline":"material/book-plus-outline.svg","material-book-plus":"material/book-plus.svg","material-book-refresh-outline":"material/book-refresh-outline.svg","material-book-refresh":"material/book-refresh.svg","material-book-remove-multiple-outline":"material/book-remove-multiple-outline.svg","material-book-remove-multiple":"material/book-remove-multiple.svg","material-book-remove-outline":"material/book-remove-outline.svg","material-book-remove":"material/book-remove.svg","material-book-search-outline":"material/book-search-outline.svg","material-book-search":"material/book-search.svg","material-book-settings-outline":"material/book-settings-outline.svg","material-book-settings":"material/book-settings.svg","material-book-sync-outline":"material/book-sync-outline.svg","material-book-sync":"material/book-sync.svg","material-book-variant":"material/book-variant.svg","material-book":"material/book.svg","material-bookmark-box-multiple-outline":"material/bookmark-box-multiple-outline.svg","material-bookmark-box-multiple":"material/bookmark-box-multiple.svg","material-bookmark-box-outline":"material/bookmark-box-outline.svg","material-bookmark-box":"material/bookmark-box.svg","material-bookmark-check-outline":"material/bookmark-check-outline.svg","material-bookmark-check":"material/bookmark-check.svg","material-bookmark-minus-outline":"material/bookmark-minus-outline.svg","material-bookmark-minus":"material/bookmark-minus.svg","material-bookmark-multiple-outline":"material/bookmark-multiple-outline.svg","material-bookmark-multiple":"material/bookmark-multiple.svg","material-bookmark-music-outline":"material/bookmark-music-outline.svg","material-bookmark-music":"material/bookmark-music.svg","material-bookmark-off-outline":"material/bookmark-off-outline.svg","material-bookmark-off":"material/bookmark-off.svg","material-bookmark-outline":"material/bookmark-outline.svg","material-bookmark-plus-outline":"material/bookmark-plus-outline.svg","material-bookmark-plus":"material/bookmark-plus.svg","material-bookmark-remove-outline":"material/bookmark-remove-outline.svg","material-bookmark-remove":"material/bookmark-remove.svg","material-bookmark":"material/bookmark.svg","material-bookshelf":"material/bookshelf.svg","material-boom-gate-alert-outline":"material/boom-gate-alert-outline.svg","material-boom-gate-alert":"material/boom-gate-alert.svg","material-boom-gate-arrow-down-outline":"material/boom-gate-arrow-down-outline.svg","material-boom-gate-arrow-down":"material/boom-gate-arrow-down.svg","material-boom-gate-arrow-up-outline":"material/boom-gate-arrow-up-outline.svg","material-boom-gate-arrow-up":"material/boom-gate-arrow-up.svg","material-boom-gate-outline":"material/boom-gate-outline.svg","material-boom-gate-up-outline":"material/boom-gate-up-outline.svg","material-boom-gate-up":"material/boom-gate-up.svg","material-boom-gate":"material/boom-gate.svg","material-boombox":"material/boombox.svg","material-boomerang":"material/boomerang.svg","material-bootstrap":"material/bootstrap.svg","material-border-all-variant":"material/border-all-variant.svg","material-border-all":"material/border-all.svg","material-border-bottom-variant":"material/border-bottom-variant.svg","material-border-bottom":"material/border-bottom.svg","material-border-color":"material/border-color.svg","material-border-horizontal":"material/border-horizontal.svg","material-border-inside":"material/border-inside.svg","material-border-left-variant":"material/border-left-variant.svg","material-border-left":"material/border-left.svg","material-border-none-variant":"material/border-none-variant.svg","material-border-none":"material/border-none.svg","material-border-outside":"material/border-outside.svg","material-border-radius":"material/border-radius.svg","material-border-right-variant":"material/border-right-variant.svg","material-border-right":"material/border-right.svg","material-border-style":"material/border-style.svg","material-border-top-variant":"material/border-top-variant.svg","material-border-top":"material/border-top.svg","material-border-vertical":"material/border-vertical.svg","material-bottle-soda-classic-outline":"material/bottle-soda-classic-outline.svg","material-bottle-soda-classic":"material/bottle-soda-classic.svg","material-bottle-soda-outline":"material/bottle-soda-outline.svg","material-bottle-soda":"material/bottle-soda.svg","material-bottle-tonic-outline":"material/bottle-tonic-outline.svg","material-bottle-tonic-plus-outline":"material/bottle-tonic-plus-outline.svg","material-bottle-tonic-plus":"material/bottle-tonic-plus.svg","material-bottle-tonic-skull-outline":"material/bottle-tonic-skull-outline.svg","material-bottle-tonic-skull":"material/bottle-tonic-skull.svg","material-bottle-tonic":"material/bottle-tonic.svg","material-bottle-wine-outline":"material/bottle-wine-outline.svg","material-bottle-wine":"material/bottle-wine.svg","material-bow-arrow":"material/bow-arrow.svg","material-bow-tie":"material/bow-tie.svg","material-bowl-mix-outline":"material/bowl-mix-outline.svg","material-bowl-mix":"material/bowl-mix.svg","material-bowl-outline":"material/bowl-outline.svg","material-bowl":"material/bowl.svg","material-bowling":"material/bowling.svg","material-box-cutter-off":"material/box-cutter-off.svg","material-box-cutter":"material/box-cutter.svg","material-box-shadow":"material/box-shadow.svg","material-box":"material/box.svg","material-boxing-glove":"material/boxing-glove.svg","material-braille":"material/braille.svg","material-brain":"material/brain.svg","material-bread-slice-outline":"material/bread-slice-outline.svg","material-bread-slice":"material/bread-slice.svg","material-bridge":"material/bridge.svg","material-briefcase-account-outline":"material/briefcase-account-outline.svg","material-briefcase-account":"material/briefcase-account.svg","material-briefcase-arrow-left-right-outline":"material/briefcase-arrow-left-right-outline.svg","material-briefcase-arrow-left-right":"material/briefcase-arrow-left-right.svg","material-briefcase-arrow-up-down-outline":"material/briefcase-arrow-up-down-outline.svg","material-briefcase-arrow-up-down":"material/briefcase-arrow-up-down.svg","material-briefcase-check-outline":"material/briefcase-check-outline.svg","material-briefcase-check":"material/briefcase-check.svg","material-briefcase-clock-outline":"material/briefcase-clock-outline.svg","material-briefcase-clock":"material/briefcase-clock.svg","material-briefcase-download-outline":"material/briefcase-download-outline.svg","material-briefcase-download":"material/briefcase-download.svg","material-briefcase-edit-outline":"material/briefcase-edit-outline.svg","material-briefcase-edit":"material/briefcase-edit.svg","material-briefcase-eye-outline":"material/briefcase-eye-outline.svg","material-briefcase-eye":"material/briefcase-eye.svg","material-briefcase-minus-outline":"material/briefcase-minus-outline.svg","material-briefcase-minus":"material/briefcase-minus.svg","material-briefcase-off-outline":"material/briefcase-off-outline.svg","material-briefcase-off":"material/briefcase-off.svg","material-briefcase-outline":"material/briefcase-outline.svg","material-briefcase-plus-outline":"material/briefcase-plus-outline.svg","material-briefcase-plus":"material/briefcase-plus.svg","material-briefcase-remove-outline":"material/briefcase-remove-outline.svg","material-briefcase-remove":"material/briefcase-remove.svg","material-briefcase-search-outline":"material/briefcase-search-outline.svg","material-briefcase-search":"material/briefcase-search.svg","material-briefcase-upload-outline":"material/briefcase-upload-outline.svg","material-briefcase-upload":"material/briefcase-upload.svg","material-briefcase-variant-off-outline":"material/briefcase-variant-off-outline.svg","material-briefcase-variant-off":"material/briefcase-variant-off.svg","material-briefcase-variant-outline":"material/briefcase-variant-outline.svg","material-briefcase-variant":"material/briefcase-variant.svg","material-briefcase":"material/briefcase.svg","material-brightness-1":"material/brightness-1.svg","material-brightness-2":"material/brightness-2.svg","material-brightness-3":"material/brightness-3.svg","material-brightness-4":"material/brightness-4.svg","material-brightness-5":"material/brightness-5.svg","material-brightness-6":"material/brightness-6.svg","material-brightness-7":"material/brightness-7.svg","material-brightness-auto":"material/brightness-auto.svg","material-brightness-percent":"material/brightness-percent.svg","material-broadcast-off":"material/broadcast-off.svg","material-broadcast":"material/broadcast.svg","material-broom":"material/broom.svg","material-brush-off":"material/brush-off.svg","material-brush-outline":"material/brush-outline.svg","material-brush-variant":"material/brush-variant.svg","material-brush":"material/brush.svg","material-bucket-outline":"material/bucket-outline.svg","material-bucket":"material/bucket.svg","material-buffet":"material/buffet.svg","material-bug-check-outline":"material/bug-check-outline.svg","material-bug-check":"material/bug-check.svg","material-bug-outline":"material/bug-outline.svg","material-bug-pause-outline":"material/bug-pause-outline.svg","material-bug-pause":"material/bug-pause.svg","material-bug-play-outline":"material/bug-play-outline.svg","material-bug-play":"material/bug-play.svg","material-bug-stop-outline":"material/bug-stop-outline.svg","material-bug-stop":"material/bug-stop.svg","material-bug":"material/bug.svg","material-bugle":"material/bugle.svg","material-bulkhead-light":"material/bulkhead-light.svg","material-bulldozer":"material/bulldozer.svg","material-bullet":"material/bullet.svg","material-bulletin-board":"material/bulletin-board.svg","material-bullhorn-outline":"material/bullhorn-outline.svg","material-bullhorn-variant-outline":"material/bullhorn-variant-outline.svg","material-bullhorn-variant":"material/bullhorn-variant.svg","material-bullhorn":"material/bullhorn.svg","material-bullseye-arrow":"material/bullseye-arrow.svg","material-bullseye":"material/bullseye.svg","material-bulma":"material/bulma.svg","material-bunk-bed-outline":"material/bunk-bed-outline.svg","material-bunk-bed":"material/bunk-bed.svg","material-bus-alert":"material/bus-alert.svg","material-bus-articulated-end":"material/bus-articulated-end.svg","material-bus-articulated-front":"material/bus-articulated-front.svg","material-bus-clock":"material/bus-clock.svg","material-bus-double-decker":"material/bus-double-decker.svg","material-bus-electric":"material/bus-electric.svg","material-bus-marker":"material/bus-marker.svg","material-bus-multiple":"material/bus-multiple.svg","material-bus-school":"material/bus-school.svg","material-bus-side":"material/bus-side.svg","material-bus-stop-covered":"material/bus-stop-covered.svg","material-bus-stop-uncovered":"material/bus-stop-uncovered.svg","material-bus-stop":"material/bus-stop.svg","material-bus":"material/bus.svg","material-butterfly-outline":"material/butterfly-outline.svg","material-butterfly":"material/butterfly.svg","material-button-cursor":"material/button-cursor.svg","material-button-pointer":"material/button-pointer.svg","material-cabin-a-frame":"material/cabin-a-frame.svg","material-cable-data":"material/cable-data.svg","material-cached":"material/cached.svg","material-cactus":"material/cactus.svg","material-cake-layered":"material/cake-layered.svg","material-cake-variant-outline":"material/cake-variant-outline.svg","material-cake-variant":"material/cake-variant.svg","material-cake":"material/cake.svg","material-calculator-variant-outline":"material/calculator-variant-outline.svg","material-calculator-variant":"material/calculator-variant.svg","material-calculator":"material/calculator.svg","material-calendar-account-outline":"material/calendar-account-outline.svg","material-calendar-account":"material/calendar-account.svg","material-calendar-alert-outline":"material/calendar-alert-outline.svg","material-calendar-alert":"material/calendar-alert.svg","material-calendar-arrow-left":"material/calendar-arrow-left.svg","material-calendar-arrow-right":"material/calendar-arrow-right.svg","material-calendar-badge-outline":"material/calendar-badge-outline.svg","material-calendar-badge":"material/calendar-badge.svg","material-calendar-blank-multiple":"material/calendar-blank-multiple.svg","material-calendar-blank-outline":"material/calendar-blank-outline.svg","material-calendar-blank":"material/calendar-blank.svg","material-calendar-check-outline":"material/calendar-check-outline.svg","material-calendar-check":"material/calendar-check.svg","material-calendar-clock-outline":"material/calendar-clock-outline.svg","material-calendar-clock":"material/calendar-clock.svg","material-calendar-collapse-horizontal-outline":"material/calendar-collapse-horizontal-outline.svg","material-calendar-collapse-horizontal":"material/calendar-collapse-horizontal.svg","material-calendar-cursor-outline":"material/calendar-cursor-outline.svg","material-calendar-cursor":"material/calendar-cursor.svg","material-calendar-edit-outline":"material/calendar-edit-outline.svg","material-calendar-edit":"material/calendar-edit.svg","material-calendar-end-outline":"material/calendar-end-outline.svg","material-calendar-end":"material/calendar-end.svg","material-calendar-expand-horizontal-outline":"material/calendar-expand-horizontal-outline.svg","material-calendar-expand-horizontal":"material/calendar-expand-horizontal.svg","material-calendar-export-outline":"material/calendar-export-outline.svg","material-calendar-export":"material/calendar-export.svg","material-calendar-filter-outline":"material/calendar-filter-outline.svg","material-calendar-filter":"material/calendar-filter.svg","material-calendar-heart-outline":"material/calendar-heart-outline.svg","material-calendar-heart":"material/calendar-heart.svg","material-calendar-import-outline":"material/calendar-import-outline.svg","material-calendar-import":"material/calendar-import.svg","material-calendar-lock-open-outline":"material/calendar-lock-open-outline.svg","material-calendar-lock-open":"material/calendar-lock-open.svg","material-calendar-lock-outline":"material/calendar-lock-outline.svg","material-calendar-lock":"material/calendar-lock.svg","material-calendar-minus-outline":"material/calendar-minus-outline.svg","material-calendar-minus":"material/calendar-minus.svg","material-calendar-month-outline":"material/calendar-month-outline.svg","material-calendar-month":"material/calendar-month.svg","material-calendar-multiple-check":"material/calendar-multiple-check.svg","material-calendar-multiple":"material/calendar-multiple.svg","material-calendar-multiselect-outline":"material/calendar-multiselect-outline.svg","material-calendar-multiselect":"material/calendar-multiselect.svg","material-calendar-outline":"material/calendar-outline.svg","material-calendar-plus-outline":"material/calendar-plus-outline.svg","material-calendar-plus":"material/calendar-plus.svg","material-calendar-question-outline":"material/calendar-question-outline.svg","material-calendar-question":"material/calendar-question.svg","material-calendar-range-outline":"material/calendar-range-outline.svg","material-calendar-range":"material/calendar-range.svg","material-calendar-refresh-outline":"material/calendar-refresh-outline.svg","material-calendar-refresh":"material/calendar-refresh.svg","material-calendar-remove-outline":"material/calendar-remove-outline.svg","material-calendar-remove":"material/calendar-remove.svg","material-calendar-search-outline":"material/calendar-search-outline.svg","material-calendar-search":"material/calendar-search.svg","material-calendar-star-outline":"material/calendar-star-outline.svg","material-calendar-star":"material/calendar-star.svg","material-calendar-start-outline":"material/calendar-start-outline.svg","material-calendar-start":"material/calendar-start.svg","material-calendar-sync-outline":"material/calendar-sync-outline.svg","material-calendar-sync":"material/calendar-sync.svg","material-calendar-text-outline":"material/calendar-text-outline.svg","material-calendar-text":"material/calendar-text.svg","material-calendar-today-outline":"material/calendar-today-outline.svg","material-calendar-today":"material/calendar-today.svg","material-calendar-week-begin-outline":"material/calendar-week-begin-outline.svg","material-calendar-week-begin":"material/calendar-week-begin.svg","material-calendar-week-outline":"material/calendar-week-outline.svg","material-calendar-week":"material/calendar-week.svg","material-calendar-weekend-outline":"material/calendar-weekend-outline.svg","material-calendar-weekend":"material/calendar-weekend.svg","material-calendar":"material/calendar.svg","material-call-made":"material/call-made.svg","material-call-merge":"material/call-merge.svg","material-call-missed":"material/call-missed.svg","material-call-received":"material/call-received.svg","material-call-split":"material/call-split.svg","material-camcorder-off":"material/camcorder-off.svg","material-camcorder":"material/camcorder.svg","material-camera-account":"material/camera-account.svg","material-camera-burst":"material/camera-burst.svg","material-camera-control":"material/camera-control.svg","material-camera-document-off":"material/camera-document-off.svg","material-camera-document":"material/camera-document.svg","material-camera-enhance-outline":"material/camera-enhance-outline.svg","material-camera-enhance":"material/camera-enhance.svg","material-camera-flip-outline":"material/camera-flip-outline.svg","material-camera-flip":"material/camera-flip.svg","material-camera-front-variant":"material/camera-front-variant.svg","material-camera-front":"material/camera-front.svg","material-camera-gopro":"material/camera-gopro.svg","material-camera-image":"material/camera-image.svg","material-camera-iris":"material/camera-iris.svg","material-camera-lock-outline":"material/camera-lock-outline.svg","material-camera-lock":"material/camera-lock.svg","material-camera-marker-outline":"material/camera-marker-outline.svg","material-camera-marker":"material/camera-marker.svg","material-camera-metering-center":"material/camera-metering-center.svg","material-camera-metering-matrix":"material/camera-metering-matrix.svg","material-camera-metering-partial":"material/camera-metering-partial.svg","material-camera-metering-spot":"material/camera-metering-spot.svg","material-camera-off-outline":"material/camera-off-outline.svg","material-camera-off":"material/camera-off.svg","material-camera-outline":"material/camera-outline.svg","material-camera-party-mode":"material/camera-party-mode.svg","material-camera-plus-outline":"material/camera-plus-outline.svg","material-camera-plus":"material/camera-plus.svg","material-camera-rear-variant":"material/camera-rear-variant.svg","material-camera-rear":"material/camera-rear.svg","material-camera-retake-outline":"material/camera-retake-outline.svg","material-camera-retake":"material/camera-retake.svg","material-camera-switch-outline":"material/camera-switch-outline.svg","material-camera-switch":"material/camera-switch.svg","material-camera-timer":"material/camera-timer.svg","material-camera-wireless-outline":"material/camera-wireless-outline.svg","material-camera-wireless":"material/camera-wireless.svg","material-camera":"material/camera.svg","material-campfire":"material/campfire.svg","material-cancel":"material/cancel.svg","material-candelabra-fire":"material/candelabra-fire.svg","material-candelabra":"material/candelabra.svg","material-candle":"material/candle.svg","material-candy-off-outline":"material/candy-off-outline.svg","material-candy-off":"material/candy-off.svg","material-candy-outline":"material/candy-outline.svg","material-candy":"material/candy.svg","material-candycane":"material/candycane.svg","material-cannabis-off":"material/cannabis-off.svg","material-cannabis":"material/cannabis.svg","material-caps-lock":"material/caps-lock.svg","material-car-2-plus":"material/car-2-plus.svg","material-car-3-plus":"material/car-3-plus.svg","material-car-arrow-left":"material/car-arrow-left.svg","material-car-arrow-right":"material/car-arrow-right.svg","material-car-back":"material/car-back.svg","material-car-battery":"material/car-battery.svg","material-car-brake-abs":"material/car-brake-abs.svg","material-car-brake-alert":"material/car-brake-alert.svg","material-car-brake-fluid-level":"material/car-brake-fluid-level.svg","material-car-brake-hold":"material/car-brake-hold.svg","material-car-brake-low-pressure":"material/car-brake-low-pressure.svg","material-car-brake-parking":"material/car-brake-parking.svg","material-car-brake-retarder":"material/car-brake-retarder.svg","material-car-brake-temperature":"material/car-brake-temperature.svg","material-car-brake-worn-linings":"material/car-brake-worn-linings.svg","material-car-child-seat":"material/car-child-seat.svg","material-car-clock":"material/car-clock.svg","material-car-clutch":"material/car-clutch.svg","material-car-cog":"material/car-cog.svg","material-car-connected":"material/car-connected.svg","material-car-convertible":"material/car-convertible.svg","material-car-coolant-level":"material/car-coolant-level.svg","material-car-cruise-control":"material/car-cruise-control.svg","material-car-defrost-front":"material/car-defrost-front.svg","material-car-defrost-rear":"material/car-defrost-rear.svg","material-car-door-lock":"material/car-door-lock.svg","material-car-door":"material/car-door.svg","material-car-electric-outline":"material/car-electric-outline.svg","material-car-electric":"material/car-electric.svg","material-car-emergency":"material/car-emergency.svg","material-car-esp":"material/car-esp.svg","material-car-estate":"material/car-estate.svg","material-car-hatchback":"material/car-hatchback.svg","material-car-info":"material/car-info.svg","material-car-key":"material/car-key.svg","material-car-lifted-pickup":"material/car-lifted-pickup.svg","material-car-light-alert":"material/car-light-alert.svg","material-car-light-dimmed":"material/car-light-dimmed.svg","material-car-light-fog":"material/car-light-fog.svg","material-car-light-high":"material/car-light-high.svg","material-car-limousine":"material/car-limousine.svg","material-car-multiple":"material/car-multiple.svg","material-car-off":"material/car-off.svg","material-car-outline":"material/car-outline.svg","material-car-parking-lights":"material/car-parking-lights.svg","material-car-pickup":"material/car-pickup.svg","material-car-search-outline":"material/car-search-outline.svg","material-car-search":"material/car-search.svg","material-car-seat-cooler":"material/car-seat-cooler.svg","material-car-seat-heater":"material/car-seat-heater.svg","material-car-seat":"material/car-seat.svg","material-car-select":"material/car-select.svg","material-car-settings":"material/car-settings.svg","material-car-shift-pattern":"material/car-shift-pattern.svg","material-car-side":"material/car-side.svg","material-car-speed-limiter":"material/car-speed-limiter.svg","material-car-sports":"material/car-sports.svg","material-car-tire-alert":"material/car-tire-alert.svg","material-car-traction-control":"material/car-traction-control.svg","material-car-turbocharger":"material/car-turbocharger.svg","material-car-wash":"material/car-wash.svg","material-car-windshield-outline":"material/car-windshield-outline.svg","material-car-windshield":"material/car-windshield.svg","material-car-wireless":"material/car-wireless.svg","material-car-wrench":"material/car-wrench.svg","material-car":"material/car.svg","material-carabiner":"material/carabiner.svg","material-caravan":"material/caravan.svg","material-card-account-details-outline":"material/card-account-details-outline.svg","material-card-account-details-star-outline":"material/card-account-details-star-outline.svg","material-card-account-details-star":"material/card-account-details-star.svg","material-card-account-details":"material/card-account-details.svg","material-card-account-mail-outline":"material/card-account-mail-outline.svg","material-card-account-mail":"material/card-account-mail.svg","material-card-account-phone-outline":"material/card-account-phone-outline.svg","material-card-account-phone":"material/card-account-phone.svg","material-card-bulleted-off-outline":"material/card-bulleted-off-outline.svg","material-card-bulleted-off":"material/card-bulleted-off.svg","material-card-bulleted-outline":"material/card-bulleted-outline.svg","material-card-bulleted-settings-outline":"material/card-bulleted-settings-outline.svg","material-card-bulleted-settings":"material/card-bulleted-settings.svg","material-card-bulleted":"material/card-bulleted.svg","material-card-minus-outline":"material/card-minus-outline.svg","material-card-minus":"material/card-minus.svg","material-card-multiple-outline":"material/card-multiple-outline.svg","material-card-multiple":"material/card-multiple.svg","material-card-off-outline":"material/card-off-outline.svg","material-card-off":"material/card-off.svg","material-card-outline":"material/card-outline.svg","material-card-plus-outline":"material/card-plus-outline.svg","material-card-plus":"material/card-plus.svg","material-card-remove-outline":"material/card-remove-outline.svg","material-card-remove":"material/card-remove.svg","material-card-search-outline":"material/card-search-outline.svg","material-card-search":"material/card-search.svg","material-card-text-outline":"material/card-text-outline.svg","material-card-text":"material/card-text.svg","material-card":"material/card.svg","material-cards-club-outline":"material/cards-club-outline.svg","material-cards-club":"material/cards-club.svg","material-cards-diamond-outline":"material/cards-diamond-outline.svg","material-cards-diamond":"material/cards-diamond.svg","material-cards-heart-outline":"material/cards-heart-outline.svg","material-cards-heart":"material/cards-heart.svg","material-cards-outline":"material/cards-outline.svg","material-cards-playing-club-multiple-outline":"material/cards-playing-club-multiple-outline.svg","material-cards-playing-club-multiple":"material/cards-playing-club-multiple.svg","material-cards-playing-club-outline":"material/cards-playing-club-outline.svg","material-cards-playing-club":"material/cards-playing-club.svg","material-cards-playing-diamond-multiple-outline":"material/cards-playing-diamond-multiple-outline.svg","material-cards-playing-diamond-multiple":"material/cards-playing-diamond-multiple.svg","material-cards-playing-diamond-outline":"material/cards-playing-diamond-outline.svg","material-cards-playing-diamond":"material/cards-playing-diamond.svg","material-cards-playing-heart-multiple-outline":"material/cards-playing-heart-multiple-outline.svg","material-cards-playing-heart-multiple":"material/cards-playing-heart-multiple.svg","material-cards-playing-heart-outline":"material/cards-playing-heart-outline.svg","material-cards-playing-heart":"material/cards-playing-heart.svg","material-cards-playing-outline":"material/cards-playing-outline.svg","material-cards-playing-spade-multiple-outline":"material/cards-playing-spade-multiple-outline.svg","material-cards-playing-spade-multiple":"material/cards-playing-spade-multiple.svg","material-cards-playing-spade-outline":"material/cards-playing-spade-outline.svg","material-cards-playing-spade":"material/cards-playing-spade.svg","material-cards-playing":"material/cards-playing.svg","material-cards-spade-outline":"material/cards-spade-outline.svg","material-cards-spade":"material/cards-spade.svg","material-cards-variant":"material/cards-variant.svg","material-cards":"material/cards.svg","material-carrot":"material/carrot.svg","material-cart-arrow-down":"material/cart-arrow-down.svg","material-cart-arrow-right":"material/cart-arrow-right.svg","material-cart-arrow-up":"material/cart-arrow-up.svg","material-cart-check":"material/cart-check.svg","material-cart-heart":"material/cart-heart.svg","material-cart-minus":"material/cart-minus.svg","material-cart-off":"material/cart-off.svg","material-cart-outline":"material/cart-outline.svg","material-cart-percent":"material/cart-percent.svg","material-cart-plus":"material/cart-plus.svg","material-cart-remove":"material/cart-remove.svg","material-cart-variant":"material/cart-variant.svg","material-cart":"material/cart.svg","material-case-sensitive-alt":"material/case-sensitive-alt.svg","material-cash-100":"material/cash-100.svg","material-cash-check":"material/cash-check.svg","material-cash-clock":"material/cash-clock.svg","material-cash-fast":"material/cash-fast.svg","material-cash-lock-open":"material/cash-lock-open.svg","material-cash-lock":"material/cash-lock.svg","material-cash-marker":"material/cash-marker.svg","material-cash-minus":"material/cash-minus.svg","material-cash-multiple":"material/cash-multiple.svg","material-cash-plus":"material/cash-plus.svg","material-cash-refund":"material/cash-refund.svg","material-cash-register":"material/cash-register.svg","material-cash-remove":"material/cash-remove.svg","material-cash-sync":"material/cash-sync.svg","material-cash":"material/cash.svg","material-cassette":"material/cassette.svg","material-cast-audio-variant":"material/cast-audio-variant.svg","material-cast-audio":"material/cast-audio.svg","material-cast-connected":"material/cast-connected.svg","material-cast-education":"material/cast-education.svg","material-cast-off":"material/cast-off.svg","material-cast-variant":"material/cast-variant.svg","material-cast":"material/cast.svg","material-castle":"material/castle.svg","material-cat":"material/cat.svg","material-cctv-off":"material/cctv-off.svg","material-cctv":"material/cctv.svg","material-ceiling-fan-light":"material/ceiling-fan-light.svg","material-ceiling-fan":"material/ceiling-fan.svg","material-ceiling-light-multiple-outline":"material/ceiling-light-multiple-outline.svg","material-ceiling-light-multiple":"material/ceiling-light-multiple.svg","material-ceiling-light-outline":"material/ceiling-light-outline.svg","material-ceiling-light":"material/ceiling-light.svg","material-cellphone-arrow-down-variant":"material/cellphone-arrow-down-variant.svg","material-cellphone-arrow-down":"material/cellphone-arrow-down.svg","material-cellphone-basic":"material/cellphone-basic.svg","material-cellphone-charging":"material/cellphone-charging.svg","material-cellphone-check":"material/cellphone-check.svg","material-cellphone-cog":"material/cellphone-cog.svg","material-cellphone-dock":"material/cellphone-dock.svg","material-cellphone-information":"material/cellphone-information.svg","material-cellphone-key":"material/cellphone-key.svg","material-cellphone-link-off":"material/cellphone-link-off.svg","material-cellphone-link":"material/cellphone-link.svg","material-cellphone-lock":"material/cellphone-lock.svg","material-cellphone-marker":"material/cellphone-marker.svg","material-cellphone-message-off":"material/cellphone-message-off.svg","material-cellphone-message":"material/cellphone-message.svg","material-cellphone-nfc-off":"material/cellphone-nfc-off.svg","material-cellphone-nfc":"material/cellphone-nfc.svg","material-cellphone-off":"material/cellphone-off.svg","material-cellphone-play":"material/cellphone-play.svg","material-cellphone-remove":"material/cellphone-remove.svg","material-cellphone-screenshot":"material/cellphone-screenshot.svg","material-cellphone-settings":"material/cellphone-settings.svg","material-cellphone-sound":"material/cellphone-sound.svg","material-cellphone-text":"material/cellphone-text.svg","material-cellphone-wireless":"material/cellphone-wireless.svg","material-cellphone":"material/cellphone.svg","material-centos":"material/centos.svg","material-certificate-outline":"material/certificate-outline.svg","material-certificate":"material/certificate.svg","material-chair-rolling":"material/chair-rolling.svg","material-chair-school":"material/chair-school.svg","material-chandelier":"material/chandelier.svg","material-charity":"material/charity.svg","material-chart-arc":"material/chart-arc.svg","material-chart-areaspline-variant":"material/chart-areaspline-variant.svg","material-chart-areaspline":"material/chart-areaspline.svg","material-chart-bar-stacked":"material/chart-bar-stacked.svg","material-chart-bar":"material/chart-bar.svg","material-chart-bell-curve-cumulative":"material/chart-bell-curve-cumulative.svg","material-chart-bell-curve":"material/chart-bell-curve.svg","material-chart-box-outline":"material/chart-box-outline.svg","material-chart-box-plus-outline":"material/chart-box-plus-outline.svg","material-chart-box":"material/chart-box.svg","material-chart-bubble":"material/chart-bubble.svg","material-chart-donut-variant":"material/chart-donut-variant.svg","material-chart-donut":"material/chart-donut.svg","material-chart-gantt":"material/chart-gantt.svg","material-chart-histogram":"material/chart-histogram.svg","material-chart-line-stacked":"material/chart-line-stacked.svg","material-chart-line-variant":"material/chart-line-variant.svg","material-chart-line":"material/chart-line.svg","material-chart-multiline":"material/chart-multiline.svg","material-chart-multiple":"material/chart-multiple.svg","material-chart-pie":"material/chart-pie.svg","material-chart-ppf":"material/chart-ppf.svg","material-chart-sankey-variant":"material/chart-sankey-variant.svg","material-chart-sankey":"material/chart-sankey.svg","material-chart-scatter-plot-hexbin":"material/chart-scatter-plot-hexbin.svg","material-chart-scatter-plot":"material/chart-scatter-plot.svg","material-chart-timeline-variant-shimmer":"material/chart-timeline-variant-shimmer.svg","material-chart-timeline-variant":"material/chart-timeline-variant.svg","material-chart-timeline":"material/chart-timeline.svg","material-chart-tree":"material/chart-tree.svg","material-chart-waterfall":"material/chart-waterfall.svg","material-chat-alert-outline":"material/chat-alert-outline.svg","material-chat-alert":"material/chat-alert.svg","material-chat-minus-outline":"material/chat-minus-outline.svg","material-chat-minus":"material/chat-minus.svg","material-chat-outline":"material/chat-outline.svg","material-chat-plus-outline":"material/chat-plus-outline.svg","material-chat-plus":"material/chat-plus.svg","material-chat-processing-outline":"material/chat-processing-outline.svg","material-chat-processing":"material/chat-processing.svg","material-chat-question-outline":"material/chat-question-outline.svg","material-chat-question":"material/chat-question.svg","material-chat-remove-outline":"material/chat-remove-outline.svg","material-chat-remove":"material/chat-remove.svg","material-chat-sleep-outline":"material/chat-sleep-outline.svg","material-chat-sleep":"material/chat-sleep.svg","material-chat":"material/chat.svg","material-check-all":"material/check-all.svg","material-check-bold":"material/check-bold.svg","material-check-circle-outline":"material/check-circle-outline.svg","material-check-circle":"material/check-circle.svg","material-check-decagram-outline":"material/check-decagram-outline.svg","material-check-decagram":"material/check-decagram.svg","material-check-network-outline":"material/check-network-outline.svg","material-check-network":"material/check-network.svg","material-check-outline":"material/check-outline.svg","material-check-underline-circle-outline":"material/check-underline-circle-outline.svg","material-check-underline-circle":"material/check-underline-circle.svg","material-check-underline":"material/check-underline.svg","material-check":"material/check.svg","material-checkbook":"material/checkbook.svg","material-checkbox-blank-badge-outline":"material/checkbox-blank-badge-outline.svg","material-checkbox-blank-badge":"material/checkbox-blank-badge.svg","material-checkbox-blank-circle-outline":"material/checkbox-blank-circle-outline.svg","material-checkbox-blank-circle":"material/checkbox-blank-circle.svg","material-checkbox-blank-off-outline":"material/checkbox-blank-off-outline.svg","material-checkbox-blank-off":"material/checkbox-blank-off.svg","material-checkbox-blank-outline":"material/checkbox-blank-outline.svg","material-checkbox-blank":"material/checkbox-blank.svg","material-checkbox-intermediate-variant":"material/checkbox-intermediate-variant.svg","material-checkbox-intermediate":"material/checkbox-intermediate.svg","material-checkbox-marked-circle-outline":"material/checkbox-marked-circle-outline.svg","material-checkbox-marked-circle-plus-outline":"material/checkbox-marked-circle-plus-outline.svg","material-checkbox-marked-circle":"material/checkbox-marked-circle.svg","material-checkbox-marked-outline":"material/checkbox-marked-outline.svg","material-checkbox-marked":"material/checkbox-marked.svg","material-checkbox-multiple-blank-circle-outline":"material/checkbox-multiple-blank-circle-outline.svg","material-checkbox-multiple-blank-circle":"material/checkbox-multiple-blank-circle.svg","material-checkbox-multiple-blank-outline":"material/checkbox-multiple-blank-outline.svg","material-checkbox-multiple-blank":"material/checkbox-multiple-blank.svg","material-checkbox-multiple-marked-circle-outline":"material/checkbox-multiple-marked-circle-outline.svg","material-checkbox-multiple-marked-circle":"material/checkbox-multiple-marked-circle.svg","material-checkbox-multiple-marked-outline":"material/checkbox-multiple-marked-outline.svg","material-checkbox-multiple-marked":"material/checkbox-multiple-marked.svg","material-checkbox-multiple-outline":"material/checkbox-multiple-outline.svg","material-checkbox-outline":"material/checkbox-outline.svg","material-checkerboard-minus":"material/checkerboard-minus.svg","material-checkerboard-plus":"material/checkerboard-plus.svg","material-checkerboard-remove":"material/checkerboard-remove.svg","material-checkerboard":"material/checkerboard.svg","material-cheese-off":"material/cheese-off.svg","material-cheese":"material/cheese.svg","material-chef-hat":"material/chef-hat.svg","material-chemical-weapon":"material/chemical-weapon.svg","material-chess-bishop":"material/chess-bishop.svg","material-chess-king":"material/chess-king.svg","material-chess-knight":"material/chess-knight.svg","material-chess-pawn":"material/chess-pawn.svg","material-chess-queen":"material/chess-queen.svg","material-chess-rook":"material/chess-rook.svg","material-chevron-double-down":"material/chevron-double-down.svg","material-chevron-double-left":"material/chevron-double-left.svg","material-chevron-double-right":"material/chevron-double-right.svg","material-chevron-double-up":"material/chevron-double-up.svg","material-chevron-down-box-outline":"material/chevron-down-box-outline.svg","material-chevron-down-box":"material/chevron-down-box.svg","material-chevron-down-circle-outline":"material/chevron-down-circle-outline.svg","material-chevron-down-circle":"material/chevron-down-circle.svg","material-chevron-down":"material/chevron-down.svg","material-chevron-left-box-outline":"material/chevron-left-box-outline.svg","material-chevron-left-box":"material/chevron-left-box.svg","material-chevron-left-circle-outline":"material/chevron-left-circle-outline.svg","material-chevron-left-circle":"material/chevron-left-circle.svg","material-chevron-left":"material/chevron-left.svg","material-chevron-right-box-outline":"material/chevron-right-box-outline.svg","material-chevron-right-box":"material/chevron-right-box.svg","material-chevron-right-circle-outline":"material/chevron-right-circle-outline.svg","material-chevron-right-circle":"material/chevron-right-circle.svg","material-chevron-right":"material/chevron-right.svg","material-chevron-triple-down":"material/chevron-triple-down.svg","material-chevron-triple-left":"material/chevron-triple-left.svg","material-chevron-triple-right":"material/chevron-triple-right.svg","material-chevron-triple-up":"material/chevron-triple-up.svg","material-chevron-up-box-outline":"material/chevron-up-box-outline.svg","material-chevron-up-box":"material/chevron-up-box.svg","material-chevron-up-circle-outline":"material/chevron-up-circle-outline.svg","material-chevron-up-circle":"material/chevron-up-circle.svg","material-chevron-up":"material/chevron-up.svg","material-chili-alert-outline":"material/chili-alert-outline.svg","material-chili-alert":"material/chili-alert.svg","material-chili-hot-outline":"material/chili-hot-outline.svg","material-chili-hot":"material/chili-hot.svg","material-chili-medium-outline":"material/chili-medium-outline.svg","material-chili-medium":"material/chili-medium.svg","material-chili-mild-outline":"material/chili-mild-outline.svg","material-chili-mild":"material/chili-mild.svg","material-chili-off-outline":"material/chili-off-outline.svg","material-chili-off":"material/chili-off.svg","material-chip":"material/chip.svg","material-church-outline":"material/church-outline.svg","material-church":"material/church.svg","material-cigar-off":"material/cigar-off.svg","material-cigar":"material/cigar.svg","material-circle-box-outline":"material/circle-box-outline.svg","material-circle-box":"material/circle-box.svg","material-circle-double":"material/circle-double.svg","material-circle-edit-outline":"material/circle-edit-outline.svg","material-circle-expand":"material/circle-expand.svg","material-circle-half-full":"material/circle-half-full.svg","material-circle-half":"material/circle-half.svg","material-circle-medium":"material/circle-medium.svg","material-circle-multiple-outline":"material/circle-multiple-outline.svg","material-circle-multiple":"material/circle-multiple.svg","material-circle-off-outline":"material/circle-off-outline.svg","material-circle-opacity":"material/circle-opacity.svg","material-circle-outline":"material/circle-outline.svg","material-circle-slice-1":"material/circle-slice-1.svg","material-circle-slice-2":"material/circle-slice-2.svg","material-circle-slice-3":"material/circle-slice-3.svg","material-circle-slice-4":"material/circle-slice-4.svg","material-circle-slice-5":"material/circle-slice-5.svg","material-circle-slice-6":"material/circle-slice-6.svg","material-circle-slice-7":"material/circle-slice-7.svg","material-circle-slice-8":"material/circle-slice-8.svg","material-circle-small":"material/circle-small.svg","material-circle":"material/circle.svg","material-circular-saw":"material/circular-saw.svg","material-city-variant-outline":"material/city-variant-outline.svg","material-city-variant":"material/city-variant.svg","material-city":"material/city.svg","material-clipboard-account-outline":"material/clipboard-account-outline.svg","material-clipboard-account":"material/clipboard-account.svg","material-clipboard-alert-outline":"material/clipboard-alert-outline.svg","material-clipboard-alert":"material/clipboard-alert.svg","material-clipboard-arrow-down-outline":"material/clipboard-arrow-down-outline.svg","material-clipboard-arrow-down":"material/clipboard-arrow-down.svg","material-clipboard-arrow-left-outline":"material/clipboard-arrow-left-outline.svg","material-clipboard-arrow-left":"material/clipboard-arrow-left.svg","material-clipboard-arrow-right-outline":"material/clipboard-arrow-right-outline.svg","material-clipboard-arrow-right":"material/clipboard-arrow-right.svg","material-clipboard-arrow-up-outline":"material/clipboard-arrow-up-outline.svg","material-clipboard-arrow-up":"material/clipboard-arrow-up.svg","material-clipboard-check-multiple-outline":"material/clipboard-check-multiple-outline.svg","material-clipboard-check-multiple":"material/clipboard-check-multiple.svg","material-clipboard-check-outline":"material/clipboard-check-outline.svg","material-clipboard-check":"material/clipboard-check.svg","material-clipboard-clock-outline":"material/clipboard-clock-outline.svg","material-clipboard-clock":"material/clipboard-clock.svg","material-clipboard-edit-outline":"material/clipboard-edit-outline.svg","material-clipboard-edit":"material/clipboard-edit.svg","material-clipboard-file-outline":"material/clipboard-file-outline.svg","material-clipboard-file":"material/clipboard-file.svg","material-clipboard-flow-outline":"material/clipboard-flow-outline.svg","material-clipboard-flow":"material/clipboard-flow.svg","material-clipboard-list-outline":"material/clipboard-list-outline.svg","material-clipboard-list":"material/clipboard-list.svg","material-clipboard-minus-outline":"material/clipboard-minus-outline.svg","material-clipboard-minus":"material/clipboard-minus.svg","material-clipboard-multiple-outline":"material/clipboard-multiple-outline.svg","material-clipboard-multiple":"material/clipboard-multiple.svg","material-clipboard-off-outline":"material/clipboard-off-outline.svg","material-clipboard-off":"material/clipboard-off.svg","material-clipboard-outline":"material/clipboard-outline.svg","material-clipboard-play-multiple-outline":"material/clipboard-play-multiple-outline.svg","material-clipboard-play-multiple":"material/clipboard-play-multiple.svg","material-clipboard-play-outline":"material/clipboard-play-outline.svg","material-clipboard-play":"material/clipboard-play.svg","material-clipboard-plus-outline":"material/clipboard-plus-outline.svg","material-clipboard-plus":"material/clipboard-plus.svg","material-clipboard-pulse-outline":"material/clipboard-pulse-outline.svg","material-clipboard-pulse":"material/clipboard-pulse.svg","material-clipboard-remove-outline":"material/clipboard-remove-outline.svg","material-clipboard-remove":"material/clipboard-remove.svg","material-clipboard-search-outline":"material/clipboard-search-outline.svg","material-clipboard-search":"material/clipboard-search.svg","material-clipboard-text-clock-outline":"material/clipboard-text-clock-outline.svg","material-clipboard-text-clock":"material/clipboard-text-clock.svg","material-clipboard-text-multiple-outline":"material/clipboard-text-multiple-outline.svg","material-clipboard-text-multiple":"material/clipboard-text-multiple.svg","material-clipboard-text-off-outline":"material/clipboard-text-off-outline.svg","material-clipboard-text-off":"material/clipboard-text-off.svg","material-clipboard-text-outline":"material/clipboard-text-outline.svg","material-clipboard-text-play-outline":"material/clipboard-text-play-outline.svg","material-clipboard-text-play":"material/clipboard-text-play.svg","material-clipboard-text-search-outline":"material/clipboard-text-search-outline.svg","material-clipboard-text-search":"material/clipboard-text-search.svg","material-clipboard-text":"material/clipboard-text.svg","material-clipboard":"material/clipboard.svg","material-clippy":"material/clippy.svg","material-clock-alert-outline":"material/clock-alert-outline.svg","material-clock-alert":"material/clock-alert.svg","material-clock-check-outline":"material/clock-check-outline.svg","material-clock-check":"material/clock-check.svg","material-clock-digital":"material/clock-digital.svg","material-clock-edit-outline":"material/clock-edit-outline.svg","material-clock-edit":"material/clock-edit.svg","material-clock-end":"material/clock-end.svg","material-clock-fast":"material/clock-fast.svg","material-clock-in":"material/clock-in.svg","material-clock-minus-outline":"material/clock-minus-outline.svg","material-clock-minus":"material/clock-minus.svg","material-clock-out":"material/clock-out.svg","material-clock-outline":"material/clock-outline.svg","material-clock-plus-outline":"material/clock-plus-outline.svg","material-clock-plus":"material/clock-plus.svg","material-clock-remove-outline":"material/clock-remove-outline.svg","material-clock-remove":"material/clock-remove.svg","material-clock-start":"material/clock-start.svg","material-clock-time-eight-outline":"material/clock-time-eight-outline.svg","material-clock-time-eight":"material/clock-time-eight.svg","material-clock-time-eleven-outline":"material/clock-time-eleven-outline.svg","material-clock-time-eleven":"material/clock-time-eleven.svg","material-clock-time-five-outline":"material/clock-time-five-outline.svg","material-clock-time-five":"material/clock-time-five.svg","material-clock-time-four-outline":"material/clock-time-four-outline.svg","material-clock-time-four":"material/clock-time-four.svg","material-clock-time-nine-outline":"material/clock-time-nine-outline.svg","material-clock-time-nine":"material/clock-time-nine.svg","material-clock-time-one-outline":"material/clock-time-one-outline.svg","material-clock-time-one":"material/clock-time-one.svg","material-clock-time-seven-outline":"material/clock-time-seven-outline.svg","material-clock-time-seven":"material/clock-time-seven.svg","material-clock-time-six-outline":"material/clock-time-six-outline.svg","material-clock-time-six":"material/clock-time-six.svg","material-clock-time-ten-outline":"material/clock-time-ten-outline.svg","material-clock-time-ten":"material/clock-time-ten.svg","material-clock-time-three-outline":"material/clock-time-three-outline.svg","material-clock-time-three":"material/clock-time-three.svg","material-clock-time-twelve-outline":"material/clock-time-twelve-outline.svg","material-clock-time-twelve":"material/clock-time-twelve.svg","material-clock-time-two-outline":"material/clock-time-two-outline.svg","material-clock-time-two":"material/clock-time-two.svg","material-clock":"material/clock.svg","material-close-box-multiple-outline":"material/close-box-multiple-outline.svg","material-close-box-multiple":"material/close-box-multiple.svg","material-close-box-outline":"material/close-box-outline.svg","material-close-box":"material/close-box.svg","material-close-circle-multiple-outline":"material/close-circle-multiple-outline.svg","material-close-circle-multiple":"material/close-circle-multiple.svg","material-close-circle-outline":"material/close-circle-outline.svg","material-close-circle":"material/close-circle.svg","material-close-network-outline":"material/close-network-outline.svg","material-close-network":"material/close-network.svg","material-close-octagon-outline":"material/close-octagon-outline.svg","material-close-octagon":"material/close-octagon.svg","material-close-outline":"material/close-outline.svg","material-close-thick":"material/close-thick.svg","material-close":"material/close.svg","material-closed-caption-outline":"material/closed-caption-outline.svg","material-closed-caption":"material/closed-caption.svg","material-cloud-alert":"material/cloud-alert.svg","material-cloud-braces":"material/cloud-braces.svg","material-cloud-check-outline":"material/cloud-check-outline.svg","material-cloud-check":"material/cloud-check.svg","material-cloud-circle":"material/cloud-circle.svg","material-cloud-download-outline":"material/cloud-download-outline.svg","material-cloud-download":"material/cloud-download.svg","material-cloud-lock-outline":"material/cloud-lock-outline.svg","material-cloud-lock":"material/cloud-lock.svg","material-cloud-off-outline":"material/cloud-off-outline.svg","material-cloud-outline":"material/cloud-outline.svg","material-cloud-percent-outline":"material/cloud-percent-outline.svg","material-cloud-percent":"material/cloud-percent.svg","material-cloud-print-outline":"material/cloud-print-outline.svg","material-cloud-print":"material/cloud-print.svg","material-cloud-question":"material/cloud-question.svg","material-cloud-refresh":"material/cloud-refresh.svg","material-cloud-search-outline":"material/cloud-search-outline.svg","material-cloud-search":"material/cloud-search.svg","material-cloud-sync-outline":"material/cloud-sync-outline.svg","material-cloud-sync":"material/cloud-sync.svg","material-cloud-tags":"material/cloud-tags.svg","material-cloud-upload-outline":"material/cloud-upload-outline.svg","material-cloud-upload":"material/cloud-upload.svg","material-cloud":"material/cloud.svg","material-clouds":"material/clouds.svg","material-clover":"material/clover.svg","material-coach-lamp-variant":"material/coach-lamp-variant.svg","material-coach-lamp":"material/coach-lamp.svg","material-coat-rack":"material/coat-rack.svg","material-code-array":"material/code-array.svg","material-code-braces-box":"material/code-braces-box.svg","material-code-braces":"material/code-braces.svg","material-code-brackets":"material/code-brackets.svg","material-code-equal":"material/code-equal.svg","material-code-greater-than-or-equal":"material/code-greater-than-or-equal.svg","material-code-greater-than":"material/code-greater-than.svg","material-code-json":"material/code-json.svg","material-code-less-than-or-equal":"material/code-less-than-or-equal.svg","material-code-less-than":"material/code-less-than.svg","material-code-not-equal-variant":"material/code-not-equal-variant.svg","material-code-not-equal":"material/code-not-equal.svg","material-code-parentheses-box":"material/code-parentheses-box.svg","material-code-parentheses":"material/code-parentheses.svg","material-code-string":"material/code-string.svg","material-code-tags-check":"material/code-tags-check.svg","material-code-tags":"material/code-tags.svg","material-codepen":"material/codepen.svg","material-coffee-maker-check-outline":"material/coffee-maker-check-outline.svg","material-coffee-maker-check":"material/coffee-maker-check.svg","material-coffee-maker-outline":"material/coffee-maker-outline.svg","material-coffee-maker":"material/coffee-maker.svg","material-coffee-off-outline":"material/coffee-off-outline.svg","material-coffee-off":"material/coffee-off.svg","material-coffee-outline":"material/coffee-outline.svg","material-coffee-to-go-outline":"material/coffee-to-go-outline.svg","material-coffee-to-go":"material/coffee-to-go.svg","material-coffee":"material/coffee.svg","material-coffin":"material/coffin.svg","material-cog-box":"material/cog-box.svg","material-cog-clockwise":"material/cog-clockwise.svg","material-cog-counterclockwise":"material/cog-counterclockwise.svg","material-cog-off-outline":"material/cog-off-outline.svg","material-cog-off":"material/cog-off.svg","material-cog-outline":"material/cog-outline.svg","material-cog-pause-outline":"material/cog-pause-outline.svg","material-cog-pause":"material/cog-pause.svg","material-cog-play-outline":"material/cog-play-outline.svg","material-cog-play":"material/cog-play.svg","material-cog-refresh-outline":"material/cog-refresh-outline.svg","material-cog-refresh":"material/cog-refresh.svg","material-cog-stop-outline":"material/cog-stop-outline.svg","material-cog-stop":"material/cog-stop.svg","material-cog-sync-outline":"material/cog-sync-outline.svg","material-cog-sync":"material/cog-sync.svg","material-cog-transfer-outline":"material/cog-transfer-outline.svg","material-cog-transfer":"material/cog-transfer.svg","material-cog":"material/cog.svg","material-cogs":"material/cogs.svg","material-collage":"material/collage.svg","material-collapse-all-outline":"material/collapse-all-outline.svg","material-collapse-all":"material/collapse-all.svg","material-color-helper":"material/color-helper.svg","material-comma-box-outline":"material/comma-box-outline.svg","material-comma-box":"material/comma-box.svg","material-comma-circle-outline":"material/comma-circle-outline.svg","material-comma-circle":"material/comma-circle.svg","material-comma":"material/comma.svg","material-comment-account-outline":"material/comment-account-outline.svg","material-comment-account":"material/comment-account.svg","material-comment-alert-outline":"material/comment-alert-outline.svg","material-comment-alert":"material/comment-alert.svg","material-comment-arrow-left-outline":"material/comment-arrow-left-outline.svg","material-comment-arrow-left":"material/comment-arrow-left.svg","material-comment-arrow-right-outline":"material/comment-arrow-right-outline.svg","material-comment-arrow-right":"material/comment-arrow-right.svg","material-comment-bookmark-outline":"material/comment-bookmark-outline.svg","material-comment-bookmark":"material/comment-bookmark.svg","material-comment-check-outline":"material/comment-check-outline.svg","material-comment-check":"material/comment-check.svg","material-comment-edit-outline":"material/comment-edit-outline.svg","material-comment-edit":"material/comment-edit.svg","material-comment-eye-outline":"material/comment-eye-outline.svg","material-comment-eye":"material/comment-eye.svg","material-comment-flash-outline":"material/comment-flash-outline.svg","material-comment-flash":"material/comment-flash.svg","material-comment-minus-outline":"material/comment-minus-outline.svg","material-comment-minus":"material/comment-minus.svg","material-comment-multiple-outline":"material/comment-multiple-outline.svg","material-comment-multiple":"material/comment-multiple.svg","material-comment-off-outline":"material/comment-off-outline.svg","material-comment-off":"material/comment-off.svg","material-comment-outline":"material/comment-outline.svg","material-comment-plus-outline":"material/comment-plus-outline.svg","material-comment-plus":"material/comment-plus.svg","material-comment-processing-outline":"material/comment-processing-outline.svg","material-comment-processing":"material/comment-processing.svg","material-comment-question-outline":"material/comment-question-outline.svg","material-comment-question":"material/comment-question.svg","material-comment-quote-outline":"material/comment-quote-outline.svg","material-comment-quote":"material/comment-quote.svg","material-comment-remove-outline":"material/comment-remove-outline.svg","material-comment-remove":"material/comment-remove.svg","material-comment-search-outline":"material/comment-search-outline.svg","material-comment-search":"material/comment-search.svg","material-comment-text-multiple-outline":"material/comment-text-multiple-outline.svg","material-comment-text-multiple":"material/comment-text-multiple.svg","material-comment-text-outline":"material/comment-text-outline.svg","material-comment-text":"material/comment-text.svg","material-comment":"material/comment.svg","material-compare-horizontal":"material/compare-horizontal.svg","material-compare-remove":"material/compare-remove.svg","material-compare-vertical":"material/compare-vertical.svg","material-compare":"material/compare.svg","material-compass-off-outline":"material/compass-off-outline.svg","material-compass-off":"material/compass-off.svg","material-compass-outline":"material/compass-outline.svg","material-compass-rose":"material/compass-rose.svg","material-compass":"material/compass.svg","material-compost":"material/compost.svg","material-cone-off":"material/cone-off.svg","material-cone":"material/cone.svg","material-connection":"material/connection.svg","material-console-line":"material/console-line.svg","material-console-network-outline":"material/console-network-outline.svg","material-console-network":"material/console-network.svg","material-console":"material/console.svg","material-consolidate":"material/consolidate.svg","material-contactless-payment-circle-outline":"material/contactless-payment-circle-outline.svg","material-contactless-payment-circle":"material/contactless-payment-circle.svg","material-contactless-payment":"material/contactless-payment.svg","material-contacts-outline":"material/contacts-outline.svg","material-contacts":"material/contacts.svg","material-contain-end":"material/contain-end.svg","material-contain-start":"material/contain-start.svg","material-contain":"material/contain.svg","material-content-copy":"material/content-copy.svg","material-content-cut":"material/content-cut.svg","material-content-duplicate":"material/content-duplicate.svg","material-content-paste":"material/content-paste.svg","material-content-save-alert-outline":"material/content-save-alert-outline.svg","material-content-save-alert":"material/content-save-alert.svg","material-content-save-all-outline":"material/content-save-all-outline.svg","material-content-save-all":"material/content-save-all.svg","material-content-save-check-outline":"material/content-save-check-outline.svg","material-content-save-check":"material/content-save-check.svg","material-content-save-cog-outline":"material/content-save-cog-outline.svg","material-content-save-cog":"material/content-save-cog.svg","material-content-save-edit-outline":"material/content-save-edit-outline.svg","material-content-save-edit":"material/content-save-edit.svg","material-content-save-minus-outline":"material/content-save-minus-outline.svg","material-content-save-minus":"material/content-save-minus.svg","material-content-save-move-outline":"material/content-save-move-outline.svg","material-content-save-move":"material/content-save-move.svg","material-content-save-off-outline":"material/content-save-off-outline.svg","material-content-save-off":"material/content-save-off.svg","material-content-save-outline":"material/content-save-outline.svg","material-content-save-plus-outline":"material/content-save-plus-outline.svg","material-content-save-plus":"material/content-save-plus.svg","material-content-save-settings-outline":"material/content-save-settings-outline.svg","material-content-save-settings":"material/content-save-settings.svg","material-content-save":"material/content-save.svg","material-contrast-box":"material/contrast-box.svg","material-contrast-circle":"material/contrast-circle.svg","material-contrast":"material/contrast.svg","material-controller-classic-outline":"material/controller-classic-outline.svg","material-controller-classic":"material/controller-classic.svg","material-controller-off":"material/controller-off.svg","material-controller":"material/controller.svg","material-cookie-alert-outline":"material/cookie-alert-outline.svg","material-cookie-alert":"material/cookie-alert.svg","material-cookie-check-outline":"material/cookie-check-outline.svg","material-cookie-check":"material/cookie-check.svg","material-cookie-clock-outline":"material/cookie-clock-outline.svg","material-cookie-clock":"material/cookie-clock.svg","material-cookie-cog-outline":"material/cookie-cog-outline.svg","material-cookie-cog":"material/cookie-cog.svg","material-cookie-edit-outline":"material/cookie-edit-outline.svg","material-cookie-edit":"material/cookie-edit.svg","material-cookie-lock-outline":"material/cookie-lock-outline.svg","material-cookie-lock":"material/cookie-lock.svg","material-cookie-minus-outline":"material/cookie-minus-outline.svg","material-cookie-minus":"material/cookie-minus.svg","material-cookie-off-outline":"material/cookie-off-outline.svg","material-cookie-off":"material/cookie-off.svg","material-cookie-outline":"material/cookie-outline.svg","material-cookie-plus-outline":"material/cookie-plus-outline.svg","material-cookie-plus":"material/cookie-plus.svg","material-cookie-refresh-outline":"material/cookie-refresh-outline.svg","material-cookie-refresh":"material/cookie-refresh.svg","material-cookie-remove-outline":"material/cookie-remove-outline.svg","material-cookie-remove":"material/cookie-remove.svg","material-cookie-settings-outline":"material/cookie-settings-outline.svg","material-cookie-settings":"material/cookie-settings.svg","material-cookie":"material/cookie.svg","material-coolant-temperature":"material/coolant-temperature.svg","material-copyleft":"material/copyleft.svg","material-copyright":"material/copyright.svg","material-cordova":"material/cordova.svg","material-corn-off":"material/corn-off.svg","material-corn":"material/corn.svg","material-cosine-wave":"material/cosine-wave.svg","material-counter":"material/counter.svg","material-countertop-outline":"material/countertop-outline.svg","material-countertop":"material/countertop.svg","material-cow-off":"material/cow-off.svg","material-cow":"material/cow.svg","material-cpu-32-bit":"material/cpu-32-bit.svg","material-cpu-64-bit":"material/cpu-64-bit.svg","material-cradle-outline":"material/cradle-outline.svg","material-cradle":"material/cradle.svg","material-crane":"material/crane.svg","material-creation":"material/creation.svg","material-creative-commons":"material/creative-commons.svg","material-credit-card-check-outline":"material/credit-card-check-outline.svg","material-credit-card-check":"material/credit-card-check.svg","material-credit-card-chip-outline":"material/credit-card-chip-outline.svg","material-credit-card-chip":"material/credit-card-chip.svg","material-credit-card-clock-outline":"material/credit-card-clock-outline.svg","material-credit-card-clock":"material/credit-card-clock.svg","material-credit-card-edit-outline":"material/credit-card-edit-outline.svg","material-credit-card-edit":"material/credit-card-edit.svg","material-credit-card-fast-outline":"material/credit-card-fast-outline.svg","material-credit-card-fast":"material/credit-card-fast.svg","material-credit-card-lock-outline":"material/credit-card-lock-outline.svg","material-credit-card-lock":"material/credit-card-lock.svg","material-credit-card-marker-outline":"material/credit-card-marker-outline.svg","material-credit-card-marker":"material/credit-card-marker.svg","material-credit-card-minus-outline":"material/credit-card-minus-outline.svg","material-credit-card-minus":"material/credit-card-minus.svg","material-credit-card-multiple-outline":"material/credit-card-multiple-outline.svg","material-credit-card-multiple":"material/credit-card-multiple.svg","material-credit-card-off-outline":"material/credit-card-off-outline.svg","material-credit-card-off":"material/credit-card-off.svg","material-credit-card-outline":"material/credit-card-outline.svg","material-credit-card-plus-outline":"material/credit-card-plus-outline.svg","material-credit-card-plus":"material/credit-card-plus.svg","material-credit-card-refresh-outline":"material/credit-card-refresh-outline.svg","material-credit-card-refresh":"material/credit-card-refresh.svg","material-credit-card-refund-outline":"material/credit-card-refund-outline.svg","material-credit-card-refund":"material/credit-card-refund.svg","material-credit-card-remove-outline":"material/credit-card-remove-outline.svg","material-credit-card-remove":"material/credit-card-remove.svg","material-credit-card-scan-outline":"material/credit-card-scan-outline.svg","material-credit-card-scan":"material/credit-card-scan.svg","material-credit-card-search-outline":"material/credit-card-search-outline.svg","material-credit-card-search":"material/credit-card-search.svg","material-credit-card-settings-outline":"material/credit-card-settings-outline.svg","material-credit-card-settings":"material/credit-card-settings.svg","material-credit-card-sync-outline":"material/credit-card-sync-outline.svg","material-credit-card-sync":"material/credit-card-sync.svg","material-credit-card-wireless-off-outline":"material/credit-card-wireless-off-outline.svg","material-credit-card-wireless-off":"material/credit-card-wireless-off.svg","material-credit-card-wireless-outline":"material/credit-card-wireless-outline.svg","material-credit-card-wireless":"material/credit-card-wireless.svg","material-credit-card":"material/credit-card.svg","material-cricket":"material/cricket.svg","material-crop-free":"material/crop-free.svg","material-crop-landscape":"material/crop-landscape.svg","material-crop-portrait":"material/crop-portrait.svg","material-crop-rotate":"material/crop-rotate.svg","material-crop-square":"material/crop-square.svg","material-crop":"material/crop.svg","material-cross-bolnisi":"material/cross-bolnisi.svg","material-cross-celtic":"material/cross-celtic.svg","material-cross-outline":"material/cross-outline.svg","material-cross":"material/cross.svg","material-crosshairs-gps":"material/crosshairs-gps.svg","material-crosshairs-off":"material/crosshairs-off.svg","material-crosshairs-question":"material/crosshairs-question.svg","material-crosshairs":"material/crosshairs.svg","material-crowd":"material/crowd.svg","material-crown-circle-outline":"material/crown-circle-outline.svg","material-crown-circle":"material/crown-circle.svg","material-crown-outline":"material/crown-outline.svg","material-crown":"material/crown.svg","material-cryengine":"material/cryengine.svg","material-crystal-ball":"material/crystal-ball.svg","material-cube-off-outline":"material/cube-off-outline.svg","material-cube-off":"material/cube-off.svg","material-cube-outline":"material/cube-outline.svg","material-cube-scan":"material/cube-scan.svg","material-cube-send":"material/cube-send.svg","material-cube-unfolded":"material/cube-unfolded.svg","material-cube":"material/cube.svg","material-cup-off-outline":"material/cup-off-outline.svg","material-cup-off":"material/cup-off.svg","material-cup-outline":"material/cup-outline.svg","material-cup-water":"material/cup-water.svg","material-cup":"material/cup.svg","material-cupboard-outline":"material/cupboard-outline.svg","material-cupboard":"material/cupboard.svg","material-cupcake":"material/cupcake.svg","material-curling":"material/curling.svg","material-currency-bdt":"material/currency-bdt.svg","material-currency-brl":"material/currency-brl.svg","material-currency-btc":"material/currency-btc.svg","material-currency-cny":"material/currency-cny.svg","material-currency-eth":"material/currency-eth.svg","material-currency-eur-off":"material/currency-eur-off.svg","material-currency-eur":"material/currency-eur.svg","material-currency-fra":"material/currency-fra.svg","material-currency-gbp":"material/currency-gbp.svg","material-currency-ils":"material/currency-ils.svg","material-currency-inr":"material/currency-inr.svg","material-currency-jpy":"material/currency-jpy.svg","material-currency-krw":"material/currency-krw.svg","material-currency-kzt":"material/currency-kzt.svg","material-currency-mnt":"material/currency-mnt.svg","material-currency-ngn":"material/currency-ngn.svg","material-currency-php":"material/currency-php.svg","material-currency-rial":"material/currency-rial.svg","material-currency-rub":"material/currency-rub.svg","material-currency-rupee":"material/currency-rupee.svg","material-currency-sign":"material/currency-sign.svg","material-currency-try":"material/currency-try.svg","material-currency-twd":"material/currency-twd.svg","material-currency-uah":"material/currency-uah.svg","material-currency-usd-off":"material/currency-usd-off.svg","material-currency-usd":"material/currency-usd.svg","material-current-ac":"material/current-ac.svg","material-current-dc":"material/current-dc.svg","material-cursor-default-click-outline":"material/cursor-default-click-outline.svg","material-cursor-default-click":"material/cursor-default-click.svg","material-cursor-default-gesture-outline":"material/cursor-default-gesture-outline.svg","material-cursor-default-gesture":"material/cursor-default-gesture.svg","material-cursor-default-outline":"material/cursor-default-outline.svg","material-cursor-default":"material/cursor-default.svg","material-cursor-move":"material/cursor-move.svg","material-cursor-pointer":"material/cursor-pointer.svg","material-cursor-text":"material/cursor-text.svg","material-curtains-closed":"material/curtains-closed.svg","material-curtains":"material/curtains.svg","material-cylinder-off":"material/cylinder-off.svg","material-cylinder":"material/cylinder.svg","material-dance-ballroom":"material/dance-ballroom.svg","material-dance-pole":"material/dance-pole.svg","material-data-matrix-edit":"material/data-matrix-edit.svg","material-data-matrix-minus":"material/data-matrix-minus.svg","material-data-matrix-plus":"material/data-matrix-plus.svg","material-data-matrix-remove":"material/data-matrix-remove.svg","material-data-matrix-scan":"material/data-matrix-scan.svg","material-data-matrix":"material/data-matrix.svg","material-database-alert-outline":"material/database-alert-outline.svg","material-database-alert":"material/database-alert.svg","material-database-arrow-down-outline":"material/database-arrow-down-outline.svg","material-database-arrow-down":"material/database-arrow-down.svg","material-database-arrow-left-outline":"material/database-arrow-left-outline.svg","material-database-arrow-left":"material/database-arrow-left.svg","material-database-arrow-right-outline":"material/database-arrow-right-outline.svg","material-database-arrow-right":"material/database-arrow-right.svg","material-database-arrow-up-outline":"material/database-arrow-up-outline.svg","material-database-arrow-up":"material/database-arrow-up.svg","material-database-check-outline":"material/database-check-outline.svg","material-database-check":"material/database-check.svg","material-database-clock-outline":"material/database-clock-outline.svg","material-database-clock":"material/database-clock.svg","material-database-cog-outline":"material/database-cog-outline.svg","material-database-cog":"material/database-cog.svg","material-database-edit-outline":"material/database-edit-outline.svg","material-database-edit":"material/database-edit.svg","material-database-export-outline":"material/database-export-outline.svg","material-database-export":"material/database-export.svg","material-database-eye-off-outline":"material/database-eye-off-outline.svg","material-database-eye-off":"material/database-eye-off.svg","material-database-eye-outline":"material/database-eye-outline.svg","material-database-eye":"material/database-eye.svg","material-database-import-outline":"material/database-import-outline.svg","material-database-import":"material/database-import.svg","material-database-lock-outline":"material/database-lock-outline.svg","material-database-lock":"material/database-lock.svg","material-database-marker-outline":"material/database-marker-outline.svg","material-database-marker":"material/database-marker.svg","material-database-minus-outline":"material/database-minus-outline.svg","material-database-minus":"material/database-minus.svg","material-database-off-outline":"material/database-off-outline.svg","material-database-off":"material/database-off.svg","material-database-outline":"material/database-outline.svg","material-database-plus-outline":"material/database-plus-outline.svg","material-database-plus":"material/database-plus.svg","material-database-refresh-outline":"material/database-refresh-outline.svg","material-database-refresh":"material/database-refresh.svg","material-database-remove-outline":"material/database-remove-outline.svg","material-database-remove":"material/database-remove.svg","material-database-search-outline":"material/database-search-outline.svg","material-database-search":"material/database-search.svg","material-database-settings-outline":"material/database-settings-outline.svg","material-database-settings":"material/database-settings.svg","material-database-sync-outline":"material/database-sync-outline.svg","material-database-sync":"material/database-sync.svg","material-database":"material/database.svg","material-death-star-variant":"material/death-star-variant.svg","material-death-star":"material/death-star.svg","material-deathly-hallows":"material/deathly-hallows.svg","material-debian":"material/debian.svg","material-debug-step-into":"material/debug-step-into.svg","material-debug-step-out":"material/debug-step-out.svg","material-debug-step-over":"material/debug-step-over.svg","material-decagram-outline":"material/decagram-outline.svg","material-decagram":"material/decagram.svg","material-decimal-comma-decrease":"material/decimal-comma-decrease.svg","material-decimal-comma-increase":"material/decimal-comma-increase.svg","material-decimal-comma":"material/decimal-comma.svg","material-decimal-decrease":"material/decimal-decrease.svg","material-decimal-increase":"material/decimal-increase.svg","material-decimal":"material/decimal.svg","material-delete-alert-outline":"material/delete-alert-outline.svg","material-delete-alert":"material/delete-alert.svg","material-delete-circle-outline":"material/delete-circle-outline.svg","material-delete-circle":"material/delete-circle.svg","material-delete-clock-outline":"material/delete-clock-outline.svg","material-delete-clock":"material/delete-clock.svg","material-delete-empty-outline":"material/delete-empty-outline.svg","material-delete-empty":"material/delete-empty.svg","material-delete-forever-outline":"material/delete-forever-outline.svg","material-delete-forever":"material/delete-forever.svg","material-delete-off-outline":"material/delete-off-outline.svg","material-delete-off":"material/delete-off.svg","material-delete-outline":"material/delete-outline.svg","material-delete-restore":"material/delete-restore.svg","material-delete-sweep-outline":"material/delete-sweep-outline.svg","material-delete-sweep":"material/delete-sweep.svg","material-delete-variant":"material/delete-variant.svg","material-delete":"material/delete.svg","material-delta":"material/delta.svg","material-desk-lamp-off":"material/desk-lamp-off.svg","material-desk-lamp-on":"material/desk-lamp-on.svg","material-desk-lamp":"material/desk-lamp.svg","material-desk":"material/desk.svg","material-deskphone":"material/deskphone.svg","material-desktop-classic":"material/desktop-classic.svg","material-desktop-tower-monitor":"material/desktop-tower-monitor.svg","material-desktop-tower":"material/desktop-tower.svg","material-details":"material/details.svg","material-dev-to":"material/dev-to.svg","material-developer-board":"material/developer-board.svg","material-deviantart":"material/deviantart.svg","material-devices":"material/devices.svg","material-dharmachakra":"material/dharmachakra.svg","material-diabetes":"material/diabetes.svg","material-dialpad":"material/dialpad.svg","material-diameter-outline":"material/diameter-outline.svg","material-diameter-variant":"material/diameter-variant.svg","material-diameter":"material/diameter.svg","material-diamond-outline":"material/diamond-outline.svg","material-diamond-stone":"material/diamond-stone.svg","material-diamond":"material/diamond.svg","material-dice-1-outline":"material/dice-1-outline.svg","material-dice-1":"material/dice-1.svg","material-dice-2-outline":"material/dice-2-outline.svg","material-dice-2":"material/dice-2.svg","material-dice-3-outline":"material/dice-3-outline.svg","material-dice-3":"material/dice-3.svg","material-dice-4-outline":"material/dice-4-outline.svg","material-dice-4":"material/dice-4.svg","material-dice-5-outline":"material/dice-5-outline.svg","material-dice-5":"material/dice-5.svg","material-dice-6-outline":"material/dice-6-outline.svg","material-dice-6":"material/dice-6.svg","material-dice-d10-outline":"material/dice-d10-outline.svg","material-dice-d10":"material/dice-d10.svg","material-dice-d12-outline":"material/dice-d12-outline.svg","material-dice-d12":"material/dice-d12.svg","material-dice-d20-outline":"material/dice-d20-outline.svg","material-dice-d20":"material/dice-d20.svg","material-dice-d4-outline":"material/dice-d4-outline.svg","material-dice-d4":"material/dice-d4.svg","material-dice-d6-outline":"material/dice-d6-outline.svg","material-dice-d6":"material/dice-d6.svg","material-dice-d8-outline":"material/dice-d8-outline.svg","material-dice-d8":"material/dice-d8.svg","material-dice-multiple-outline":"material/dice-multiple-outline.svg","material-dice-multiple":"material/dice-multiple.svg","material-digital-ocean":"material/digital-ocean.svg","material-dip-switch":"material/dip-switch.svg","material-directions-fork":"material/directions-fork.svg","material-directions":"material/directions.svg","material-disc-alert":"material/disc-alert.svg","material-disc-player":"material/disc-player.svg","material-disc":"material/disc.svg","material-dishwasher-alert":"material/dishwasher-alert.svg","material-dishwasher-off":"material/dishwasher-off.svg","material-dishwasher":"material/dishwasher.svg","material-disqus":"material/disqus.svg","material-distribute-horizontal-center":"material/distribute-horizontal-center.svg","material-distribute-horizontal-left":"material/distribute-horizontal-left.svg","material-distribute-horizontal-right":"material/distribute-horizontal-right.svg","material-distribute-vertical-bottom":"material/distribute-vertical-bottom.svg","material-distribute-vertical-center":"material/distribute-vertical-center.svg","material-distribute-vertical-top":"material/distribute-vertical-top.svg","material-diversify":"material/diversify.svg","material-diving-flippers":"material/diving-flippers.svg","material-diving-helmet":"material/diving-helmet.svg","material-diving-scuba-flag":"material/diving-scuba-flag.svg","material-diving-scuba-mask":"material/diving-scuba-mask.svg","material-diving-scuba-tank-multiple":"material/diving-scuba-tank-multiple.svg","material-diving-scuba-tank":"material/diving-scuba-tank.svg","material-diving-scuba":"material/diving-scuba.svg","material-diving-snorkel":"material/diving-snorkel.svg","material-diving":"material/diving.svg","material-division-box":"material/division-box.svg","material-division":"material/division.svg","material-dlna":"material/dlna.svg","material-dna":"material/dna.svg","material-dns-outline":"material/dns-outline.svg","material-dns":"material/dns.svg","material-dock-bottom":"material/dock-bottom.svg","material-dock-left":"material/dock-left.svg","material-dock-right":"material/dock-right.svg","material-dock-top":"material/dock-top.svg","material-dock-window":"material/dock-window.svg","material-docker":"material/docker.svg","material-doctor":"material/doctor.svg","material-dog-service":"material/dog-service.svg","material-dog-side-off":"material/dog-side-off.svg","material-dog-side":"material/dog-side.svg","material-dog":"material/dog.svg","material-dolby":"material/dolby.svg","material-dolly":"material/dolly.svg","material-dolphin":"material/dolphin.svg","material-domain-off":"material/domain-off.svg","material-domain-plus":"material/domain-plus.svg","material-domain-remove":"material/domain-remove.svg","material-domain":"material/domain.svg","material-dome-light":"material/dome-light.svg","material-domino-mask":"material/domino-mask.svg","material-donkey":"material/donkey.svg","material-door-closed-lock":"material/door-closed-lock.svg","material-door-closed":"material/door-closed.svg","material-door-open":"material/door-open.svg","material-door-sliding-lock":"material/door-sliding-lock.svg","material-door-sliding-open":"material/door-sliding-open.svg","material-door-sliding":"material/door-sliding.svg","material-door":"material/door.svg","material-doorbell-video":"material/doorbell-video.svg","material-doorbell":"material/doorbell.svg","material-dot-net":"material/dot-net.svg","material-dots-circle":"material/dots-circle.svg","material-dots-grid":"material/dots-grid.svg","material-dots-hexagon":"material/dots-hexagon.svg","material-dots-horizontal-circle-outline":"material/dots-horizontal-circle-outline.svg","material-dots-horizontal-circle":"material/dots-horizontal-circle.svg","material-dots-horizontal":"material/dots-horizontal.svg","material-dots-square":"material/dots-square.svg","material-dots-triangle":"material/dots-triangle.svg","material-dots-vertical-circle-outline":"material/dots-vertical-circle-outline.svg","material-dots-vertical-circle":"material/dots-vertical-circle.svg","material-dots-vertical":"material/dots-vertical.svg","material-download-box-outline":"material/download-box-outline.svg","material-download-box":"material/download-box.svg","material-download-circle-outline":"material/download-circle-outline.svg","material-download-circle":"material/download-circle.svg","material-download-lock-outline":"material/download-lock-outline.svg","material-download-lock":"material/download-lock.svg","material-download-multiple":"material/download-multiple.svg","material-download-network-outline":"material/download-network-outline.svg","material-download-network":"material/download-network.svg","material-download-off-outline":"material/download-off-outline.svg","material-download-off":"material/download-off.svg","material-download-outline":"material/download-outline.svg","material-download":"material/download.svg","material-drag-horizontal-variant":"material/drag-horizontal-variant.svg","material-drag-horizontal":"material/drag-horizontal.svg","material-drag-variant":"material/drag-variant.svg","material-drag-vertical-variant":"material/drag-vertical-variant.svg","material-drag-vertical":"material/drag-vertical.svg","material-drag":"material/drag.svg","material-drama-masks":"material/drama-masks.svg","material-draw-pen":"material/draw-pen.svg","material-draw":"material/draw.svg","material-drawing-box":"material/drawing-box.svg","material-drawing":"material/drawing.svg","material-dresser-outline":"material/dresser-outline.svg","material-dresser":"material/dresser.svg","material-drone":"material/drone.svg","material-dropbox":"material/dropbox.svg","material-drupal":"material/drupal.svg","material-duck":"material/duck.svg","material-dumbbell":"material/dumbbell.svg","material-dump-truck":"material/dump-truck.svg","material-ear-hearing-loop":"material/ear-hearing-loop.svg","material-ear-hearing-off":"material/ear-hearing-off.svg","material-ear-hearing":"material/ear-hearing.svg","material-earbuds-off-outline":"material/earbuds-off-outline.svg","material-earbuds-off":"material/earbuds-off.svg","material-earbuds-outline":"material/earbuds-outline.svg","material-earbuds":"material/earbuds.svg","material-earth-arrow-right":"material/earth-arrow-right.svg","material-earth-box-minus":"material/earth-box-minus.svg","material-earth-box-off":"material/earth-box-off.svg","material-earth-box-plus":"material/earth-box-plus.svg","material-earth-box-remove":"material/earth-box-remove.svg","material-earth-box":"material/earth-box.svg","material-earth-minus":"material/earth-minus.svg","material-earth-off":"material/earth-off.svg","material-earth-plus":"material/earth-plus.svg","material-earth-remove":"material/earth-remove.svg","material-earth":"material/earth.svg","material-egg-easter":"material/egg-easter.svg","material-egg-fried":"material/egg-fried.svg","material-egg-off-outline":"material/egg-off-outline.svg","material-egg-off":"material/egg-off.svg","material-egg-outline":"material/egg-outline.svg","material-egg":"material/egg.svg","material-eiffel-tower":"material/eiffel-tower.svg","material-eight-track":"material/eight-track.svg","material-eject-circle-outline":"material/eject-circle-outline.svg","material-eject-circle":"material/eject-circle.svg","material-eject-outline":"material/eject-outline.svg","material-eject":"material/eject.svg","material-electric-switch-closed":"material/electric-switch-closed.svg","material-electric-switch":"material/electric-switch.svg","material-electron-framework":"material/electron-framework.svg","material-elephant":"material/elephant.svg","material-elevation-decline":"material/elevation-decline.svg","material-elevation-rise":"material/elevation-rise.svg","material-elevator-down":"material/elevator-down.svg","material-elevator-passenger-off-outline":"material/elevator-passenger-off-outline.svg","material-elevator-passenger-off":"material/elevator-passenger-off.svg","material-elevator-passenger-outline":"material/elevator-passenger-outline.svg","material-elevator-passenger":"material/elevator-passenger.svg","material-elevator-up":"material/elevator-up.svg","material-elevator":"material/elevator.svg","material-ellipse-outline":"material/ellipse-outline.svg","material-ellipse":"material/ellipse.svg","material-email-alert-outline":"material/email-alert-outline.svg","material-email-alert":"material/email-alert.svg","material-email-arrow-left-outline":"material/email-arrow-left-outline.svg","material-email-arrow-left":"material/email-arrow-left.svg","material-email-arrow-right-outline":"material/email-arrow-right-outline.svg","material-email-arrow-right":"material/email-arrow-right.svg","material-email-box":"material/email-box.svg","material-email-check-outline":"material/email-check-outline.svg","material-email-check":"material/email-check.svg","material-email-edit-outline":"material/email-edit-outline.svg","material-email-edit":"material/email-edit.svg","material-email-fast-outline":"material/email-fast-outline.svg","material-email-fast":"material/email-fast.svg","material-email-lock-outline":"material/email-lock-outline.svg","material-email-lock":"material/email-lock.svg","material-email-mark-as-unread":"material/email-mark-as-unread.svg","material-email-minus-outline":"material/email-minus-outline.svg","material-email-minus":"material/email-minus.svg","material-email-multiple-outline":"material/email-multiple-outline.svg","material-email-multiple":"material/email-multiple.svg","material-email-newsletter":"material/email-newsletter.svg","material-email-off-outline":"material/email-off-outline.svg","material-email-off":"material/email-off.svg","material-email-open-multiple-outline":"material/email-open-multiple-outline.svg","material-email-open-multiple":"material/email-open-multiple.svg","material-email-open-outline":"material/email-open-outline.svg","material-email-open":"material/email-open.svg","material-email-outline":"material/email-outline.svg","material-email-plus-outline":"material/email-plus-outline.svg","material-email-plus":"material/email-plus.svg","material-email-remove-outline":"material/email-remove-outline.svg","material-email-remove":"material/email-remove.svg","material-email-seal-outline":"material/email-seal-outline.svg","material-email-seal":"material/email-seal.svg","material-email-search-outline":"material/email-search-outline.svg","material-email-search":"material/email-search.svg","material-email-sync-outline":"material/email-sync-outline.svg","material-email-sync":"material/email-sync.svg","material-email-variant":"material/email-variant.svg","material-email":"material/email.svg","material-ember":"material/ember.svg","material-emby":"material/emby.svg","material-emoticon-angry-outline":"material/emoticon-angry-outline.svg","material-emoticon-angry":"material/emoticon-angry.svg","material-emoticon-confused-outline":"material/emoticon-confused-outline.svg","material-emoticon-confused":"material/emoticon-confused.svg","material-emoticon-cool-outline":"material/emoticon-cool-outline.svg","material-emoticon-cool":"material/emoticon-cool.svg","material-emoticon-cry-outline":"material/emoticon-cry-outline.svg","material-emoticon-cry":"material/emoticon-cry.svg","material-emoticon-dead-outline":"material/emoticon-dead-outline.svg","material-emoticon-dead":"material/emoticon-dead.svg","material-emoticon-devil-outline":"material/emoticon-devil-outline.svg","material-emoticon-devil":"material/emoticon-devil.svg","material-emoticon-excited-outline":"material/emoticon-excited-outline.svg","material-emoticon-excited":"material/emoticon-excited.svg","material-emoticon-frown-outline":"material/emoticon-frown-outline.svg","material-emoticon-frown":"material/emoticon-frown.svg","material-emoticon-happy-outline":"material/emoticon-happy-outline.svg","material-emoticon-happy":"material/emoticon-happy.svg","material-emoticon-kiss-outline":"material/emoticon-kiss-outline.svg","material-emoticon-kiss":"material/emoticon-kiss.svg","material-emoticon-lol-outline":"material/emoticon-lol-outline.svg","material-emoticon-lol":"material/emoticon-lol.svg","material-emoticon-neutral-outline":"material/emoticon-neutral-outline.svg","material-emoticon-neutral":"material/emoticon-neutral.svg","material-emoticon-outline":"material/emoticon-outline.svg","material-emoticon-poop-outline":"material/emoticon-poop-outline.svg","material-emoticon-poop":"material/emoticon-poop.svg","material-emoticon-sad-outline":"material/emoticon-sad-outline.svg","material-emoticon-sad":"material/emoticon-sad.svg","material-emoticon-sick-outline":"material/emoticon-sick-outline.svg","material-emoticon-sick":"material/emoticon-sick.svg","material-emoticon-tongue-outline":"material/emoticon-tongue-outline.svg","material-emoticon-tongue":"material/emoticon-tongue.svg","material-emoticon-wink-outline":"material/emoticon-wink-outline.svg","material-emoticon-wink":"material/emoticon-wink.svg","material-emoticon":"material/emoticon.svg","material-engine-off-outline":"material/engine-off-outline.svg","material-engine-off":"material/engine-off.svg","material-engine-outline":"material/engine-outline.svg","material-engine":"material/engine.svg","material-epsilon":"material/epsilon.svg","material-equal-box":"material/equal-box.svg","material-equal":"material/equal.svg","material-equalizer-outline":"material/equalizer-outline.svg","material-equalizer":"material/equalizer.svg","material-eraser-variant":"material/eraser-variant.svg","material-eraser":"material/eraser.svg","material-escalator-box":"material/escalator-box.svg","material-escalator-down":"material/escalator-down.svg","material-escalator-up":"material/escalator-up.svg","material-escalator":"material/escalator.svg","material-eslint":"material/eslint.svg","material-et":"material/et.svg","material-ethereum":"material/ethereum.svg","material-ethernet-cable-off":"material/ethernet-cable-off.svg","material-ethernet-cable":"material/ethernet-cable.svg","material-ethernet":"material/ethernet.svg","material-ev-plug-ccs1":"material/ev-plug-ccs1.svg","material-ev-plug-ccs2":"material/ev-plug-ccs2.svg","material-ev-plug-chademo":"material/ev-plug-chademo.svg","material-ev-plug-tesla":"material/ev-plug-tesla.svg","material-ev-plug-type1":"material/ev-plug-type1.svg","material-ev-plug-type2":"material/ev-plug-type2.svg","material-ev-station":"material/ev-station.svg","material-evernote":"material/evernote.svg","material-excavator":"material/excavator.svg","material-exclamation-thick":"material/exclamation-thick.svg","material-exclamation":"material/exclamation.svg","material-exit-run":"material/exit-run.svg","material-exit-to-app":"material/exit-to-app.svg","material-expand-all-outline":"material/expand-all-outline.svg","material-expand-all":"material/expand-all.svg","material-expansion-card-variant":"material/expansion-card-variant.svg","material-expansion-card":"material/expansion-card.svg","material-exponent-box":"material/exponent-box.svg","material-exponent":"material/exponent.svg","material-export-variant":"material/export-variant.svg","material-export":"material/export.svg","material-eye-arrow-left-outline":"material/eye-arrow-left-outline.svg","material-eye-arrow-left":"material/eye-arrow-left.svg","material-eye-arrow-right-outline":"material/eye-arrow-right-outline.svg","material-eye-arrow-right":"material/eye-arrow-right.svg","material-eye-check-outline":"material/eye-check-outline.svg","material-eye-check":"material/eye-check.svg","material-eye-circle-outline":"material/eye-circle-outline.svg","material-eye-circle":"material/eye-circle.svg","material-eye-minus-outline":"material/eye-minus-outline.svg","material-eye-minus":"material/eye-minus.svg","material-eye-off-outline":"material/eye-off-outline.svg","material-eye-off":"material/eye-off.svg","material-eye-outline":"material/eye-outline.svg","material-eye-plus-outline":"material/eye-plus-outline.svg","material-eye-plus":"material/eye-plus.svg","material-eye-refresh-outline":"material/eye-refresh-outline.svg","material-eye-refresh":"material/eye-refresh.svg","material-eye-remove-outline":"material/eye-remove-outline.svg","material-eye-remove":"material/eye-remove.svg","material-eye-settings-outline":"material/eye-settings-outline.svg","material-eye-settings":"material/eye-settings.svg","material-eye":"material/eye.svg","material-eyedropper-minus":"material/eyedropper-minus.svg","material-eyedropper-off":"material/eyedropper-off.svg","material-eyedropper-plus":"material/eyedropper-plus.svg","material-eyedropper-remove":"material/eyedropper-remove.svg","material-eyedropper-variant":"material/eyedropper-variant.svg","material-eyedropper":"material/eyedropper.svg","material-face-agent":"material/face-agent.svg","material-face-man-outline":"material/face-man-outline.svg","material-face-man-profile":"material/face-man-profile.svg","material-face-man-shimmer-outline":"material/face-man-shimmer-outline.svg","material-face-man-shimmer":"material/face-man-shimmer.svg","material-face-man":"material/face-man.svg","material-face-mask-outline":"material/face-mask-outline.svg","material-face-mask":"material/face-mask.svg","material-face-recognition":"material/face-recognition.svg","material-face-woman-outline":"material/face-woman-outline.svg","material-face-woman-profile":"material/face-woman-profile.svg","material-face-woman-shimmer-outline":"material/face-woman-shimmer-outline.svg","material-face-woman-shimmer":"material/face-woman-shimmer.svg","material-face-woman":"material/face-woman.svg","material-facebook-gaming":"material/facebook-gaming.svg","material-facebook-messenger":"material/facebook-messenger.svg","material-facebook-workplace":"material/facebook-workplace.svg","material-facebook":"material/facebook.svg","material-factory":"material/factory.svg","material-family-tree":"material/family-tree.svg","material-fan-alert":"material/fan-alert.svg","material-fan-auto":"material/fan-auto.svg","material-fan-chevron-down":"material/fan-chevron-down.svg","material-fan-chevron-up":"material/fan-chevron-up.svg","material-fan-clock":"material/fan-clock.svg","material-fan-minus":"material/fan-minus.svg","material-fan-off":"material/fan-off.svg","material-fan-plus":"material/fan-plus.svg","material-fan-remove":"material/fan-remove.svg","material-fan-speed-1":"material/fan-speed-1.svg","material-fan-speed-2":"material/fan-speed-2.svg","material-fan-speed-3":"material/fan-speed-3.svg","material-fan":"material/fan.svg","material-fast-forward-10":"material/fast-forward-10.svg","material-fast-forward-15":"material/fast-forward-15.svg","material-fast-forward-30":"material/fast-forward-30.svg","material-fast-forward-45":"material/fast-forward-45.svg","material-fast-forward-5":"material/fast-forward-5.svg","material-fast-forward-60":"material/fast-forward-60.svg","material-fast-forward-outline":"material/fast-forward-outline.svg","material-fast-forward":"material/fast-forward.svg","material-faucet-variant":"material/faucet-variant.svg","material-faucet":"material/faucet.svg","material-fax":"material/fax.svg","material-feather":"material/feather.svg","material-feature-search-outline":"material/feature-search-outline.svg","material-feature-search":"material/feature-search.svg","material-fedora":"material/fedora.svg","material-fence-electric":"material/fence-electric.svg","material-fence":"material/fence.svg","material-fencing":"material/fencing.svg","material-ferris-wheel":"material/ferris-wheel.svg","material-ferry":"material/ferry.svg","material-file-account-outline":"material/file-account-outline.svg","material-file-account":"material/file-account.svg","material-file-alert-outline":"material/file-alert-outline.svg","material-file-alert":"material/file-alert.svg","material-file-arrow-left-right-outline":"material/file-arrow-left-right-outline.svg","material-file-arrow-left-right":"material/file-arrow-left-right.svg","material-file-arrow-up-down-outline":"material/file-arrow-up-down-outline.svg","material-file-arrow-up-down":"material/file-arrow-up-down.svg","material-file-cabinet":"material/file-cabinet.svg","material-file-cad-box":"material/file-cad-box.svg","material-file-cad":"material/file-cad.svg","material-file-cancel-outline":"material/file-cancel-outline.svg","material-file-cancel":"material/file-cancel.svg","material-file-certificate-outline":"material/file-certificate-outline.svg","material-file-certificate":"material/file-certificate.svg","material-file-chart-check-outline":"material/file-chart-check-outline.svg","material-file-chart-check":"material/file-chart-check.svg","material-file-chart-outline":"material/file-chart-outline.svg","material-file-chart":"material/file-chart.svg","material-file-check-outline":"material/file-check-outline.svg","material-file-check":"material/file-check.svg","material-file-clock-outline":"material/file-clock-outline.svg","material-file-clock":"material/file-clock.svg","material-file-cloud-outline":"material/file-cloud-outline.svg","material-file-cloud":"material/file-cloud.svg","material-file-code-outline":"material/file-code-outline.svg","material-file-code":"material/file-code.svg","material-file-cog-outline":"material/file-cog-outline.svg","material-file-cog":"material/file-cog.svg","material-file-compare":"material/file-compare.svg","material-file-delimited-outline":"material/file-delimited-outline.svg","material-file-delimited":"material/file-delimited.svg","material-file-document-alert-outline":"material/file-document-alert-outline.svg","material-file-document-alert":"material/file-document-alert.svg","material-file-document-check-outline":"material/file-document-check-outline.svg","material-file-document-check":"material/file-document-check.svg","material-file-document-edit-outline":"material/file-document-edit-outline.svg","material-file-document-edit":"material/file-document-edit.svg","material-file-document-minus-outline":"material/file-document-minus-outline.svg","material-file-document-minus":"material/file-document-minus.svg","material-file-document-multiple-outline":"material/file-document-multiple-outline.svg","material-file-document-multiple":"material/file-document-multiple.svg","material-file-document-outline":"material/file-document-outline.svg","material-file-document-plus-outline":"material/file-document-plus-outline.svg","material-file-document-plus":"material/file-document-plus.svg","material-file-document-remove-outline":"material/file-document-remove-outline.svg","material-file-document-remove":"material/file-document-remove.svg","material-file-document":"material/file-document.svg","material-file-download-outline":"material/file-download-outline.svg","material-file-download":"material/file-download.svg","material-file-edit-outline":"material/file-edit-outline.svg","material-file-edit":"material/file-edit.svg","material-file-excel-box-outline":"material/file-excel-box-outline.svg","material-file-excel-box":"material/file-excel-box.svg","material-file-excel-outline":"material/file-excel-outline.svg","material-file-excel":"material/file-excel.svg","material-file-export-outline":"material/file-export-outline.svg","material-file-export":"material/file-export.svg","material-file-eye-outline":"material/file-eye-outline.svg","material-file-eye":"material/file-eye.svg","material-file-find-outline":"material/file-find-outline.svg","material-file-find":"material/file-find.svg","material-file-gif-box":"material/file-gif-box.svg","material-file-hidden":"material/file-hidden.svg","material-file-image-marker-outline":"material/file-image-marker-outline.svg","material-file-image-marker":"material/file-image-marker.svg","material-file-image-minus-outline":"material/file-image-minus-outline.svg","material-file-image-minus":"material/file-image-minus.svg","material-file-image-outline":"material/file-image-outline.svg","material-file-image-plus-outline":"material/file-image-plus-outline.svg","material-file-image-plus":"material/file-image-plus.svg","material-file-image-remove-outline":"material/file-image-remove-outline.svg","material-file-image-remove":"material/file-image-remove.svg","material-file-image":"material/file-image.svg","material-file-import-outline":"material/file-import-outline.svg","material-file-import":"material/file-import.svg","material-file-jpg-box":"material/file-jpg-box.svg","material-file-key-outline":"material/file-key-outline.svg","material-file-key":"material/file-key.svg","material-file-link-outline":"material/file-link-outline.svg","material-file-link":"material/file-link.svg","material-file-lock-open-outline":"material/file-lock-open-outline.svg","material-file-lock-open":"material/file-lock-open.svg","material-file-lock-outline":"material/file-lock-outline.svg","material-file-lock":"material/file-lock.svg","material-file-marker-outline":"material/file-marker-outline.svg","material-file-marker":"material/file-marker.svg","material-file-minus-outline":"material/file-minus-outline.svg","material-file-minus":"material/file-minus.svg","material-file-move-outline":"material/file-move-outline.svg","material-file-move":"material/file-move.svg","material-file-multiple-outline":"material/file-multiple-outline.svg","material-file-multiple":"material/file-multiple.svg","material-file-music-outline":"material/file-music-outline.svg","material-file-music":"material/file-music.svg","material-file-outline":"material/file-outline.svg","material-file-pdf-box":"material/file-pdf-box.svg","material-file-percent-outline":"material/file-percent-outline.svg","material-file-percent":"material/file-percent.svg","material-file-phone-outline":"material/file-phone-outline.svg","material-file-phone":"material/file-phone.svg","material-file-plus-outline":"material/file-plus-outline.svg","material-file-plus":"material/file-plus.svg","material-file-png-box":"material/file-png-box.svg","material-file-powerpoint-box-outline":"material/file-powerpoint-box-outline.svg","material-file-powerpoint-box":"material/file-powerpoint-box.svg","material-file-powerpoint-outline":"material/file-powerpoint-outline.svg","material-file-powerpoint":"material/file-powerpoint.svg","material-file-presentation-box":"material/file-presentation-box.svg","material-file-question-outline":"material/file-question-outline.svg","material-file-question":"material/file-question.svg","material-file-refresh-outline":"material/file-refresh-outline.svg","material-file-refresh":"material/file-refresh.svg","material-file-remove-outline":"material/file-remove-outline.svg","material-file-remove":"material/file-remove.svg","material-file-replace-outline":"material/file-replace-outline.svg","material-file-replace":"material/file-replace.svg","material-file-restore-outline":"material/file-restore-outline.svg","material-file-restore":"material/file-restore.svg","material-file-rotate-left-outline":"material/file-rotate-left-outline.svg","material-file-rotate-left":"material/file-rotate-left.svg","material-file-rotate-right-outline":"material/file-rotate-right-outline.svg","material-file-rotate-right":"material/file-rotate-right.svg","material-file-search-outline":"material/file-search-outline.svg","material-file-search":"material/file-search.svg","material-file-send-outline":"material/file-send-outline.svg","material-file-send":"material/file-send.svg","material-file-settings-outline":"material/file-settings-outline.svg","material-file-settings":"material/file-settings.svg","material-file-sign":"material/file-sign.svg","material-file-star-outline":"material/file-star-outline.svg","material-file-star":"material/file-star.svg","material-file-swap-outline":"material/file-swap-outline.svg","material-file-swap":"material/file-swap.svg","material-file-sync-outline":"material/file-sync-outline.svg","material-file-sync":"material/file-sync.svg","material-file-table-box-multiple-outline":"material/file-table-box-multiple-outline.svg","material-file-table-box-multiple":"material/file-table-box-multiple.svg","material-file-table-box-outline":"material/file-table-box-outline.svg","material-file-table-box":"material/file-table-box.svg","material-file-table-outline":"material/file-table-outline.svg","material-file-table":"material/file-table.svg","material-file-tree-outline":"material/file-tree-outline.svg","material-file-tree":"material/file-tree.svg","material-file-undo-outline":"material/file-undo-outline.svg","material-file-undo":"material/file-undo.svg","material-file-upload-outline":"material/file-upload-outline.svg","material-file-upload":"material/file-upload.svg","material-file-video-outline":"material/file-video-outline.svg","material-file-video":"material/file-video.svg","material-file-word-box-outline":"material/file-word-box-outline.svg","material-file-word-box":"material/file-word-box.svg","material-file-word-outline":"material/file-word-outline.svg","material-file-word":"material/file-word.svg","material-file-xml-box":"material/file-xml-box.svg","material-file":"material/file.svg","material-film":"material/film.svg","material-filmstrip-box-multiple":"material/filmstrip-box-multiple.svg","material-filmstrip-box":"material/filmstrip-box.svg","material-filmstrip-off":"material/filmstrip-off.svg","material-filmstrip":"material/filmstrip.svg","material-filter-check-outline":"material/filter-check-outline.svg","material-filter-check":"material/filter-check.svg","material-filter-cog-outline":"material/filter-cog-outline.svg","material-filter-cog":"material/filter-cog.svg","material-filter-menu-outline":"material/filter-menu-outline.svg","material-filter-menu":"material/filter-menu.svg","material-filter-minus-outline":"material/filter-minus-outline.svg","material-filter-minus":"material/filter-minus.svg","material-filter-multiple-outline":"material/filter-multiple-outline.svg","material-filter-multiple":"material/filter-multiple.svg","material-filter-off-outline":"material/filter-off-outline.svg","material-filter-off":"material/filter-off.svg","material-filter-outline":"material/filter-outline.svg","material-filter-plus-outline":"material/filter-plus-outline.svg","material-filter-plus":"material/filter-plus.svg","material-filter-remove-outline":"material/filter-remove-outline.svg","material-filter-remove":"material/filter-remove.svg","material-filter-settings-outline":"material/filter-settings-outline.svg","material-filter-settings":"material/filter-settings.svg","material-filter-variant-minus":"material/filter-variant-minus.svg","material-filter-variant-plus":"material/filter-variant-plus.svg","material-filter-variant-remove":"material/filter-variant-remove.svg","material-filter-variant":"material/filter-variant.svg","material-filter":"material/filter.svg","material-finance":"material/finance.svg","material-find-replace":"material/find-replace.svg","material-fingerprint-off":"material/fingerprint-off.svg","material-fingerprint":"material/fingerprint.svg","material-fire-alert":"material/fire-alert.svg","material-fire-circle":"material/fire-circle.svg","material-fire-extinguisher":"material/fire-extinguisher.svg","material-fire-hydrant-alert":"material/fire-hydrant-alert.svg","material-fire-hydrant-off":"material/fire-hydrant-off.svg","material-fire-hydrant":"material/fire-hydrant.svg","material-fire-off":"material/fire-off.svg","material-fire-truck":"material/fire-truck.svg","material-fire":"material/fire.svg","material-firebase":"material/firebase.svg","material-firefox":"material/firefox.svg","material-fireplace-off":"material/fireplace-off.svg","material-fireplace":"material/fireplace.svg","material-firewire":"material/firewire.svg","material-firework-off":"material/firework-off.svg","material-firework":"material/firework.svg","material-fish-off":"material/fish-off.svg","material-fish":"material/fish.svg","material-fishbowl-outline":"material/fishbowl-outline.svg","material-fishbowl":"material/fishbowl.svg","material-fit-to-page-outline":"material/fit-to-page-outline.svg","material-fit-to-page":"material/fit-to-page.svg","material-fit-to-screen-outline":"material/fit-to-screen-outline.svg","material-fit-to-screen":"material/fit-to-screen.svg","material-flag-checkered":"material/flag-checkered.svg","material-flag-minus-outline":"material/flag-minus-outline.svg","material-flag-minus":"material/flag-minus.svg","material-flag-off-outline":"material/flag-off-outline.svg","material-flag-off":"material/flag-off.svg","material-flag-outline":"material/flag-outline.svg","material-flag-plus-outline":"material/flag-plus-outline.svg","material-flag-plus":"material/flag-plus.svg","material-flag-remove-outline":"material/flag-remove-outline.svg","material-flag-remove":"material/flag-remove.svg","material-flag-triangle":"material/flag-triangle.svg","material-flag-variant-minus-outline":"material/flag-variant-minus-outline.svg","material-flag-variant-minus":"material/flag-variant-minus.svg","material-flag-variant-off-outline":"material/flag-variant-off-outline.svg","material-flag-variant-off":"material/flag-variant-off.svg","material-flag-variant-outline":"material/flag-variant-outline.svg","material-flag-variant-plus-outline":"material/flag-variant-plus-outline.svg","material-flag-variant-plus":"material/flag-variant-plus.svg","material-flag-variant-remove-outline":"material/flag-variant-remove-outline.svg","material-flag-variant-remove":"material/flag-variant-remove.svg","material-flag-variant":"material/flag-variant.svg","material-flag":"material/flag.svg","material-flare":"material/flare.svg","material-flash-alert-outline":"material/flash-alert-outline.svg","material-flash-alert":"material/flash-alert.svg","material-flash-auto":"material/flash-auto.svg","material-flash-off-outline":"material/flash-off-outline.svg","material-flash-off":"material/flash-off.svg","material-flash-outline":"material/flash-outline.svg","material-flash-red-eye":"material/flash-red-eye.svg","material-flash-triangle-outline":"material/flash-triangle-outline.svg","material-flash-triangle":"material/flash-triangle.svg","material-flash":"material/flash.svg","material-flashlight-off":"material/flashlight-off.svg","material-flashlight":"material/flashlight.svg","material-flask-empty-minus-outline":"material/flask-empty-minus-outline.svg","material-flask-empty-minus":"material/flask-empty-minus.svg","material-flask-empty-off-outline":"material/flask-empty-off-outline.svg","material-flask-empty-off":"material/flask-empty-off.svg","material-flask-empty-outline":"material/flask-empty-outline.svg","material-flask-empty-plus-outline":"material/flask-empty-plus-outline.svg","material-flask-empty-plus":"material/flask-empty-plus.svg","material-flask-empty-remove-outline":"material/flask-empty-remove-outline.svg","material-flask-empty-remove":"material/flask-empty-remove.svg","material-flask-empty":"material/flask-empty.svg","material-flask-minus-outline":"material/flask-minus-outline.svg","material-flask-minus":"material/flask-minus.svg","material-flask-off-outline":"material/flask-off-outline.svg","material-flask-off":"material/flask-off.svg","material-flask-outline":"material/flask-outline.svg","material-flask-plus-outline":"material/flask-plus-outline.svg","material-flask-plus":"material/flask-plus.svg","material-flask-remove-outline":"material/flask-remove-outline.svg","material-flask-remove":"material/flask-remove.svg","material-flask-round-bottom-empty-outline":"material/flask-round-bottom-empty-outline.svg","material-flask-round-bottom-empty":"material/flask-round-bottom-empty.svg","material-flask-round-bottom-outline":"material/flask-round-bottom-outline.svg","material-flask-round-bottom":"material/flask-round-bottom.svg","material-flask":"material/flask.svg","material-fleur-de-lis":"material/fleur-de-lis.svg","material-flip-horizontal":"material/flip-horizontal.svg","material-flip-to-back":"material/flip-to-back.svg","material-flip-to-front":"material/flip-to-front.svg","material-flip-vertical":"material/flip-vertical.svg","material-floor-lamp-dual-outline":"material/floor-lamp-dual-outline.svg","material-floor-lamp-dual":"material/floor-lamp-dual.svg","material-floor-lamp-outline":"material/floor-lamp-outline.svg","material-floor-lamp-torchiere-outline":"material/floor-lamp-torchiere-outline.svg","material-floor-lamp-torchiere-variant-outline":"material/floor-lamp-torchiere-variant-outline.svg","material-floor-lamp-torchiere-variant":"material/floor-lamp-torchiere-variant.svg","material-floor-lamp-torchiere":"material/floor-lamp-torchiere.svg","material-floor-lamp":"material/floor-lamp.svg","material-floor-plan":"material/floor-plan.svg","material-floppy-variant":"material/floppy-variant.svg","material-floppy":"material/floppy.svg","material-flower-outline":"material/flower-outline.svg","material-flower-pollen-outline":"material/flower-pollen-outline.svg","material-flower-pollen":"material/flower-pollen.svg","material-flower-poppy":"material/flower-poppy.svg","material-flower-tulip-outline":"material/flower-tulip-outline.svg","material-flower-tulip":"material/flower-tulip.svg","material-flower":"material/flower.svg","material-focus-auto":"material/focus-auto.svg","material-focus-field-horizontal":"material/focus-field-horizontal.svg","material-focus-field-vertical":"material/focus-field-vertical.svg","material-focus-field":"material/focus-field.svg","material-folder-account-outline":"material/folder-account-outline.svg","material-folder-account":"material/folder-account.svg","material-folder-alert-outline":"material/folder-alert-outline.svg","material-folder-alert":"material/folder-alert.svg","material-folder-arrow-down-outline":"material/folder-arrow-down-outline.svg","material-folder-arrow-down":"material/folder-arrow-down.svg","material-folder-arrow-left-outline":"material/folder-arrow-left-outline.svg","material-folder-arrow-left-right-outline":"material/folder-arrow-left-right-outline.svg","material-folder-arrow-left-right":"material/folder-arrow-left-right.svg","material-folder-arrow-left":"material/folder-arrow-left.svg","material-folder-arrow-right-outline":"material/folder-arrow-right-outline.svg","material-folder-arrow-right":"material/folder-arrow-right.svg","material-folder-arrow-up-down-outline":"material/folder-arrow-up-down-outline.svg","material-folder-arrow-up-down":"material/folder-arrow-up-down.svg","material-folder-arrow-up-outline":"material/folder-arrow-up-outline.svg","material-folder-arrow-up":"material/folder-arrow-up.svg","material-folder-cancel-outline":"material/folder-cancel-outline.svg","material-folder-cancel":"material/folder-cancel.svg","material-folder-check-outline":"material/folder-check-outline.svg","material-folder-check":"material/folder-check.svg","material-folder-clock-outline":"material/folder-clock-outline.svg","material-folder-clock":"material/folder-clock.svg","material-folder-cog-outline":"material/folder-cog-outline.svg","material-folder-cog":"material/folder-cog.svg","material-folder-download-outline":"material/folder-download-outline.svg","material-folder-download":"material/folder-download.svg","material-folder-edit-outline":"material/folder-edit-outline.svg","material-folder-edit":"material/folder-edit.svg","material-folder-eye-outline":"material/folder-eye-outline.svg","material-folder-eye":"material/folder-eye.svg","material-folder-file-outline":"material/folder-file-outline.svg","material-folder-file":"material/folder-file.svg","material-folder-google-drive":"material/folder-google-drive.svg","material-folder-heart-outline":"material/folder-heart-outline.svg","material-folder-heart":"material/folder-heart.svg","material-folder-hidden":"material/folder-hidden.svg","material-folder-home-outline":"material/folder-home-outline.svg","material-folder-home":"material/folder-home.svg","material-folder-image":"material/folder-image.svg","material-folder-information-outline":"material/folder-information-outline.svg","material-folder-information":"material/folder-information.svg","material-folder-key-network-outline":"material/folder-key-network-outline.svg","material-folder-key-network":"material/folder-key-network.svg","material-folder-key-outline":"material/folder-key-outline.svg","material-folder-key":"material/folder-key.svg","material-folder-lock-open-outline":"material/folder-lock-open-outline.svg","material-folder-lock-open":"material/folder-lock-open.svg","material-folder-lock-outline":"material/folder-lock-outline.svg","material-folder-lock":"material/folder-lock.svg","material-folder-marker-outline":"material/folder-marker-outline.svg","material-folder-marker":"material/folder-marker.svg","material-folder-minus-outline":"material/folder-minus-outline.svg","material-folder-minus":"material/folder-minus.svg","material-folder-move-outline":"material/folder-move-outline.svg","material-folder-move":"material/folder-move.svg","material-folder-multiple-image":"material/folder-multiple-image.svg","material-folder-multiple-outline":"material/folder-multiple-outline.svg","material-folder-multiple-plus-outline":"material/folder-multiple-plus-outline.svg","material-folder-multiple-plus":"material/folder-multiple-plus.svg","material-folder-multiple":"material/folder-multiple.svg","material-folder-music-outline":"material/folder-music-outline.svg","material-folder-music":"material/folder-music.svg","material-folder-network-outline":"material/folder-network-outline.svg","material-folder-network":"material/folder-network.svg","material-folder-off-outline":"material/folder-off-outline.svg","material-folder-off":"material/folder-off.svg","material-folder-open-outline":"material/folder-open-outline.svg","material-folder-open":"material/folder-open.svg","material-folder-outline":"material/folder-outline.svg","material-folder-play-outline":"material/folder-play-outline.svg","material-folder-play":"material/folder-play.svg","material-folder-plus-outline":"material/folder-plus-outline.svg","material-folder-plus":"material/folder-plus.svg","material-folder-pound-outline":"material/folder-pound-outline.svg","material-folder-pound":"material/folder-pound.svg","material-folder-question-outline":"material/folder-question-outline.svg","material-folder-question":"material/folder-question.svg","material-folder-refresh-outline":"material/folder-refresh-outline.svg","material-folder-refresh":"material/folder-refresh.svg","material-folder-remove-outline":"material/folder-remove-outline.svg","material-folder-remove":"material/folder-remove.svg","material-folder-search-outline":"material/folder-search-outline.svg","material-folder-search":"material/folder-search.svg","material-folder-settings-outline":"material/folder-settings-outline.svg","material-folder-settings":"material/folder-settings.svg","material-folder-star-multiple-outline":"material/folder-star-multiple-outline.svg","material-folder-star-multiple":"material/folder-star-multiple.svg","material-folder-star-outline":"material/folder-star-outline.svg","material-folder-star":"material/folder-star.svg","material-folder-swap-outline":"material/folder-swap-outline.svg","material-folder-swap":"material/folder-swap.svg","material-folder-sync-outline":"material/folder-sync-outline.svg","material-folder-sync":"material/folder-sync.svg","material-folder-table-outline":"material/folder-table-outline.svg","material-folder-table":"material/folder-table.svg","material-folder-text-outline":"material/folder-text-outline.svg","material-folder-text":"material/folder-text.svg","material-folder-upload-outline":"material/folder-upload-outline.svg","material-folder-upload":"material/folder-upload.svg","material-folder-wrench-outline":"material/folder-wrench-outline.svg","material-folder-wrench":"material/folder-wrench.svg","material-folder-zip-outline":"material/folder-zip-outline.svg","material-folder-zip":"material/folder-zip.svg","material-folder":"material/folder.svg","material-font-awesome":"material/font-awesome.svg","material-food-apple-outline":"material/food-apple-outline.svg","material-food-apple":"material/food-apple.svg","material-food-croissant":"material/food-croissant.svg","material-food-drumstick-off-outline":"material/food-drumstick-off-outline.svg","material-food-drumstick-off":"material/food-drumstick-off.svg","material-food-drumstick-outline":"material/food-drumstick-outline.svg","material-food-drumstick":"material/food-drumstick.svg","material-food-fork-drink":"material/food-fork-drink.svg","material-food-halal":"material/food-halal.svg","material-food-hot-dog":"material/food-hot-dog.svg","material-food-kosher":"material/food-kosher.svg","material-food-off-outline":"material/food-off-outline.svg","material-food-off":"material/food-off.svg","material-food-outline":"material/food-outline.svg","material-food-steak-off":"material/food-steak-off.svg","material-food-steak":"material/food-steak.svg","material-food-takeout-box-outline":"material/food-takeout-box-outline.svg","material-food-takeout-box":"material/food-takeout-box.svg","material-food-turkey":"material/food-turkey.svg","material-food-variant-off":"material/food-variant-off.svg","material-food-variant":"material/food-variant.svg","material-food":"material/food.svg","material-foot-print":"material/foot-print.svg","material-football-australian":"material/football-australian.svg","material-football-helmet":"material/football-helmet.svg","material-football":"material/football.svg","material-forest":"material/forest.svg","material-forklift":"material/forklift.svg","material-form-dropdown":"material/form-dropdown.svg","material-form-select":"material/form-select.svg","material-form-textarea":"material/form-textarea.svg","material-form-textbox-lock":"material/form-textbox-lock.svg","material-form-textbox-password":"material/form-textbox-password.svg","material-form-textbox":"material/form-textbox.svg","material-format-align-bottom":"material/format-align-bottom.svg","material-format-align-center":"material/format-align-center.svg","material-format-align-justify":"material/format-align-justify.svg","material-format-align-left":"material/format-align-left.svg","material-format-align-middle":"material/format-align-middle.svg","material-format-align-right":"material/format-align-right.svg","material-format-align-top":"material/format-align-top.svg","material-format-annotation-minus":"material/format-annotation-minus.svg","material-format-annotation-plus":"material/format-annotation-plus.svg","material-format-bold":"material/format-bold.svg","material-format-clear":"material/format-clear.svg","material-format-color-fill":"material/format-color-fill.svg","material-format-color-highlight":"material/format-color-highlight.svg","material-format-color-marker-cancel":"material/format-color-marker-cancel.svg","material-format-color-text":"material/format-color-text.svg","material-format-columns":"material/format-columns.svg","material-format-float-center":"material/format-float-center.svg","material-format-float-left":"material/format-float-left.svg","material-format-float-none":"material/format-float-none.svg","material-format-float-right":"material/format-float-right.svg","material-format-font-size-decrease":"material/format-font-size-decrease.svg","material-format-font-size-increase":"material/format-font-size-increase.svg","material-format-font":"material/format-font.svg","material-format-header-1":"material/format-header-1.svg","material-format-header-2":"material/format-header-2.svg","material-format-header-3":"material/format-header-3.svg","material-format-header-4":"material/format-header-4.svg","material-format-header-5":"material/format-header-5.svg","material-format-header-6":"material/format-header-6.svg","material-format-header-decrease":"material/format-header-decrease.svg","material-format-header-equal":"material/format-header-equal.svg","material-format-header-increase":"material/format-header-increase.svg","material-format-header-pound":"material/format-header-pound.svg","material-format-horizontal-align-center":"material/format-horizontal-align-center.svg","material-format-horizontal-align-left":"material/format-horizontal-align-left.svg","material-format-horizontal-align-right":"material/format-horizontal-align-right.svg","material-format-indent-decrease":"material/format-indent-decrease.svg","material-format-indent-increase":"material/format-indent-increase.svg","material-format-italic":"material/format-italic.svg","material-format-letter-case-lower":"material/format-letter-case-lower.svg","material-format-letter-case-upper":"material/format-letter-case-upper.svg","material-format-letter-case":"material/format-letter-case.svg","material-format-letter-ends-with":"material/format-letter-ends-with.svg","material-format-letter-matches":"material/format-letter-matches.svg","material-format-letter-spacing-variant":"material/format-letter-spacing-variant.svg","material-format-letter-spacing":"material/format-letter-spacing.svg","material-format-letter-starts-with":"material/format-letter-starts-with.svg","material-format-line-height":"material/format-line-height.svg","material-format-line-spacing":"material/format-line-spacing.svg","material-format-line-style":"material/format-line-style.svg","material-format-line-weight":"material/format-line-weight.svg","material-format-list-bulleted-square":"material/format-list-bulleted-square.svg","material-format-list-bulleted-triangle":"material/format-list-bulleted-triangle.svg","material-format-list-bulleted-type":"material/format-list-bulleted-type.svg","material-format-list-bulleted":"material/format-list-bulleted.svg","material-format-list-checkbox":"material/format-list-checkbox.svg","material-format-list-checks":"material/format-list-checks.svg","material-format-list-group-plus":"material/format-list-group-plus.svg","material-format-list-group":"material/format-list-group.svg","material-format-list-numbered-rtl":"material/format-list-numbered-rtl.svg","material-format-list-numbered":"material/format-list-numbered.svg","material-format-list-text":"material/format-list-text.svg","material-format-overline":"material/format-overline.svg","material-format-page-break":"material/format-page-break.svg","material-format-page-split":"material/format-page-split.svg","material-format-paint":"material/format-paint.svg","material-format-paragraph-spacing":"material/format-paragraph-spacing.svg","material-format-paragraph":"material/format-paragraph.svg","material-format-pilcrow-arrow-left":"material/format-pilcrow-arrow-left.svg","material-format-pilcrow-arrow-right":"material/format-pilcrow-arrow-right.svg","material-format-pilcrow":"material/format-pilcrow.svg","material-format-quote-close-outline":"material/format-quote-close-outline.svg","material-format-quote-close":"material/format-quote-close.svg","material-format-quote-open-outline":"material/format-quote-open-outline.svg","material-format-quote-open":"material/format-quote-open.svg","material-format-rotate-90":"material/format-rotate-90.svg","material-format-section":"material/format-section.svg","material-format-size":"material/format-size.svg","material-format-strikethrough-variant":"material/format-strikethrough-variant.svg","material-format-strikethrough":"material/format-strikethrough.svg","material-format-subscript":"material/format-subscript.svg","material-format-superscript":"material/format-superscript.svg","material-format-text-rotation-angle-down":"material/format-text-rotation-angle-down.svg","material-format-text-rotation-angle-up":"material/format-text-rotation-angle-up.svg","material-format-text-rotation-down-vertical":"material/format-text-rotation-down-vertical.svg","material-format-text-rotation-down":"material/format-text-rotation-down.svg","material-format-text-rotation-none":"material/format-text-rotation-none.svg","material-format-text-rotation-up":"material/format-text-rotation-up.svg","material-format-text-rotation-vertical":"material/format-text-rotation-vertical.svg","material-format-text-variant-outline":"material/format-text-variant-outline.svg","material-format-text-variant":"material/format-text-variant.svg","material-format-text-wrapping-clip":"material/format-text-wrapping-clip.svg","material-format-text-wrapping-overflow":"material/format-text-wrapping-overflow.svg","material-format-text-wrapping-wrap":"material/format-text-wrapping-wrap.svg","material-format-text":"material/format-text.svg","material-format-textbox":"material/format-textbox.svg","material-format-title":"material/format-title.svg","material-format-underline-wavy":"material/format-underline-wavy.svg","material-format-underline":"material/format-underline.svg","material-format-vertical-align-bottom":"material/format-vertical-align-bottom.svg","material-format-vertical-align-center":"material/format-vertical-align-center.svg","material-format-vertical-align-top":"material/format-vertical-align-top.svg","material-format-wrap-inline":"material/format-wrap-inline.svg","material-format-wrap-square":"material/format-wrap-square.svg","material-format-wrap-tight":"material/format-wrap-tight.svg","material-format-wrap-top-bottom":"material/format-wrap-top-bottom.svg","material-forum-minus-outline":"material/forum-minus-outline.svg","material-forum-minus":"material/forum-minus.svg","material-forum-outline":"material/forum-outline.svg","material-forum-plus-outline":"material/forum-plus-outline.svg","material-forum-plus":"material/forum-plus.svg","material-forum-remove-outline":"material/forum-remove-outline.svg","material-forum-remove":"material/forum-remove.svg","material-forum":"material/forum.svg","material-forward":"material/forward.svg","material-forwardburger":"material/forwardburger.svg","material-fountain-pen-tip":"material/fountain-pen-tip.svg","material-fountain-pen":"material/fountain-pen.svg","material-fountain":"material/fountain.svg","material-fraction-one-half":"material/fraction-one-half.svg","material-freebsd":"material/freebsd.svg","material-french-fries":"material/french-fries.svg","material-frequently-asked-questions":"material/frequently-asked-questions.svg","material-fridge-alert-outline":"material/fridge-alert-outline.svg","material-fridge-alert":"material/fridge-alert.svg","material-fridge-bottom":"material/fridge-bottom.svg","material-fridge-industrial-alert-outline":"material/fridge-industrial-alert-outline.svg","material-fridge-industrial-alert":"material/fridge-industrial-alert.svg","material-fridge-industrial-off-outline":"material/fridge-industrial-off-outline.svg","material-fridge-industrial-off":"material/fridge-industrial-off.svg","material-fridge-industrial-outline":"material/fridge-industrial-outline.svg","material-fridge-industrial":"material/fridge-industrial.svg","material-fridge-off-outline":"material/fridge-off-outline.svg","material-fridge-off":"material/fridge-off.svg","material-fridge-outline":"material/fridge-outline.svg","material-fridge-top":"material/fridge-top.svg","material-fridge-variant-alert-outline":"material/fridge-variant-alert-outline.svg","material-fridge-variant-alert":"material/fridge-variant-alert.svg","material-fridge-variant-off-outline":"material/fridge-variant-off-outline.svg","material-fridge-variant-off":"material/fridge-variant-off.svg","material-fridge-variant-outline":"material/fridge-variant-outline.svg","material-fridge-variant":"material/fridge-variant.svg","material-fridge":"material/fridge.svg","material-fruit-cherries-off":"material/fruit-cherries-off.svg","material-fruit-cherries":"material/fruit-cherries.svg","material-fruit-citrus-off":"material/fruit-citrus-off.svg","material-fruit-citrus":"material/fruit-citrus.svg","material-fruit-grapes-outline":"material/fruit-grapes-outline.svg","material-fruit-grapes":"material/fruit-grapes.svg","material-fruit-pear":"material/fruit-pear.svg","material-fruit-pineapple":"material/fruit-pineapple.svg","material-fruit-watermelon":"material/fruit-watermelon.svg","material-fuel-cell":"material/fuel-cell.svg","material-fuel":"material/fuel.svg","material-fullscreen-exit":"material/fullscreen-exit.svg","material-fullscreen":"material/fullscreen.svg","material-function-variant":"material/function-variant.svg","material-function":"material/function.svg","material-furigana-horizontal":"material/furigana-horizontal.svg","material-furigana-vertical":"material/furigana-vertical.svg","material-fuse-alert":"material/fuse-alert.svg","material-fuse-blade":"material/fuse-blade.svg","material-fuse-off":"material/fuse-off.svg","material-fuse":"material/fuse.svg","material-gamepad-circle-down":"material/gamepad-circle-down.svg","material-gamepad-circle-left":"material/gamepad-circle-left.svg","material-gamepad-circle-outline":"material/gamepad-circle-outline.svg","material-gamepad-circle-right":"material/gamepad-circle-right.svg","material-gamepad-circle-up":"material/gamepad-circle-up.svg","material-gamepad-circle":"material/gamepad-circle.svg","material-gamepad-down":"material/gamepad-down.svg","material-gamepad-left":"material/gamepad-left.svg","material-gamepad-outline":"material/gamepad-outline.svg","material-gamepad-right":"material/gamepad-right.svg","material-gamepad-round-down":"material/gamepad-round-down.svg","material-gamepad-round-left":"material/gamepad-round-left.svg","material-gamepad-round-outline":"material/gamepad-round-outline.svg","material-gamepad-round-right":"material/gamepad-round-right.svg","material-gamepad-round-up":"material/gamepad-round-up.svg","material-gamepad-round":"material/gamepad-round.svg","material-gamepad-square-outline":"material/gamepad-square-outline.svg","material-gamepad-square":"material/gamepad-square.svg","material-gamepad-up":"material/gamepad-up.svg","material-gamepad-variant-outline":"material/gamepad-variant-outline.svg","material-gamepad-variant":"material/gamepad-variant.svg","material-gamepad":"material/gamepad.svg","material-gamma":"material/gamma.svg","material-gantry-crane":"material/gantry-crane.svg","material-garage-alert-variant":"material/garage-alert-variant.svg","material-garage-alert":"material/garage-alert.svg","material-garage-lock":"material/garage-lock.svg","material-garage-open-variant":"material/garage-open-variant.svg","material-garage-open":"material/garage-open.svg","material-garage-variant-lock":"material/garage-variant-lock.svg","material-garage-variant":"material/garage-variant.svg","material-garage":"material/garage.svg","material-gas-burner":"material/gas-burner.svg","material-gas-cylinder":"material/gas-cylinder.svg","material-gas-station-off-outline":"material/gas-station-off-outline.svg","material-gas-station-off":"material/gas-station-off.svg","material-gas-station-outline":"material/gas-station-outline.svg","material-gas-station":"material/gas-station.svg","material-gate-alert":"material/gate-alert.svg","material-gate-and":"material/gate-and.svg","material-gate-arrow-left":"material/gate-arrow-left.svg","material-gate-arrow-right":"material/gate-arrow-right.svg","material-gate-buffer":"material/gate-buffer.svg","material-gate-nand":"material/gate-nand.svg","material-gate-nor":"material/gate-nor.svg","material-gate-not":"material/gate-not.svg","material-gate-open":"material/gate-open.svg","material-gate-or":"material/gate-or.svg","material-gate-xnor":"material/gate-xnor.svg","material-gate-xor":"material/gate-xor.svg","material-gate":"material/gate.svg","material-gatsby":"material/gatsby.svg","material-gauge-empty":"material/gauge-empty.svg","material-gauge-full":"material/gauge-full.svg","material-gauge-low":"material/gauge-low.svg","material-gauge":"material/gauge.svg","material-gavel":"material/gavel.svg","material-gender-female":"material/gender-female.svg","material-gender-male-female-variant":"material/gender-male-female-variant.svg","material-gender-male-female":"material/gender-male-female.svg","material-gender-male":"material/gender-male.svg","material-gender-non-binary":"material/gender-non-binary.svg","material-gender-transgender":"material/gender-transgender.svg","material-gentoo":"material/gentoo.svg","material-gesture-double-tap":"material/gesture-double-tap.svg","material-gesture-pinch":"material/gesture-pinch.svg","material-gesture-spread":"material/gesture-spread.svg","material-gesture-swipe-down":"material/gesture-swipe-down.svg","material-gesture-swipe-horizontal":"material/gesture-swipe-horizontal.svg","material-gesture-swipe-left":"material/gesture-swipe-left.svg","material-gesture-swipe-right":"material/gesture-swipe-right.svg","material-gesture-swipe-up":"material/gesture-swipe-up.svg","material-gesture-swipe-vertical":"material/gesture-swipe-vertical.svg","material-gesture-swipe":"material/gesture-swipe.svg","material-gesture-tap-box":"material/gesture-tap-box.svg","material-gesture-tap-button":"material/gesture-tap-button.svg","material-gesture-tap-hold":"material/gesture-tap-hold.svg","material-gesture-tap":"material/gesture-tap.svg","material-gesture-two-double-tap":"material/gesture-two-double-tap.svg","material-gesture-two-tap":"material/gesture-two-tap.svg","material-gesture":"material/gesture.svg","material-ghost-off-outline":"material/ghost-off-outline.svg","material-ghost-off":"material/ghost-off.svg","material-ghost-outline":"material/ghost-outline.svg","material-ghost":"material/ghost.svg","material-gift-off-outline":"material/gift-off-outline.svg","material-gift-off":"material/gift-off.svg","material-gift-open-outline":"material/gift-open-outline.svg","material-gift-open":"material/gift-open.svg","material-gift-outline":"material/gift-outline.svg","material-gift":"material/gift.svg","material-git":"material/git.svg","material-github":"material/github.svg","material-gitlab":"material/gitlab.svg","material-glass-cocktail-off":"material/glass-cocktail-off.svg","material-glass-cocktail":"material/glass-cocktail.svg","material-glass-flute":"material/glass-flute.svg","material-glass-fragile":"material/glass-fragile.svg","material-glass-mug-off":"material/glass-mug-off.svg","material-glass-mug-variant-off":"material/glass-mug-variant-off.svg","material-glass-mug-variant":"material/glass-mug-variant.svg","material-glass-mug":"material/glass-mug.svg","material-glass-pint-outline":"material/glass-pint-outline.svg","material-glass-stange":"material/glass-stange.svg","material-glass-tulip":"material/glass-tulip.svg","material-glass-wine":"material/glass-wine.svg","material-glasses":"material/glasses.svg","material-globe-light-outline":"material/globe-light-outline.svg","material-globe-light":"material/globe-light.svg","material-globe-model":"material/globe-model.svg","material-gmail":"material/gmail.svg","material-gnome":"material/gnome.svg","material-go-kart-track":"material/go-kart-track.svg","material-go-kart":"material/go-kart.svg","material-gog":"material/gog.svg","material-gold":"material/gold.svg","material-golf-cart":"material/golf-cart.svg","material-golf-tee":"material/golf-tee.svg","material-golf":"material/golf.svg","material-gondola":"material/gondola.svg","material-goodreads":"material/goodreads.svg","material-google-ads":"material/google-ads.svg","material-google-analytics":"material/google-analytics.svg","material-google-assistant":"material/google-assistant.svg","material-google-cardboard":"material/google-cardboard.svg","material-google-chrome":"material/google-chrome.svg","material-google-circles-communities":"material/google-circles-communities.svg","material-google-circles-extended":"material/google-circles-extended.svg","material-google-circles-group":"material/google-circles-group.svg","material-google-circles":"material/google-circles.svg","material-google-classroom":"material/google-classroom.svg","material-google-cloud":"material/google-cloud.svg","material-google-downasaur":"material/google-downasaur.svg","material-google-drive":"material/google-drive.svg","material-google-earth":"material/google-earth.svg","material-google-fit":"material/google-fit.svg","material-google-glass":"material/google-glass.svg","material-google-hangouts":"material/google-hangouts.svg","material-google-keep":"material/google-keep.svg","material-google-lens":"material/google-lens.svg","material-google-maps":"material/google-maps.svg","material-google-my-business":"material/google-my-business.svg","material-google-nearby":"material/google-nearby.svg","material-google-play":"material/google-play.svg","material-google-plus":"material/google-plus.svg","material-google-podcast":"material/google-podcast.svg","material-google-spreadsheet":"material/google-spreadsheet.svg","material-google-street-view":"material/google-street-view.svg","material-google-translate":"material/google-translate.svg","material-google":"material/google.svg","material-gradient-horizontal":"material/gradient-horizontal.svg","material-gradient-vertical":"material/gradient-vertical.svg","material-grain":"material/grain.svg","material-graph-outline":"material/graph-outline.svg","material-graph":"material/graph.svg","material-graphql":"material/graphql.svg","material-grass":"material/grass.svg","material-grave-stone":"material/grave-stone.svg","material-grease-pencil":"material/grease-pencil.svg","material-greater-than-or-equal":"material/greater-than-or-equal.svg","material-greater-than":"material/greater-than.svg","material-greenhouse":"material/greenhouse.svg","material-grid-large":"material/grid-large.svg","material-grid-off":"material/grid-off.svg","material-grid":"material/grid.svg","material-grill-outline":"material/grill-outline.svg","material-grill":"material/grill.svg","material-group":"material/group.svg","material-guitar-acoustic":"material/guitar-acoustic.svg","material-guitar-electric":"material/guitar-electric.svg","material-guitar-pick-outline":"material/guitar-pick-outline.svg","material-guitar-pick":"material/guitar-pick.svg","material-guy-fawkes-mask":"material/guy-fawkes-mask.svg","material-gymnastics":"material/gymnastics.svg","material-hail":"material/hail.svg","material-hair-dryer-outline":"material/hair-dryer-outline.svg","material-hair-dryer":"material/hair-dryer.svg","material-halloween":"material/halloween.svg","material-hamburger-check":"material/hamburger-check.svg","material-hamburger-minus":"material/hamburger-minus.svg","material-hamburger-off":"material/hamburger-off.svg","material-hamburger-plus":"material/hamburger-plus.svg","material-hamburger-remove":"material/hamburger-remove.svg","material-hamburger":"material/hamburger.svg","material-hammer-screwdriver":"material/hammer-screwdriver.svg","material-hammer-sickle":"material/hammer-sickle.svg","material-hammer-wrench":"material/hammer-wrench.svg","material-hammer":"material/hammer.svg","material-hand-back-left-off-outline":"material/hand-back-left-off-outline.svg","material-hand-back-left-off":"material/hand-back-left-off.svg","material-hand-back-left-outline":"material/hand-back-left-outline.svg","material-hand-back-left":"material/hand-back-left.svg","material-hand-back-right-off-outline":"material/hand-back-right-off-outline.svg","material-hand-back-right-off":"material/hand-back-right-off.svg","material-hand-back-right-outline":"material/hand-back-right-outline.svg","material-hand-back-right":"material/hand-back-right.svg","material-hand-clap-off":"material/hand-clap-off.svg","material-hand-clap":"material/hand-clap.svg","material-hand-coin-outline":"material/hand-coin-outline.svg","material-hand-coin":"material/hand-coin.svg","material-hand-cycle":"material/hand-cycle.svg","material-hand-extended-outline":"material/hand-extended-outline.svg","material-hand-extended":"material/hand-extended.svg","material-hand-front-left-outline":"material/hand-front-left-outline.svg","material-hand-front-left":"material/hand-front-left.svg","material-hand-front-right-outline":"material/hand-front-right-outline.svg","material-hand-front-right":"material/hand-front-right.svg","material-hand-heart-outline":"material/hand-heart-outline.svg","material-hand-heart":"material/hand-heart.svg","material-hand-okay":"material/hand-okay.svg","material-hand-peace-variant":"material/hand-peace-variant.svg","material-hand-peace":"material/hand-peace.svg","material-hand-pointing-down":"material/hand-pointing-down.svg","material-hand-pointing-left":"material/hand-pointing-left.svg","material-hand-pointing-right":"material/hand-pointing-right.svg","material-hand-pointing-up":"material/hand-pointing-up.svg","material-hand-saw":"material/hand-saw.svg","material-hand-wash-outline":"material/hand-wash-outline.svg","material-hand-wash":"material/hand-wash.svg","material-hand-water":"material/hand-water.svg","material-hand-wave-outline":"material/hand-wave-outline.svg","material-hand-wave":"material/hand-wave.svg","material-handball":"material/handball.svg","material-handcuffs":"material/handcuffs.svg","material-hands-pray":"material/hands-pray.svg","material-handshake-outline":"material/handshake-outline.svg","material-handshake":"material/handshake.svg","material-hanger":"material/hanger.svg","material-hard-hat":"material/hard-hat.svg","material-harddisk-plus":"material/harddisk-plus.svg","material-harddisk-remove":"material/harddisk-remove.svg","material-harddisk":"material/harddisk.svg","material-hat-fedora":"material/hat-fedora.svg","material-hazard-lights":"material/hazard-lights.svg","material-hdmi-port":"material/hdmi-port.svg","material-hdr-off":"material/hdr-off.svg","material-hdr":"material/hdr.svg","material-head-alert-outline":"material/head-alert-outline.svg","material-head-alert":"material/head-alert.svg","material-head-check-outline":"material/head-check-outline.svg","material-head-check":"material/head-check.svg","material-head-cog-outline":"material/head-cog-outline.svg","material-head-cog":"material/head-cog.svg","material-head-dots-horizontal-outline":"material/head-dots-horizontal-outline.svg","material-head-dots-horizontal":"material/head-dots-horizontal.svg","material-head-flash-outline":"material/head-flash-outline.svg","material-head-flash":"material/head-flash.svg","material-head-heart-outline":"material/head-heart-outline.svg","material-head-heart":"material/head-heart.svg","material-head-lightbulb-outline":"material/head-lightbulb-outline.svg","material-head-lightbulb":"material/head-lightbulb.svg","material-head-minus-outline":"material/head-minus-outline.svg","material-head-minus":"material/head-minus.svg","material-head-outline":"material/head-outline.svg","material-head-plus-outline":"material/head-plus-outline.svg","material-head-plus":"material/head-plus.svg","material-head-question-outline":"material/head-question-outline.svg","material-head-question":"material/head-question.svg","material-head-remove-outline":"material/head-remove-outline.svg","material-head-remove":"material/head-remove.svg","material-head-snowflake-outline":"material/head-snowflake-outline.svg","material-head-snowflake":"material/head-snowflake.svg","material-head-sync-outline":"material/head-sync-outline.svg","material-head-sync":"material/head-sync.svg","material-head":"material/head.svg","material-headphones-bluetooth":"material/headphones-bluetooth.svg","material-headphones-box":"material/headphones-box.svg","material-headphones-off":"material/headphones-off.svg","material-headphones-settings":"material/headphones-settings.svg","material-headphones":"material/headphones.svg","material-headset-dock":"material/headset-dock.svg","material-headset-off":"material/headset-off.svg","material-headset":"material/headset.svg","material-heart-box-outline":"material/heart-box-outline.svg","material-heart-box":"material/heart-box.svg","material-heart-broken-outline":"material/heart-broken-outline.svg","material-heart-broken":"material/heart-broken.svg","material-heart-circle-outline":"material/heart-circle-outline.svg","material-heart-circle":"material/heart-circle.svg","material-heart-cog-outline":"material/heart-cog-outline.svg","material-heart-cog":"material/heart-cog.svg","material-heart-flash":"material/heart-flash.svg","material-heart-half-full":"material/heart-half-full.svg","material-heart-half-outline":"material/heart-half-outline.svg","material-heart-half":"material/heart-half.svg","material-heart-minus-outline":"material/heart-minus-outline.svg","material-heart-minus":"material/heart-minus.svg","material-heart-multiple-outline":"material/heart-multiple-outline.svg","material-heart-multiple":"material/heart-multiple.svg","material-heart-off-outline":"material/heart-off-outline.svg","material-heart-off":"material/heart-off.svg","material-heart-outline":"material/heart-outline.svg","material-heart-plus-outline":"material/heart-plus-outline.svg","material-heart-plus":"material/heart-plus.svg","material-heart-pulse":"material/heart-pulse.svg","material-heart-remove-outline":"material/heart-remove-outline.svg","material-heart-remove":"material/heart-remove.svg","material-heart-settings-outline":"material/heart-settings-outline.svg","material-heart-settings":"material/heart-settings.svg","material-heart":"material/heart.svg","material-heat-pump-outline":"material/heat-pump-outline.svg","material-heat-pump":"material/heat-pump.svg","material-heat-wave":"material/heat-wave.svg","material-heating-coil":"material/heating-coil.svg","material-helicopter":"material/helicopter.svg","material-help-box":"material/help-box.svg","material-help-circle-outline":"material/help-circle-outline.svg","material-help-circle":"material/help-circle.svg","material-help-network-outline":"material/help-network-outline.svg","material-help-network":"material/help-network.svg","material-help-rhombus-outline":"material/help-rhombus-outline.svg","material-help-rhombus":"material/help-rhombus.svg","material-help":"material/help.svg","material-hexadecimal":"material/hexadecimal.svg","material-hexagon-multiple-outline":"material/hexagon-multiple-outline.svg","material-hexagon-multiple":"material/hexagon-multiple.svg","material-hexagon-outline":"material/hexagon-outline.svg","material-hexagon-slice-1":"material/hexagon-slice-1.svg","material-hexagon-slice-2":"material/hexagon-slice-2.svg","material-hexagon-slice-3":"material/hexagon-slice-3.svg","material-hexagon-slice-4":"material/hexagon-slice-4.svg","material-hexagon-slice-5":"material/hexagon-slice-5.svg","material-hexagon-slice-6":"material/hexagon-slice-6.svg","material-hexagon":"material/hexagon.svg","material-hexagram-outline":"material/hexagram-outline.svg","material-hexagram":"material/hexagram.svg","material-high-definition-box":"material/high-definition-box.svg","material-high-definition":"material/high-definition.svg","material-highway":"material/highway.svg","material-hiking":"material/hiking.svg","material-history":"material/history.svg","material-hockey-puck":"material/hockey-puck.svg","material-hockey-sticks":"material/hockey-sticks.svg","material-hololens":"material/hololens.svg","material-home-account":"material/home-account.svg","material-home-alert-outline":"material/home-alert-outline.svg","material-home-alert":"material/home-alert.svg","material-home-analytics":"material/home-analytics.svg","material-home-assistant":"material/home-assistant.svg","material-home-automation":"material/home-automation.svg","material-home-battery-outline":"material/home-battery-outline.svg","material-home-battery":"material/home-battery.svg","material-home-circle-outline":"material/home-circle-outline.svg","material-home-circle":"material/home-circle.svg","material-home-city-outline":"material/home-city-outline.svg","material-home-city":"material/home-city.svg","material-home-clock-outline":"material/home-clock-outline.svg","material-home-clock":"material/home-clock.svg","material-home-edit-outline":"material/home-edit-outline.svg","material-home-edit":"material/home-edit.svg","material-home-export-outline":"material/home-export-outline.svg","material-home-flood":"material/home-flood.svg","material-home-floor-0":"material/home-floor-0.svg","material-home-floor-1":"material/home-floor-1.svg","material-home-floor-2":"material/home-floor-2.svg","material-home-floor-3":"material/home-floor-3.svg","material-home-floor-a":"material/home-floor-a.svg","material-home-floor-b":"material/home-floor-b.svg","material-home-floor-g":"material/home-floor-g.svg","material-home-floor-l":"material/home-floor-l.svg","material-home-floor-negative-1":"material/home-floor-negative-1.svg","material-home-group-minus":"material/home-group-minus.svg","material-home-group-plus":"material/home-group-plus.svg","material-home-group-remove":"material/home-group-remove.svg","material-home-group":"material/home-group.svg","material-home-heart":"material/home-heart.svg","material-home-import-outline":"material/home-import-outline.svg","material-home-lightbulb-outline":"material/home-lightbulb-outline.svg","material-home-lightbulb":"material/home-lightbulb.svg","material-home-lightning-bolt-outline":"material/home-lightning-bolt-outline.svg","material-home-lightning-bolt":"material/home-lightning-bolt.svg","material-home-lock-open":"material/home-lock-open.svg","material-home-lock":"material/home-lock.svg","material-home-map-marker":"material/home-map-marker.svg","material-home-minus-outline":"material/home-minus-outline.svg","material-home-minus":"material/home-minus.svg","material-home-modern":"material/home-modern.svg","material-home-off-outline":"material/home-off-outline.svg","material-home-off":"material/home-off.svg","material-home-outline":"material/home-outline.svg","material-home-plus-outline":"material/home-plus-outline.svg","material-home-plus":"material/home-plus.svg","material-home-remove-outline":"material/home-remove-outline.svg","material-home-remove":"material/home-remove.svg","material-home-roof":"material/home-roof.svg","material-home-search-outline":"material/home-search-outline.svg","material-home-search":"material/home-search.svg","material-home-silo-outline":"material/home-silo-outline.svg","material-home-silo":"material/home-silo.svg","material-home-switch-outline":"material/home-switch-outline.svg","material-home-switch":"material/home-switch.svg","material-home-thermometer-outline":"material/home-thermometer-outline.svg","material-home-thermometer":"material/home-thermometer.svg","material-home-variant-outline":"material/home-variant-outline.svg","material-home-variant":"material/home-variant.svg","material-home":"material/home.svg","material-hook-off":"material/hook-off.svg","material-hook":"material/hook.svg","material-hoop-house":"material/hoop-house.svg","material-hops":"material/hops.svg","material-horizontal-rotate-clockwise":"material/horizontal-rotate-clockwise.svg","material-horizontal-rotate-counterclockwise":"material/horizontal-rotate-counterclockwise.svg","material-horse-human":"material/horse-human.svg","material-horse-variant-fast":"material/horse-variant-fast.svg","material-horse-variant":"material/horse-variant.svg","material-horse":"material/horse.svg","material-horseshoe":"material/horseshoe.svg","material-hospital-box-outline":"material/hospital-box-outline.svg","material-hospital-box":"material/hospital-box.svg","material-hospital-building":"material/hospital-building.svg","material-hospital-marker":"material/hospital-marker.svg","material-hospital":"material/hospital.svg","material-hot-tub":"material/hot-tub.svg","material-hours-24":"material/hours-24.svg","material-hubspot":"material/hubspot.svg","material-hulu":"material/hulu.svg","material-human-baby-changing-table":"material/human-baby-changing-table.svg","material-human-cane":"material/human-cane.svg","material-human-capacity-decrease":"material/human-capacity-decrease.svg","material-human-capacity-increase":"material/human-capacity-increase.svg","material-human-child":"material/human-child.svg","material-human-dolly":"material/human-dolly.svg","material-human-edit":"material/human-edit.svg","material-human-female-boy":"material/human-female-boy.svg","material-human-female-dance":"material/human-female-dance.svg","material-human-female-female":"material/human-female-female.svg","material-human-female-girl":"material/human-female-girl.svg","material-human-female":"material/human-female.svg","material-human-greeting-proximity":"material/human-greeting-proximity.svg","material-human-greeting-variant":"material/human-greeting-variant.svg","material-human-greeting":"material/human-greeting.svg","material-human-handsdown":"material/human-handsdown.svg","material-human-handsup":"material/human-handsup.svg","material-human-male-board-poll":"material/human-male-board-poll.svg","material-human-male-board":"material/human-male-board.svg","material-human-male-boy":"material/human-male-boy.svg","material-human-male-child":"material/human-male-child.svg","material-human-male-female-child":"material/human-male-female-child.svg","material-human-male-female":"material/human-male-female.svg","material-human-male-girl":"material/human-male-girl.svg","material-human-male-height-variant":"material/human-male-height-variant.svg","material-human-male-height":"material/human-male-height.svg","material-human-male-male":"material/human-male-male.svg","material-human-male":"material/human-male.svg","material-human-non-binary":"material/human-non-binary.svg","material-human-pregnant":"material/human-pregnant.svg","material-human-queue":"material/human-queue.svg","material-human-scooter":"material/human-scooter.svg","material-human-walker":"material/human-walker.svg","material-human-wheelchair":"material/human-wheelchair.svg","material-human-white-cane":"material/human-white-cane.svg","material-human":"material/human.svg","material-humble-bundle":"material/humble-bundle.svg","material-hvac-off":"material/hvac-off.svg","material-hvac":"material/hvac.svg","material-hydraulic-oil-level":"material/hydraulic-oil-level.svg","material-hydraulic-oil-temperature":"material/hydraulic-oil-temperature.svg","material-hydro-power":"material/hydro-power.svg","material-hydrogen-station":"material/hydrogen-station.svg","material-ice-cream-off":"material/ice-cream-off.svg","material-ice-cream":"material/ice-cream.svg","material-ice-pop":"material/ice-pop.svg","material-id-card":"material/id-card.svg","material-identifier":"material/identifier.svg","material-ideogram-cjk-variant":"material/ideogram-cjk-variant.svg","material-ideogram-cjk":"material/ideogram-cjk.svg","material-image-album":"material/image-album.svg","material-image-area-close":"material/image-area-close.svg","material-image-area":"material/image-area.svg","material-image-auto-adjust":"material/image-auto-adjust.svg","material-image-broken-variant":"material/image-broken-variant.svg","material-image-broken":"material/image-broken.svg","material-image-check-outline":"material/image-check-outline.svg","material-image-check":"material/image-check.svg","material-image-edit-outline":"material/image-edit-outline.svg","material-image-edit":"material/image-edit.svg","material-image-filter-black-white":"material/image-filter-black-white.svg","material-image-filter-center-focus-strong-outline":"material/image-filter-center-focus-strong-outline.svg","material-image-filter-center-focus-strong":"material/image-filter-center-focus-strong.svg","material-image-filter-center-focus-weak":"material/image-filter-center-focus-weak.svg","material-image-filter-center-focus":"material/image-filter-center-focus.svg","material-image-filter-drama":"material/image-filter-drama.svg","material-image-filter-frames":"material/image-filter-frames.svg","material-image-filter-hdr":"material/image-filter-hdr.svg","material-image-filter-none":"material/image-filter-none.svg","material-image-filter-tilt-shift":"material/image-filter-tilt-shift.svg","material-image-filter-vintage":"material/image-filter-vintage.svg","material-image-frame":"material/image-frame.svg","material-image-lock-outline":"material/image-lock-outline.svg","material-image-lock":"material/image-lock.svg","material-image-marker-outline":"material/image-marker-outline.svg","material-image-marker":"material/image-marker.svg","material-image-minus-outline":"material/image-minus-outline.svg","material-image-minus":"material/image-minus.svg","material-image-move":"material/image-move.svg","material-image-multiple-outline":"material/image-multiple-outline.svg","material-image-multiple":"material/image-multiple.svg","material-image-off-outline":"material/image-off-outline.svg","material-image-off":"material/image-off.svg","material-image-outline":"material/image-outline.svg","material-image-plus-outline":"material/image-plus-outline.svg","material-image-plus":"material/image-plus.svg","material-image-refresh-outline":"material/image-refresh-outline.svg","material-image-refresh":"material/image-refresh.svg","material-image-remove-outline":"material/image-remove-outline.svg","material-image-remove":"material/image-remove.svg","material-image-search-outline":"material/image-search-outline.svg","material-image-search":"material/image-search.svg","material-image-size-select-actual":"material/image-size-select-actual.svg","material-image-size-select-large":"material/image-size-select-large.svg","material-image-size-select-small":"material/image-size-select-small.svg","material-image-sync-outline":"material/image-sync-outline.svg","material-image-sync":"material/image-sync.svg","material-image-text":"material/image-text.svg","material-image":"material/image.svg","material-import":"material/import.svg","material-inbox-arrow-down-outline":"material/inbox-arrow-down-outline.svg","material-inbox-arrow-down":"material/inbox-arrow-down.svg","material-inbox-arrow-up-outline":"material/inbox-arrow-up-outline.svg","material-inbox-arrow-up":"material/inbox-arrow-up.svg","material-inbox-full-outline":"material/inbox-full-outline.svg","material-inbox-full":"material/inbox-full.svg","material-inbox-multiple-outline":"material/inbox-multiple-outline.svg","material-inbox-multiple":"material/inbox-multiple.svg","material-inbox-outline":"material/inbox-outline.svg","material-inbox-remove-outline":"material/inbox-remove-outline.svg","material-inbox-remove":"material/inbox-remove.svg","material-inbox":"material/inbox.svg","material-incognito-circle-off":"material/incognito-circle-off.svg","material-incognito-circle":"material/incognito-circle.svg","material-incognito-off":"material/incognito-off.svg","material-incognito":"material/incognito.svg","material-induction":"material/induction.svg","material-infinity":"material/infinity.svg","material-information-off-outline":"material/information-off-outline.svg","material-information-off":"material/information-off.svg","material-information-outline":"material/information-outline.svg","material-information-variant":"material/information-variant.svg","material-information":"material/information.svg","material-instagram":"material/instagram.svg","material-instrument-triangle":"material/instrument-triangle.svg","material-integrated-circuit-chip":"material/integrated-circuit-chip.svg","material-invert-colors-off":"material/invert-colors-off.svg","material-invert-colors":"material/invert-colors.svg","material-iobroker":"material/iobroker.svg","material-ip-network-outline":"material/ip-network-outline.svg","material-ip-network":"material/ip-network.svg","material-ip-outline":"material/ip-outline.svg","material-ip":"material/ip.svg","material-ipod":"material/ipod.svg","material-iron-board":"material/iron-board.svg","material-iron-outline":"material/iron-outline.svg","material-iron":"material/iron.svg","material-island":"material/island.svg","material-iv-bag":"material/iv-bag.svg","material-jabber":"material/jabber.svg","material-jeepney":"material/jeepney.svg","material-jellyfish-outline":"material/jellyfish-outline.svg","material-jellyfish":"material/jellyfish.svg","material-jira":"material/jira.svg","material-jquery":"material/jquery.svg","material-jsfiddle":"material/jsfiddle.svg","material-jump-rope":"material/jump-rope.svg","material-kabaddi":"material/kabaddi.svg","material-kangaroo":"material/kangaroo.svg","material-karate":"material/karate.svg","material-kayaking":"material/kayaking.svg","material-keg":"material/keg.svg","material-kettle-alert-outline":"material/kettle-alert-outline.svg","material-kettle-alert":"material/kettle-alert.svg","material-kettle-off-outline":"material/kettle-off-outline.svg","material-kettle-off":"material/kettle-off.svg","material-kettle-outline":"material/kettle-outline.svg","material-kettle-pour-over":"material/kettle-pour-over.svg","material-kettle-steam-outline":"material/kettle-steam-outline.svg","material-kettle-steam":"material/kettle-steam.svg","material-kettle":"material/kettle.svg","material-kettlebell":"material/kettlebell.svg","material-key-alert-outline":"material/key-alert-outline.svg","material-key-alert":"material/key-alert.svg","material-key-arrow-right":"material/key-arrow-right.svg","material-key-chain-variant":"material/key-chain-variant.svg","material-key-chain":"material/key-chain.svg","material-key-change":"material/key-change.svg","material-key-link":"material/key-link.svg","material-key-minus":"material/key-minus.svg","material-key-outline":"material/key-outline.svg","material-key-plus":"material/key-plus.svg","material-key-remove":"material/key-remove.svg","material-key-star":"material/key-star.svg","material-key-variant":"material/key-variant.svg","material-key-wireless":"material/key-wireless.svg","material-key":"material/key.svg","material-keyboard-backspace":"material/keyboard-backspace.svg","material-keyboard-caps":"material/keyboard-caps.svg","material-keyboard-close":"material/keyboard-close.svg","material-keyboard-esc":"material/keyboard-esc.svg","material-keyboard-f1":"material/keyboard-f1.svg","material-keyboard-f10":"material/keyboard-f10.svg","material-keyboard-f11":"material/keyboard-f11.svg","material-keyboard-f12":"material/keyboard-f12.svg","material-keyboard-f2":"material/keyboard-f2.svg","material-keyboard-f3":"material/keyboard-f3.svg","material-keyboard-f4":"material/keyboard-f4.svg","material-keyboard-f5":"material/keyboard-f5.svg","material-keyboard-f6":"material/keyboard-f6.svg","material-keyboard-f7":"material/keyboard-f7.svg","material-keyboard-f8":"material/keyboard-f8.svg","material-keyboard-f9":"material/keyboard-f9.svg","material-keyboard-off-outline":"material/keyboard-off-outline.svg","material-keyboard-off":"material/keyboard-off.svg","material-keyboard-outline":"material/keyboard-outline.svg","material-keyboard-return":"material/keyboard-return.svg","material-keyboard-settings-outline":"material/keyboard-settings-outline.svg","material-keyboard-settings":"material/keyboard-settings.svg","material-keyboard-space":"material/keyboard-space.svg","material-keyboard-tab-reverse":"material/keyboard-tab-reverse.svg","material-keyboard-tab":"material/keyboard-tab.svg","material-keyboard-variant":"material/keyboard-variant.svg","material-keyboard":"material/keyboard.svg","material-khanda":"material/khanda.svg","material-kickstarter":"material/kickstarter.svg","material-kite-outline":"material/kite-outline.svg","material-kite":"material/kite.svg","material-kitesurfing":"material/kitesurfing.svg","material-klingon":"material/klingon.svg","material-knife-military":"material/knife-military.svg","material-knife":"material/knife.svg","material-knob":"material/knob.svg","material-koala":"material/koala.svg","material-kodi":"material/kodi.svg","material-kubernetes":"material/kubernetes.svg","material-label-multiple-outline":"material/label-multiple-outline.svg","material-label-multiple":"material/label-multiple.svg","material-label-off-outline":"material/label-off-outline.svg","material-label-off":"material/label-off.svg","material-label-outline":"material/label-outline.svg","material-label-percent-outline":"material/label-percent-outline.svg","material-label-percent":"material/label-percent.svg","material-label-variant-outline":"material/label-variant-outline.svg","material-label-variant":"material/label-variant.svg","material-label":"material/label.svg","material-ladder":"material/ladder.svg","material-ladybug":"material/ladybug.svg","material-lambda":"material/lambda.svg","material-lamp-outline":"material/lamp-outline.svg","material-lamp":"material/lamp.svg","material-lamps-outline":"material/lamps-outline.svg","material-lamps":"material/lamps.svg","material-lan-check":"material/lan-check.svg","material-lan-connect":"material/lan-connect.svg","material-lan-disconnect":"material/lan-disconnect.svg","material-lan-pending":"material/lan-pending.svg","material-lan":"material/lan.svg","material-land-fields":"material/land-fields.svg","material-land-plots-circle-variant":"material/land-plots-circle-variant.svg","material-land-plots-circle":"material/land-plots-circle.svg","material-land-plots":"material/land-plots.svg","material-land-rows-horizontal":"material/land-rows-horizontal.svg","material-land-rows-vertical":"material/land-rows-vertical.svg","material-landslide-outline":"material/landslide-outline.svg","material-landslide":"material/landslide.svg","material-language-c":"material/language-c.svg","material-language-cpp":"material/language-cpp.svg","material-language-csharp":"material/language-csharp.svg","material-language-css3":"material/language-css3.svg","material-language-fortran":"material/language-fortran.svg","material-language-go":"material/language-go.svg","material-language-haskell":"material/language-haskell.svg","material-language-html5":"material/language-html5.svg","material-language-java":"material/language-java.svg","material-language-javascript":"material/language-javascript.svg","material-language-kotlin":"material/language-kotlin.svg","material-language-lua":"material/language-lua.svg","material-language-markdown-outline":"material/language-markdown-outline.svg","material-language-markdown":"material/language-markdown.svg","material-language-php":"material/language-php.svg","material-language-python":"material/language-python.svg","material-language-r":"material/language-r.svg","material-language-ruby-on-rails":"material/language-ruby-on-rails.svg","material-language-ruby":"material/language-ruby.svg","material-language-rust":"material/language-rust.svg","material-language-swift":"material/language-swift.svg","material-language-typescript":"material/language-typescript.svg","material-language-xaml":"material/language-xaml.svg","material-laptop-account":"material/laptop-account.svg","material-laptop-off":"material/laptop-off.svg","material-laptop":"material/laptop.svg","material-laravel":"material/laravel.svg","material-laser-pointer":"material/laser-pointer.svg","material-lasso":"material/lasso.svg","material-lastpass":"material/lastpass.svg","material-latitude":"material/latitude.svg","material-launch":"material/launch.svg","material-lava-lamp":"material/lava-lamp.svg","material-layers-edit":"material/layers-edit.svg","material-layers-minus":"material/layers-minus.svg","material-layers-off-outline":"material/layers-off-outline.svg","material-layers-off":"material/layers-off.svg","material-layers-outline":"material/layers-outline.svg","material-layers-plus":"material/layers-plus.svg","material-layers-remove":"material/layers-remove.svg","material-layers-search-outline":"material/layers-search-outline.svg","material-layers-search":"material/layers-search.svg","material-layers-triple-outline":"material/layers-triple-outline.svg","material-layers-triple":"material/layers-triple.svg","material-layers":"material/layers.svg","material-lead-pencil":"material/lead-pencil.svg","material-leaf-circle-outline":"material/leaf-circle-outline.svg","material-leaf-circle":"material/leaf-circle.svg","material-leaf-maple-off":"material/leaf-maple-off.svg","material-leaf-maple":"material/leaf-maple.svg","material-leaf-off":"material/leaf-off.svg","material-leaf":"material/leaf.svg","material-leak-off":"material/leak-off.svg","material-leak":"material/leak.svg","material-lectern":"material/lectern.svg","material-led-off":"material/led-off.svg","material-led-on":"material/led-on.svg","material-led-outline":"material/led-outline.svg","material-led-strip-variant-off":"material/led-strip-variant-off.svg","material-led-strip-variant":"material/led-strip-variant.svg","material-led-strip":"material/led-strip.svg","material-led-variant-off":"material/led-variant-off.svg","material-led-variant-on":"material/led-variant-on.svg","material-led-variant-outline":"material/led-variant-outline.svg","material-leek":"material/leek.svg","material-less-than-or-equal":"material/less-than-or-equal.svg","material-less-than":"material/less-than.svg","material-library-outline":"material/library-outline.svg","material-library-shelves":"material/library-shelves.svg","material-library":"material/library.svg","material-license":"material/license.svg","material-lifebuoy":"material/lifebuoy.svg","material-light-flood-down":"material/light-flood-down.svg","material-light-flood-up":"material/light-flood-up.svg","material-light-recessed":"material/light-recessed.svg","material-light-switch-off":"material/light-switch-off.svg","material-light-switch":"material/light-switch.svg","material-lightbulb-alert-outline":"material/lightbulb-alert-outline.svg","material-lightbulb-alert":"material/lightbulb-alert.svg","material-lightbulb-auto-outline":"material/lightbulb-auto-outline.svg","material-lightbulb-auto":"material/lightbulb-auto.svg","material-lightbulb-cfl-off":"material/lightbulb-cfl-off.svg","material-lightbulb-cfl-spiral-off":"material/lightbulb-cfl-spiral-off.svg","material-lightbulb-cfl-spiral":"material/lightbulb-cfl-spiral.svg","material-lightbulb-cfl":"material/lightbulb-cfl.svg","material-lightbulb-fluorescent-tube-outline":"material/lightbulb-fluorescent-tube-outline.svg","material-lightbulb-fluorescent-tube":"material/lightbulb-fluorescent-tube.svg","material-lightbulb-group-off-outline":"material/lightbulb-group-off-outline.svg","material-lightbulb-group-off":"material/lightbulb-group-off.svg","material-lightbulb-group-outline":"material/lightbulb-group-outline.svg","material-lightbulb-group":"material/lightbulb-group.svg","material-lightbulb-multiple-off-outline":"material/lightbulb-multiple-off-outline.svg","material-lightbulb-multiple-off":"material/lightbulb-multiple-off.svg","material-lightbulb-multiple-outline":"material/lightbulb-multiple-outline.svg","material-lightbulb-multiple":"material/lightbulb-multiple.svg","material-lightbulb-night-outline":"material/lightbulb-night-outline.svg","material-lightbulb-night":"material/lightbulb-night.svg","material-lightbulb-off-outline":"material/lightbulb-off-outline.svg","material-lightbulb-off":"material/lightbulb-off.svg","material-lightbulb-on-10":"material/lightbulb-on-10.svg","material-lightbulb-on-20":"material/lightbulb-on-20.svg","material-lightbulb-on-30":"material/lightbulb-on-30.svg","material-lightbulb-on-40":"material/lightbulb-on-40.svg","material-lightbulb-on-50":"material/lightbulb-on-50.svg","material-lightbulb-on-60":"material/lightbulb-on-60.svg","material-lightbulb-on-70":"material/lightbulb-on-70.svg","material-lightbulb-on-80":"material/lightbulb-on-80.svg","material-lightbulb-on-90":"material/lightbulb-on-90.svg","material-lightbulb-on-outline":"material/lightbulb-on-outline.svg","material-lightbulb-on":"material/lightbulb-on.svg","material-lightbulb-outline":"material/lightbulb-outline.svg","material-lightbulb-question-outline":"material/lightbulb-question-outline.svg","material-lightbulb-question":"material/lightbulb-question.svg","material-lightbulb-spot-off":"material/lightbulb-spot-off.svg","material-lightbulb-spot":"material/lightbulb-spot.svg","material-lightbulb-variant-outline":"material/lightbulb-variant-outline.svg","material-lightbulb-variant":"material/lightbulb-variant.svg","material-lightbulb":"material/lightbulb.svg","material-lighthouse-on":"material/lighthouse-on.svg","material-lighthouse":"material/lighthouse.svg","material-lightning-bolt-circle":"material/lightning-bolt-circle.svg","material-lightning-bolt-outline":"material/lightning-bolt-outline.svg","material-lightning-bolt":"material/lightning-bolt.svg","material-line-scan":"material/line-scan.svg","material-lingerie":"material/lingerie.svg","material-link-box-outline":"material/link-box-outline.svg","material-link-box-variant-outline":"material/link-box-variant-outline.svg","material-link-box-variant":"material/link-box-variant.svg","material-link-box":"material/link-box.svg","material-link-lock":"material/link-lock.svg","material-link-off":"material/link-off.svg","material-link-plus":"material/link-plus.svg","material-link-variant-minus":"material/link-variant-minus.svg","material-link-variant-off":"material/link-variant-off.svg","material-link-variant-plus":"material/link-variant-plus.svg","material-link-variant-remove":"material/link-variant-remove.svg","material-link-variant":"material/link-variant.svg","material-link":"material/link.svg","material-linkedin":"material/linkedin.svg","material-linux-mint":"material/linux-mint.svg","material-linux":"material/linux.svg","material-lipstick":"material/lipstick.svg","material-liquid-spot":"material/liquid-spot.svg","material-liquor":"material/liquor.svg","material-list-box-outline":"material/list-box-outline.svg","material-list-box":"material/list-box.svg","material-list-status":"material/list-status.svg","material-litecoin":"material/litecoin.svg","material-loading":"material/loading.svg","material-location-enter":"material/location-enter.svg","material-location-exit":"material/location-exit.svg","material-lock-alert-outline":"material/lock-alert-outline.svg","material-lock-alert":"material/lock-alert.svg","material-lock-check-outline":"material/lock-check-outline.svg","material-lock-check":"material/lock-check.svg","material-lock-clock":"material/lock-clock.svg","material-lock-minus-outline":"material/lock-minus-outline.svg","material-lock-minus":"material/lock-minus.svg","material-lock-off-outline":"material/lock-off-outline.svg","material-lock-off":"material/lock-off.svg","material-lock-open-alert-outline":"material/lock-open-alert-outline.svg","material-lock-open-alert":"material/lock-open-alert.svg","material-lock-open-check-outline":"material/lock-open-check-outline.svg","material-lock-open-check":"material/lock-open-check.svg","material-lock-open-minus-outline":"material/lock-open-minus-outline.svg","material-lock-open-minus":"material/lock-open-minus.svg","material-lock-open-outline":"material/lock-open-outline.svg","material-lock-open-plus-outline":"material/lock-open-plus-outline.svg","material-lock-open-plus":"material/lock-open-plus.svg","material-lock-open-remove-outline":"material/lock-open-remove-outline.svg","material-lock-open-remove":"material/lock-open-remove.svg","material-lock-open-variant-outline":"material/lock-open-variant-outline.svg","material-lock-open-variant":"material/lock-open-variant.svg","material-lock-open":"material/lock-open.svg","material-lock-outline":"material/lock-outline.svg","material-lock-pattern":"material/lock-pattern.svg","material-lock-plus-outline":"material/lock-plus-outline.svg","material-lock-plus":"material/lock-plus.svg","material-lock-question":"material/lock-question.svg","material-lock-remove-outline":"material/lock-remove-outline.svg","material-lock-remove":"material/lock-remove.svg","material-lock-reset":"material/lock-reset.svg","material-lock-smart":"material/lock-smart.svg","material-lock":"material/lock.svg","material-locker-multiple":"material/locker-multiple.svg","material-locker":"material/locker.svg","material-login-variant":"material/login-variant.svg","material-login":"material/login.svg","material-logout-variant":"material/logout-variant.svg","material-logout":"material/logout.svg","material-longitude":"material/longitude.svg","material-looks":"material/looks.svg","material-lotion-outline":"material/lotion-outline.svg","material-lotion-plus-outline":"material/lotion-plus-outline.svg","material-lotion-plus":"material/lotion-plus.svg","material-lotion":"material/lotion.svg","material-loupe":"material/loupe.svg","material-lumx":"material/lumx.svg","material-lungs":"material/lungs.svg","material-mace":"material/mace.svg","material-magazine-pistol":"material/magazine-pistol.svg","material-magazine-rifle":"material/magazine-rifle.svg","material-magic-staff":"material/magic-staff.svg","material-magnet-on":"material/magnet-on.svg","material-magnet":"material/magnet.svg","material-magnify-close":"material/magnify-close.svg","material-magnify-expand":"material/magnify-expand.svg","material-magnify-minus-cursor":"material/magnify-minus-cursor.svg","material-magnify-minus-outline":"material/magnify-minus-outline.svg","material-magnify-minus":"material/magnify-minus.svg","material-magnify-plus-cursor":"material/magnify-plus-cursor.svg","material-magnify-plus-outline":"material/magnify-plus-outline.svg","material-magnify-plus":"material/magnify-plus.svg","material-magnify-remove-cursor":"material/magnify-remove-cursor.svg","material-magnify-remove-outline":"material/magnify-remove-outline.svg","material-magnify-scan":"material/magnify-scan.svg","material-magnify":"material/magnify.svg","material-mail":"material/mail.svg","material-mailbox-open-outline":"material/mailbox-open-outline.svg","material-mailbox-open-up-outline":"material/mailbox-open-up-outline.svg","material-mailbox-open-up":"material/mailbox-open-up.svg","material-mailbox-open":"material/mailbox-open.svg","material-mailbox-outline":"material/mailbox-outline.svg","material-mailbox-up-outline":"material/mailbox-up-outline.svg","material-mailbox-up":"material/mailbox-up.svg","material-mailbox":"material/mailbox.svg","material-manjaro":"material/manjaro.svg","material-map-check-outline":"material/map-check-outline.svg","material-map-check":"material/map-check.svg","material-map-clock-outline":"material/map-clock-outline.svg","material-map-clock":"material/map-clock.svg","material-map-legend":"material/map-legend.svg","material-map-marker-account-outline":"material/map-marker-account-outline.svg","material-map-marker-account":"material/map-marker-account.svg","material-map-marker-alert-outline":"material/map-marker-alert-outline.svg","material-map-marker-alert":"material/map-marker-alert.svg","material-map-marker-check-outline":"material/map-marker-check-outline.svg","material-map-marker-check":"material/map-marker-check.svg","material-map-marker-circle":"material/map-marker-circle.svg","material-map-marker-distance":"material/map-marker-distance.svg","material-map-marker-down":"material/map-marker-down.svg","material-map-marker-left-outline":"material/map-marker-left-outline.svg","material-map-marker-left":"material/map-marker-left.svg","material-map-marker-minus-outline":"material/map-marker-minus-outline.svg","material-map-marker-minus":"material/map-marker-minus.svg","material-map-marker-multiple-outline":"material/map-marker-multiple-outline.svg","material-map-marker-multiple":"material/map-marker-multiple.svg","material-map-marker-off-outline":"material/map-marker-off-outline.svg","material-map-marker-off":"material/map-marker-off.svg","material-map-marker-outline":"material/map-marker-outline.svg","material-map-marker-path":"material/map-marker-path.svg","material-map-marker-plus-outline":"material/map-marker-plus-outline.svg","material-map-marker-plus":"material/map-marker-plus.svg","material-map-marker-question-outline":"material/map-marker-question-outline.svg","material-map-marker-question":"material/map-marker-question.svg","material-map-marker-radius-outline":"material/map-marker-radius-outline.svg","material-map-marker-radius":"material/map-marker-radius.svg","material-map-marker-remove-outline":"material/map-marker-remove-outline.svg","material-map-marker-remove-variant":"material/map-marker-remove-variant.svg","material-map-marker-remove":"material/map-marker-remove.svg","material-map-marker-right-outline":"material/map-marker-right-outline.svg","material-map-marker-right":"material/map-marker-right.svg","material-map-marker-star-outline":"material/map-marker-star-outline.svg","material-map-marker-star":"material/map-marker-star.svg","material-map-marker-up":"material/map-marker-up.svg","material-map-marker":"material/map-marker.svg","material-map-minus":"material/map-minus.svg","material-map-outline":"material/map-outline.svg","material-map-plus":"material/map-plus.svg","material-map-search-outline":"material/map-search-outline.svg","material-map-search":"material/map-search.svg","material-map":"material/map.svg","material-mapbox":"material/mapbox.svg","material-margin":"material/margin.svg","material-marker-cancel":"material/marker-cancel.svg","material-marker-check":"material/marker-check.svg","material-marker":"material/marker.svg","material-mastodon":"material/mastodon.svg","material-material-design":"material/material-design.svg","material-material-ui":"material/material-ui.svg","material-math-compass":"material/math-compass.svg","material-math-cos":"material/math-cos.svg","material-math-integral-box":"material/math-integral-box.svg","material-math-integral":"material/math-integral.svg","material-math-log":"material/math-log.svg","material-math-norm-box":"material/math-norm-box.svg","material-math-norm":"material/math-norm.svg","material-math-sin":"material/math-sin.svg","material-math-tan":"material/math-tan.svg","material-matrix":"material/matrix.svg","material-medal-outline":"material/medal-outline.svg","material-medal":"material/medal.svg","material-medical-bag":"material/medical-bag.svg","material-medical-cotton-swab":"material/medical-cotton-swab.svg","material-medication-outline":"material/medication-outline.svg","material-medication":"material/medication.svg","material-meditation":"material/meditation.svg","material-memory":"material/memory.svg","material-menorah-fire":"material/menorah-fire.svg","material-menorah":"material/menorah.svg","material-menu-down-outline":"material/menu-down-outline.svg","material-menu-down":"material/menu-down.svg","material-menu-left-outline":"material/menu-left-outline.svg","material-menu-left":"material/menu-left.svg","material-menu-open":"material/menu-open.svg","material-menu-right-outline":"material/menu-right-outline.svg","material-menu-right":"material/menu-right.svg","material-menu-swap-outline":"material/menu-swap-outline.svg","material-menu-swap":"material/menu-swap.svg","material-menu-up-outline":"material/menu-up-outline.svg","material-menu-up":"material/menu-up.svg","material-menu":"material/menu.svg","material-merge":"material/merge.svg","material-message-alert-outline":"material/message-alert-outline.svg","material-message-alert":"material/message-alert.svg","material-message-arrow-left-outline":"material/message-arrow-left-outline.svg","material-message-arrow-left":"material/message-arrow-left.svg","material-message-arrow-right-outline":"material/message-arrow-right-outline.svg","material-message-arrow-right":"material/message-arrow-right.svg","material-message-badge-outline":"material/message-badge-outline.svg","material-message-badge":"material/message-badge.svg","material-message-bookmark-outline":"material/message-bookmark-outline.svg","material-message-bookmark":"material/message-bookmark.svg","material-message-bulleted-off":"material/message-bulleted-off.svg","material-message-bulleted":"material/message-bulleted.svg","material-message-check-outline":"material/message-check-outline.svg","material-message-check":"material/message-check.svg","material-message-cog-outline":"material/message-cog-outline.svg","material-message-cog":"material/message-cog.svg","material-message-draw":"material/message-draw.svg","material-message-fast-outline":"material/message-fast-outline.svg","material-message-fast":"material/message-fast.svg","material-message-flash-outline":"material/message-flash-outline.svg","material-message-flash":"material/message-flash.svg","material-message-image-outline":"material/message-image-outline.svg","material-message-image":"material/message-image.svg","material-message-lock-outline":"material/message-lock-outline.svg","material-message-lock":"material/message-lock.svg","material-message-minus-outline":"material/message-minus-outline.svg","material-message-minus":"material/message-minus.svg","material-message-off-outline":"material/message-off-outline.svg","material-message-off":"material/message-off.svg","material-message-outline":"material/message-outline.svg","material-message-plus-outline":"material/message-plus-outline.svg","material-message-plus":"material/message-plus.svg","material-message-processing-outline":"material/message-processing-outline.svg","material-message-processing":"material/message-processing.svg","material-message-question-outline":"material/message-question-outline.svg","material-message-question":"material/message-question.svg","material-message-reply-outline":"material/message-reply-outline.svg","material-message-reply-text-outline":"material/message-reply-text-outline.svg","material-message-reply-text":"material/message-reply-text.svg","material-message-reply":"material/message-reply.svg","material-message-settings-outline":"material/message-settings-outline.svg","material-message-settings":"material/message-settings.svg","material-message-star-outline":"material/message-star-outline.svg","material-message-star":"material/message-star.svg","material-message-text-clock-outline":"material/message-text-clock-outline.svg","material-message-text-clock":"material/message-text-clock.svg","material-message-text-fast-outline":"material/message-text-fast-outline.svg","material-message-text-fast":"material/message-text-fast.svg","material-message-text-lock-outline":"material/message-text-lock-outline.svg","material-message-text-lock":"material/message-text-lock.svg","material-message-text-outline":"material/message-text-outline.svg","material-message-text":"material/message-text.svg","material-message-video":"material/message-video.svg","material-message":"material/message.svg","material-meteor":"material/meteor.svg","material-meter-electric-outline":"material/meter-electric-outline.svg","material-meter-electric":"material/meter-electric.svg","material-meter-gas-outline":"material/meter-gas-outline.svg","material-meter-gas":"material/meter-gas.svg","material-metronome-tick":"material/metronome-tick.svg","material-metronome":"material/metronome.svg","material-micro-sd":"material/micro-sd.svg","material-microphone-message-off":"material/microphone-message-off.svg","material-microphone-message":"material/microphone-message.svg","material-microphone-minus":"material/microphone-minus.svg","material-microphone-off":"material/microphone-off.svg","material-microphone-outline":"material/microphone-outline.svg","material-microphone-plus":"material/microphone-plus.svg","material-microphone-question-outline":"material/microphone-question-outline.svg","material-microphone-question":"material/microphone-question.svg","material-microphone-settings":"material/microphone-settings.svg","material-microphone-variant-off":"material/microphone-variant-off.svg","material-microphone-variant":"material/microphone-variant.svg","material-microphone":"material/microphone.svg","material-microscope":"material/microscope.svg","material-microsoft-access":"material/microsoft-access.svg","material-microsoft-azure-devops":"material/microsoft-azure-devops.svg","material-microsoft-azure":"material/microsoft-azure.svg","material-microsoft-bing":"material/microsoft-bing.svg","material-microsoft-dynamics-365":"material/microsoft-dynamics-365.svg","material-microsoft-edge":"material/microsoft-edge.svg","material-microsoft-excel":"material/microsoft-excel.svg","material-microsoft-internet-explorer":"material/microsoft-internet-explorer.svg","material-microsoft-office":"material/microsoft-office.svg","material-microsoft-onedrive":"material/microsoft-onedrive.svg","material-microsoft-onenote":"material/microsoft-onenote.svg","material-microsoft-outlook":"material/microsoft-outlook.svg","material-microsoft-powerpoint":"material/microsoft-powerpoint.svg","material-microsoft-sharepoint":"material/microsoft-sharepoint.svg","material-microsoft-teams":"material/microsoft-teams.svg","material-microsoft-visual-studio-code":"material/microsoft-visual-studio-code.svg","material-microsoft-visual-studio":"material/microsoft-visual-studio.svg","material-microsoft-windows-classic":"material/microsoft-windows-classic.svg","material-microsoft-windows":"material/microsoft-windows.svg","material-microsoft-word":"material/microsoft-word.svg","material-microsoft-xbox-controller-battery-alert":"material/microsoft-xbox-controller-battery-alert.svg","material-microsoft-xbox-controller-battery-charging":"material/microsoft-xbox-controller-battery-charging.svg","material-microsoft-xbox-controller-battery-empty":"material/microsoft-xbox-controller-battery-empty.svg","material-microsoft-xbox-controller-battery-full":"material/microsoft-xbox-controller-battery-full.svg","material-microsoft-xbox-controller-battery-low":"material/microsoft-xbox-controller-battery-low.svg","material-microsoft-xbox-controller-battery-medium":"material/microsoft-xbox-controller-battery-medium.svg","material-microsoft-xbox-controller-battery-unknown":"material/microsoft-xbox-controller-battery-unknown.svg","material-microsoft-xbox-controller-menu":"material/microsoft-xbox-controller-menu.svg","material-microsoft-xbox-controller-off":"material/microsoft-xbox-controller-off.svg","material-microsoft-xbox-controller-view":"material/microsoft-xbox-controller-view.svg","material-microsoft-xbox-controller":"material/microsoft-xbox-controller.svg","material-microsoft-xbox":"material/microsoft-xbox.svg","material-microsoft":"material/microsoft.svg","material-microwave-off":"material/microwave-off.svg","material-microwave":"material/microwave.svg","material-middleware-outline":"material/middleware-outline.svg","material-middleware":"material/middleware.svg","material-midi-port":"material/midi-port.svg","material-midi":"material/midi.svg","material-mine":"material/mine.svg","material-minecraft":"material/minecraft.svg","material-mini-sd":"material/mini-sd.svg","material-minidisc":"material/minidisc.svg","material-minus-box-multiple-outline":"material/minus-box-multiple-outline.svg","material-minus-box-multiple":"material/minus-box-multiple.svg","material-minus-box-outline":"material/minus-box-outline.svg","material-minus-box":"material/minus-box.svg","material-minus-circle-multiple-outline":"material/minus-circle-multiple-outline.svg","material-minus-circle-multiple":"material/minus-circle-multiple.svg","material-minus-circle-off-outline":"material/minus-circle-off-outline.svg","material-minus-circle-off":"material/minus-circle-off.svg","material-minus-circle-outline":"material/minus-circle-outline.svg","material-minus-circle":"material/minus-circle.svg","material-minus-network-outline":"material/minus-network-outline.svg","material-minus-network":"material/minus-network.svg","material-minus-thick":"material/minus-thick.svg","material-minus":"material/minus.svg","material-mirror-rectangle":"material/mirror-rectangle.svg","material-mirror-variant":"material/mirror-variant.svg","material-mirror":"material/mirror.svg","material-mixed-martial-arts":"material/mixed-martial-arts.svg","material-mixed-reality":"material/mixed-reality.svg","material-molecule-co":"material/molecule-co.svg","material-molecule-co2":"material/molecule-co2.svg","material-molecule":"material/molecule.svg","material-monitor-account":"material/monitor-account.svg","material-monitor-arrow-down-variant":"material/monitor-arrow-down-variant.svg","material-monitor-arrow-down":"material/monitor-arrow-down.svg","material-monitor-cellphone-star":"material/monitor-cellphone-star.svg","material-monitor-cellphone":"material/monitor-cellphone.svg","material-monitor-dashboard":"material/monitor-dashboard.svg","material-monitor-edit":"material/monitor-edit.svg","material-monitor-eye":"material/monitor-eye.svg","material-monitor-lock":"material/monitor-lock.svg","material-monitor-multiple":"material/monitor-multiple.svg","material-monitor-off":"material/monitor-off.svg","material-monitor-screenshot":"material/monitor-screenshot.svg","material-monitor-share":"material/monitor-share.svg","material-monitor-shimmer":"material/monitor-shimmer.svg","material-monitor-small":"material/monitor-small.svg","material-monitor-speaker-off":"material/monitor-speaker-off.svg","material-monitor-speaker":"material/monitor-speaker.svg","material-monitor-star":"material/monitor-star.svg","material-monitor":"material/monitor.svg","material-moon-first-quarter":"material/moon-first-quarter.svg","material-moon-full":"material/moon-full.svg","material-moon-last-quarter":"material/moon-last-quarter.svg","material-moon-new":"material/moon-new.svg","material-moon-waning-crescent":"material/moon-waning-crescent.svg","material-moon-waning-gibbous":"material/moon-waning-gibbous.svg","material-moon-waxing-crescent":"material/moon-waxing-crescent.svg","material-moon-waxing-gibbous":"material/moon-waxing-gibbous.svg","material-moped-electric-outline":"material/moped-electric-outline.svg","material-moped-electric":"material/moped-electric.svg","material-moped-outline":"material/moped-outline.svg","material-moped":"material/moped.svg","material-more":"material/more.svg","material-mortar-pestle-plus":"material/mortar-pestle-plus.svg","material-mortar-pestle":"material/mortar-pestle.svg","material-mosque-outline":"material/mosque-outline.svg","material-mosque":"material/mosque.svg","material-mother-heart":"material/mother-heart.svg","material-mother-nurse":"material/mother-nurse.svg","material-motion-outline":"material/motion-outline.svg","material-motion-pause-outline":"material/motion-pause-outline.svg","material-motion-pause":"material/motion-pause.svg","material-motion-play-outline":"material/motion-play-outline.svg","material-motion-play":"material/motion-play.svg","material-motion-sensor-off":"material/motion-sensor-off.svg","material-motion-sensor":"material/motion-sensor.svg","material-motion":"material/motion.svg","material-motorbike-electric":"material/motorbike-electric.svg","material-motorbike-off":"material/motorbike-off.svg","material-motorbike":"material/motorbike.svg","material-mouse-bluetooth":"material/mouse-bluetooth.svg","material-mouse-move-down":"material/mouse-move-down.svg","material-mouse-move-up":"material/mouse-move-up.svg","material-mouse-move-vertical":"material/mouse-move-vertical.svg","material-mouse-off":"material/mouse-off.svg","material-mouse-variant-off":"material/mouse-variant-off.svg","material-mouse-variant":"material/mouse-variant.svg","material-mouse":"material/mouse.svg","material-move-resize-variant":"material/move-resize-variant.svg","material-move-resize":"material/move-resize.svg","material-movie-check-outline":"material/movie-check-outline.svg","material-movie-check":"material/movie-check.svg","material-movie-cog-outline":"material/movie-cog-outline.svg","material-movie-cog":"material/movie-cog.svg","material-movie-edit-outline":"material/movie-edit-outline.svg","material-movie-edit":"material/movie-edit.svg","material-movie-filter-outline":"material/movie-filter-outline.svg","material-movie-filter":"material/movie-filter.svg","material-movie-minus-outline":"material/movie-minus-outline.svg","material-movie-minus":"material/movie-minus.svg","material-movie-off-outline":"material/movie-off-outline.svg","material-movie-off":"material/movie-off.svg","material-movie-open-check-outline":"material/movie-open-check-outline.svg","material-movie-open-check":"material/movie-open-check.svg","material-movie-open-cog-outline":"material/movie-open-cog-outline.svg","material-movie-open-cog":"material/movie-open-cog.svg","material-movie-open-edit-outline":"material/movie-open-edit-outline.svg","material-movie-open-edit":"material/movie-open-edit.svg","material-movie-open-minus-outline":"material/movie-open-minus-outline.svg","material-movie-open-minus":"material/movie-open-minus.svg","material-movie-open-off-outline":"material/movie-open-off-outline.svg","material-movie-open-off":"material/movie-open-off.svg","material-movie-open-outline":"material/movie-open-outline.svg","material-movie-open-play-outline":"material/movie-open-play-outline.svg","material-movie-open-play":"material/movie-open-play.svg","material-movie-open-plus-outline":"material/movie-open-plus-outline.svg","material-movie-open-plus":"material/movie-open-plus.svg","material-movie-open-remove-outline":"material/movie-open-remove-outline.svg","material-movie-open-remove":"material/movie-open-remove.svg","material-movie-open-settings-outline":"material/movie-open-settings-outline.svg","material-movie-open-settings":"material/movie-open-settings.svg","material-movie-open-star-outline":"material/movie-open-star-outline.svg","material-movie-open-star":"material/movie-open-star.svg","material-movie-open":"material/movie-open.svg","material-movie-outline":"material/movie-outline.svg","material-movie-play-outline":"material/movie-play-outline.svg","material-movie-play":"material/movie-play.svg","material-movie-plus-outline":"material/movie-plus-outline.svg","material-movie-plus":"material/movie-plus.svg","material-movie-remove-outline":"material/movie-remove-outline.svg","material-movie-remove":"material/movie-remove.svg","material-movie-roll":"material/movie-roll.svg","material-movie-search-outline":"material/movie-search-outline.svg","material-movie-search":"material/movie-search.svg","material-movie-settings-outline":"material/movie-settings-outline.svg","material-movie-settings":"material/movie-settings.svg","material-movie-star-outline":"material/movie-star-outline.svg","material-movie-star":"material/movie-star.svg","material-movie":"material/movie.svg","material-mower-bag-on":"material/mower-bag-on.svg","material-mower-bag":"material/mower-bag.svg","material-mower-on":"material/mower-on.svg","material-mower":"material/mower.svg","material-muffin":"material/muffin.svg","material-multicast":"material/multicast.svg","material-multimedia":"material/multimedia.svg","material-multiplication-box":"material/multiplication-box.svg","material-multiplication":"material/multiplication.svg","material-mushroom-off-outline":"material/mushroom-off-outline.svg","material-mushroom-off":"material/mushroom-off.svg","material-mushroom-outline":"material/mushroom-outline.svg","material-mushroom":"material/mushroom.svg","material-music-accidental-double-flat":"material/music-accidental-double-flat.svg","material-music-accidental-double-sharp":"material/music-accidental-double-sharp.svg","material-music-accidental-flat":"material/music-accidental-flat.svg","material-music-accidental-natural":"material/music-accidental-natural.svg","material-music-accidental-sharp":"material/music-accidental-sharp.svg","material-music-box-multiple-outline":"material/music-box-multiple-outline.svg","material-music-box-multiple":"material/music-box-multiple.svg","material-music-box-outline":"material/music-box-outline.svg","material-music-box":"material/music-box.svg","material-music-circle-outline":"material/music-circle-outline.svg","material-music-circle":"material/music-circle.svg","material-music-clef-alto":"material/music-clef-alto.svg","material-music-clef-bass":"material/music-clef-bass.svg","material-music-clef-treble":"material/music-clef-treble.svg","material-music-note-bluetooth-off":"material/music-note-bluetooth-off.svg","material-music-note-bluetooth":"material/music-note-bluetooth.svg","material-music-note-eighth-dotted":"material/music-note-eighth-dotted.svg","material-music-note-eighth":"material/music-note-eighth.svg","material-music-note-half-dotted":"material/music-note-half-dotted.svg","material-music-note-half":"material/music-note-half.svg","material-music-note-minus":"material/music-note-minus.svg","material-music-note-off-outline":"material/music-note-off-outline.svg","material-music-note-off":"material/music-note-off.svg","material-music-note-outline":"material/music-note-outline.svg","material-music-note-plus":"material/music-note-plus.svg","material-music-note-quarter-dotted":"material/music-note-quarter-dotted.svg","material-music-note-quarter":"material/music-note-quarter.svg","material-music-note-sixteenth-dotted":"material/music-note-sixteenth-dotted.svg","material-music-note-sixteenth":"material/music-note-sixteenth.svg","material-music-note-whole-dotted":"material/music-note-whole-dotted.svg","material-music-note-whole":"material/music-note-whole.svg","material-music-note":"material/music-note.svg","material-music-off":"material/music-off.svg","material-music-rest-eighth":"material/music-rest-eighth.svg","material-music-rest-half":"material/music-rest-half.svg","material-music-rest-quarter":"material/music-rest-quarter.svg","material-music-rest-sixteenth":"material/music-rest-sixteenth.svg","material-music-rest-whole":"material/music-rest-whole.svg","material-music":"material/music.svg","material-mustache":"material/mustache.svg","material-nail":"material/nail.svg","material-nas":"material/nas.svg","material-nativescript":"material/nativescript.svg","material-nature-people":"material/nature-people.svg","material-nature":"material/nature.svg","material-navigation-outline":"material/navigation-outline.svg","material-navigation-variant-outline":"material/navigation-variant-outline.svg","material-navigation-variant":"material/navigation-variant.svg","material-navigation":"material/navigation.svg","material-near-me":"material/near-me.svg","material-necklace":"material/necklace.svg","material-needle-off":"material/needle-off.svg","material-needle":"material/needle.svg","material-netflix":"material/netflix.svg","material-network-off-outline":"material/network-off-outline.svg","material-network-off":"material/network-off.svg","material-network-outline":"material/network-outline.svg","material-network-pos":"material/network-pos.svg","material-network-strength-1-alert":"material/network-strength-1-alert.svg","material-network-strength-1":"material/network-strength-1.svg","material-network-strength-2-alert":"material/network-strength-2-alert.svg","material-network-strength-2":"material/network-strength-2.svg","material-network-strength-3-alert":"material/network-strength-3-alert.svg","material-network-strength-3":"material/network-strength-3.svg","material-network-strength-4-alert":"material/network-strength-4-alert.svg","material-network-strength-4-cog":"material/network-strength-4-cog.svg","material-network-strength-4":"material/network-strength-4.svg","material-network-strength-off-outline":"material/network-strength-off-outline.svg","material-network-strength-off":"material/network-strength-off.svg","material-network-strength-outline":"material/network-strength-outline.svg","material-network":"material/network.svg","material-new-box":"material/new-box.svg","material-newspaper-check":"material/newspaper-check.svg","material-newspaper-minus":"material/newspaper-minus.svg","material-newspaper-plus":"material/newspaper-plus.svg","material-newspaper-remove":"material/newspaper-remove.svg","material-newspaper-variant-multiple-outline":"material/newspaper-variant-multiple-outline.svg","material-newspaper-variant-multiple":"material/newspaper-variant-multiple.svg","material-newspaper-variant-outline":"material/newspaper-variant-outline.svg","material-newspaper-variant":"material/newspaper-variant.svg","material-newspaper":"material/newspaper.svg","material-nfc-search-variant":"material/nfc-search-variant.svg","material-nfc-tap":"material/nfc-tap.svg","material-nfc-variant-off":"material/nfc-variant-off.svg","material-nfc-variant":"material/nfc-variant.svg","material-nfc":"material/nfc.svg","material-ninja":"material/ninja.svg","material-nintendo-game-boy":"material/nintendo-game-boy.svg","material-nintendo-switch":"material/nintendo-switch.svg","material-nintendo-wii":"material/nintendo-wii.svg","material-nintendo-wiiu":"material/nintendo-wiiu.svg","material-nix":"material/nix.svg","material-nodejs":"material/nodejs.svg","material-noodles":"material/noodles.svg","material-not-equal-variant":"material/not-equal-variant.svg","material-not-equal":"material/not-equal.svg","material-note-alert-outline":"material/note-alert-outline.svg","material-note-alert":"material/note-alert.svg","material-note-check-outline":"material/note-check-outline.svg","material-note-check":"material/note-check.svg","material-note-edit-outline":"material/note-edit-outline.svg","material-note-edit":"material/note-edit.svg","material-note-minus-outline":"material/note-minus-outline.svg","material-note-minus":"material/note-minus.svg","material-note-multiple-outline":"material/note-multiple-outline.svg","material-note-multiple":"material/note-multiple.svg","material-note-off-outline":"material/note-off-outline.svg","material-note-off":"material/note-off.svg","material-note-outline":"material/note-outline.svg","material-note-plus-outline":"material/note-plus-outline.svg","material-note-plus":"material/note-plus.svg","material-note-remove-outline":"material/note-remove-outline.svg","material-note-remove":"material/note-remove.svg","material-note-search-outline":"material/note-search-outline.svg","material-note-search":"material/note-search.svg","material-note-text-outline":"material/note-text-outline.svg","material-note-text":"material/note-text.svg","material-note":"material/note.svg","material-notebook-check-outline":"material/notebook-check-outline.svg","material-notebook-check":"material/notebook-check.svg","material-notebook-edit-outline":"material/notebook-edit-outline.svg","material-notebook-edit":"material/notebook-edit.svg","material-notebook-heart-outline":"material/notebook-heart-outline.svg","material-notebook-heart":"material/notebook-heart.svg","material-notebook-minus-outline":"material/notebook-minus-outline.svg","material-notebook-minus":"material/notebook-minus.svg","material-notebook-multiple":"material/notebook-multiple.svg","material-notebook-outline":"material/notebook-outline.svg","material-notebook-plus-outline":"material/notebook-plus-outline.svg","material-notebook-plus":"material/notebook-plus.svg","material-notebook-remove-outline":"material/notebook-remove-outline.svg","material-notebook-remove":"material/notebook-remove.svg","material-notebook":"material/notebook.svg","material-notification-clear-all":"material/notification-clear-all.svg","material-npm":"material/npm.svg","material-nuke":"material/nuke.svg","material-null":"material/null.svg","material-numeric-0-box-multiple-outline":"material/numeric-0-box-multiple-outline.svg","material-numeric-0-box-multiple":"material/numeric-0-box-multiple.svg","material-numeric-0-box-outline":"material/numeric-0-box-outline.svg","material-numeric-0-box":"material/numeric-0-box.svg","material-numeric-0-circle-outline":"material/numeric-0-circle-outline.svg","material-numeric-0-circle":"material/numeric-0-circle.svg","material-numeric-0":"material/numeric-0.svg","material-numeric-1-box-multiple-outline":"material/numeric-1-box-multiple-outline.svg","material-numeric-1-box-multiple":"material/numeric-1-box-multiple.svg","material-numeric-1-box-outline":"material/numeric-1-box-outline.svg","material-numeric-1-box":"material/numeric-1-box.svg","material-numeric-1-circle-outline":"material/numeric-1-circle-outline.svg","material-numeric-1-circle":"material/numeric-1-circle.svg","material-numeric-1":"material/numeric-1.svg","material-numeric-10-box-multiple-outline":"material/numeric-10-box-multiple-outline.svg","material-numeric-10-box-multiple":"material/numeric-10-box-multiple.svg","material-numeric-10-box-outline":"material/numeric-10-box-outline.svg","material-numeric-10-box":"material/numeric-10-box.svg","material-numeric-10-circle-outline":"material/numeric-10-circle-outline.svg","material-numeric-10-circle":"material/numeric-10-circle.svg","material-numeric-10":"material/numeric-10.svg","material-numeric-2-box-multiple-outline":"material/numeric-2-box-multiple-outline.svg","material-numeric-2-box-multiple":"material/numeric-2-box-multiple.svg","material-numeric-2-box-outline":"material/numeric-2-box-outline.svg","material-numeric-2-box":"material/numeric-2-box.svg","material-numeric-2-circle-outline":"material/numeric-2-circle-outline.svg","material-numeric-2-circle":"material/numeric-2-circle.svg","material-numeric-2":"material/numeric-2.svg","material-numeric-3-box-multiple-outline":"material/numeric-3-box-multiple-outline.svg","material-numeric-3-box-multiple":"material/numeric-3-box-multiple.svg","material-numeric-3-box-outline":"material/numeric-3-box-outline.svg","material-numeric-3-box":"material/numeric-3-box.svg","material-numeric-3-circle-outline":"material/numeric-3-circle-outline.svg","material-numeric-3-circle":"material/numeric-3-circle.svg","material-numeric-3":"material/numeric-3.svg","material-numeric-4-box-multiple-outline":"material/numeric-4-box-multiple-outline.svg","material-numeric-4-box-multiple":"material/numeric-4-box-multiple.svg","material-numeric-4-box-outline":"material/numeric-4-box-outline.svg","material-numeric-4-box":"material/numeric-4-box.svg","material-numeric-4-circle-outline":"material/numeric-4-circle-outline.svg","material-numeric-4-circle":"material/numeric-4-circle.svg","material-numeric-4":"material/numeric-4.svg","material-numeric-5-box-multiple-outline":"material/numeric-5-box-multiple-outline.svg","material-numeric-5-box-multiple":"material/numeric-5-box-multiple.svg","material-numeric-5-box-outline":"material/numeric-5-box-outline.svg","material-numeric-5-box":"material/numeric-5-box.svg","material-numeric-5-circle-outline":"material/numeric-5-circle-outline.svg","material-numeric-5-circle":"material/numeric-5-circle.svg","material-numeric-5":"material/numeric-5.svg","material-numeric-6-box-multiple-outline":"material/numeric-6-box-multiple-outline.svg","material-numeric-6-box-multiple":"material/numeric-6-box-multiple.svg","material-numeric-6-box-outline":"material/numeric-6-box-outline.svg","material-numeric-6-box":"material/numeric-6-box.svg","material-numeric-6-circle-outline":"material/numeric-6-circle-outline.svg","material-numeric-6-circle":"material/numeric-6-circle.svg","material-numeric-6":"material/numeric-6.svg","material-numeric-7-box-multiple-outline":"material/numeric-7-box-multiple-outline.svg","material-numeric-7-box-multiple":"material/numeric-7-box-multiple.svg","material-numeric-7-box-outline":"material/numeric-7-box-outline.svg","material-numeric-7-box":"material/numeric-7-box.svg","material-numeric-7-circle-outline":"material/numeric-7-circle-outline.svg","material-numeric-7-circle":"material/numeric-7-circle.svg","material-numeric-7":"material/numeric-7.svg","material-numeric-8-box-multiple-outline":"material/numeric-8-box-multiple-outline.svg","material-numeric-8-box-multiple":"material/numeric-8-box-multiple.svg","material-numeric-8-box-outline":"material/numeric-8-box-outline.svg","material-numeric-8-box":"material/numeric-8-box.svg","material-numeric-8-circle-outline":"material/numeric-8-circle-outline.svg","material-numeric-8-circle":"material/numeric-8-circle.svg","material-numeric-8":"material/numeric-8.svg","material-numeric-9-box-multiple-outline":"material/numeric-9-box-multiple-outline.svg","material-numeric-9-box-multiple":"material/numeric-9-box-multiple.svg","material-numeric-9-box-outline":"material/numeric-9-box-outline.svg","material-numeric-9-box":"material/numeric-9-box.svg","material-numeric-9-circle-outline":"material/numeric-9-circle-outline.svg","material-numeric-9-circle":"material/numeric-9-circle.svg","material-numeric-9-plus-box-multiple-outline":"material/numeric-9-plus-box-multiple-outline.svg","material-numeric-9-plus-box-multiple":"material/numeric-9-plus-box-multiple.svg","material-numeric-9-plus-box-outline":"material/numeric-9-plus-box-outline.svg","material-numeric-9-plus-box":"material/numeric-9-plus-box.svg","material-numeric-9-plus-circle-outline":"material/numeric-9-plus-circle-outline.svg","material-numeric-9-plus-circle":"material/numeric-9-plus-circle.svg","material-numeric-9-plus":"material/numeric-9-plus.svg","material-numeric-9":"material/numeric-9.svg","material-numeric-negative-1":"material/numeric-negative-1.svg","material-numeric-off":"material/numeric-off.svg","material-numeric-positive-1":"material/numeric-positive-1.svg","material-numeric":"material/numeric.svg","material-nut":"material/nut.svg","material-nutrition":"material/nutrition.svg","material-nuxt":"material/nuxt.svg","material-oar":"material/oar.svg","material-ocarina":"material/ocarina.svg","material-oci":"material/oci.svg","material-ocr":"material/ocr.svg","material-octagon-outline":"material/octagon-outline.svg","material-octagon":"material/octagon.svg","material-octagram-outline":"material/octagram-outline.svg","material-octagram":"material/octagram.svg","material-octahedron-off":"material/octahedron-off.svg","material-octahedron":"material/octahedron.svg","material-odnoklassniki":"material/odnoklassniki.svg","material-offer":"material/offer.svg","material-office-building-cog-outline":"material/office-building-cog-outline.svg","material-office-building-cog":"material/office-building-cog.svg","material-office-building-marker-outline":"material/office-building-marker-outline.svg","material-office-building-marker":"material/office-building-marker.svg","material-office-building-minus-outline":"material/office-building-minus-outline.svg","material-office-building-minus":"material/office-building-minus.svg","material-office-building-outline":"material/office-building-outline.svg","material-office-building-plus-outline":"material/office-building-plus-outline.svg","material-office-building-plus":"material/office-building-plus.svg","material-office-building-remove-outline":"material/office-building-remove-outline.svg","material-office-building-remove":"material/office-building-remove.svg","material-office-building":"material/office-building.svg","material-oil-lamp":"material/oil-lamp.svg","material-oil-level":"material/oil-level.svg","material-oil-temperature":"material/oil-temperature.svg","material-oil":"material/oil.svg","material-om":"material/om.svg","material-omega":"material/omega.svg","material-one-up":"material/one-up.svg","material-onepassword":"material/onepassword.svg","material-opacity":"material/opacity.svg","material-open-in-app":"material/open-in-app.svg","material-open-in-new":"material/open-in-new.svg","material-open-source-initiative":"material/open-source-initiative.svg","material-openid":"material/openid.svg","material-opera":"material/opera.svg","material-orbit-variant":"material/orbit-variant.svg","material-orbit":"material/orbit.svg","material-order-alphabetical-ascending":"material/order-alphabetical-ascending.svg","material-order-alphabetical-descending":"material/order-alphabetical-descending.svg","material-order-bool-ascending-variant":"material/order-bool-ascending-variant.svg","material-order-bool-ascending":"material/order-bool-ascending.svg","material-order-bool-descending-variant":"material/order-bool-descending-variant.svg","material-order-bool-descending":"material/order-bool-descending.svg","material-order-numeric-ascending":"material/order-numeric-ascending.svg","material-order-numeric-descending":"material/order-numeric-descending.svg","material-origin":"material/origin.svg","material-ornament-variant":"material/ornament-variant.svg","material-ornament":"material/ornament.svg","material-outdoor-lamp":"material/outdoor-lamp.svg","material-overscan":"material/overscan.svg","material-owl":"material/owl.svg","material-pac-man":"material/pac-man.svg","material-package-check":"material/package-check.svg","material-package-down":"material/package-down.svg","material-package-up":"material/package-up.svg","material-package-variant-closed-check":"material/package-variant-closed-check.svg","material-package-variant-closed-minus":"material/package-variant-closed-minus.svg","material-package-variant-closed-plus":"material/package-variant-closed-plus.svg","material-package-variant-closed-remove":"material/package-variant-closed-remove.svg","material-package-variant-closed":"material/package-variant-closed.svg","material-package-variant-minus":"material/package-variant-minus.svg","material-package-variant-plus":"material/package-variant-plus.svg","material-package-variant-remove":"material/package-variant-remove.svg","material-package-variant":"material/package-variant.svg","material-package":"material/package.svg","material-page-first":"material/page-first.svg","material-page-last":"material/page-last.svg","material-page-layout-body":"material/page-layout-body.svg","material-page-layout-footer":"material/page-layout-footer.svg","material-page-layout-header-footer":"material/page-layout-header-footer.svg","material-page-layout-header":"material/page-layout-header.svg","material-page-layout-sidebar-left":"material/page-layout-sidebar-left.svg","material-page-layout-sidebar-right":"material/page-layout-sidebar-right.svg","material-page-next-outline":"material/page-next-outline.svg","material-page-next":"material/page-next.svg","material-page-previous-outline":"material/page-previous-outline.svg","material-page-previous":"material/page-previous.svg","material-pail-minus-outline":"material/pail-minus-outline.svg","material-pail-minus":"material/pail-minus.svg","material-pail-off-outline":"material/pail-off-outline.svg","material-pail-off":"material/pail-off.svg","material-pail-outline":"material/pail-outline.svg","material-pail-plus-outline":"material/pail-plus-outline.svg","material-pail-plus":"material/pail-plus.svg","material-pail-remove-outline":"material/pail-remove-outline.svg","material-pail-remove":"material/pail-remove.svg","material-pail":"material/pail.svg","material-palette-advanced":"material/palette-advanced.svg","material-palette-outline":"material/palette-outline.svg","material-palette-swatch-outline":"material/palette-swatch-outline.svg","material-palette-swatch-variant":"material/palette-swatch-variant.svg","material-palette-swatch":"material/palette-swatch.svg","material-palette":"material/palette.svg","material-palm-tree":"material/palm-tree.svg","material-pan-bottom-left":"material/pan-bottom-left.svg","material-pan-bottom-right":"material/pan-bottom-right.svg","material-pan-down":"material/pan-down.svg","material-pan-horizontal":"material/pan-horizontal.svg","material-pan-left":"material/pan-left.svg","material-pan-right":"material/pan-right.svg","material-pan-top-left":"material/pan-top-left.svg","material-pan-top-right":"material/pan-top-right.svg","material-pan-up":"material/pan-up.svg","material-pan-vertical":"material/pan-vertical.svg","material-pan":"material/pan.svg","material-panda":"material/panda.svg","material-pandora":"material/pandora.svg","material-panorama-fisheye":"material/panorama-fisheye.svg","material-panorama-horizontal-outline":"material/panorama-horizontal-outline.svg","material-panorama-horizontal":"material/panorama-horizontal.svg","material-panorama-outline":"material/panorama-outline.svg","material-panorama-sphere-outline":"material/panorama-sphere-outline.svg","material-panorama-sphere":"material/panorama-sphere.svg","material-panorama-variant-outline":"material/panorama-variant-outline.svg","material-panorama-variant":"material/panorama-variant.svg","material-panorama-vertical-outline":"material/panorama-vertical-outline.svg","material-panorama-vertical":"material/panorama-vertical.svg","material-panorama-wide-angle-outline":"material/panorama-wide-angle-outline.svg","material-panorama-wide-angle":"material/panorama-wide-angle.svg","material-panorama":"material/panorama.svg","material-paper-cut-vertical":"material/paper-cut-vertical.svg","material-paper-roll-outline":"material/paper-roll-outline.svg","material-paper-roll":"material/paper-roll.svg","material-paperclip-check":"material/paperclip-check.svg","material-paperclip-lock":"material/paperclip-lock.svg","material-paperclip-minus":"material/paperclip-minus.svg","material-paperclip-off":"material/paperclip-off.svg","material-paperclip-plus":"material/paperclip-plus.svg","material-paperclip-remove":"material/paperclip-remove.svg","material-paperclip":"material/paperclip.svg","material-parachute-outline":"material/parachute-outline.svg","material-parachute":"material/parachute.svg","material-paragliding":"material/paragliding.svg","material-parking":"material/parking.svg","material-party-popper":"material/party-popper.svg","material-passport-biometric":"material/passport-biometric.svg","material-passport":"material/passport.svg","material-pasta":"material/pasta.svg","material-patio-heater":"material/patio-heater.svg","material-patreon":"material/patreon.svg","material-pause-box-outline":"material/pause-box-outline.svg","material-pause-box":"material/pause-box.svg","material-pause-circle-outline":"material/pause-circle-outline.svg","material-pause-circle":"material/pause-circle.svg","material-pause-octagon-outline":"material/pause-octagon-outline.svg","material-pause-octagon":"material/pause-octagon.svg","material-pause":"material/pause.svg","material-paw-off-outline":"material/paw-off-outline.svg","material-paw-off":"material/paw-off.svg","material-paw-outline":"material/paw-outline.svg","material-paw":"material/paw.svg","material-peace":"material/peace.svg","material-peanut-off-outline":"material/peanut-off-outline.svg","material-peanut-off":"material/peanut-off.svg","material-peanut-outline":"material/peanut-outline.svg","material-peanut":"material/peanut.svg","material-pen-lock":"material/pen-lock.svg","material-pen-minus":"material/pen-minus.svg","material-pen-off":"material/pen-off.svg","material-pen-plus":"material/pen-plus.svg","material-pen-remove":"material/pen-remove.svg","material-pen":"material/pen.svg","material-pencil-box-multiple-outline":"material/pencil-box-multiple-outline.svg","material-pencil-box-multiple":"material/pencil-box-multiple.svg","material-pencil-box-outline":"material/pencil-box-outline.svg","material-pencil-box":"material/pencil-box.svg","material-pencil-circle-outline":"material/pencil-circle-outline.svg","material-pencil-circle":"material/pencil-circle.svg","material-pencil-lock-outline":"material/pencil-lock-outline.svg","material-pencil-lock":"material/pencil-lock.svg","material-pencil-minus-outline":"material/pencil-minus-outline.svg","material-pencil-minus":"material/pencil-minus.svg","material-pencil-off-outline":"material/pencil-off-outline.svg","material-pencil-off":"material/pencil-off.svg","material-pencil-outline":"material/pencil-outline.svg","material-pencil-plus-outline":"material/pencil-plus-outline.svg","material-pencil-plus":"material/pencil-plus.svg","material-pencil-remove-outline":"material/pencil-remove-outline.svg","material-pencil-remove":"material/pencil-remove.svg","material-pencil-ruler":"material/pencil-ruler.svg","material-pencil":"material/pencil.svg","material-penguin":"material/penguin.svg","material-pentagon-outline":"material/pentagon-outline.svg","material-pentagon":"material/pentagon.svg","material-pentagram":"material/pentagram.svg","material-percent-box-outline":"material/percent-box-outline.svg","material-percent-box":"material/percent-box.svg","material-percent-circle-outline":"material/percent-circle-outline.svg","material-percent-circle":"material/percent-circle.svg","material-percent-outline":"material/percent-outline.svg","material-percent":"material/percent.svg","material-periodic-table":"material/periodic-table.svg","material-perspective-less":"material/perspective-less.svg","material-perspective-more":"material/perspective-more.svg","material-ph":"material/ph.svg","material-phone-alert-outline":"material/phone-alert-outline.svg","material-phone-alert":"material/phone-alert.svg","material-phone-bluetooth-outline":"material/phone-bluetooth-outline.svg","material-phone-bluetooth":"material/phone-bluetooth.svg","material-phone-cancel-outline":"material/phone-cancel-outline.svg","material-phone-cancel":"material/phone-cancel.svg","material-phone-check-outline":"material/phone-check-outline.svg","material-phone-check":"material/phone-check.svg","material-phone-classic-off":"material/phone-classic-off.svg","material-phone-classic":"material/phone-classic.svg","material-phone-clock":"material/phone-clock.svg","material-phone-dial-outline":"material/phone-dial-outline.svg","material-phone-dial":"material/phone-dial.svg","material-phone-forward-outline":"material/phone-forward-outline.svg","material-phone-forward":"material/phone-forward.svg","material-phone-hangup-outline":"material/phone-hangup-outline.svg","material-phone-hangup":"material/phone-hangup.svg","material-phone-in-talk-outline":"material/phone-in-talk-outline.svg","material-phone-in-talk":"material/phone-in-talk.svg","material-phone-incoming-outgoing-outline":"material/phone-incoming-outgoing-outline.svg","material-phone-incoming-outgoing":"material/phone-incoming-outgoing.svg","material-phone-incoming-outline":"material/phone-incoming-outline.svg","material-phone-incoming":"material/phone-incoming.svg","material-phone-lock-outline":"material/phone-lock-outline.svg","material-phone-lock":"material/phone-lock.svg","material-phone-log-outline":"material/phone-log-outline.svg","material-phone-log":"material/phone-log.svg","material-phone-message-outline":"material/phone-message-outline.svg","material-phone-message":"material/phone-message.svg","material-phone-minus-outline":"material/phone-minus-outline.svg","material-phone-minus":"material/phone-minus.svg","material-phone-missed-outline":"material/phone-missed-outline.svg","material-phone-missed":"material/phone-missed.svg","material-phone-off-outline":"material/phone-off-outline.svg","material-phone-off":"material/phone-off.svg","material-phone-outgoing-outline":"material/phone-outgoing-outline.svg","material-phone-outgoing":"material/phone-outgoing.svg","material-phone-outline":"material/phone-outline.svg","material-phone-paused-outline":"material/phone-paused-outline.svg","material-phone-paused":"material/phone-paused.svg","material-phone-plus-outline":"material/phone-plus-outline.svg","material-phone-plus":"material/phone-plus.svg","material-phone-refresh-outline":"material/phone-refresh-outline.svg","material-phone-refresh":"material/phone-refresh.svg","material-phone-remove-outline":"material/phone-remove-outline.svg","material-phone-remove":"material/phone-remove.svg","material-phone-return-outline":"material/phone-return-outline.svg","material-phone-return":"material/phone-return.svg","material-phone-ring-outline":"material/phone-ring-outline.svg","material-phone-ring":"material/phone-ring.svg","material-phone-rotate-landscape":"material/phone-rotate-landscape.svg","material-phone-rotate-portrait":"material/phone-rotate-portrait.svg","material-phone-settings-outline":"material/phone-settings-outline.svg","material-phone-settings":"material/phone-settings.svg","material-phone-sync-outline":"material/phone-sync-outline.svg","material-phone-sync":"material/phone-sync.svg","material-phone-voip":"material/phone-voip.svg","material-phone":"material/phone.svg","material-pi-box":"material/pi-box.svg","material-pi-hole":"material/pi-hole.svg","material-pi":"material/pi.svg","material-piano-off":"material/piano-off.svg","material-piano":"material/piano.svg","material-pickaxe":"material/pickaxe.svg","material-picture-in-picture-bottom-right-outline":"material/picture-in-picture-bottom-right-outline.svg","material-picture-in-picture-bottom-right":"material/picture-in-picture-bottom-right.svg","material-picture-in-picture-top-right-outline":"material/picture-in-picture-top-right-outline.svg","material-picture-in-picture-top-right":"material/picture-in-picture-top-right.svg","material-pier-crane":"material/pier-crane.svg","material-pier":"material/pier.svg","material-pig-variant-outline":"material/pig-variant-outline.svg","material-pig-variant":"material/pig-variant.svg","material-pig":"material/pig.svg","material-piggy-bank-outline":"material/piggy-bank-outline.svg","material-piggy-bank":"material/piggy-bank.svg","material-pill-multiple":"material/pill-multiple.svg","material-pill-off":"material/pill-off.svg","material-pill":"material/pill.svg","material-pillar":"material/pillar.svg","material-pin-off-outline":"material/pin-off-outline.svg","material-pin-off":"material/pin-off.svg","material-pin-outline":"material/pin-outline.svg","material-pin":"material/pin.svg","material-pine-tree-box":"material/pine-tree-box.svg","material-pine-tree-fire":"material/pine-tree-fire.svg","material-pine-tree":"material/pine-tree.svg","material-pinterest":"material/pinterest.svg","material-pinwheel-outline":"material/pinwheel-outline.svg","material-pinwheel":"material/pinwheel.svg","material-pipe-disconnected":"material/pipe-disconnected.svg","material-pipe-leak":"material/pipe-leak.svg","material-pipe-valve":"material/pipe-valve.svg","material-pipe-wrench":"material/pipe-wrench.svg","material-pipe":"material/pipe.svg","material-pirate":"material/pirate.svg","material-pistol":"material/pistol.svg","material-piston":"material/piston.svg","material-pitchfork":"material/pitchfork.svg","material-pizza":"material/pizza.svg","material-plane-car":"material/plane-car.svg","material-plane-train":"material/plane-train.svg","material-play-box-lock-open-outline":"material/play-box-lock-open-outline.svg","material-play-box-lock-open":"material/play-box-lock-open.svg","material-play-box-lock-outline":"material/play-box-lock-outline.svg","material-play-box-lock":"material/play-box-lock.svg","material-play-box-multiple-outline":"material/play-box-multiple-outline.svg","material-play-box-multiple":"material/play-box-multiple.svg","material-play-box-outline":"material/play-box-outline.svg","material-play-box":"material/play-box.svg","material-play-circle-outline":"material/play-circle-outline.svg","material-play-circle":"material/play-circle.svg","material-play-network-outline":"material/play-network-outline.svg","material-play-network":"material/play-network.svg","material-play-outline":"material/play-outline.svg","material-play-pause":"material/play-pause.svg","material-play-protected-content":"material/play-protected-content.svg","material-play-speed":"material/play-speed.svg","material-play":"material/play.svg","material-playlist-check":"material/playlist-check.svg","material-playlist-edit":"material/playlist-edit.svg","material-playlist-minus":"material/playlist-minus.svg","material-playlist-music-outline":"material/playlist-music-outline.svg","material-playlist-music":"material/playlist-music.svg","material-playlist-play":"material/playlist-play.svg","material-playlist-plus":"material/playlist-plus.svg","material-playlist-remove":"material/playlist-remove.svg","material-playlist-star":"material/playlist-star.svg","material-plex":"material/plex.svg","material-pliers":"material/pliers.svg","material-plus-box-multiple-outline":"material/plus-box-multiple-outline.svg","material-plus-box-multiple":"material/plus-box-multiple.svg","material-plus-box-outline":"material/plus-box-outline.svg","material-plus-box":"material/plus-box.svg","material-plus-circle-multiple-outline":"material/plus-circle-multiple-outline.svg","material-plus-circle-multiple":"material/plus-circle-multiple.svg","material-plus-circle-outline":"material/plus-circle-outline.svg","material-plus-circle":"material/plus-circle.svg","material-plus-lock-open":"material/plus-lock-open.svg","material-plus-lock":"material/plus-lock.svg","material-plus-minus-box":"material/plus-minus-box.svg","material-plus-minus-variant":"material/plus-minus-variant.svg","material-plus-minus":"material/plus-minus.svg","material-plus-network-outline":"material/plus-network-outline.svg","material-plus-network":"material/plus-network.svg","material-plus-outline":"material/plus-outline.svg","material-plus-thick":"material/plus-thick.svg","material-plus":"material/plus.svg","material-podcast":"material/podcast.svg","material-podium-bronze":"material/podium-bronze.svg","material-podium-gold":"material/podium-gold.svg","material-podium-silver":"material/podium-silver.svg","material-podium":"material/podium.svg","material-point-of-sale":"material/point-of-sale.svg","material-pokeball":"material/pokeball.svg","material-pokemon-go":"material/pokemon-go.svg","material-poker-chip":"material/poker-chip.svg","material-polaroid":"material/polaroid.svg","material-police-badge-outline":"material/police-badge-outline.svg","material-police-badge":"material/police-badge.svg","material-police-station":"material/police-station.svg","material-poll":"material/poll.svg","material-polo":"material/polo.svg","material-polymer":"material/polymer.svg","material-pool-thermometer":"material/pool-thermometer.svg","material-pool":"material/pool.svg","material-popcorn":"material/popcorn.svg","material-post-lamp":"material/post-lamp.svg","material-post-outline":"material/post-outline.svg","material-post":"material/post.svg","material-postage-stamp":"material/postage-stamp.svg","material-pot-mix-outline":"material/pot-mix-outline.svg","material-pot-mix":"material/pot-mix.svg","material-pot-outline":"material/pot-outline.svg","material-pot-steam-outline":"material/pot-steam-outline.svg","material-pot-steam":"material/pot-steam.svg","material-pot":"material/pot.svg","material-pound-box-outline":"material/pound-box-outline.svg","material-pound-box":"material/pound-box.svg","material-pound":"material/pound.svg","material-power-cycle":"material/power-cycle.svg","material-power-off":"material/power-off.svg","material-power-on":"material/power-on.svg","material-power-plug-off-outline":"material/power-plug-off-outline.svg","material-power-plug-off":"material/power-plug-off.svg","material-power-plug-outline":"material/power-plug-outline.svg","material-power-plug":"material/power-plug.svg","material-power-settings":"material/power-settings.svg","material-power-sleep":"material/power-sleep.svg","material-power-socket-au":"material/power-socket-au.svg","material-power-socket-ch":"material/power-socket-ch.svg","material-power-socket-de":"material/power-socket-de.svg","material-power-socket-eu":"material/power-socket-eu.svg","material-power-socket-fr":"material/power-socket-fr.svg","material-power-socket-it":"material/power-socket-it.svg","material-power-socket-jp":"material/power-socket-jp.svg","material-power-socket-uk":"material/power-socket-uk.svg","material-power-socket-us":"material/power-socket-us.svg","material-power-socket":"material/power-socket.svg","material-power-standby":"material/power-standby.svg","material-power":"material/power.svg","material-powershell":"material/powershell.svg","material-prescription":"material/prescription.svg","material-presentation-play":"material/presentation-play.svg","material-presentation":"material/presentation.svg","material-pretzel":"material/pretzel.svg","material-printer-3d-nozzle-alert-outline":"material/printer-3d-nozzle-alert-outline.svg","material-printer-3d-nozzle-alert":"material/printer-3d-nozzle-alert.svg","material-printer-3d-nozzle-heat-outline":"material/printer-3d-nozzle-heat-outline.svg","material-printer-3d-nozzle-heat":"material/printer-3d-nozzle-heat.svg","material-printer-3d-nozzle-off-outline":"material/printer-3d-nozzle-off-outline.svg","material-printer-3d-nozzle-off":"material/printer-3d-nozzle-off.svg","material-printer-3d-nozzle-outline":"material/printer-3d-nozzle-outline.svg","material-printer-3d-nozzle":"material/printer-3d-nozzle.svg","material-printer-3d-off":"material/printer-3d-off.svg","material-printer-3d":"material/printer-3d.svg","material-printer-alert":"material/printer-alert.svg","material-printer-check":"material/printer-check.svg","material-printer-eye":"material/printer-eye.svg","material-printer-off-outline":"material/printer-off-outline.svg","material-printer-off":"material/printer-off.svg","material-printer-outline":"material/printer-outline.svg","material-printer-pos":"material/printer-pos.svg","material-printer-search":"material/printer-search.svg","material-printer-settings":"material/printer-settings.svg","material-printer-wireless":"material/printer-wireless.svg","material-printer":"material/printer.svg","material-priority-high":"material/priority-high.svg","material-priority-low":"material/priority-low.svg","material-professional-hexagon":"material/professional-hexagon.svg","material-progress-alert":"material/progress-alert.svg","material-progress-check":"material/progress-check.svg","material-progress-clock":"material/progress-clock.svg","material-progress-close":"material/progress-close.svg","material-progress-download":"material/progress-download.svg","material-progress-helper":"material/progress-helper.svg","material-progress-pencil":"material/progress-pencil.svg","material-progress-question":"material/progress-question.svg","material-progress-star":"material/progress-star.svg","material-progress-upload":"material/progress-upload.svg","material-progress-wrench":"material/progress-wrench.svg","material-projector-off":"material/projector-off.svg","material-projector-screen-off-outline":"material/projector-screen-off-outline.svg","material-projector-screen-off":"material/projector-screen-off.svg","material-projector-screen-outline":"material/projector-screen-outline.svg","material-projector-screen-variant-off-outline":"material/projector-screen-variant-off-outline.svg","material-projector-screen-variant-off":"material/projector-screen-variant-off.svg","material-projector-screen-variant-outline":"material/projector-screen-variant-outline.svg","material-projector-screen-variant":"material/projector-screen-variant.svg","material-projector-screen":"material/projector-screen.svg","material-projector":"material/projector.svg","material-propane-tank-outline":"material/propane-tank-outline.svg","material-propane-tank":"material/propane-tank.svg","material-protocol":"material/protocol.svg","material-publish-off":"material/publish-off.svg","material-publish":"material/publish.svg","material-pulse":"material/pulse.svg","material-pump-off":"material/pump-off.svg","material-pump":"material/pump.svg","material-pumpkin":"material/pumpkin.svg","material-purse-outline":"material/purse-outline.svg","material-purse":"material/purse.svg","material-puzzle-check-outline":"material/puzzle-check-outline.svg","material-puzzle-check":"material/puzzle-check.svg","material-puzzle-edit-outline":"material/puzzle-edit-outline.svg","material-puzzle-edit":"material/puzzle-edit.svg","material-puzzle-heart-outline":"material/puzzle-heart-outline.svg","material-puzzle-heart":"material/puzzle-heart.svg","material-puzzle-minus-outline":"material/puzzle-minus-outline.svg","material-puzzle-minus":"material/puzzle-minus.svg","material-puzzle-outline":"material/puzzle-outline.svg","material-puzzle-plus-outline":"material/puzzle-plus-outline.svg","material-puzzle-plus":"material/puzzle-plus.svg","material-puzzle-remove-outline":"material/puzzle-remove-outline.svg","material-puzzle-remove":"material/puzzle-remove.svg","material-puzzle-star-outline":"material/puzzle-star-outline.svg","material-puzzle-star":"material/puzzle-star.svg","material-puzzle":"material/puzzle.svg","material-pyramid-off":"material/pyramid-off.svg","material-pyramid":"material/pyramid.svg","material-qi":"material/qi.svg","material-qqchat":"material/qqchat.svg","material-qrcode-edit":"material/qrcode-edit.svg","material-qrcode-minus":"material/qrcode-minus.svg","material-qrcode-plus":"material/qrcode-plus.svg","material-qrcode-remove":"material/qrcode-remove.svg","material-qrcode-scan":"material/qrcode-scan.svg","material-qrcode":"material/qrcode.svg","material-quadcopter":"material/quadcopter.svg","material-quality-high":"material/quality-high.svg","material-quality-low":"material/quality-low.svg","material-quality-medium":"material/quality-medium.svg","material-quora":"material/quora.svg","material-rabbit-variant-outline":"material/rabbit-variant-outline.svg","material-rabbit-variant":"material/rabbit-variant.svg","material-rabbit":"material/rabbit.svg","material-racing-helmet":"material/racing-helmet.svg","material-racquetball":"material/racquetball.svg","material-radar":"material/radar.svg","material-radiator-disabled":"material/radiator-disabled.svg","material-radiator-off":"material/radiator-off.svg","material-radiator":"material/radiator.svg","material-radio-am":"material/radio-am.svg","material-radio-fm":"material/radio-fm.svg","material-radio-handheld":"material/radio-handheld.svg","material-radio-off":"material/radio-off.svg","material-radio-tower":"material/radio-tower.svg","material-radio":"material/radio.svg","material-radioactive-circle-outline":"material/radioactive-circle-outline.svg","material-radioactive-circle":"material/radioactive-circle.svg","material-radioactive-off":"material/radioactive-off.svg","material-radioactive":"material/radioactive.svg","material-radiobox-blank":"material/radiobox-blank.svg","material-radiobox-marked":"material/radiobox-marked.svg","material-radiology-box-outline":"material/radiology-box-outline.svg","material-radiology-box":"material/radiology-box.svg","material-radius-outline":"material/radius-outline.svg","material-radius":"material/radius.svg","material-railroad-light":"material/railroad-light.svg","material-rake":"material/rake.svg","material-raspberry-pi":"material/raspberry-pi.svg","material-raw-off":"material/raw-off.svg","material-raw":"material/raw.svg","material-ray-end-arrow":"material/ray-end-arrow.svg","material-ray-end":"material/ray-end.svg","material-ray-start-arrow":"material/ray-start-arrow.svg","material-ray-start-end":"material/ray-start-end.svg","material-ray-start-vertex-end":"material/ray-start-vertex-end.svg","material-ray-start":"material/ray-start.svg","material-ray-vertex":"material/ray-vertex.svg","material-razor-double-edge":"material/razor-double-edge.svg","material-razor-single-edge":"material/razor-single-edge.svg","material-react":"material/react.svg","material-read":"material/read.svg","material-receipt-outline":"material/receipt-outline.svg","material-receipt-text-check-outline":"material/receipt-text-check-outline.svg","material-receipt-text-check":"material/receipt-text-check.svg","material-receipt-text-minus-outline":"material/receipt-text-minus-outline.svg","material-receipt-text-minus":"material/receipt-text-minus.svg","material-receipt-text-outline":"material/receipt-text-outline.svg","material-receipt-text-plus-outline":"material/receipt-text-plus-outline.svg","material-receipt-text-plus":"material/receipt-text-plus.svg","material-receipt-text-remove-outline":"material/receipt-text-remove-outline.svg","material-receipt-text-remove":"material/receipt-text-remove.svg","material-receipt-text":"material/receipt-text.svg","material-receipt":"material/receipt.svg","material-record-circle-outline":"material/record-circle-outline.svg","material-record-circle":"material/record-circle.svg","material-record-player":"material/record-player.svg","material-record-rec":"material/record-rec.svg","material-record":"material/record.svg","material-rectangle-outline":"material/rectangle-outline.svg","material-rectangle":"material/rectangle.svg","material-recycle-variant":"material/recycle-variant.svg","material-recycle":"material/recycle.svg","material-reddit":"material/reddit.svg","material-redhat":"material/redhat.svg","material-redo-variant":"material/redo-variant.svg","material-redo":"material/redo.svg","material-reflect-horizontal":"material/reflect-horizontal.svg","material-reflect-vertical":"material/reflect-vertical.svg","material-refresh-auto":"material/refresh-auto.svg","material-refresh-circle":"material/refresh-circle.svg","material-refresh":"material/refresh.svg","material-regex":"material/regex.svg","material-registered-trademark":"material/registered-trademark.svg","material-reiterate":"material/reiterate.svg","material-relation-many-to-many":"material/relation-many-to-many.svg","material-relation-many-to-one-or-many":"material/relation-many-to-one-or-many.svg","material-relation-many-to-one":"material/relation-many-to-one.svg","material-relation-many-to-only-one":"material/relation-many-to-only-one.svg","material-relation-many-to-zero-or-many":"material/relation-many-to-zero-or-many.svg","material-relation-many-to-zero-or-one":"material/relation-many-to-zero-or-one.svg","material-relation-one-or-many-to-many":"material/relation-one-or-many-to-many.svg","material-relation-one-or-many-to-one-or-many":"material/relation-one-or-many-to-one-or-many.svg","material-relation-one-or-many-to-one":"material/relation-one-or-many-to-one.svg","material-relation-one-or-many-to-only-one":"material/relation-one-or-many-to-only-one.svg","material-relation-one-or-many-to-zero-or-many":"material/relation-one-or-many-to-zero-or-many.svg","material-relation-one-or-many-to-zero-or-one":"material/relation-one-or-many-to-zero-or-one.svg","material-relation-one-to-many":"material/relation-one-to-many.svg","material-relation-one-to-one-or-many":"material/relation-one-to-one-or-many.svg","material-relation-one-to-one":"material/relation-one-to-one.svg","material-relation-one-to-only-one":"material/relation-one-to-only-one.svg","material-relation-one-to-zero-or-many":"material/relation-one-to-zero-or-many.svg","material-relation-one-to-zero-or-one":"material/relation-one-to-zero-or-one.svg","material-relation-only-one-to-many":"material/relation-only-one-to-many.svg","material-relation-only-one-to-one-or-many":"material/relation-only-one-to-one-or-many.svg","material-relation-only-one-to-one":"material/relation-only-one-to-one.svg","material-relation-only-one-to-only-one":"material/relation-only-one-to-only-one.svg","material-relation-only-one-to-zero-or-many":"material/relation-only-one-to-zero-or-many.svg","material-relation-only-one-to-zero-or-one":"material/relation-only-one-to-zero-or-one.svg","material-relation-zero-or-many-to-many":"material/relation-zero-or-many-to-many.svg","material-relation-zero-or-many-to-one-or-many":"material/relation-zero-or-many-to-one-or-many.svg","material-relation-zero-or-many-to-one":"material/relation-zero-or-many-to-one.svg","material-relation-zero-or-many-to-only-one":"material/relation-zero-or-many-to-only-one.svg","material-relation-zero-or-many-to-zero-or-many":"material/relation-zero-or-many-to-zero-or-many.svg","material-relation-zero-or-many-to-zero-or-one":"material/relation-zero-or-many-to-zero-or-one.svg","material-relation-zero-or-one-to-many":"material/relation-zero-or-one-to-many.svg","material-relation-zero-or-one-to-one-or-many":"material/relation-zero-or-one-to-one-or-many.svg","material-relation-zero-or-one-to-one":"material/relation-zero-or-one-to-one.svg","material-relation-zero-or-one-to-only-one":"material/relation-zero-or-one-to-only-one.svg","material-relation-zero-or-one-to-zero-or-many":"material/relation-zero-or-one-to-zero-or-many.svg","material-relation-zero-or-one-to-zero-or-one":"material/relation-zero-or-one-to-zero-or-one.svg","material-relative-scale":"material/relative-scale.svg","material-reload-alert":"material/reload-alert.svg","material-reload":"material/reload.svg","material-reminder":"material/reminder.svg","material-remote-desktop":"material/remote-desktop.svg","material-remote-off":"material/remote-off.svg","material-remote-tv-off":"material/remote-tv-off.svg","material-remote-tv":"material/remote-tv.svg","material-remote":"material/remote.svg","material-rename-box":"material/rename-box.svg","material-reorder-horizontal":"material/reorder-horizontal.svg","material-reorder-vertical":"material/reorder-vertical.svg","material-repeat-off":"material/repeat-off.svg","material-repeat-once":"material/repeat-once.svg","material-repeat-variant":"material/repeat-variant.svg","material-repeat":"material/repeat.svg","material-replay":"material/replay.svg","material-reply-all-outline":"material/reply-all-outline.svg","material-reply-all":"material/reply-all.svg","material-reply-circle":"material/reply-circle.svg","material-reply-outline":"material/reply-outline.svg","material-reply":"material/reply.svg","material-reproduction":"material/reproduction.svg","material-resistor-nodes":"material/resistor-nodes.svg","material-resistor":"material/resistor.svg","material-resize-bottom-right":"material/resize-bottom-right.svg","material-resize":"material/resize.svg","material-responsive":"material/responsive.svg","material-restart-alert":"material/restart-alert.svg","material-restart-off":"material/restart-off.svg","material-restart":"material/restart.svg","material-restore-alert":"material/restore-alert.svg","material-restore":"material/restore.svg","material-rewind-10":"material/rewind-10.svg","material-rewind-15":"material/rewind-15.svg","material-rewind-30":"material/rewind-30.svg","material-rewind-45":"material/rewind-45.svg","material-rewind-5":"material/rewind-5.svg","material-rewind-60":"material/rewind-60.svg","material-rewind-outline":"material/rewind-outline.svg","material-rewind":"material/rewind.svg","material-rhombus-medium-outline":"material/rhombus-medium-outline.svg","material-rhombus-medium":"material/rhombus-medium.svg","material-rhombus-outline":"material/rhombus-outline.svg","material-rhombus-split-outline":"material/rhombus-split-outline.svg","material-rhombus-split":"material/rhombus-split.svg","material-rhombus":"material/rhombus.svg","material-ribbon":"material/ribbon.svg","material-rice":"material/rice.svg","material-rickshaw-electric":"material/rickshaw-electric.svg","material-rickshaw":"material/rickshaw.svg","material-ring":"material/ring.svg","material-rivet":"material/rivet.svg","material-road-variant":"material/road-variant.svg","material-road":"material/road.svg","material-robber":"material/robber.svg","material-robot-angry-outline":"material/robot-angry-outline.svg","material-robot-angry":"material/robot-angry.svg","material-robot-confused-outline":"material/robot-confused-outline.svg","material-robot-confused":"material/robot-confused.svg","material-robot-dead-outline":"material/robot-dead-outline.svg","material-robot-dead":"material/robot-dead.svg","material-robot-excited-outline":"material/robot-excited-outline.svg","material-robot-excited":"material/robot-excited.svg","material-robot-happy-outline":"material/robot-happy-outline.svg","material-robot-happy":"material/robot-happy.svg","material-robot-industrial-outline":"material/robot-industrial-outline.svg","material-robot-industrial":"material/robot-industrial.svg","material-robot-love-outline":"material/robot-love-outline.svg","material-robot-love":"material/robot-love.svg","material-robot-mower-outline":"material/robot-mower-outline.svg","material-robot-mower":"material/robot-mower.svg","material-robot-off-outline":"material/robot-off-outline.svg","material-robot-off":"material/robot-off.svg","material-robot-outline":"material/robot-outline.svg","material-robot-vacuum-alert":"material/robot-vacuum-alert.svg","material-robot-vacuum-variant-alert":"material/robot-vacuum-variant-alert.svg","material-robot-vacuum-variant":"material/robot-vacuum-variant.svg","material-robot-vacuum":"material/robot-vacuum.svg","material-robot":"material/robot.svg","material-rocket-launch-outline":"material/rocket-launch-outline.svg","material-rocket-launch":"material/rocket-launch.svg","material-rocket-outline":"material/rocket-outline.svg","material-rocket":"material/rocket.svg","material-rodent":"material/rodent.svg","material-roller-shade-closed":"material/roller-shade-closed.svg","material-roller-shade":"material/roller-shade.svg","material-roller-skate-off":"material/roller-skate-off.svg","material-roller-skate":"material/roller-skate.svg","material-rollerblade-off":"material/rollerblade-off.svg","material-rollerblade":"material/rollerblade.svg","material-rollupjs":"material/rollupjs.svg","material-rolodex-outline":"material/rolodex-outline.svg","material-rolodex":"material/rolodex.svg","material-roman-numeral-1":"material/roman-numeral-1.svg","material-roman-numeral-10":"material/roman-numeral-10.svg","material-roman-numeral-2":"material/roman-numeral-2.svg","material-roman-numeral-3":"material/roman-numeral-3.svg","material-roman-numeral-4":"material/roman-numeral-4.svg","material-roman-numeral-5":"material/roman-numeral-5.svg","material-roman-numeral-6":"material/roman-numeral-6.svg","material-roman-numeral-7":"material/roman-numeral-7.svg","material-roman-numeral-8":"material/roman-numeral-8.svg","material-roman-numeral-9":"material/roman-numeral-9.svg","material-room-service-outline":"material/room-service-outline.svg","material-room-service":"material/room-service.svg","material-rotate-360":"material/rotate-360.svg","material-rotate-3d-variant":"material/rotate-3d-variant.svg","material-rotate-3d":"material/rotate-3d.svg","material-rotate-left-variant":"material/rotate-left-variant.svg","material-rotate-left":"material/rotate-left.svg","material-rotate-orbit":"material/rotate-orbit.svg","material-rotate-right-variant":"material/rotate-right-variant.svg","material-rotate-right":"material/rotate-right.svg","material-rounded-corner":"material/rounded-corner.svg","material-router-network":"material/router-network.svg","material-router-wireless-off":"material/router-wireless-off.svg","material-router-wireless-settings":"material/router-wireless-settings.svg","material-router-wireless":"material/router-wireless.svg","material-router":"material/router.svg","material-routes-clock":"material/routes-clock.svg","material-routes":"material/routes.svg","material-rowing":"material/rowing.svg","material-rss-box":"material/rss-box.svg","material-rss-off":"material/rss-off.svg","material-rss":"material/rss.svg","material-rug":"material/rug.svg","material-rugby":"material/rugby.svg","material-ruler-square-compass":"material/ruler-square-compass.svg","material-ruler-square":"material/ruler-square.svg","material-ruler":"material/ruler.svg","material-run-fast":"material/run-fast.svg","material-run":"material/run.svg","material-rv-truck":"material/rv-truck.svg","material-sack-percent":"material/sack-percent.svg","material-sack":"material/sack.svg","material-safe-square-outline":"material/safe-square-outline.svg","material-safe-square":"material/safe-square.svg","material-safe":"material/safe.svg","material-safety-goggles":"material/safety-goggles.svg","material-sail-boat-sink":"material/sail-boat-sink.svg","material-sail-boat":"material/sail-boat.svg","material-sale-outline":"material/sale-outline.svg","material-sale":"material/sale.svg","material-salesforce":"material/salesforce.svg","material-sass":"material/sass.svg","material-satellite-uplink":"material/satellite-uplink.svg","material-satellite-variant":"material/satellite-variant.svg","material-satellite":"material/satellite.svg","material-sausage-off":"material/sausage-off.svg","material-sausage":"material/sausage.svg","material-saw-blade":"material/saw-blade.svg","material-sawtooth-wave":"material/sawtooth-wave.svg","material-saxophone":"material/saxophone.svg","material-scale-balance":"material/scale-balance.svg","material-scale-bathroom":"material/scale-bathroom.svg","material-scale-off":"material/scale-off.svg","material-scale-unbalanced":"material/scale-unbalanced.svg","material-scale":"material/scale.svg","material-scan-helper":"material/scan-helper.svg","material-scanner-off":"material/scanner-off.svg","material-scanner":"material/scanner.svg","material-scatter-plot-outline":"material/scatter-plot-outline.svg","material-scatter-plot":"material/scatter-plot.svg","material-scent-off":"material/scent-off.svg","material-scent":"material/scent.svg","material-school-outline":"material/school-outline.svg","material-school":"material/school.svg","material-scissors-cutting":"material/scissors-cutting.svg","material-scooter-electric":"material/scooter-electric.svg","material-scooter":"material/scooter.svg","material-scoreboard-outline":"material/scoreboard-outline.svg","material-scoreboard":"material/scoreboard.svg","material-screen-rotation-lock":"material/screen-rotation-lock.svg","material-screen-rotation":"material/screen-rotation.svg","material-screw-flat-top":"material/screw-flat-top.svg","material-screw-lag":"material/screw-lag.svg","material-screw-machine-flat-top":"material/screw-machine-flat-top.svg","material-screw-machine-round-top":"material/screw-machine-round-top.svg","material-screw-round-top":"material/screw-round-top.svg","material-screwdriver":"material/screwdriver.svg","material-script-outline":"material/script-outline.svg","material-script-text-key-outline":"material/script-text-key-outline.svg","material-script-text-key":"material/script-text-key.svg","material-script-text-outline":"material/script-text-outline.svg","material-script-text-play-outline":"material/script-text-play-outline.svg","material-script-text-play":"material/script-text-play.svg","material-script-text":"material/script-text.svg","material-script":"material/script.svg","material-sd":"material/sd.svg","material-seal-variant":"material/seal-variant.svg","material-seal":"material/seal.svg","material-search-web":"material/search-web.svg","material-seat-flat-angled":"material/seat-flat-angled.svg","material-seat-flat":"material/seat-flat.svg","material-seat-individual-suite":"material/seat-individual-suite.svg","material-seat-legroom-extra":"material/seat-legroom-extra.svg","material-seat-legroom-normal":"material/seat-legroom-normal.svg","material-seat-legroom-reduced":"material/seat-legroom-reduced.svg","material-seat-outline":"material/seat-outline.svg","material-seat-passenger":"material/seat-passenger.svg","material-seat-recline-extra":"material/seat-recline-extra.svg","material-seat-recline-normal":"material/seat-recline-normal.svg","material-seat":"material/seat.svg","material-seatbelt":"material/seatbelt.svg","material-security-network":"material/security-network.svg","material-security":"material/security.svg","material-seed-off-outline":"material/seed-off-outline.svg","material-seed-off":"material/seed-off.svg","material-seed-outline":"material/seed-outline.svg","material-seed-plus-outline":"material/seed-plus-outline.svg","material-seed-plus":"material/seed-plus.svg","material-seed":"material/seed.svg","material-seesaw":"material/seesaw.svg","material-segment":"material/segment.svg","material-select-all":"material/select-all.svg","material-select-arrow-down":"material/select-arrow-down.svg","material-select-arrow-up":"material/select-arrow-up.svg","material-select-color":"material/select-color.svg","material-select-compare":"material/select-compare.svg","material-select-drag":"material/select-drag.svg","material-select-group":"material/select-group.svg","material-select-inverse":"material/select-inverse.svg","material-select-marker":"material/select-marker.svg","material-select-multiple-marker":"material/select-multiple-marker.svg","material-select-multiple":"material/select-multiple.svg","material-select-off":"material/select-off.svg","material-select-place":"material/select-place.svg","material-select-remove":"material/select-remove.svg","material-select-search":"material/select-search.svg","material-select":"material/select.svg","material-selection-drag":"material/selection-drag.svg","material-selection-ellipse-arrow-inside":"material/selection-ellipse-arrow-inside.svg","material-selection-ellipse-remove":"material/selection-ellipse-remove.svg","material-selection-ellipse":"material/selection-ellipse.svg","material-selection-marker":"material/selection-marker.svg","material-selection-multiple-marker":"material/selection-multiple-marker.svg","material-selection-multiple":"material/selection-multiple.svg","material-selection-off":"material/selection-off.svg","material-selection-remove":"material/selection-remove.svg","material-selection-search":"material/selection-search.svg","material-selection":"material/selection.svg","material-semantic-web":"material/semantic-web.svg","material-send-check-outline":"material/send-check-outline.svg","material-send-check":"material/send-check.svg","material-send-circle-outline":"material/send-circle-outline.svg","material-send-circle":"material/send-circle.svg","material-send-clock-outline":"material/send-clock-outline.svg","material-send-clock":"material/send-clock.svg","material-send-lock-outline":"material/send-lock-outline.svg","material-send-lock":"material/send-lock.svg","material-send-outline":"material/send-outline.svg","material-send":"material/send.svg","material-serial-port":"material/serial-port.svg","material-server-minus":"material/server-minus.svg","material-server-network-off":"material/server-network-off.svg","material-server-network":"material/server-network.svg","material-server-off":"material/server-off.svg","material-server-plus":"material/server-plus.svg","material-server-remove":"material/server-remove.svg","material-server-security":"material/server-security.svg","material-server":"material/server.svg","material-set-all":"material/set-all.svg","material-set-center-right":"material/set-center-right.svg","material-set-center":"material/set-center.svg","material-set-left-center":"material/set-left-center.svg","material-set-left-right":"material/set-left-right.svg","material-set-left":"material/set-left.svg","material-set-merge":"material/set-merge.svg","material-set-none":"material/set-none.svg","material-set-right":"material/set-right.svg","material-set-split":"material/set-split.svg","material-set-square":"material/set-square.svg","material-set-top-box":"material/set-top-box.svg","material-settings-helper":"material/settings-helper.svg","material-shaker-outline":"material/shaker-outline.svg","material-shaker":"material/shaker.svg","material-shape-circle-plus":"material/shape-circle-plus.svg","material-shape-outline":"material/shape-outline.svg","material-shape-oval-plus":"material/shape-oval-plus.svg","material-shape-plus":"material/shape-plus.svg","material-shape-polygon-plus":"material/shape-polygon-plus.svg","material-shape-rectangle-plus":"material/shape-rectangle-plus.svg","material-shape-square-plus":"material/shape-square-plus.svg","material-shape-square-rounded-plus":"material/shape-square-rounded-plus.svg","material-shape":"material/shape.svg","material-share-all-outline":"material/share-all-outline.svg","material-share-all":"material/share-all.svg","material-share-circle":"material/share-circle.svg","material-share-off-outline":"material/share-off-outline.svg","material-share-off":"material/share-off.svg","material-share-outline":"material/share-outline.svg","material-share-variant-outline":"material/share-variant-outline.svg","material-share-variant":"material/share-variant.svg","material-share":"material/share.svg","material-shark-fin-outline":"material/shark-fin-outline.svg","material-shark-fin":"material/shark-fin.svg","material-shark-off":"material/shark-off.svg","material-shark":"material/shark.svg","material-sheep":"material/sheep.svg","material-shield-account-outline":"material/shield-account-outline.svg","material-shield-account-variant-outline":"material/shield-account-variant-outline.svg","material-shield-account-variant":"material/shield-account-variant.svg","material-shield-account":"material/shield-account.svg","material-shield-airplane-outline":"material/shield-airplane-outline.svg","material-shield-airplane":"material/shield-airplane.svg","material-shield-alert-outline":"material/shield-alert-outline.svg","material-shield-alert":"material/shield-alert.svg","material-shield-bug-outline":"material/shield-bug-outline.svg","material-shield-bug":"material/shield-bug.svg","material-shield-car":"material/shield-car.svg","material-shield-check-outline":"material/shield-check-outline.svg","material-shield-check":"material/shield-check.svg","material-shield-cross-outline":"material/shield-cross-outline.svg","material-shield-cross":"material/shield-cross.svg","material-shield-crown-outline":"material/shield-crown-outline.svg","material-shield-crown":"material/shield-crown.svg","material-shield-edit-outline":"material/shield-edit-outline.svg","material-shield-edit":"material/shield-edit.svg","material-shield-half-full":"material/shield-half-full.svg","material-shield-half":"material/shield-half.svg","material-shield-home-outline":"material/shield-home-outline.svg","material-shield-home":"material/shield-home.svg","material-shield-key-outline":"material/shield-key-outline.svg","material-shield-key":"material/shield-key.svg","material-shield-link-variant-outline":"material/shield-link-variant-outline.svg","material-shield-link-variant":"material/shield-link-variant.svg","material-shield-lock-open-outline":"material/shield-lock-open-outline.svg","material-shield-lock-open":"material/shield-lock-open.svg","material-shield-lock-outline":"material/shield-lock-outline.svg","material-shield-lock":"material/shield-lock.svg","material-shield-moon-outline":"material/shield-moon-outline.svg","material-shield-moon":"material/shield-moon.svg","material-shield-off-outline":"material/shield-off-outline.svg","material-shield-off":"material/shield-off.svg","material-shield-outline":"material/shield-outline.svg","material-shield-plus-outline":"material/shield-plus-outline.svg","material-shield-plus":"material/shield-plus.svg","material-shield-refresh-outline":"material/shield-refresh-outline.svg","material-shield-refresh":"material/shield-refresh.svg","material-shield-remove-outline":"material/shield-remove-outline.svg","material-shield-remove":"material/shield-remove.svg","material-shield-search":"material/shield-search.svg","material-shield-star-outline":"material/shield-star-outline.svg","material-shield-star":"material/shield-star.svg","material-shield-sun-outline":"material/shield-sun-outline.svg","material-shield-sun":"material/shield-sun.svg","material-shield-sword-outline":"material/shield-sword-outline.svg","material-shield-sword":"material/shield-sword.svg","material-shield-sync-outline":"material/shield-sync-outline.svg","material-shield-sync":"material/shield-sync.svg","material-shield":"material/shield.svg","material-shimmer":"material/shimmer.svg","material-ship-wheel":"material/ship-wheel.svg","material-shipping-pallet":"material/shipping-pallet.svg","material-shoe-ballet":"material/shoe-ballet.svg","material-shoe-cleat":"material/shoe-cleat.svg","material-shoe-formal":"material/shoe-formal.svg","material-shoe-heel":"material/shoe-heel.svg","material-shoe-print":"material/shoe-print.svg","material-shoe-sneaker":"material/shoe-sneaker.svg","material-shopping-music":"material/shopping-music.svg","material-shopping-outline":"material/shopping-outline.svg","material-shopping-search-outline":"material/shopping-search-outline.svg","material-shopping-search":"material/shopping-search.svg","material-shopping":"material/shopping.svg","material-shore":"material/shore.svg","material-shovel-off":"material/shovel-off.svg","material-shovel":"material/shovel.svg","material-shower-head":"material/shower-head.svg","material-shower":"material/shower.svg","material-shredder":"material/shredder.svg","material-shuffle-disabled":"material/shuffle-disabled.svg","material-shuffle-variant":"material/shuffle-variant.svg","material-shuffle":"material/shuffle.svg","material-shuriken":"material/shuriken.svg","material-sickle":"material/sickle.svg","material-sigma-lower":"material/sigma-lower.svg","material-sigma":"material/sigma.svg","material-sign-caution":"material/sign-caution.svg","material-sign-direction-minus":"material/sign-direction-minus.svg","material-sign-direction-plus":"material/sign-direction-plus.svg","material-sign-direction-remove":"material/sign-direction-remove.svg","material-sign-direction":"material/sign-direction.svg","material-sign-language-outline":"material/sign-language-outline.svg","material-sign-language":"material/sign-language.svg","material-sign-pole":"material/sign-pole.svg","material-sign-real-estate":"material/sign-real-estate.svg","material-sign-text":"material/sign-text.svg","material-sign-yield":"material/sign-yield.svg","material-signal-2g":"material/signal-2g.svg","material-signal-3g":"material/signal-3g.svg","material-signal-4g":"material/signal-4g.svg","material-signal-5g":"material/signal-5g.svg","material-signal-cellular-1":"material/signal-cellular-1.svg","material-signal-cellular-2":"material/signal-cellular-2.svg","material-signal-cellular-3":"material/signal-cellular-3.svg","material-signal-cellular-outline":"material/signal-cellular-outline.svg","material-signal-distance-variant":"material/signal-distance-variant.svg","material-signal-hspa-plus":"material/signal-hspa-plus.svg","material-signal-hspa":"material/signal-hspa.svg","material-signal-off":"material/signal-off.svg","material-signal-variant":"material/signal-variant.svg","material-signal":"material/signal.svg","material-signature-freehand":"material/signature-freehand.svg","material-signature-image":"material/signature-image.svg","material-signature-text":"material/signature-text.svg","material-signature":"material/signature.svg","material-silo-outline":"material/silo-outline.svg","material-silo":"material/silo.svg","material-silverware-clean":"material/silverware-clean.svg","material-silverware-fork-knife":"material/silverware-fork-knife.svg","material-silverware-fork":"material/silverware-fork.svg","material-silverware-spoon":"material/silverware-spoon.svg","material-silverware-variant":"material/silverware-variant.svg","material-silverware":"material/silverware.svg","material-sim-alert-outline":"material/sim-alert-outline.svg","material-sim-alert":"material/sim-alert.svg","material-sim-off-outline":"material/sim-off-outline.svg","material-sim-off":"material/sim-off.svg","material-sim-outline":"material/sim-outline.svg","material-sim":"material/sim.svg","material-simple-icons":"material/simple-icons.svg","material-sina-weibo":"material/sina-weibo.svg","material-sine-wave":"material/sine-wave.svg","material-sitemap-outline":"material/sitemap-outline.svg","material-sitemap":"material/sitemap.svg","material-size-l":"material/size-l.svg","material-size-m":"material/size-m.svg","material-size-s":"material/size-s.svg","material-size-xl":"material/size-xl.svg","material-size-xs":"material/size-xs.svg","material-size-xxl":"material/size-xxl.svg","material-size-xxs":"material/size-xxs.svg","material-size-xxxl":"material/size-xxxl.svg","material-skate-off":"material/skate-off.svg","material-skate":"material/skate.svg","material-skateboard":"material/skateboard.svg","material-skateboarding":"material/skateboarding.svg","material-skew-less":"material/skew-less.svg","material-skew-more":"material/skew-more.svg","material-ski-cross-country":"material/ski-cross-country.svg","material-ski-water":"material/ski-water.svg","material-ski":"material/ski.svg","material-skip-backward-outline":"material/skip-backward-outline.svg","material-skip-backward":"material/skip-backward.svg","material-skip-forward-outline":"material/skip-forward-outline.svg","material-skip-forward":"material/skip-forward.svg","material-skip-next-circle-outline":"material/skip-next-circle-outline.svg","material-skip-next-circle":"material/skip-next-circle.svg","material-skip-next-outline":"material/skip-next-outline.svg","material-skip-next":"material/skip-next.svg","material-skip-previous-circle-outline":"material/skip-previous-circle-outline.svg","material-skip-previous-circle":"material/skip-previous-circle.svg","material-skip-previous-outline":"material/skip-previous-outline.svg","material-skip-previous":"material/skip-previous.svg","material-skull-crossbones-outline":"material/skull-crossbones-outline.svg","material-skull-crossbones":"material/skull-crossbones.svg","material-skull-outline":"material/skull-outline.svg","material-skull-scan-outline":"material/skull-scan-outline.svg","material-skull-scan":"material/skull-scan.svg","material-skull":"material/skull.svg","material-skype-business":"material/skype-business.svg","material-skype":"material/skype.svg","material-slack":"material/slack.svg","material-slash-forward-box":"material/slash-forward-box.svg","material-slash-forward":"material/slash-forward.svg","material-sledding":"material/sledding.svg","material-sleep-off":"material/sleep-off.svg","material-sleep":"material/sleep.svg","material-slide":"material/slide.svg","material-slope-downhill":"material/slope-downhill.svg","material-slope-uphill":"material/slope-uphill.svg","material-slot-machine-outline":"material/slot-machine-outline.svg","material-slot-machine":"material/slot-machine.svg","material-smart-card-off-outline":"material/smart-card-off-outline.svg","material-smart-card-off":"material/smart-card-off.svg","material-smart-card-outline":"material/smart-card-outline.svg","material-smart-card-reader-outline":"material/smart-card-reader-outline.svg","material-smart-card-reader":"material/smart-card-reader.svg","material-smart-card":"material/smart-card.svg","material-smog":"material/smog.svg","material-smoke-detector-alert-outline":"material/smoke-detector-alert-outline.svg","material-smoke-detector-alert":"material/smoke-detector-alert.svg","material-smoke-detector-off-outline":"material/smoke-detector-off-outline.svg","material-smoke-detector-off":"material/smoke-detector-off.svg","material-smoke-detector-outline":"material/smoke-detector-outline.svg","material-smoke-detector-variant-alert":"material/smoke-detector-variant-alert.svg","material-smoke-detector-variant-off":"material/smoke-detector-variant-off.svg","material-smoke-detector-variant":"material/smoke-detector-variant.svg","material-smoke-detector":"material/smoke-detector.svg","material-smoke":"material/smoke.svg","material-smoking-off":"material/smoking-off.svg","material-smoking-pipe-off":"material/smoking-pipe-off.svg","material-smoking-pipe":"material/smoking-pipe.svg","material-smoking":"material/smoking.svg","material-snail":"material/snail.svg","material-snake":"material/snake.svg","material-snapchat":"material/snapchat.svg","material-snowboard":"material/snowboard.svg","material-snowflake-alert":"material/snowflake-alert.svg","material-snowflake-check":"material/snowflake-check.svg","material-snowflake-melt":"material/snowflake-melt.svg","material-snowflake-off":"material/snowflake-off.svg","material-snowflake-thermometer":"material/snowflake-thermometer.svg","material-snowflake-variant":"material/snowflake-variant.svg","material-snowflake":"material/snowflake.svg","material-snowman":"material/snowman.svg","material-snowmobile":"material/snowmobile.svg","material-snowshoeing":"material/snowshoeing.svg","material-soccer-field":"material/soccer-field.svg","material-soccer":"material/soccer.svg","material-social-distance-2-meters":"material/social-distance-2-meters.svg","material-social-distance-6-feet":"material/social-distance-6-feet.svg","material-sofa-outline":"material/sofa-outline.svg","material-sofa-single-outline":"material/sofa-single-outline.svg","material-sofa-single":"material/sofa-single.svg","material-sofa":"material/sofa.svg","material-solar-panel-large":"material/solar-panel-large.svg","material-solar-panel":"material/solar-panel.svg","material-solar-power-variant-outline":"material/solar-power-variant-outline.svg","material-solar-power-variant":"material/solar-power-variant.svg","material-solar-power":"material/solar-power.svg","material-soldering-iron":"material/soldering-iron.svg","material-solid":"material/solid.svg","material-sony-playstation":"material/sony-playstation.svg","material-sort-alphabetical-ascending-variant":"material/sort-alphabetical-ascending-variant.svg","material-sort-alphabetical-ascending":"material/sort-alphabetical-ascending.svg","material-sort-alphabetical-descending-variant":"material/sort-alphabetical-descending-variant.svg","material-sort-alphabetical-descending":"material/sort-alphabetical-descending.svg","material-sort-alphabetical-variant":"material/sort-alphabetical-variant.svg","material-sort-ascending":"material/sort-ascending.svg","material-sort-bool-ascending-variant":"material/sort-bool-ascending-variant.svg","material-sort-bool-ascending":"material/sort-bool-ascending.svg","material-sort-bool-descending-variant":"material/sort-bool-descending-variant.svg","material-sort-bool-descending":"material/sort-bool-descending.svg","material-sort-calendar-ascending":"material/sort-calendar-ascending.svg","material-sort-calendar-descending":"material/sort-calendar-descending.svg","material-sort-clock-ascending-outline":"material/sort-clock-ascending-outline.svg","material-sort-clock-ascending":"material/sort-clock-ascending.svg","material-sort-clock-descending-outline":"material/sort-clock-descending-outline.svg","material-sort-clock-descending":"material/sort-clock-descending.svg","material-sort-descending":"material/sort-descending.svg","material-sort-numeric-ascending-variant":"material/sort-numeric-ascending-variant.svg","material-sort-numeric-ascending":"material/sort-numeric-ascending.svg","material-sort-numeric-descending-variant":"material/sort-numeric-descending-variant.svg","material-sort-numeric-descending":"material/sort-numeric-descending.svg","material-sort-numeric-variant":"material/sort-numeric-variant.svg","material-sort-reverse-variant":"material/sort-reverse-variant.svg","material-sort-variant-lock-open":"material/sort-variant-lock-open.svg","material-sort-variant-lock":"material/sort-variant-lock.svg","material-sort-variant-off":"material/sort-variant-off.svg","material-sort-variant-remove":"material/sort-variant-remove.svg","material-sort-variant":"material/sort-variant.svg","material-sort":"material/sort.svg","material-soundbar":"material/soundbar.svg","material-soundcloud":"material/soundcloud.svg","material-source-branch-check":"material/source-branch-check.svg","material-source-branch-minus":"material/source-branch-minus.svg","material-source-branch-plus":"material/source-branch-plus.svg","material-source-branch-refresh":"material/source-branch-refresh.svg","material-source-branch-remove":"material/source-branch-remove.svg","material-source-branch-sync":"material/source-branch-sync.svg","material-source-branch":"material/source-branch.svg","material-source-commit-end-local":"material/source-commit-end-local.svg","material-source-commit-end":"material/source-commit-end.svg","material-source-commit-local":"material/source-commit-local.svg","material-source-commit-next-local":"material/source-commit-next-local.svg","material-source-commit-start-next-local":"material/source-commit-start-next-local.svg","material-source-commit-start":"material/source-commit-start.svg","material-source-commit":"material/source-commit.svg","material-source-fork":"material/source-fork.svg","material-source-merge":"material/source-merge.svg","material-source-pull":"material/source-pull.svg","material-source-repository-multiple":"material/source-repository-multiple.svg","material-source-repository":"material/source-repository.svg","material-soy-sauce-off":"material/soy-sauce-off.svg","material-soy-sauce":"material/soy-sauce.svg","material-spa-outline":"material/spa-outline.svg","material-spa":"material/spa.svg","material-space-invaders":"material/space-invaders.svg","material-space-station":"material/space-station.svg","material-spade":"material/spade.svg","material-speaker-bluetooth":"material/speaker-bluetooth.svg","material-speaker-message":"material/speaker-message.svg","material-speaker-multiple":"material/speaker-multiple.svg","material-speaker-off":"material/speaker-off.svg","material-speaker-pause":"material/speaker-pause.svg","material-speaker-play":"material/speaker-play.svg","material-speaker-stop":"material/speaker-stop.svg","material-speaker-wireless":"material/speaker-wireless.svg","material-speaker":"material/speaker.svg","material-spear":"material/spear.svg","material-speedometer-medium":"material/speedometer-medium.svg","material-speedometer-slow":"material/speedometer-slow.svg","material-speedometer":"material/speedometer.svg","material-spellcheck":"material/spellcheck.svg","material-sphere-off":"material/sphere-off.svg","material-sphere":"material/sphere.svg","material-spider-thread":"material/spider-thread.svg","material-spider-web":"material/spider-web.svg","material-spider":"material/spider.svg","material-spirit-level":"material/spirit-level.svg","material-spoon-sugar":"material/spoon-sugar.svg","material-spotify":"material/spotify.svg","material-spotlight-beam":"material/spotlight-beam.svg","material-spotlight":"material/spotlight.svg","material-spray-bottle":"material/spray-bottle.svg","material-spray":"material/spray.svg","material-sprinkler-fire":"material/sprinkler-fire.svg","material-sprinkler-variant":"material/sprinkler-variant.svg","material-sprinkler":"material/sprinkler.svg","material-sprout-outline":"material/sprout-outline.svg","material-sprout":"material/sprout.svg","material-square-circle":"material/square-circle.svg","material-square-edit-outline":"material/square-edit-outline.svg","material-square-medium-outline":"material/square-medium-outline.svg","material-square-medium":"material/square-medium.svg","material-square-off-outline":"material/square-off-outline.svg","material-square-off":"material/square-off.svg","material-square-opacity":"material/square-opacity.svg","material-square-outline":"material/square-outline.svg","material-square-root-box":"material/square-root-box.svg","material-square-root":"material/square-root.svg","material-square-rounded-badge-outline":"material/square-rounded-badge-outline.svg","material-square-rounded-badge":"material/square-rounded-badge.svg","material-square-rounded-outline":"material/square-rounded-outline.svg","material-square-rounded":"material/square-rounded.svg","material-square-small":"material/square-small.svg","material-square-wave":"material/square-wave.svg","material-square":"material/square.svg","material-squeegee":"material/squeegee.svg","material-ssh":"material/ssh.svg","material-stack-exchange":"material/stack-exchange.svg","material-stack-overflow":"material/stack-overflow.svg","material-stackpath":"material/stackpath.svg","material-stadium-outline":"material/stadium-outline.svg","material-stadium-variant":"material/stadium-variant.svg","material-stadium":"material/stadium.svg","material-stairs-box":"material/stairs-box.svg","material-stairs-down":"material/stairs-down.svg","material-stairs-up":"material/stairs-up.svg","material-stairs":"material/stairs.svg","material-stamper":"material/stamper.svg","material-standard-definition":"material/standard-definition.svg","material-star-box-multiple-outline":"material/star-box-multiple-outline.svg","material-star-box-multiple":"material/star-box-multiple.svg","material-star-box-outline":"material/star-box-outline.svg","material-star-box":"material/star-box.svg","material-star-check-outline":"material/star-check-outline.svg","material-star-check":"material/star-check.svg","material-star-circle-outline":"material/star-circle-outline.svg","material-star-circle":"material/star-circle.svg","material-star-cog-outline":"material/star-cog-outline.svg","material-star-cog":"material/star-cog.svg","material-star-crescent":"material/star-crescent.svg","material-star-david":"material/star-david.svg","material-star-face":"material/star-face.svg","material-star-four-points-outline":"material/star-four-points-outline.svg","material-star-four-points":"material/star-four-points.svg","material-star-half-full":"material/star-half-full.svg","material-star-half":"material/star-half.svg","material-star-minus-outline":"material/star-minus-outline.svg","material-star-minus":"material/star-minus.svg","material-star-off-outline":"material/star-off-outline.svg","material-star-off":"material/star-off.svg","material-star-outline":"material/star-outline.svg","material-star-plus-outline":"material/star-plus-outline.svg","material-star-plus":"material/star-plus.svg","material-star-remove-outline":"material/star-remove-outline.svg","material-star-remove":"material/star-remove.svg","material-star-settings-outline":"material/star-settings-outline.svg","material-star-settings":"material/star-settings.svg","material-star-shooting-outline":"material/star-shooting-outline.svg","material-star-shooting":"material/star-shooting.svg","material-star-three-points-outline":"material/star-three-points-outline.svg","material-star-three-points":"material/star-three-points.svg","material-star":"material/star.svg","material-state-machine":"material/state-machine.svg","material-steam":"material/steam.svg","material-steering-off":"material/steering-off.svg","material-steering":"material/steering.svg","material-step-backward-2":"material/step-backward-2.svg","material-step-backward":"material/step-backward.svg","material-step-forward-2":"material/step-forward-2.svg","material-step-forward":"material/step-forward.svg","material-stethoscope":"material/stethoscope.svg","material-sticker-alert-outline":"material/sticker-alert-outline.svg","material-sticker-alert":"material/sticker-alert.svg","material-sticker-check-outline":"material/sticker-check-outline.svg","material-sticker-check":"material/sticker-check.svg","material-sticker-circle-outline":"material/sticker-circle-outline.svg","material-sticker-emoji":"material/sticker-emoji.svg","material-sticker-minus-outline":"material/sticker-minus-outline.svg","material-sticker-minus":"material/sticker-minus.svg","material-sticker-outline":"material/sticker-outline.svg","material-sticker-plus-outline":"material/sticker-plus-outline.svg","material-sticker-plus":"material/sticker-plus.svg","material-sticker-remove-outline":"material/sticker-remove-outline.svg","material-sticker-remove":"material/sticker-remove.svg","material-sticker-text-outline":"material/sticker-text-outline.svg","material-sticker-text":"material/sticker-text.svg","material-sticker":"material/sticker.svg","material-stocking":"material/stocking.svg","material-stomach":"material/stomach.svg","material-stool-outline":"material/stool-outline.svg","material-stool":"material/stool.svg","material-stop-circle-outline":"material/stop-circle-outline.svg","material-stop-circle":"material/stop-circle.svg","material-stop":"material/stop.svg","material-storage-tank-outline":"material/storage-tank-outline.svg","material-storage-tank":"material/storage-tank.svg","material-store-24-hour":"material/store-24-hour.svg","material-store-alert-outline":"material/store-alert-outline.svg","material-store-alert":"material/store-alert.svg","material-store-check-outline":"material/store-check-outline.svg","material-store-check":"material/store-check.svg","material-store-clock-outline":"material/store-clock-outline.svg","material-store-clock":"material/store-clock.svg","material-store-cog-outline":"material/store-cog-outline.svg","material-store-cog":"material/store-cog.svg","material-store-edit-outline":"material/store-edit-outline.svg","material-store-edit":"material/store-edit.svg","material-store-marker-outline":"material/store-marker-outline.svg","material-store-marker":"material/store-marker.svg","material-store-minus-outline":"material/store-minus-outline.svg","material-store-minus":"material/store-minus.svg","material-store-off-outline":"material/store-off-outline.svg","material-store-off":"material/store-off.svg","material-store-outline":"material/store-outline.svg","material-store-plus-outline":"material/store-plus-outline.svg","material-store-plus":"material/store-plus.svg","material-store-remove-outline":"material/store-remove-outline.svg","material-store-remove":"material/store-remove.svg","material-store-search-outline":"material/store-search-outline.svg","material-store-search":"material/store-search.svg","material-store-settings-outline":"material/store-settings-outline.svg","material-store-settings":"material/store-settings.svg","material-store":"material/store.svg","material-storefront-check-outline":"material/storefront-check-outline.svg","material-storefront-check":"material/storefront-check.svg","material-storefront-edit-outline":"material/storefront-edit-outline.svg","material-storefront-edit":"material/storefront-edit.svg","material-storefront-minus-outline":"material/storefront-minus-outline.svg","material-storefront-minus":"material/storefront-minus.svg","material-storefront-outline":"material/storefront-outline.svg","material-storefront-plus-outline":"material/storefront-plus-outline.svg","material-storefront-plus":"material/storefront-plus.svg","material-storefront-remove-outline":"material/storefront-remove-outline.svg","material-storefront-remove":"material/storefront-remove.svg","material-storefront":"material/storefront.svg","material-stove":"material/stove.svg","material-strategy":"material/strategy.svg","material-stretch-to-page-outline":"material/stretch-to-page-outline.svg","material-stretch-to-page":"material/stretch-to-page.svg","material-string-lights-off":"material/string-lights-off.svg","material-string-lights":"material/string-lights.svg","material-subdirectory-arrow-left":"material/subdirectory-arrow-left.svg","material-subdirectory-arrow-right":"material/subdirectory-arrow-right.svg","material-submarine":"material/submarine.svg","material-subtitles-outline":"material/subtitles-outline.svg","material-subtitles":"material/subtitles.svg","material-subway-alert-variant":"material/subway-alert-variant.svg","material-subway-variant":"material/subway-variant.svg","material-subway":"material/subway.svg","material-summit":"material/summit.svg","material-sun-angle-outline":"material/sun-angle-outline.svg","material-sun-angle":"material/sun-angle.svg","material-sun-clock-outline":"material/sun-clock-outline.svg","material-sun-clock":"material/sun-clock.svg","material-sun-compass":"material/sun-compass.svg","material-sun-snowflake-variant":"material/sun-snowflake-variant.svg","material-sun-snowflake":"material/sun-snowflake.svg","material-sun-thermometer-outline":"material/sun-thermometer-outline.svg","material-sun-thermometer":"material/sun-thermometer.svg","material-sun-wireless-outline":"material/sun-wireless-outline.svg","material-sun-wireless":"material/sun-wireless.svg","material-sunglasses":"material/sunglasses.svg","material-surfing":"material/surfing.svg","material-surround-sound-2-0":"material/surround-sound-2-0.svg","material-surround-sound-2-1":"material/surround-sound-2-1.svg","material-surround-sound-3-1":"material/surround-sound-3-1.svg","material-surround-sound-5-1-2":"material/surround-sound-5-1-2.svg","material-surround-sound-5-1":"material/surround-sound-5-1.svg","material-surround-sound-7-1":"material/surround-sound-7-1.svg","material-surround-sound":"material/surround-sound.svg","material-svg":"material/svg.svg","material-swap-horizontal-bold":"material/swap-horizontal-bold.svg","material-swap-horizontal-circle-outline":"material/swap-horizontal-circle-outline.svg","material-swap-horizontal-circle":"material/swap-horizontal-circle.svg","material-swap-horizontal-variant":"material/swap-horizontal-variant.svg","material-swap-horizontal":"material/swap-horizontal.svg","material-swap-vertical-bold":"material/swap-vertical-bold.svg","material-swap-vertical-circle-outline":"material/swap-vertical-circle-outline.svg","material-swap-vertical-circle":"material/swap-vertical-circle.svg","material-swap-vertical-variant":"material/swap-vertical-variant.svg","material-swap-vertical":"material/swap-vertical.svg","material-swim":"material/swim.svg","material-switch":"material/switch.svg","material-sword-cross":"material/sword-cross.svg","material-sword":"material/sword.svg","material-syllabary-hangul":"material/syllabary-hangul.svg","material-syllabary-hiragana":"material/syllabary-hiragana.svg","material-syllabary-katakana-halfwidth":"material/syllabary-katakana-halfwidth.svg","material-syllabary-katakana":"material/syllabary-katakana.svg","material-symbol":"material/symbol.svg","material-symfony":"material/symfony.svg","material-synagogue-outline":"material/synagogue-outline.svg","material-synagogue":"material/synagogue.svg","material-sync-alert":"material/sync-alert.svg","material-sync-circle":"material/sync-circle.svg","material-sync-off":"material/sync-off.svg","material-sync":"material/sync.svg","material-tab-minus":"material/tab-minus.svg","material-tab-plus":"material/tab-plus.svg","material-tab-remove":"material/tab-remove.svg","material-tab-search":"material/tab-search.svg","material-tab-unselected":"material/tab-unselected.svg","material-tab":"material/tab.svg","material-table-account":"material/table-account.svg","material-table-alert":"material/table-alert.svg","material-table-arrow-down":"material/table-arrow-down.svg","material-table-arrow-left":"material/table-arrow-left.svg","material-table-arrow-right":"material/table-arrow-right.svg","material-table-arrow-up":"material/table-arrow-up.svg","material-table-border":"material/table-border.svg","material-table-cancel":"material/table-cancel.svg","material-table-chair":"material/table-chair.svg","material-table-check":"material/table-check.svg","material-table-clock":"material/table-clock.svg","material-table-cog":"material/table-cog.svg","material-table-column-plus-after":"material/table-column-plus-after.svg","material-table-column-plus-before":"material/table-column-plus-before.svg","material-table-column-remove":"material/table-column-remove.svg","material-table-column-width":"material/table-column-width.svg","material-table-column":"material/table-column.svg","material-table-edit":"material/table-edit.svg","material-table-eye-off":"material/table-eye-off.svg","material-table-eye":"material/table-eye.svg","material-table-filter":"material/table-filter.svg","material-table-furniture":"material/table-furniture.svg","material-table-headers-eye-off":"material/table-headers-eye-off.svg","material-table-headers-eye":"material/table-headers-eye.svg","material-table-heart":"material/table-heart.svg","material-table-key":"material/table-key.svg","material-table-large-plus":"material/table-large-plus.svg","material-table-large-remove":"material/table-large-remove.svg","material-table-large":"material/table-large.svg","material-table-lock":"material/table-lock.svg","material-table-merge-cells":"material/table-merge-cells.svg","material-table-minus":"material/table-minus.svg","material-table-multiple":"material/table-multiple.svg","material-table-network":"material/table-network.svg","material-table-of-contents":"material/table-of-contents.svg","material-table-off":"material/table-off.svg","material-table-picnic":"material/table-picnic.svg","material-table-pivot":"material/table-pivot.svg","material-table-plus":"material/table-plus.svg","material-table-question":"material/table-question.svg","material-table-refresh":"material/table-refresh.svg","material-table-remove":"material/table-remove.svg","material-table-row-height":"material/table-row-height.svg","material-table-row-plus-after":"material/table-row-plus-after.svg","material-table-row-plus-before":"material/table-row-plus-before.svg","material-table-row-remove":"material/table-row-remove.svg","material-table-row":"material/table-row.svg","material-table-search":"material/table-search.svg","material-table-settings":"material/table-settings.svg","material-table-split-cell":"material/table-split-cell.svg","material-table-star":"material/table-star.svg","material-table-sync":"material/table-sync.svg","material-table-tennis":"material/table-tennis.svg","material-table":"material/table.svg","material-tablet-cellphone":"material/tablet-cellphone.svg","material-tablet-dashboard":"material/tablet-dashboard.svg","material-tablet":"material/tablet.svg","material-taco":"material/taco.svg","material-tag-arrow-down-outline":"material/tag-arrow-down-outline.svg","material-tag-arrow-down":"material/tag-arrow-down.svg","material-tag-arrow-left-outline":"material/tag-arrow-left-outline.svg","material-tag-arrow-left":"material/tag-arrow-left.svg","material-tag-arrow-right-outline":"material/tag-arrow-right-outline.svg","material-tag-arrow-right":"material/tag-arrow-right.svg","material-tag-arrow-up-outline":"material/tag-arrow-up-outline.svg","material-tag-arrow-up":"material/tag-arrow-up.svg","material-tag-check-outline":"material/tag-check-outline.svg","material-tag-check":"material/tag-check.svg","material-tag-faces":"material/tag-faces.svg","material-tag-heart-outline":"material/tag-heart-outline.svg","material-tag-heart":"material/tag-heart.svg","material-tag-minus-outline":"material/tag-minus-outline.svg","material-tag-minus":"material/tag-minus.svg","material-tag-multiple-outline":"material/tag-multiple-outline.svg","material-tag-multiple":"material/tag-multiple.svg","material-tag-off-outline":"material/tag-off-outline.svg","material-tag-off":"material/tag-off.svg","material-tag-outline":"material/tag-outline.svg","material-tag-plus-outline":"material/tag-plus-outline.svg","material-tag-plus":"material/tag-plus.svg","material-tag-remove-outline":"material/tag-remove-outline.svg","material-tag-remove":"material/tag-remove.svg","material-tag-search-outline":"material/tag-search-outline.svg","material-tag-search":"material/tag-search.svg","material-tag-text-outline":"material/tag-text-outline.svg","material-tag-text":"material/tag-text.svg","material-tag":"material/tag.svg","material-tailwind":"material/tailwind.svg","material-tally-mark-1":"material/tally-mark-1.svg","material-tally-mark-2":"material/tally-mark-2.svg","material-tally-mark-3":"material/tally-mark-3.svg","material-tally-mark-4":"material/tally-mark-4.svg","material-tally-mark-5":"material/tally-mark-5.svg","material-tangram":"material/tangram.svg","material-tank":"material/tank.svg","material-tanker-truck":"material/tanker-truck.svg","material-tape-drive":"material/tape-drive.svg","material-tape-measure":"material/tape-measure.svg","material-target-account":"material/target-account.svg","material-target-variant":"material/target-variant.svg","material-target":"material/target.svg","material-taxi":"material/taxi.svg","material-tea-outline":"material/tea-outline.svg","material-tea":"material/tea.svg","material-teamviewer":"material/teamviewer.svg","material-teddy-bear":"material/teddy-bear.svg","material-telescope":"material/telescope.svg","material-television-ambient-light":"material/television-ambient-light.svg","material-television-box":"material/television-box.svg","material-television-classic-off":"material/television-classic-off.svg","material-television-classic":"material/television-classic.svg","material-television-guide":"material/television-guide.svg","material-television-off":"material/television-off.svg","material-television-pause":"material/television-pause.svg","material-television-play":"material/television-play.svg","material-television-shimmer":"material/television-shimmer.svg","material-television-speaker-off":"material/television-speaker-off.svg","material-television-speaker":"material/television-speaker.svg","material-television-stop":"material/television-stop.svg","material-television":"material/television.svg","material-temperature-celsius":"material/temperature-celsius.svg","material-temperature-fahrenheit":"material/temperature-fahrenheit.svg","material-temperature-kelvin":"material/temperature-kelvin.svg","material-temple-buddhist-outline":"material/temple-buddhist-outline.svg","material-temple-buddhist":"material/temple-buddhist.svg","material-temple-hindu-outline":"material/temple-hindu-outline.svg","material-temple-hindu":"material/temple-hindu.svg","material-tennis-ball":"material/tennis-ball.svg","material-tennis":"material/tennis.svg","material-tent":"material/tent.svg","material-terraform":"material/terraform.svg","material-terrain":"material/terrain.svg","material-test-tube-empty":"material/test-tube-empty.svg","material-test-tube-off":"material/test-tube-off.svg","material-test-tube":"material/test-tube.svg","material-text-account":"material/text-account.svg","material-text-box-check-outline":"material/text-box-check-outline.svg","material-text-box-check":"material/text-box-check.svg","material-text-box-edit-outline":"material/text-box-edit-outline.svg","material-text-box-edit":"material/text-box-edit.svg","material-text-box-minus-outline":"material/text-box-minus-outline.svg","material-text-box-minus":"material/text-box-minus.svg","material-text-box-multiple-outline":"material/text-box-multiple-outline.svg","material-text-box-multiple":"material/text-box-multiple.svg","material-text-box-outline":"material/text-box-outline.svg","material-text-box-plus-outline":"material/text-box-plus-outline.svg","material-text-box-plus":"material/text-box-plus.svg","material-text-box-remove-outline":"material/text-box-remove-outline.svg","material-text-box-remove":"material/text-box-remove.svg","material-text-box-search-outline":"material/text-box-search-outline.svg","material-text-box-search":"material/text-box-search.svg","material-text-box":"material/text-box.svg","material-text-long":"material/text-long.svg","material-text-recognition":"material/text-recognition.svg","material-text-search-variant":"material/text-search-variant.svg","material-text-search":"material/text-search.svg","material-text-shadow":"material/text-shadow.svg","material-text-short":"material/text-short.svg","material-text":"material/text.svg","material-texture-box":"material/texture-box.svg","material-texture":"material/texture.svg","material-theater":"material/theater.svg","material-theme-light-dark":"material/theme-light-dark.svg","material-thermometer-alert":"material/thermometer-alert.svg","material-thermometer-auto":"material/thermometer-auto.svg","material-thermometer-bluetooth":"material/thermometer-bluetooth.svg","material-thermometer-check":"material/thermometer-check.svg","material-thermometer-chevron-down":"material/thermometer-chevron-down.svg","material-thermometer-chevron-up":"material/thermometer-chevron-up.svg","material-thermometer-high":"material/thermometer-high.svg","material-thermometer-lines":"material/thermometer-lines.svg","material-thermometer-low":"material/thermometer-low.svg","material-thermometer-minus":"material/thermometer-minus.svg","material-thermometer-off":"material/thermometer-off.svg","material-thermometer-plus":"material/thermometer-plus.svg","material-thermometer-probe-off":"material/thermometer-probe-off.svg","material-thermometer-probe":"material/thermometer-probe.svg","material-thermometer-water":"material/thermometer-water.svg","material-thermometer":"material/thermometer.svg","material-thermostat-auto":"material/thermostat-auto.svg","material-thermostat-box-auto":"material/thermostat-box-auto.svg","material-thermostat-box":"material/thermostat-box.svg","material-thermostat":"material/thermostat.svg","material-thought-bubble-outline":"material/thought-bubble-outline.svg","material-thought-bubble":"material/thought-bubble.svg","material-thumb-down-outline":"material/thumb-down-outline.svg","material-thumb-down":"material/thumb-down.svg","material-thumb-up-outline":"material/thumb-up-outline.svg","material-thumb-up":"material/thumb-up.svg","material-thumbs-up-down-outline":"material/thumbs-up-down-outline.svg","material-thumbs-up-down":"material/thumbs-up-down.svg","material-ticket-account":"material/ticket-account.svg","material-ticket-confirmation-outline":"material/ticket-confirmation-outline.svg","material-ticket-confirmation":"material/ticket-confirmation.svg","material-ticket-outline":"material/ticket-outline.svg","material-ticket-percent-outline":"material/ticket-percent-outline.svg","material-ticket-percent":"material/ticket-percent.svg","material-ticket":"material/ticket.svg","material-tie":"material/tie.svg","material-tilde-off":"material/tilde-off.svg","material-tilde":"material/tilde.svg","material-timelapse":"material/timelapse.svg","material-timeline-alert-outline":"material/timeline-alert-outline.svg","material-timeline-alert":"material/timeline-alert.svg","material-timeline-check-outline":"material/timeline-check-outline.svg","material-timeline-check":"material/timeline-check.svg","material-timeline-clock-outline":"material/timeline-clock-outline.svg","material-timeline-clock":"material/timeline-clock.svg","material-timeline-minus-outline":"material/timeline-minus-outline.svg","material-timeline-minus":"material/timeline-minus.svg","material-timeline-outline":"material/timeline-outline.svg","material-timeline-plus-outline":"material/timeline-plus-outline.svg","material-timeline-plus":"material/timeline-plus.svg","material-timeline-question-outline":"material/timeline-question-outline.svg","material-timeline-question":"material/timeline-question.svg","material-timeline-remove-outline":"material/timeline-remove-outline.svg","material-timeline-remove":"material/timeline-remove.svg","material-timeline-text-outline":"material/timeline-text-outline.svg","material-timeline-text":"material/timeline-text.svg","material-timeline":"material/timeline.svg","material-timer-10":"material/timer-10.svg","material-timer-3":"material/timer-3.svg","material-timer-alert-outline":"material/timer-alert-outline.svg","material-timer-alert":"material/timer-alert.svg","material-timer-cancel-outline":"material/timer-cancel-outline.svg","material-timer-cancel":"material/timer-cancel.svg","material-timer-check-outline":"material/timer-check-outline.svg","material-timer-check":"material/timer-check.svg","material-timer-cog-outline":"material/timer-cog-outline.svg","material-timer-cog":"material/timer-cog.svg","material-timer-edit-outline":"material/timer-edit-outline.svg","material-timer-edit":"material/timer-edit.svg","material-timer-lock-open-outline":"material/timer-lock-open-outline.svg","material-timer-lock-open":"material/timer-lock-open.svg","material-timer-lock-outline":"material/timer-lock-outline.svg","material-timer-lock":"material/timer-lock.svg","material-timer-marker-outline":"material/timer-marker-outline.svg","material-timer-marker":"material/timer-marker.svg","material-timer-minus-outline":"material/timer-minus-outline.svg","material-timer-minus":"material/timer-minus.svg","material-timer-music-outline":"material/timer-music-outline.svg","material-timer-music":"material/timer-music.svg","material-timer-off-outline":"material/timer-off-outline.svg","material-timer-off":"material/timer-off.svg","material-timer-outline":"material/timer-outline.svg","material-timer-pause-outline":"material/timer-pause-outline.svg","material-timer-pause":"material/timer-pause.svg","material-timer-play-outline":"material/timer-play-outline.svg","material-timer-play":"material/timer-play.svg","material-timer-plus-outline":"material/timer-plus-outline.svg","material-timer-plus":"material/timer-plus.svg","material-timer-refresh-outline":"material/timer-refresh-outline.svg","material-timer-refresh":"material/timer-refresh.svg","material-timer-remove-outline":"material/timer-remove-outline.svg","material-timer-remove":"material/timer-remove.svg","material-timer-sand-complete":"material/timer-sand-complete.svg","material-timer-sand-empty":"material/timer-sand-empty.svg","material-timer-sand-full":"material/timer-sand-full.svg","material-timer-sand-paused":"material/timer-sand-paused.svg","material-timer-sand":"material/timer-sand.svg","material-timer-settings-outline":"material/timer-settings-outline.svg","material-timer-settings":"material/timer-settings.svg","material-timer-star-outline":"material/timer-star-outline.svg","material-timer-star":"material/timer-star.svg","material-timer-stop-outline":"material/timer-stop-outline.svg","material-timer-stop":"material/timer-stop.svg","material-timer-sync-outline":"material/timer-sync-outline.svg","material-timer-sync":"material/timer-sync.svg","material-timer":"material/timer.svg","material-timetable":"material/timetable.svg","material-tire":"material/tire.svg","material-toaster-off":"material/toaster-off.svg","material-toaster-oven":"material/toaster-oven.svg","material-toaster":"material/toaster.svg","material-toggle-switch-off-outline":"material/toggle-switch-off-outline.svg","material-toggle-switch-off":"material/toggle-switch-off.svg","material-toggle-switch-outline":"material/toggle-switch-outline.svg","material-toggle-switch-variant-off":"material/toggle-switch-variant-off.svg","material-toggle-switch-variant":"material/toggle-switch-variant.svg","material-toggle-switch":"material/toggle-switch.svg","material-toilet":"material/toilet.svg","material-toolbox-outline":"material/toolbox-outline.svg","material-toolbox":"material/toolbox.svg","material-tools":"material/tools.svg","material-tooltip-account":"material/tooltip-account.svg","material-tooltip-cellphone":"material/tooltip-cellphone.svg","material-tooltip-check-outline":"material/tooltip-check-outline.svg","material-tooltip-check":"material/tooltip-check.svg","material-tooltip-edit-outline":"material/tooltip-edit-outline.svg","material-tooltip-edit":"material/tooltip-edit.svg","material-tooltip-image-outline":"material/tooltip-image-outline.svg","material-tooltip-image":"material/tooltip-image.svg","material-tooltip-minus-outline":"material/tooltip-minus-outline.svg","material-tooltip-minus":"material/tooltip-minus.svg","material-tooltip-outline":"material/tooltip-outline.svg","material-tooltip-plus-outline":"material/tooltip-plus-outline.svg","material-tooltip-plus":"material/tooltip-plus.svg","material-tooltip-remove-outline":"material/tooltip-remove-outline.svg","material-tooltip-remove":"material/tooltip-remove.svg","material-tooltip-text-outline":"material/tooltip-text-outline.svg","material-tooltip-text":"material/tooltip-text.svg","material-tooltip":"material/tooltip.svg","material-tooth-outline":"material/tooth-outline.svg","material-tooth":"material/tooth.svg","material-toothbrush-electric":"material/toothbrush-electric.svg","material-toothbrush-paste":"material/toothbrush-paste.svg","material-toothbrush":"material/toothbrush.svg","material-torch":"material/torch.svg","material-tortoise":"material/tortoise.svg","material-toslink":"material/toslink.svg","material-tournament":"material/tournament.svg","material-tow-truck":"material/tow-truck.svg","material-tower-beach":"material/tower-beach.svg","material-tower-fire":"material/tower-fire.svg","material-town-hall":"material/town-hall.svg","material-toy-brick-marker-outline":"material/toy-brick-marker-outline.svg","material-toy-brick-marker":"material/toy-brick-marker.svg","material-toy-brick-minus-outline":"material/toy-brick-minus-outline.svg","material-toy-brick-minus":"material/toy-brick-minus.svg","material-toy-brick-outline":"material/toy-brick-outline.svg","material-toy-brick-plus-outline":"material/toy-brick-plus-outline.svg","material-toy-brick-plus":"material/toy-brick-plus.svg","material-toy-brick-remove-outline":"material/toy-brick-remove-outline.svg","material-toy-brick-remove":"material/toy-brick-remove.svg","material-toy-brick-search-outline":"material/toy-brick-search-outline.svg","material-toy-brick-search":"material/toy-brick-search.svg","material-toy-brick":"material/toy-brick.svg","material-track-light-off":"material/track-light-off.svg","material-track-light":"material/track-light.svg","material-trackpad-lock":"material/trackpad-lock.svg","material-trackpad":"material/trackpad.svg","material-tractor-variant":"material/tractor-variant.svg","material-tractor":"material/tractor.svg","material-trademark":"material/trademark.svg","material-traffic-cone":"material/traffic-cone.svg","material-traffic-light-outline":"material/traffic-light-outline.svg","material-traffic-light":"material/traffic-light.svg","material-train-car-autorack":"material/train-car-autorack.svg","material-train-car-box-full":"material/train-car-box-full.svg","material-train-car-box-open":"material/train-car-box-open.svg","material-train-car-box":"material/train-car-box.svg","material-train-car-caboose":"material/train-car-caboose.svg","material-train-car-centerbeam-full":"material/train-car-centerbeam-full.svg","material-train-car-centerbeam":"material/train-car-centerbeam.svg","material-train-car-container":"material/train-car-container.svg","material-train-car-flatbed-car":"material/train-car-flatbed-car.svg","material-train-car-flatbed-tank":"material/train-car-flatbed-tank.svg","material-train-car-flatbed":"material/train-car-flatbed.svg","material-train-car-gondola-full":"material/train-car-gondola-full.svg","material-train-car-gondola":"material/train-car-gondola.svg","material-train-car-hopper-covered":"material/train-car-hopper-covered.svg","material-train-car-hopper-full":"material/train-car-hopper-full.svg","material-train-car-hopper":"material/train-car-hopper.svg","material-train-car-intermodal":"material/train-car-intermodal.svg","material-train-car-passenger-door-open":"material/train-car-passenger-door-open.svg","material-train-car-passenger-door":"material/train-car-passenger-door.svg","material-train-car-passenger-variant":"material/train-car-passenger-variant.svg","material-train-car-passenger":"material/train-car-passenger.svg","material-train-car-tank":"material/train-car-tank.svg","material-train-car":"material/train-car.svg","material-train-variant":"material/train-variant.svg","material-train":"material/train.svg","material-tram-side":"material/tram-side.svg","material-tram":"material/tram.svg","material-transcribe-close":"material/transcribe-close.svg","material-transcribe":"material/transcribe.svg","material-transfer-down":"material/transfer-down.svg","material-transfer-left":"material/transfer-left.svg","material-transfer-right":"material/transfer-right.svg","material-transfer-up":"material/transfer-up.svg","material-transfer":"material/transfer.svg","material-transit-connection-horizontal":"material/transit-connection-horizontal.svg","material-transit-connection-variant":"material/transit-connection-variant.svg","material-transit-connection":"material/transit-connection.svg","material-transit-detour":"material/transit-detour.svg","material-transit-skip":"material/transit-skip.svg","material-transit-transfer":"material/transit-transfer.svg","material-transition-masked":"material/transition-masked.svg","material-transition":"material/transition.svg","material-translate-off":"material/translate-off.svg","material-translate-variant":"material/translate-variant.svg","material-translate":"material/translate.svg","material-transmission-tower-export":"material/transmission-tower-export.svg","material-transmission-tower-import":"material/transmission-tower-import.svg","material-transmission-tower-off":"material/transmission-tower-off.svg","material-transmission-tower":"material/transmission-tower.svg","material-trash-can-outline":"material/trash-can-outline.svg","material-trash-can":"material/trash-can.svg","material-tray-alert":"material/tray-alert.svg","material-tray-arrow-down":"material/tray-arrow-down.svg","material-tray-arrow-up":"material/tray-arrow-up.svg","material-tray-full":"material/tray-full.svg","material-tray-minus":"material/tray-minus.svg","material-tray-plus":"material/tray-plus.svg","material-tray-remove":"material/tray-remove.svg","material-tray":"material/tray.svg","material-treasure-chest":"material/treasure-chest.svg","material-tree-outline":"material/tree-outline.svg","material-tree":"material/tree.svg","material-trello":"material/trello.svg","material-trending-down":"material/trending-down.svg","material-trending-neutral":"material/trending-neutral.svg","material-trending-up":"material/trending-up.svg","material-triangle-outline":"material/triangle-outline.svg","material-triangle-small-down":"material/triangle-small-down.svg","material-triangle-small-up":"material/triangle-small-up.svg","material-triangle-wave":"material/triangle-wave.svg","material-triangle":"material/triangle.svg","material-triforce":"material/triforce.svg","material-trophy-award":"material/trophy-award.svg","material-trophy-broken":"material/trophy-broken.svg","material-trophy-outline":"material/trophy-outline.svg","material-trophy-variant-outline":"material/trophy-variant-outline.svg","material-trophy-variant":"material/trophy-variant.svg","material-trophy":"material/trophy.svg","material-truck-alert-outline":"material/truck-alert-outline.svg","material-truck-alert":"material/truck-alert.svg","material-truck-cargo-container":"material/truck-cargo-container.svg","material-truck-check-outline":"material/truck-check-outline.svg","material-truck-check":"material/truck-check.svg","material-truck-delivery-outline":"material/truck-delivery-outline.svg","material-truck-delivery":"material/truck-delivery.svg","material-truck-fast-outline":"material/truck-fast-outline.svg","material-truck-fast":"material/truck-fast.svg","material-truck-flatbed":"material/truck-flatbed.svg","material-truck-minus-outline":"material/truck-minus-outline.svg","material-truck-minus":"material/truck-minus.svg","material-truck-outline":"material/truck-outline.svg","material-truck-plus-outline":"material/truck-plus-outline.svg","material-truck-plus":"material/truck-plus.svg","material-truck-remove-outline":"material/truck-remove-outline.svg","material-truck-remove":"material/truck-remove.svg","material-truck-snowflake":"material/truck-snowflake.svg","material-truck-trailer":"material/truck-trailer.svg","material-truck":"material/truck.svg","material-trumpet":"material/trumpet.svg","material-tshirt-crew-outline":"material/tshirt-crew-outline.svg","material-tshirt-crew":"material/tshirt-crew.svg","material-tshirt-v-outline":"material/tshirt-v-outline.svg","material-tshirt-v":"material/tshirt-v.svg","material-tsunami":"material/tsunami.svg","material-tumble-dryer-alert":"material/tumble-dryer-alert.svg","material-tumble-dryer-off":"material/tumble-dryer-off.svg","material-tumble-dryer":"material/tumble-dryer.svg","material-tune-variant":"material/tune-variant.svg","material-tune-vertical-variant":"material/tune-vertical-variant.svg","material-tune-vertical":"material/tune-vertical.svg","material-tune":"material/tune.svg","material-tunnel-outline":"material/tunnel-outline.svg","material-tunnel":"material/tunnel.svg","material-turbine":"material/turbine.svg","material-turkey":"material/turkey.svg","material-turnstile-outline":"material/turnstile-outline.svg","material-turnstile":"material/turnstile.svg","material-turtle":"material/turtle.svg","material-twitch":"material/twitch.svg","material-twitter":"material/twitter.svg","material-two-factor-authentication":"material/two-factor-authentication.svg","material-typewriter":"material/typewriter.svg","material-ubisoft":"material/ubisoft.svg","material-ubuntu":"material/ubuntu.svg","material-ufo-outline":"material/ufo-outline.svg","material-ufo":"material/ufo.svg","material-ultra-high-definition":"material/ultra-high-definition.svg","material-umbraco":"material/umbraco.svg","material-umbrella-beach-outline":"material/umbrella-beach-outline.svg","material-umbrella-beach":"material/umbrella-beach.svg","material-umbrella-closed-outline":"material/umbrella-closed-outline.svg","material-umbrella-closed-variant":"material/umbrella-closed-variant.svg","material-umbrella-closed":"material/umbrella-closed.svg","material-umbrella-outline":"material/umbrella-outline.svg","material-umbrella":"material/umbrella.svg","material-undo-variant":"material/undo-variant.svg","material-undo":"material/undo.svg","material-unfold-less-horizontal":"material/unfold-less-horizontal.svg","material-unfold-less-vertical":"material/unfold-less-vertical.svg","material-unfold-more-horizontal":"material/unfold-more-horizontal.svg","material-unfold-more-vertical":"material/unfold-more-vertical.svg","material-ungroup":"material/ungroup.svg","material-unicode":"material/unicode.svg","material-unicorn-variant":"material/unicorn-variant.svg","material-unicorn":"material/unicorn.svg","material-unicycle":"material/unicycle.svg","material-unity":"material/unity.svg","material-unreal":"material/unreal.svg","material-update":"material/update.svg","material-upload-lock-outline":"material/upload-lock-outline.svg","material-upload-lock":"material/upload-lock.svg","material-upload-multiple":"material/upload-multiple.svg","material-upload-network-outline":"material/upload-network-outline.svg","material-upload-network":"material/upload-network.svg","material-upload-off-outline":"material/upload-off-outline.svg","material-upload-off":"material/upload-off.svg","material-upload-outline":"material/upload-outline.svg","material-upload":"material/upload.svg","material-usb-flash-drive-outline":"material/usb-flash-drive-outline.svg","material-usb-flash-drive":"material/usb-flash-drive.svg","material-usb-port":"material/usb-port.svg","material-usb":"material/usb.svg","material-vacuum-outline":"material/vacuum-outline.svg","material-vacuum":"material/vacuum.svg","material-valve-closed":"material/valve-closed.svg","material-valve-open":"material/valve-open.svg","material-valve":"material/valve.svg","material-van-passenger":"material/van-passenger.svg","material-van-utility":"material/van-utility.svg","material-vanish-quarter":"material/vanish-quarter.svg","material-vanish":"material/vanish.svg","material-vanity-light":"material/vanity-light.svg","material-variable-box":"material/variable-box.svg","material-variable":"material/variable.svg","material-vector-arrange-above":"material/vector-arrange-above.svg","material-vector-arrange-below":"material/vector-arrange-below.svg","material-vector-bezier":"material/vector-bezier.svg","material-vector-circle-variant":"material/vector-circle-variant.svg","material-vector-circle":"material/vector-circle.svg","material-vector-combine":"material/vector-combine.svg","material-vector-curve":"material/vector-curve.svg","material-vector-difference-ab":"material/vector-difference-ab.svg","material-vector-difference-ba":"material/vector-difference-ba.svg","material-vector-difference":"material/vector-difference.svg","material-vector-ellipse":"material/vector-ellipse.svg","material-vector-intersection":"material/vector-intersection.svg","material-vector-line":"material/vector-line.svg","material-vector-link":"material/vector-link.svg","material-vector-point-edit":"material/vector-point-edit.svg","material-vector-point-minus":"material/vector-point-minus.svg","material-vector-point-plus":"material/vector-point-plus.svg","material-vector-point-select":"material/vector-point-select.svg","material-vector-point":"material/vector-point.svg","material-vector-polygon-variant":"material/vector-polygon-variant.svg","material-vector-polygon":"material/vector-polygon.svg","material-vector-polyline-edit":"material/vector-polyline-edit.svg","material-vector-polyline-minus":"material/vector-polyline-minus.svg","material-vector-polyline-plus":"material/vector-polyline-plus.svg","material-vector-polyline-remove":"material/vector-polyline-remove.svg","material-vector-polyline":"material/vector-polyline.svg","material-vector-radius":"material/vector-radius.svg","material-vector-rectangle":"material/vector-rectangle.svg","material-vector-selection":"material/vector-selection.svg","material-vector-square-close":"material/vector-square-close.svg","material-vector-square-edit":"material/vector-square-edit.svg","material-vector-square-minus":"material/vector-square-minus.svg","material-vector-square-open":"material/vector-square-open.svg","material-vector-square-plus":"material/vector-square-plus.svg","material-vector-square-remove":"material/vector-square-remove.svg","material-vector-square":"material/vector-square.svg","material-vector-triangle":"material/vector-triangle.svg","material-vector-union":"material/vector-union.svg","material-vhs":"material/vhs.svg","material-vibrate-off":"material/vibrate-off.svg","material-vibrate":"material/vibrate.svg","material-video-2d":"material/video-2d.svg","material-video-3d-off":"material/video-3d-off.svg","material-video-3d-variant":"material/video-3d-variant.svg","material-video-3d":"material/video-3d.svg","material-video-4k-box":"material/video-4k-box.svg","material-video-account":"material/video-account.svg","material-video-box-off":"material/video-box-off.svg","material-video-box":"material/video-box.svg","material-video-check-outline":"material/video-check-outline.svg","material-video-check":"material/video-check.svg","material-video-high-definition":"material/video-high-definition.svg","material-video-image":"material/video-image.svg","material-video-input-antenna":"material/video-input-antenna.svg","material-video-input-component":"material/video-input-component.svg","material-video-input-hdmi":"material/video-input-hdmi.svg","material-video-input-scart":"material/video-input-scart.svg","material-video-input-svideo":"material/video-input-svideo.svg","material-video-marker-outline":"material/video-marker-outline.svg","material-video-marker":"material/video-marker.svg","material-video-minus-outline":"material/video-minus-outline.svg","material-video-minus":"material/video-minus.svg","material-video-off-outline":"material/video-off-outline.svg","material-video-off":"material/video-off.svg","material-video-outline":"material/video-outline.svg","material-video-plus-outline":"material/video-plus-outline.svg","material-video-plus":"material/video-plus.svg","material-video-stabilization":"material/video-stabilization.svg","material-video-switch-outline":"material/video-switch-outline.svg","material-video-switch":"material/video-switch.svg","material-video-vintage":"material/video-vintage.svg","material-video-wireless-outline":"material/video-wireless-outline.svg","material-video-wireless":"material/video-wireless.svg","material-video":"material/video.svg","material-view-agenda-outline":"material/view-agenda-outline.svg","material-view-agenda":"material/view-agenda.svg","material-view-array-outline":"material/view-array-outline.svg","material-view-array":"material/view-array.svg","material-view-carousel-outline":"material/view-carousel-outline.svg","material-view-carousel":"material/view-carousel.svg","material-view-column-outline":"material/view-column-outline.svg","material-view-column":"material/view-column.svg","material-view-comfy-outline":"material/view-comfy-outline.svg","material-view-comfy":"material/view-comfy.svg","material-view-compact-outline":"material/view-compact-outline.svg","material-view-compact":"material/view-compact.svg","material-view-dashboard-edit-outline":"material/view-dashboard-edit-outline.svg","material-view-dashboard-edit":"material/view-dashboard-edit.svg","material-view-dashboard-outline":"material/view-dashboard-outline.svg","material-view-dashboard-variant-outline":"material/view-dashboard-variant-outline.svg","material-view-dashboard-variant":"material/view-dashboard-variant.svg","material-view-dashboard":"material/view-dashboard.svg","material-view-day-outline":"material/view-day-outline.svg","material-view-day":"material/view-day.svg","material-view-gallery-outline":"material/view-gallery-outline.svg","material-view-gallery":"material/view-gallery.svg","material-view-grid-outline":"material/view-grid-outline.svg","material-view-grid-plus-outline":"material/view-grid-plus-outline.svg","material-view-grid-plus":"material/view-grid-plus.svg","material-view-grid":"material/view-grid.svg","material-view-headline":"material/view-headline.svg","material-view-list-outline":"material/view-list-outline.svg","material-view-list":"material/view-list.svg","material-view-module-outline":"material/view-module-outline.svg","material-view-module":"material/view-module.svg","material-view-parallel-outline":"material/view-parallel-outline.svg","material-view-parallel":"material/view-parallel.svg","material-view-quilt-outline":"material/view-quilt-outline.svg","material-view-quilt":"material/view-quilt.svg","material-view-sequential-outline":"material/view-sequential-outline.svg","material-view-sequential":"material/view-sequential.svg","material-view-split-horizontal":"material/view-split-horizontal.svg","material-view-split-vertical":"material/view-split-vertical.svg","material-view-stream-outline":"material/view-stream-outline.svg","material-view-stream":"material/view-stream.svg","material-view-week-outline":"material/view-week-outline.svg","material-view-week":"material/view-week.svg","material-vimeo":"material/vimeo.svg","material-violin":"material/violin.svg","material-virtual-reality":"material/virtual-reality.svg","material-virus-off-outline":"material/virus-off-outline.svg","material-virus-off":"material/virus-off.svg","material-virus-outline":"material/virus-outline.svg","material-virus":"material/virus.svg","material-vlc":"material/vlc.svg","material-voicemail":"material/voicemail.svg","material-volcano-outline":"material/volcano-outline.svg","material-volcano":"material/volcano.svg","material-volleyball":"material/volleyball.svg","material-volume-equal":"material/volume-equal.svg","material-volume-high":"material/volume-high.svg","material-volume-low":"material/volume-low.svg","material-volume-medium":"material/volume-medium.svg","material-volume-minus":"material/volume-minus.svg","material-volume-mute":"material/volume-mute.svg","material-volume-off":"material/volume-off.svg","material-volume-plus":"material/volume-plus.svg","material-volume-source":"material/volume-source.svg","material-volume-variant-off":"material/volume-variant-off.svg","material-volume-vibrate":"material/volume-vibrate.svg","material-vote-outline":"material/vote-outline.svg","material-vote":"material/vote.svg","material-vpn":"material/vpn.svg","material-vuejs":"material/vuejs.svg","material-vuetify":"material/vuetify.svg","material-walk":"material/walk.svg","material-wall-fire":"material/wall-fire.svg","material-wall-sconce-flat-outline":"material/wall-sconce-flat-outline.svg","material-wall-sconce-flat-variant-outline":"material/wall-sconce-flat-variant-outline.svg","material-wall-sconce-flat-variant":"material/wall-sconce-flat-variant.svg","material-wall-sconce-flat":"material/wall-sconce-flat.svg","material-wall-sconce-outline":"material/wall-sconce-outline.svg","material-wall-sconce-round-outline":"material/wall-sconce-round-outline.svg","material-wall-sconce-round-variant-outline":"material/wall-sconce-round-variant-outline.svg","material-wall-sconce-round-variant":"material/wall-sconce-round-variant.svg","material-wall-sconce-round":"material/wall-sconce-round.svg","material-wall-sconce":"material/wall-sconce.svg","material-wall":"material/wall.svg","material-wallet-giftcard":"material/wallet-giftcard.svg","material-wallet-membership":"material/wallet-membership.svg","material-wallet-outline":"material/wallet-outline.svg","material-wallet-plus-outline":"material/wallet-plus-outline.svg","material-wallet-plus":"material/wallet-plus.svg","material-wallet-travel":"material/wallet-travel.svg","material-wallet":"material/wallet.svg","material-wallpaper":"material/wallpaper.svg","material-wan":"material/wan.svg","material-wardrobe-outline":"material/wardrobe-outline.svg","material-wardrobe":"material/wardrobe.svg","material-registry":"material/registry.svg","material-washing-machine-alert":"material/washing-machine-alert.svg","material-washing-machine-off":"material/washing-machine-off.svg","material-washing-machine":"material/washing-machine.svg","material-watch-export-variant":"material/watch-export-variant.svg","material-watch-export":"material/watch-export.svg","material-watch-import-variant":"material/watch-import-variant.svg","material-watch-import":"material/watch-import.svg","material-watch-variant":"material/watch-variant.svg","material-watch-vibrate-off":"material/watch-vibrate-off.svg","material-watch-vibrate":"material/watch-vibrate.svg","material-watch":"material/watch.svg","material-water-alert-outline":"material/water-alert-outline.svg","material-water-alert":"material/water-alert.svg","material-water-boiler-alert":"material/water-boiler-alert.svg","material-water-boiler-auto":"material/water-boiler-auto.svg","material-water-boiler-off":"material/water-boiler-off.svg","material-water-boiler":"material/water-boiler.svg","material-water-check-outline":"material/water-check-outline.svg","material-water-check":"material/water-check.svg","material-water-circle":"material/water-circle.svg","material-water-minus-outline":"material/water-minus-outline.svg","material-water-minus":"material/water-minus.svg","material-water-off-outline":"material/water-off-outline.svg","material-water-off":"material/water-off.svg","material-water-opacity":"material/water-opacity.svg","material-water-outline":"material/water-outline.svg","material-water-percent-alert":"material/water-percent-alert.svg","material-water-percent":"material/water-percent.svg","material-water-plus-outline":"material/water-plus-outline.svg","material-water-plus":"material/water-plus.svg","material-water-polo":"material/water-polo.svg","material-water-pump-off":"material/water-pump-off.svg","material-water-pump":"material/water-pump.svg","material-water-remove-outline":"material/water-remove-outline.svg","material-water-remove":"material/water-remove.svg","material-water-sync":"material/water-sync.svg","material-water-thermometer-outline":"material/water-thermometer-outline.svg","material-water-thermometer":"material/water-thermometer.svg","material-water-well-outline":"material/water-well-outline.svg","material-water-well":"material/water-well.svg","material-water":"material/water.svg","material-waterfall":"material/waterfall.svg","material-watering-can-outline":"material/watering-can-outline.svg","material-watering-can":"material/watering-can.svg","material-watermark":"material/watermark.svg","material-wave":"material/wave.svg","material-waveform":"material/waveform.svg","material-waves-arrow-left":"material/waves-arrow-left.svg","material-waves-arrow-right":"material/waves-arrow-right.svg","material-waves-arrow-up":"material/waves-arrow-up.svg","material-waves":"material/waves.svg","material-waze":"material/waze.svg","material-weather-cloudy-alert":"material/weather-cloudy-alert.svg","material-weather-cloudy-arrow-right":"material/weather-cloudy-arrow-right.svg","material-weather-cloudy-clock":"material/weather-cloudy-clock.svg","material-weather-cloudy":"material/weather-cloudy.svg","material-weather-dust":"material/weather-dust.svg","material-weather-fog":"material/weather-fog.svg","material-weather-hail":"material/weather-hail.svg","material-weather-hazy":"material/weather-hazy.svg","material-weather-hurricane":"material/weather-hurricane.svg","material-weather-lightning-rainy":"material/weather-lightning-rainy.svg","material-weather-lightning":"material/weather-lightning.svg","material-weather-night-partly-cloudy":"material/weather-night-partly-cloudy.svg","material-weather-night":"material/weather-night.svg","material-weather-partly-cloudy":"material/weather-partly-cloudy.svg","material-weather-partly-lightning":"material/weather-partly-lightning.svg","material-weather-partly-rainy":"material/weather-partly-rainy.svg","material-weather-partly-snowy-rainy":"material/weather-partly-snowy-rainy.svg","material-weather-partly-snowy":"material/weather-partly-snowy.svg","material-weather-pouring":"material/weather-pouring.svg","material-weather-rainy":"material/weather-rainy.svg","material-weather-snowy-heavy":"material/weather-snowy-heavy.svg","material-weather-snowy-rainy":"material/weather-snowy-rainy.svg","material-weather-snowy":"material/weather-snowy.svg","material-weather-sunny-alert":"material/weather-sunny-alert.svg","material-weather-sunny-off":"material/weather-sunny-off.svg","material-weather-sunny":"material/weather-sunny.svg","material-weather-sunset-down":"material/weather-sunset-down.svg","material-weather-sunset-up":"material/weather-sunset-up.svg","material-weather-sunset":"material/weather-sunset.svg","material-weather-tornado":"material/weather-tornado.svg","material-weather-windy-variant":"material/weather-windy-variant.svg","material-weather-windy":"material/weather-windy.svg","material-web-box":"material/web-box.svg","material-web-cancel":"material/web-cancel.svg","material-web-check":"material/web-check.svg","material-web-clock":"material/web-clock.svg","material-web-minus":"material/web-minus.svg","material-web-off":"material/web-off.svg","material-web-plus":"material/web-plus.svg","material-web-refresh":"material/web-refresh.svg","material-web-remove":"material/web-remove.svg","material-web-sync":"material/web-sync.svg","material-web":"material/web.svg","material-webcam-off":"material/webcam-off.svg","material-webcam":"material/webcam.svg","material-webhook":"material/webhook.svg","material-webpack":"material/webpack.svg","material-webrtc":"material/webrtc.svg","material-wechat":"material/wechat.svg","material-weight-gram":"material/weight-gram.svg","material-weight-kilogram":"material/weight-kilogram.svg","material-weight-lifter":"material/weight-lifter.svg","material-weight-pound":"material/weight-pound.svg","material-weight":"material/weight.svg","material-whatsapp":"material/whatsapp.svg","material-wheel-barrow":"material/wheel-barrow.svg","material-wheelchair-accessibility":"material/wheelchair-accessibility.svg","material-wheelchair":"material/wheelchair.svg","material-whistle-outline":"material/whistle-outline.svg","material-whistle":"material/whistle.svg","material-white-balance-auto":"material/white-balance-auto.svg","material-white-balance-incandescent":"material/white-balance-incandescent.svg","material-white-balance-iridescent":"material/white-balance-iridescent.svg","material-white-balance-sunny":"material/white-balance-sunny.svg","material-widgets-outline":"material/widgets-outline.svg","material-widgets":"material/widgets.svg","material-wifi-alert":"material/wifi-alert.svg","material-wifi-arrow-down":"material/wifi-arrow-down.svg","material-wifi-arrow-left-right":"material/wifi-arrow-left-right.svg","material-wifi-arrow-left":"material/wifi-arrow-left.svg","material-wifi-arrow-right":"material/wifi-arrow-right.svg","material-wifi-arrow-up-down":"material/wifi-arrow-up-down.svg","material-wifi-arrow-up":"material/wifi-arrow-up.svg","material-wifi-cancel":"material/wifi-cancel.svg","material-wifi-check":"material/wifi-check.svg","material-wifi-cog":"material/wifi-cog.svg","material-wifi-lock-open":"material/wifi-lock-open.svg","material-wifi-lock":"material/wifi-lock.svg","material-wifi-marker":"material/wifi-marker.svg","material-wifi-minus":"material/wifi-minus.svg","material-wifi-off":"material/wifi-off.svg","material-wifi-plus":"material/wifi-plus.svg","material-wifi-refresh":"material/wifi-refresh.svg","material-wifi-remove":"material/wifi-remove.svg","material-wifi-settings":"material/wifi-settings.svg","material-wifi-star":"material/wifi-star.svg","material-wifi-strength-1-alert":"material/wifi-strength-1-alert.svg","material-wifi-strength-1-lock-open":"material/wifi-strength-1-lock-open.svg","material-wifi-strength-1-lock":"material/wifi-strength-1-lock.svg","material-wifi-strength-1":"material/wifi-strength-1.svg","material-wifi-strength-2-alert":"material/wifi-strength-2-alert.svg","material-wifi-strength-2-lock-open":"material/wifi-strength-2-lock-open.svg","material-wifi-strength-2-lock":"material/wifi-strength-2-lock.svg","material-wifi-strength-2":"material/wifi-strength-2.svg","material-wifi-strength-3-alert":"material/wifi-strength-3-alert.svg","material-wifi-strength-3-lock-open":"material/wifi-strength-3-lock-open.svg","material-wifi-strength-3-lock":"material/wifi-strength-3-lock.svg","material-wifi-strength-3":"material/wifi-strength-3.svg","material-wifi-strength-4-alert":"material/wifi-strength-4-alert.svg","material-wifi-strength-4-lock-open":"material/wifi-strength-4-lock-open.svg","material-wifi-strength-4-lock":"material/wifi-strength-4-lock.svg","material-wifi-strength-4":"material/wifi-strength-4.svg","material-wifi-strength-alert-outline":"material/wifi-strength-alert-outline.svg","material-wifi-strength-lock-open-outline":"material/wifi-strength-lock-open-outline.svg","material-wifi-strength-lock-outline":"material/wifi-strength-lock-outline.svg","material-wifi-strength-off-outline":"material/wifi-strength-off-outline.svg","material-wifi-strength-off":"material/wifi-strength-off.svg","material-wifi-strength-outline":"material/wifi-strength-outline.svg","material-wifi-sync":"material/wifi-sync.svg","material-wifi":"material/wifi.svg","material-wikipedia":"material/wikipedia.svg","material-wind-power-outline":"material/wind-power-outline.svg","material-wind-power":"material/wind-power.svg","material-wind-turbine-alert":"material/wind-turbine-alert.svg","material-wind-turbine-check":"material/wind-turbine-check.svg","material-wind-turbine":"material/wind-turbine.svg","material-window-close":"material/window-close.svg","material-window-closed-variant":"material/window-closed-variant.svg","material-window-closed":"material/window-closed.svg","material-window-maximize":"material/window-maximize.svg","material-window-minimize":"material/window-minimize.svg","material-window-open-variant":"material/window-open-variant.svg","material-window-open":"material/window-open.svg","material-window-restore":"material/window-restore.svg","material-window-shutter-alert":"material/window-shutter-alert.svg","material-window-shutter-auto":"material/window-shutter-auto.svg","material-window-shutter-cog":"material/window-shutter-cog.svg","material-window-shutter-open":"material/window-shutter-open.svg","material-window-shutter-settings":"material/window-shutter-settings.svg","material-window-shutter":"material/window-shutter.svg","material-windsock":"material/windsock.svg","material-wiper-wash-alert":"material/wiper-wash-alert.svg","material-wiper-wash":"material/wiper-wash.svg","material-wiper":"material/wiper.svg","material-wizard-hat":"material/wizard-hat.svg","material-wordpress":"material/wordpress.svg","material-wrap-disabled":"material/wrap-disabled.svg","material-wrap":"material/wrap.svg","material-wrench-check-outline":"material/wrench-check-outline.svg","material-wrench-check":"material/wrench-check.svg","material-wrench-clock-outline":"material/wrench-clock-outline.svg","material-wrench-clock":"material/wrench-clock.svg","material-wrench-cog-outline":"material/wrench-cog-outline.svg","material-wrench-cog":"material/wrench-cog.svg","material-wrench-outline":"material/wrench-outline.svg","material-wrench":"material/wrench.svg","material-xamarin":"material/xamarin.svg","material-xml":"material/xml.svg","material-xmpp":"material/xmpp.svg","material-yahoo":"material/yahoo.svg","material-yeast":"material/yeast.svg","material-yin-yang":"material/yin-yang.svg","material-yoga":"material/yoga.svg","material-youtube-gaming":"material/youtube-gaming.svg","material-youtube-studio":"material/youtube-studio.svg","material-youtube-subscription":"material/youtube-subscription.svg","material-youtube-tv":"material/youtube-tv.svg","material-youtube":"material/youtube.svg","material-yurt":"material/yurt.svg","material-z-wave":"material/z-wave.svg","material-zend":"material/zend.svg","material-zigbee":"material/zigbee.svg","material-zip-box-outline":"material/zip-box-outline.svg","material-zip-box":"material/zip-box.svg","material-zip-disk":"material/zip-disk.svg","material-zodiac-aquarius":"material/zodiac-aquarius.svg","material-zodiac-aries":"material/zodiac-aries.svg","material-zodiac-cancer":"material/zodiac-cancer.svg","material-zodiac-capricorn":"material/zodiac-capricorn.svg","material-zodiac-gemini":"material/zodiac-gemini.svg","material-zodiac-leo":"material/zodiac-leo.svg","material-zodiac-libra":"material/zodiac-libra.svg","material-zodiac-pisces":"material/zodiac-pisces.svg","material-zodiac-sagittarius":"material/zodiac-sagittarius.svg","material-zodiac-scorpio":"material/zodiac-scorpio.svg","material-zodiac-taurus":"material/zodiac-taurus.svg","material-zodiac-virgo":"material/zodiac-virgo.svg","octicons-accessibility-16":"octicons/accessibility-16.svg","octicons-alert-16":"octicons/alert-16.svg","octicons-alert-24":"octicons/alert-24.svg","octicons-alert-fill-12":"octicons/alert-fill-12.svg","octicons-apps-16":"octicons/apps-16.svg","octicons-archive-16":"octicons/archive-16.svg","octicons-archive-24":"octicons/archive-24.svg","octicons-arrow-both-16":"octicons/arrow-both-16.svg","octicons-arrow-both-24":"octicons/arrow-both-24.svg","octicons-arrow-down-16":"octicons/arrow-down-16.svg","octicons-arrow-down-24":"octicons/arrow-down-24.svg","octicons-arrow-down-left-24":"octicons/arrow-down-left-24.svg","octicons-arrow-down-right-24":"octicons/arrow-down-right-24.svg","octicons-arrow-left-16":"octicons/arrow-left-16.svg","octicons-arrow-left-24":"octicons/arrow-left-24.svg","octicons-arrow-right-16":"octicons/arrow-right-16.svg","octicons-arrow-right-24":"octicons/arrow-right-24.svg","octicons-arrow-switch-16":"octicons/arrow-switch-16.svg","octicons-arrow-switch-24":"octicons/arrow-switch-24.svg","octicons-arrow-up-16":"octicons/arrow-up-16.svg","octicons-arrow-up-24":"octicons/arrow-up-24.svg","octicons-arrow-up-left-24":"octicons/arrow-up-left-24.svg","octicons-arrow-up-right-24":"octicons/arrow-up-right-24.svg","octicons-beaker-16":"octicons/beaker-16.svg","octicons-beaker-24":"octicons/beaker-24.svg","octicons-bell-16":"octicons/bell-16.svg","octicons-bell-24":"octicons/bell-24.svg","octicons-bell-fill-16":"octicons/bell-fill-16.svg","octicons-bell-fill-24":"octicons/bell-fill-24.svg","octicons-bell-slash-16":"octicons/bell-slash-16.svg","octicons-bell-slash-24":"octicons/bell-slash-24.svg","octicons-blocked-16":"octicons/blocked-16.svg","octicons-blocked-24":"octicons/blocked-24.svg","octicons-bold-16":"octicons/bold-16.svg","octicons-bold-24":"octicons/bold-24.svg","octicons-book-16":"octicons/book-16.svg","octicons-book-24":"octicons/book-24.svg","octicons-bookmark-16":"octicons/bookmark-16.svg","octicons-bookmark-24":"octicons/bookmark-24.svg","octicons-bookmark-fill-24":"octicons/bookmark-fill-24.svg","octicons-bookmark-slash-16":"octicons/bookmark-slash-16.svg","octicons-bookmark-slash-24":"octicons/bookmark-slash-24.svg","octicons-bookmark-slash-fill-24":"octicons/bookmark-slash-fill-24.svg","octicons-briefcase-16":"octicons/briefcase-16.svg","octicons-briefcase-24":"octicons/briefcase-24.svg","octicons-broadcast-16":"octicons/broadcast-16.svg","octicons-broadcast-24":"octicons/broadcast-24.svg","octicons-browser-16":"octicons/browser-16.svg","octicons-browser-24":"octicons/browser-24.svg","octicons-bug-16":"octicons/bug-16.svg","octicons-bug-24":"octicons/bug-24.svg","octicons-cache-16":"octicons/cache-16.svg","octicons-calendar-16":"octicons/calendar-16.svg","octicons-calendar-24":"octicons/calendar-24.svg","octicons-check-16":"octicons/check-16.svg","octicons-check-24":"octicons/check-24.svg","octicons-check-circle-16":"octicons/check-circle-16.svg","octicons-check-circle-24":"octicons/check-circle-24.svg","octicons-check-circle-fill-12":"octicons/check-circle-fill-12.svg","octicons-check-circle-fill-16":"octicons/check-circle-fill-16.svg","octicons-check-circle-fill-24":"octicons/check-circle-fill-24.svg","octicons-checkbox-16":"octicons/checkbox-16.svg","octicons-checkbox-24":"octicons/checkbox-24.svg","octicons-checklist-16":"octicons/checklist-16.svg","octicons-checklist-24":"octicons/checklist-24.svg","octicons-chevron-down-16":"octicons/chevron-down-16.svg","octicons-chevron-down-24":"octicons/chevron-down-24.svg","octicons-chevron-left-16":"octicons/chevron-left-16.svg","octicons-chevron-left-24":"octicons/chevron-left-24.svg","octicons-chevron-right-16":"octicons/chevron-right-16.svg","octicons-chevron-right-24":"octicons/chevron-right-24.svg","octicons-chevron-up-16":"octicons/chevron-up-16.svg","octicons-chevron-up-24":"octicons/chevron-up-24.svg","octicons-circle-16":"octicons/circle-16.svg","octicons-circle-24":"octicons/circle-24.svg","octicons-circle-slash-16":"octicons/circle-slash-16.svg","octicons-circle-slash-24":"octicons/circle-slash-24.svg","octicons-clock-16":"octicons/clock-16.svg","octicons-clock-24":"octicons/clock-24.svg","octicons-cloud-16":"octicons/cloud-16.svg","octicons-cloud-24":"octicons/cloud-24.svg","octicons-cloud-offline-16":"octicons/cloud-offline-16.svg","octicons-cloud-offline-24":"octicons/cloud-offline-24.svg","octicons-code-16":"octicons/code-16.svg","octicons-code-24":"octicons/code-24.svg","octicons-code-of-conduct-16":"octicons/code-of-conduct-16.svg","octicons-code-of-conduct-24":"octicons/code-of-conduct-24.svg","octicons-code-review-16":"octicons/code-review-16.svg","octicons-code-review-24":"octicons/code-review-24.svg","octicons-code-square-16":"octicons/code-square-16.svg","octicons-code-square-24":"octicons/code-square-24.svg","octicons-codescan-16":"octicons/codescan-16.svg","octicons-codescan-24":"octicons/codescan-24.svg","octicons-codescan-checkmark-16":"octicons/codescan-checkmark-16.svg","octicons-codescan-checkmark-24":"octicons/codescan-checkmark-24.svg","octicons-codespaces-16":"octicons/codespaces-16.svg","octicons-codespaces-24":"octicons/codespaces-24.svg","octicons-columns-16":"octicons/columns-16.svg","octicons-columns-24":"octicons/columns-24.svg","octicons-command-palette-16":"octicons/command-palette-16.svg","octicons-command-palette-24":"octicons/command-palette-24.svg","octicons-comment-16":"octicons/comment-16.svg","octicons-comment-24":"octicons/comment-24.svg","octicons-comment-discussion-16":"octicons/comment-discussion-16.svg","octicons-comment-discussion-24":"octicons/comment-discussion-24.svg","octicons-commit-24":"octicons/commit-24.svg","octicons-container-16":"octicons/container-16.svg","octicons-container-24":"octicons/container-24.svg","octicons-copilot-16":"octicons/copilot-16.svg","octicons-copilot-24":"octicons/copilot-24.svg","octicons-copilot-48":"octicons/copilot-48.svg","octicons-copilot-96":"octicons/copilot-96.svg","octicons-copilot-error-16":"octicons/copilot-error-16.svg","octicons-copilot-warning-16":"octicons/copilot-warning-16.svg","octicons-copy-16":"octicons/copy-16.svg","octicons-copy-24":"octicons/copy-24.svg","octicons-cpu-16":"octicons/cpu-16.svg","octicons-cpu-24":"octicons/cpu-24.svg","octicons-credit-card-16":"octicons/credit-card-16.svg","octicons-credit-card-24":"octicons/credit-card-24.svg","octicons-cross-reference-16":"octicons/cross-reference-16.svg","octicons-cross-reference-24":"octicons/cross-reference-24.svg","octicons-dash-16":"octicons/dash-16.svg","octicons-dash-24":"octicons/dash-24.svg","octicons-database-16":"octicons/database-16.svg","octicons-database-24":"octicons/database-24.svg","octicons-dependabot-16":"octicons/dependabot-16.svg","octicons-dependabot-24":"octicons/dependabot-24.svg","octicons-desktop-download-16":"octicons/desktop-download-16.svg","octicons-desktop-download-24":"octicons/desktop-download-24.svg","octicons-device-camera-16":"octicons/device-camera-16.svg","octicons-device-camera-video-16":"octicons/device-camera-video-16.svg","octicons-device-camera-video-24":"octicons/device-camera-video-24.svg","octicons-device-desktop-16":"octicons/device-desktop-16.svg","octicons-device-desktop-24":"octicons/device-desktop-24.svg","octicons-device-mobile-16":"octicons/device-mobile-16.svg","octicons-device-mobile-24":"octicons/device-mobile-24.svg","octicons-diamond-16":"octicons/diamond-16.svg","octicons-diamond-24":"octicons/diamond-24.svg","octicons-diff-16":"octicons/diff-16.svg","octicons-diff-24":"octicons/diff-24.svg","octicons-diff-added-16":"octicons/diff-added-16.svg","octicons-diff-ignored-16":"octicons/diff-ignored-16.svg","octicons-diff-modified-16":"octicons/diff-modified-16.svg","octicons-diff-removed-16":"octicons/diff-removed-16.svg","octicons-diff-renamed-16":"octicons/diff-renamed-16.svg","octicons-dot-16":"octicons/dot-16.svg","octicons-dot-24":"octicons/dot-24.svg","octicons-dot-fill-16":"octicons/dot-fill-16.svg","octicons-dot-fill-24":"octicons/dot-fill-24.svg","octicons-download-16":"octicons/download-16.svg","octicons-download-24":"octicons/download-24.svg","octicons-duplicate-16":"octicons/duplicate-16.svg","octicons-duplicate-24":"octicons/duplicate-24.svg","octicons-ellipsis-16":"octicons/ellipsis-16.svg","octicons-eye-16":"octicons/eye-16.svg","octicons-eye-24":"octicons/eye-24.svg","octicons-eye-closed-16":"octicons/eye-closed-16.svg","octicons-eye-closed-24":"octicons/eye-closed-24.svg","octicons-feed-discussion-16":"octicons/feed-discussion-16.svg","octicons-feed-forked-16":"octicons/feed-forked-16.svg","octicons-feed-heart-16":"octicons/feed-heart-16.svg","octicons-feed-merged-16":"octicons/feed-merged-16.svg","octicons-feed-person-16":"octicons/feed-person-16.svg","octicons-feed-repo-16":"octicons/feed-repo-16.svg","octicons-feed-rocket-16":"octicons/feed-rocket-16.svg","octicons-feed-star-16":"octicons/feed-star-16.svg","octicons-feed-tag-16":"octicons/feed-tag-16.svg","octicons-feed-trophy-16":"octicons/feed-trophy-16.svg","octicons-file-16":"octicons/file-16.svg","octicons-file-24":"octicons/file-24.svg","octicons-file-added-16":"octicons/file-added-16.svg","octicons-file-badge-16":"octicons/file-badge-16.svg","octicons-file-binary-16":"octicons/file-binary-16.svg","octicons-file-binary-24":"octicons/file-binary-24.svg","octicons-file-code-16":"octicons/file-code-16.svg","octicons-file-code-24":"octicons/file-code-24.svg","octicons-file-diff-16":"octicons/file-diff-16.svg","octicons-file-diff-24":"octicons/file-diff-24.svg","octicons-file-directory-16":"octicons/file-directory-16.svg","octicons-file-directory-24":"octicons/file-directory-24.svg","octicons-file-directory-fill-16":"octicons/file-directory-fill-16.svg","octicons-file-directory-fill-24":"octicons/file-directory-fill-24.svg","octicons-file-directory-open-fill-16":"octicons/file-directory-open-fill-16.svg","octicons-file-media-24":"octicons/file-media-24.svg","octicons-file-moved-16":"octicons/file-moved-16.svg","octicons-file-removed-16":"octicons/file-removed-16.svg","octicons-file-submodule-16":"octicons/file-submodule-16.svg","octicons-file-submodule-24":"octicons/file-submodule-24.svg","octicons-file-symlink-file-16":"octicons/file-symlink-file-16.svg","octicons-file-symlink-file-24":"octicons/file-symlink-file-24.svg","octicons-file-zip-16":"octicons/file-zip-16.svg","octicons-file-zip-24":"octicons/file-zip-24.svg","octicons-filter-16":"octicons/filter-16.svg","octicons-filter-24":"octicons/filter-24.svg","octicons-flame-16":"octicons/flame-16.svg","octicons-flame-24":"octicons/flame-24.svg","octicons-fold-16":"octicons/fold-16.svg","octicons-fold-24":"octicons/fold-24.svg","octicons-fold-down-16":"octicons/fold-down-16.svg","octicons-fold-down-24":"octicons/fold-down-24.svg","octicons-fold-up-16":"octicons/fold-up-16.svg","octicons-fold-up-24":"octicons/fold-up-24.svg","octicons-gear-16":"octicons/gear-16.svg","octicons-gear-24":"octicons/gear-24.svg","octicons-gift-16":"octicons/gift-16.svg","octicons-gift-24":"octicons/gift-24.svg","octicons-git-branch-16":"octicons/git-branch-16.svg","octicons-git-branch-24":"octicons/git-branch-24.svg","octicons-git-commit-16":"octicons/git-commit-16.svg","octicons-git-commit-24":"octicons/git-commit-24.svg","octicons-git-compare-16":"octicons/git-compare-16.svg","octicons-git-compare-24":"octicons/git-compare-24.svg","octicons-git-merge-16":"octicons/git-merge-16.svg","octicons-git-merge-24":"octicons/git-merge-24.svg","octicons-git-merge-queue-16":"octicons/git-merge-queue-16.svg","octicons-git-pull-request-16":"octicons/git-pull-request-16.svg","octicons-git-pull-request-24":"octicons/git-pull-request-24.svg","octicons-git-pull-request-closed-16":"octicons/git-pull-request-closed-16.svg","octicons-git-pull-request-closed-24":"octicons/git-pull-request-closed-24.svg","octicons-git-pull-request-draft-16":"octicons/git-pull-request-draft-16.svg","octicons-git-pull-request-draft-24":"octicons/git-pull-request-draft-24.svg","octicons-globe-16":"octicons/globe-16.svg","octicons-globe-24":"octicons/globe-24.svg","octicons-grabber-16":"octicons/grabber-16.svg","octicons-grabber-24":"octicons/grabber-24.svg","octicons-graph-16":"octicons/graph-16.svg","octicons-graph-24":"octicons/graph-24.svg","octicons-hash-16":"octicons/hash-16.svg","octicons-hash-24":"octicons/hash-24.svg","octicons-heading-16":"octicons/heading-16.svg","octicons-heading-24":"octicons/heading-24.svg","octicons-heart-16":"octicons/heart-16.svg","octicons-heart-24":"octicons/heart-24.svg","octicons-heart-fill-16":"octicons/heart-fill-16.svg","octicons-heart-fill-24":"octicons/heart-fill-24.svg","octicons-history-16":"octicons/history-16.svg","octicons-history-24":"octicons/history-24.svg","octicons-home-16":"octicons/home-16.svg","octicons-home-24":"octicons/home-24.svg","octicons-home-fill-24":"octicons/home-fill-24.svg","octicons-horizontal-rule-16":"octicons/horizontal-rule-16.svg","octicons-horizontal-rule-24":"octicons/horizontal-rule-24.svg","octicons-hourglass-16":"octicons/hourglass-16.svg","octicons-hourglass-24":"octicons/hourglass-24.svg","octicons-hubot-16":"octicons/hubot-16.svg","octicons-hubot-24":"octicons/hubot-24.svg","octicons-id-badge-16":"octicons/id-badge-16.svg","octicons-image-16":"octicons/image-16.svg","octicons-image-24":"octicons/image-24.svg","octicons-inbox-16":"octicons/inbox-16.svg","octicons-inbox-24":"octicons/inbox-24.svg","octicons-infinity-16":"octicons/infinity-16.svg","octicons-infinity-24":"octicons/infinity-24.svg","octicons-info-16":"octicons/info-16.svg","octicons-info-24":"octicons/info-24.svg","octicons-issue-closed-16":"octicons/issue-closed-16.svg","octicons-issue-closed-24":"octicons/issue-closed-24.svg","octicons-issue-draft-16":"octicons/issue-draft-16.svg","octicons-issue-draft-24":"octicons/issue-draft-24.svg","octicons-issue-opened-16":"octicons/issue-opened-16.svg","octicons-issue-opened-24":"octicons/issue-opened-24.svg","octicons-issue-reopened-16":"octicons/issue-reopened-16.svg","octicons-issue-reopened-24":"octicons/issue-reopened-24.svg","octicons-italic-16":"octicons/italic-16.svg","octicons-italic-24":"octicons/italic-24.svg","octicons-iterations-16":"octicons/iterations-16.svg","octicons-iterations-24":"octicons/iterations-24.svg","octicons-kebab-horizontal-16":"octicons/kebab-horizontal-16.svg","octicons-kebab-horizontal-24":"octicons/kebab-horizontal-24.svg","octicons-key-16":"octicons/key-16.svg","octicons-key-24":"octicons/key-24.svg","octicons-key-asterisk-16":"octicons/key-asterisk-16.svg","octicons-law-16":"octicons/law-16.svg","octicons-law-24":"octicons/law-24.svg","octicons-light-bulb-16":"octicons/light-bulb-16.svg","octicons-light-bulb-24":"octicons/light-bulb-24.svg","octicons-link-16":"octicons/link-16.svg","octicons-link-24":"octicons/link-24.svg","octicons-link-external-16":"octicons/link-external-16.svg","octicons-link-external-24":"octicons/link-external-24.svg","octicons-list-ordered-16":"octicons/list-ordered-16.svg","octicons-list-ordered-24":"octicons/list-ordered-24.svg","octicons-list-unordered-16":"octicons/list-unordered-16.svg","octicons-list-unordered-24":"octicons/list-unordered-24.svg","octicons-location-16":"octicons/location-16.svg","octicons-location-24":"octicons/location-24.svg","octicons-lock-16":"octicons/lock-16.svg","octicons-lock-24":"octicons/lock-24.svg","octicons-log-16":"octicons/log-16.svg","octicons-logo-gist-16":"octicons/logo-gist-16.svg","octicons-logo-github-16":"octicons/logo-github-16.svg","octicons-mail-16":"octicons/mail-16.svg","octicons-mail-24":"octicons/mail-24.svg","octicons-mark-github-16":"octicons/mark-github-16.svg","octicons-markdown-16":"octicons/markdown-16.svg","octicons-megaphone-16":"octicons/megaphone-16.svg","octicons-megaphone-24":"octicons/megaphone-24.svg","octicons-mention-16":"octicons/mention-16.svg","octicons-mention-24":"octicons/mention-24.svg","octicons-meter-16":"octicons/meter-16.svg","octicons-milestone-16":"octicons/milestone-16.svg","octicons-milestone-24":"octicons/milestone-24.svg","octicons-mirror-16":"octicons/mirror-16.svg","octicons-mirror-24":"octicons/mirror-24.svg","octicons-moon-16":"octicons/moon-16.svg","octicons-moon-24":"octicons/moon-24.svg","octicons-mortar-board-16":"octicons/mortar-board-16.svg","octicons-mortar-board-24":"octicons/mortar-board-24.svg","octicons-multi-select-16":"octicons/multi-select-16.svg","octicons-multi-select-24":"octicons/multi-select-24.svg","octicons-mute-16":"octicons/mute-16.svg","octicons-mute-24":"octicons/mute-24.svg","octicons-no-entry-16":"octicons/no-entry-16.svg","octicons-no-entry-24":"octicons/no-entry-24.svg","octicons-no-entry-fill-12":"octicons/no-entry-fill-12.svg","octicons-north-star-16":"octicons/north-star-16.svg","octicons-north-star-24":"octicons/north-star-24.svg","octicons-note-16":"octicons/note-16.svg","octicons-note-24":"octicons/note-24.svg","octicons-number-16":"octicons/number-16.svg","octicons-number-24":"octicons/number-24.svg","octicons-organization-16":"octicons/organization-16.svg","octicons-organization-24":"octicons/organization-24.svg","octicons-package-16":"octicons/package-16.svg","octicons-package-24":"octicons/package-24.svg","octicons-package-dependencies-16":"octicons/package-dependencies-16.svg","octicons-package-dependencies-24":"octicons/package-dependencies-24.svg","octicons-package-dependents-16":"octicons/package-dependents-16.svg","octicons-package-dependents-24":"octicons/package-dependents-24.svg","octicons-paintbrush-16":"octicons/paintbrush-16.svg","octicons-paper-airplane-16":"octicons/paper-airplane-16.svg","octicons-paper-airplane-24":"octicons/paper-airplane-24.svg","octicons-paperclip-16":"octicons/paperclip-16.svg","octicons-paperclip-24":"octicons/paperclip-24.svg","octicons-paste-16":"octicons/paste-16.svg","octicons-paste-24":"octicons/paste-24.svg","octicons-pencil-16":"octicons/pencil-16.svg","octicons-pencil-24":"octicons/pencil-24.svg","octicons-people-16":"octicons/people-16.svg","octicons-people-24":"octicons/people-24.svg","octicons-person-16":"octicons/person-16.svg","octicons-person-24":"octicons/person-24.svg","octicons-person-add-16":"octicons/person-add-16.svg","octicons-person-add-24":"octicons/person-add-24.svg","octicons-person-fill-16":"octicons/person-fill-16.svg","octicons-person-fill-24":"octicons/person-fill-24.svg","octicons-pin-16":"octicons/pin-16.svg","octicons-pin-24":"octicons/pin-24.svg","octicons-play-16":"octicons/play-16.svg","octicons-play-24":"octicons/play-24.svg","octicons-plug-16":"octicons/plug-16.svg","octicons-plug-24":"octicons/plug-24.svg","octicons-plus-16":"octicons/plus-16.svg","octicons-plus-24":"octicons/plus-24.svg","octicons-plus-circle-16":"octicons/plus-circle-16.svg","octicons-plus-circle-24":"octicons/plus-circle-24.svg","octicons-project-16":"octicons/project-16.svg","octicons-project-24":"octicons/project-24.svg","octicons-pulse-16":"octicons/pulse-16.svg","octicons-pulse-24":"octicons/pulse-24.svg","octicons-question-16":"octicons/question-16.svg","octicons-question-24":"octicons/question-24.svg","octicons-quote-16":"octicons/quote-16.svg","octicons-quote-24":"octicons/quote-24.svg","octicons-reply-16":"octicons/reply-16.svg","octicons-reply-24":"octicons/reply-24.svg","octicons-repo-16":"octicons/repo-16.svg","octicons-repo-24":"octicons/repo-24.svg","octicons-repo-clone-16":"octicons/repo-clone-16.svg","octicons-repo-deleted-16":"octicons/repo-deleted-16.svg","octicons-repo-forked-16":"octicons/repo-forked-16.svg","octicons-repo-forked-24":"octicons/repo-forked-24.svg","octicons-repo-locked-16":"octicons/repo-locked-16.svg","octicons-repo-locked-24":"octicons/repo-locked-24.svg","octicons-repo-pull-16":"octicons/repo-pull-16.svg","octicons-repo-push-16":"octicons/repo-push-16.svg","octicons-repo-push-24":"octicons/repo-push-24.svg","octicons-repo-template-16":"octicons/repo-template-16.svg","octicons-repo-template-24":"octicons/repo-template-24.svg","octicons-report-16":"octicons/report-16.svg","octicons-report-24":"octicons/report-24.svg","octicons-rocket-16":"octicons/rocket-16.svg","octicons-rocket-24":"octicons/rocket-24.svg","octicons-rows-16":"octicons/rows-16.svg","octicons-rows-24":"octicons/rows-24.svg","octicons-rss-16":"octicons/rss-16.svg","octicons-rss-24":"octicons/rss-24.svg","octicons-ruby-16":"octicons/ruby-16.svg","octicons-ruby-24":"octicons/ruby-24.svg","octicons-screen-full-16":"octicons/screen-full-16.svg","octicons-screen-full-24":"octicons/screen-full-24.svg","octicons-screen-normal-16":"octicons/screen-normal-16.svg","octicons-screen-normal-24":"octicons/screen-normal-24.svg","octicons-search-16":"octicons/search-16.svg","octicons-search-24":"octicons/search-24.svg","octicons-server-16":"octicons/server-16.svg","octicons-server-24":"octicons/server-24.svg","octicons-share-16":"octicons/share-16.svg","octicons-share-24":"octicons/share-24.svg","octicons-share-android-16":"octicons/share-android-16.svg","octicons-share-android-24":"octicons/share-android-24.svg","octicons-shield-16":"octicons/shield-16.svg","octicons-shield-24":"octicons/shield-24.svg","octicons-shield-check-16":"octicons/shield-check-16.svg","octicons-shield-check-24":"octicons/shield-check-24.svg","octicons-shield-lock-16":"octicons/shield-lock-16.svg","octicons-shield-lock-24":"octicons/shield-lock-24.svg","octicons-shield-x-16":"octicons/shield-x-16.svg","octicons-shield-x-24":"octicons/shield-x-24.svg","octicons-sidebar-collapse-16":"octicons/sidebar-collapse-16.svg","octicons-sidebar-collapse-24":"octicons/sidebar-collapse-24.svg","octicons-sidebar-expand-16":"octicons/sidebar-expand-16.svg","octicons-sidebar-expand-24":"octicons/sidebar-expand-24.svg","octicons-sign-in-16":"octicons/sign-in-16.svg","octicons-sign-in-24":"octicons/sign-in-24.svg","octicons-sign-out-16":"octicons/sign-out-16.svg","octicons-sign-out-24":"octicons/sign-out-24.svg","octicons-single-select-16":"octicons/single-select-16.svg","octicons-single-select-24":"octicons/single-select-24.svg","octicons-skip-16":"octicons/skip-16.svg","octicons-skip-24":"octicons/skip-24.svg","octicons-sliders-16":"octicons/sliders-16.svg","octicons-smiley-16":"octicons/smiley-16.svg","octicons-smiley-24":"octicons/smiley-24.svg","octicons-sort-asc-16":"octicons/sort-asc-16.svg","octicons-sort-asc-24":"octicons/sort-asc-24.svg","octicons-sort-desc-16":"octicons/sort-desc-16.svg","octicons-sort-desc-24":"octicons/sort-desc-24.svg","octicons-square-16":"octicons/square-16.svg","octicons-square-24":"octicons/square-24.svg","octicons-square-fill-16":"octicons/square-fill-16.svg","octicons-square-fill-24":"octicons/square-fill-24.svg","octicons-squirrel-16":"octicons/squirrel-16.svg","octicons-squirrel-24":"octicons/squirrel-24.svg","octicons-stack-16":"octicons/stack-16.svg","octicons-stack-24":"octicons/stack-24.svg","octicons-star-16":"octicons/star-16.svg","octicons-star-24":"octicons/star-24.svg","octicons-star-fill-16":"octicons/star-fill-16.svg","octicons-star-fill-24":"octicons/star-fill-24.svg","octicons-stop-16":"octicons/stop-16.svg","octicons-stop-24":"octicons/stop-24.svg","octicons-stopwatch-16":"octicons/stopwatch-16.svg","octicons-stopwatch-24":"octicons/stopwatch-24.svg","octicons-strikethrough-16":"octicons/strikethrough-16.svg","octicons-strikethrough-24":"octicons/strikethrough-24.svg","octicons-sun-16":"octicons/sun-16.svg","octicons-sun-24":"octicons/sun-24.svg","octicons-sync-16":"octicons/sync-16.svg","octicons-sync-24":"octicons/sync-24.svg","octicons-tab-24":"octicons/tab-24.svg","octicons-tab-external-16":"octicons/tab-external-16.svg","octicons-table-16":"octicons/table-16.svg","octicons-table-24":"octicons/table-24.svg","octicons-tag-16":"octicons/tag-16.svg","octicons-tag-24":"octicons/tag-24.svg","octicons-tasklist-16":"octicons/tasklist-16.svg","octicons-tasklist-24":"octicons/tasklist-24.svg","octicons-telescope-16":"octicons/telescope-16.svg","octicons-telescope-24":"octicons/telescope-24.svg","octicons-telescope-fill-16":"octicons/telescope-fill-16.svg","octicons-telescope-fill-24":"octicons/telescope-fill-24.svg","octicons-terminal-16":"octicons/terminal-16.svg","octicons-terminal-24":"octicons/terminal-24.svg","octicons-three-bars-16":"octicons/three-bars-16.svg","octicons-thumbsdown-16":"octicons/thumbsdown-16.svg","octicons-thumbsdown-24":"octicons/thumbsdown-24.svg","octicons-thumbsup-16":"octicons/thumbsup-16.svg","octicons-thumbsup-24":"octicons/thumbsup-24.svg","octicons-tools-16":"octicons/tools-16.svg","octicons-tools-24":"octicons/tools-24.svg","octicons-trash-16":"octicons/trash-16.svg","octicons-trash-24":"octicons/trash-24.svg","octicons-triangle-down-16":"octicons/triangle-down-16.svg","octicons-triangle-down-24":"octicons/triangle-down-24.svg","octicons-triangle-left-16":"octicons/triangle-left-16.svg","octicons-triangle-left-24":"octicons/triangle-left-24.svg","octicons-triangle-right-16":"octicons/triangle-right-16.svg","octicons-triangle-right-24":"octicons/triangle-right-24.svg","octicons-triangle-up-16":"octicons/triangle-up-16.svg","octicons-triangle-up-24":"octicons/triangle-up-24.svg","octicons-trophy-16":"octicons/trophy-16.svg","octicons-trophy-24":"octicons/trophy-24.svg","octicons-typography-16":"octicons/typography-16.svg","octicons-typography-24":"octicons/typography-24.svg","octicons-unfold-16":"octicons/unfold-16.svg","octicons-unfold-24":"octicons/unfold-24.svg","octicons-unlock-16":"octicons/unlock-16.svg","octicons-unlock-24":"octicons/unlock-24.svg","octicons-unmute-16":"octicons/unmute-16.svg","octicons-unmute-24":"octicons/unmute-24.svg","octicons-unverified-16":"octicons/unverified-16.svg","octicons-unverified-24":"octicons/unverified-24.svg","octicons-upload-16":"octicons/upload-16.svg","octicons-upload-24":"octicons/upload-24.svg","octicons-verified-16":"octicons/verified-16.svg","octicons-verified-24":"octicons/verified-24.svg","octicons-versions-16":"octicons/versions-16.svg","octicons-versions-24":"octicons/versions-24.svg","octicons-video-16":"octicons/video-16.svg","octicons-video-24":"octicons/video-24.svg","octicons-webhook-16":"octicons/webhook-16.svg","octicons-workflow-16":"octicons/workflow-16.svg","octicons-workflow-24":"octicons/workflow-24.svg","octicons-x-16":"octicons/x-16.svg","octicons-x-24":"octicons/x-24.svg","octicons-x-circle-16":"octicons/x-circle-16.svg","octicons-x-circle-24":"octicons/x-circle-24.svg","octicons-x-circle-fill-12":"octicons/x-circle-fill-12.svg","octicons-x-circle-fill-16":"octicons/x-circle-fill-16.svg","octicons-x-circle-fill-24":"octicons/x-circle-fill-24.svg","octicons-zap-16":"octicons/zap-16.svg","octicons-zap-24":"octicons/zap-24.svg"}},"emojis":{"base":"https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/","data":{"100":"1f4af.svg","1234":"1f522.svg","8ball":"1f3b1.svg","a":"1f170.svg","ab":"1f18e.svg","abacus":"1f9ee.svg","abc":"1f524.svg","abcd":"1f521.svg","accept":"1f251.svg","accordion":"1fa97.svg","adhesive_bandage":"1fa79.svg","adult":"1f9d1.svg","adult_tone1":"1f9d1-1f3fb.svg","adult_tone2":"1f9d1-1f3fc.svg","adult_tone3":"1f9d1-1f3fd.svg","adult_tone4":"1f9d1-1f3fe.svg","adult_tone5":"1f9d1-1f3ff.svg","aerial_tramway":"1f6a1.svg","airplane":"2708.svg","airplane_arriving":"1f6ec.svg","airplane_departure":"1f6eb.svg","airplane_small":"1f6e9.svg","alarm_clock":"23f0.svg","alembic":"2697.svg","alien":"1f47d.svg","ambulance":"1f691.svg","amphora":"1f3fa.svg","anatomical_heart":"1fac0.svg","anchor":"2693.svg","angel":"1f47c.svg","angel_tone1":"1f47c-1f3fb.svg","angel_tone2":"1f47c-1f3fc.svg","angel_tone3":"1f47c-1f3fd.svg","angel_tone4":"1f47c-1f3fe.svg","angel_tone5":"1f47c-1f3ff.svg","anger":"1f4a2.svg","anger_right":"1f5ef.svg","angry":"1f620.svg","anguished":"1f627.svg","ant":"1f41c.svg","apple":"1f34e.svg","aquarius":"2652.svg","aries":"2648.svg","arrow_backward":"25c0.svg","arrow_double_down":"23ec.svg","arrow_double_up":"23eb.svg","arrow_down":"2b07.svg","arrow_down_small":"1f53d.svg","arrow_forward":"25b6.svg","arrow_heading_down":"2935.svg","arrow_heading_up":"2934.svg","arrow_left":"2b05.svg","arrow_lower_left":"2199.svg","arrow_lower_right":"2198.svg","arrow_right":"27a1.svg","arrow_right_hook":"21aa.svg","arrow_up":"2b06.svg","arrow_up_down":"2195.svg","arrow_up_small":"1f53c.svg","arrow_upper_left":"2196.svg","arrow_upper_right":"2197.svg","arrows_clockwise":"1f503.svg","arrows_counterclockwise":"1f504.svg","art":"1f3a8.svg","articulated_lorry":"1f69b.svg","artist":"1f9d1-200d-1f3a8.svg","artist_tone1":"1f9d1-1f3fb-200d-1f3a8.svg","artist_tone2":"1f9d1-1f3fc-200d-1f3a8.svg","artist_tone3":"1f9d1-1f3fd-200d-1f3a8.svg","artist_tone4":"1f9d1-1f3fe-200d-1f3a8.svg","artist_tone5":"1f9d1-1f3ff-200d-1f3a8.svg","asterisk":"2a-20e3.svg","astonished":"1f632.svg","astronaut":"1f9d1-200d-1f680.svg","astronaut_tone1":"1f9d1-1f3fb-200d-1f680.svg","astronaut_tone2":"1f9d1-1f3fc-200d-1f680.svg","astronaut_tone3":"1f9d1-1f3fd-200d-1f680.svg","astronaut_tone4":"1f9d1-1f3fe-200d-1f680.svg","astronaut_tone5":"1f9d1-1f3ff-200d-1f680.svg","athletic_shoe":"1f45f.svg","atm":"1f3e7.svg","atom":"269b.svg","auto_rickshaw":"1f6fa.svg","avocado":"1f951.svg","axe":"1fa93.svg","b":"1f171.svg","baby":"1f476.svg","baby_bottle":"1f37c.svg","baby_chick":"1f424.svg","baby_symbol":"1f6bc.svg","baby_tone1":"1f476-1f3fb.svg","baby_tone2":"1f476-1f3fc.svg","baby_tone3":"1f476-1f3fd.svg","baby_tone4":"1f476-1f3fe.svg","baby_tone5":"1f476-1f3ff.svg","back":"1f519.svg","bacon":"1f953.svg","badger":"1f9a1.svg","badminton":"1f3f8.svg","bagel":"1f96f.svg","baggage_claim":"1f6c4.svg","bald":"1f9b2.svg","ballet_shoes":"1fa70.svg","balloon":"1f388.svg","ballot_box":"1f5f3.svg","ballot_box_with_check":"2611.svg","bamboo":"1f38d.svg","banana":"1f34c.svg","bangbang":"203c.svg","banjo":"1fa95.svg","bank":"1f3e6.svg","bar_chart":"1f4ca.svg","barber":"1f488.svg","baseball":"26be.svg","basket":"1f9fa.svg","basketball":"1f3c0.svg","bat":"1f987.svg","bath":"1f6c0.svg","bath_tone1":"1f6c0-1f3fb.svg","bath_tone2":"1f6c0-1f3fc.svg","bath_tone3":"1f6c0-1f3fd.svg","bath_tone4":"1f6c0-1f3fe.svg","bath_tone5":"1f6c0-1f3ff.svg","bathtub":"1f6c1.svg","battery":"1f50b.svg","beach":"1f3d6.svg","beach_umbrella":"26f1.svg","bear":"1f43b.svg","bearded_person":"1f9d4.svg","bearded_person_tone1":"1f9d4-1f3fb.svg","bearded_person_tone2":"1f9d4-1f3fc.svg","bearded_person_tone3":"1f9d4-1f3fd.svg","bearded_person_tone4":"1f9d4-1f3fe.svg","bearded_person_tone5":"1f9d4-1f3ff.svg","beaver":"1f9ab.svg","bed":"1f6cf.svg","bee":"1f41d.svg","beer":"1f37a.svg","beers":"1f37b.svg","beetle":"1fab2.svg","beginner":"1f530.svg","bell":"1f514.svg","bell_pepper":"1fad1.svg","bellhop":"1f6ce.svg","bento":"1f371.svg","beverage_box":"1f9c3.svg","bike":"1f6b2.svg","bikini":"1f459.svg","billed_cap":"1f9e2.svg","biohazard":"2623.svg","bird":"1f426.svg","birthday":"1f382.svg","bison":"1f9ac.svg","black_cat":"1f408-200d-2b1b.svg","black_circle":"26ab.svg","black_heart":"1f5a4.svg","black_joker":"1f0cf.svg","black_large_square":"2b1b.svg","black_medium_small_square":"25fe.svg","black_medium_square":"25fc.svg","black_nib":"2712.svg","black_small_square":"25aa.svg","black_square_button":"1f532.svg","blond-haired_man":"1f471-200d-2642-fe0f.svg","blond-haired_man_tone1":"1f471-1f3fb-200d-2642-fe0f.svg","blond-haired_man_tone2":"1f471-1f3fc-200d-2642-fe0f.svg","blond-haired_man_tone3":"1f471-1f3fd-200d-2642-fe0f.svg","blond-haired_man_tone4":"1f471-1f3fe-200d-2642-fe0f.svg","blond-haired_man_tone5":"1f471-1f3ff-200d-2642-fe0f.svg","blond-haired_woman":"1f471-200d-2640-fe0f.svg","blond-haired_woman_tone1":"1f471-1f3fb-200d-2640-fe0f.svg","blond-haired_woman_tone2":"1f471-1f3fc-200d-2640-fe0f.svg","blond-haired_woman_tone3":"1f471-1f3fd-200d-2640-fe0f.svg","blond-haired_woman_tone4":"1f471-1f3fe-200d-2640-fe0f.svg","blond-haired_woman_tone5":"1f471-1f3ff-200d-2640-fe0f.svg","blond_haired_person":"1f471.svg","blond_haired_person_tone1":"1f471-1f3fb.svg","blond_haired_person_tone2":"1f471-1f3fc.svg","blond_haired_person_tone3":"1f471-1f3fd.svg","blond_haired_person_tone4":"1f471-1f3fe.svg","blond_haired_person_tone5":"1f471-1f3ff.svg","blossom":"1f33c.svg","blowfish":"1f421.svg","blue_book":"1f4d8.svg","blue_car":"1f699.svg","blue_circle":"1f535.svg","blue_heart":"1f499.svg","blue_square":"1f7e6.svg","blueberries":"1fad0.svg","blush":"1f60a.svg","boar":"1f417.svg","bomb":"1f4a3.svg","bone":"1f9b4.svg","book":"1f4d6.svg","bookmark":"1f516.svg","bookmark_tabs":"1f4d1.svg","books":"1f4da.svg","boom":"1f4a5.svg","boomerang":"1fa83.svg","boot":"1f462.svg","bouquet":"1f490.svg","bow_and_arrow":"1f3f9.svg","bowl_with_spoon":"1f963.svg","bowling":"1f3b3.svg","boxing_glove":"1f94a.svg","boy":"1f466.svg","boy_tone1":"1f466-1f3fb.svg","boy_tone2":"1f466-1f3fc.svg","boy_tone3":"1f466-1f3fd.svg","boy_tone4":"1f466-1f3fe.svg","boy_tone5":"1f466-1f3ff.svg","brain":"1f9e0.svg","bread":"1f35e.svg","breast_feeding":"1f931.svg","breast_feeding_tone1":"1f931-1f3fb.svg","breast_feeding_tone2":"1f931-1f3fc.svg","breast_feeding_tone3":"1f931-1f3fd.svg","breast_feeding_tone4":"1f931-1f3fe.svg","breast_feeding_tone5":"1f931-1f3ff.svg","bricks":"1f9f1.svg","bridge_at_night":"1f309.svg","briefcase":"1f4bc.svg","briefs":"1fa72.svg","broccoli":"1f966.svg","broken_heart":"1f494.svg","broom":"1f9f9.svg","brown_circle":"1f7e4.svg","brown_heart":"1f90e.svg","brown_square":"1f7eb.svg","bubble_tea":"1f9cb.svg","bucket":"1faa3.svg","bug":"1f41b.svg","bulb":"1f4a1.svg","bullettrain_front":"1f685.svg","bullettrain_side":"1f684.svg","burrito":"1f32f.svg","bus":"1f68c.svg","busstop":"1f68f.svg","bust_in_silhouette":"1f464.svg","busts_in_silhouette":"1f465.svg","butter":"1f9c8.svg","butterfly":"1f98b.svg","cactus":"1f335.svg","cake":"1f370.svg","calendar":"1f4c6.svg","calendar_spiral":"1f5d3.svg","call_me":"1f919.svg","call_me_tone1":"1f919-1f3fb.svg","call_me_tone2":"1f919-1f3fc.svg","call_me_tone3":"1f919-1f3fd.svg","call_me_tone4":"1f919-1f3fe.svg","call_me_tone5":"1f919-1f3ff.svg","calling":"1f4f2.svg","camel":"1f42b.svg","camera":"1f4f7.svg","camera_with_flash":"1f4f8.svg","camping":"1f3d5.svg","cancer":"264b.svg","candle":"1f56f.svg","candy":"1f36c.svg","canned_food":"1f96b.svg","canoe":"1f6f6.svg","capital_abcd":"1f520.svg","capricorn":"2651.svg","card_box":"1f5c3.svg","card_index":"1f4c7.svg","carousel_horse":"1f3a0.svg","carpentry_saw":"1fa9a.svg","carrot":"1f955.svg","cat2":"1f408.svg","cat":"1f431.svg","cd":"1f4bf.svg","chains":"26d3.svg","chair":"1fa91.svg","champagne":"1f37e.svg","champagne_glass":"1f942.svg","chart":"1f4b9.svg","chart_with_downwards_trend":"1f4c9.svg","chart_with_upwards_trend":"1f4c8.svg","checkered_flag":"1f3c1.svg","cheese":"1f9c0.svg","cherries":"1f352.svg","cherry_blossom":"1f338.svg","chess_pawn":"265f.svg","chestnut":"1f330.svg","chicken":"1f414.svg","child":"1f9d2.svg","child_tone1":"1f9d2-1f3fb.svg","child_tone2":"1f9d2-1f3fc.svg","child_tone3":"1f9d2-1f3fd.svg","child_tone4":"1f9d2-1f3fe.svg","child_tone5":"1f9d2-1f3ff.svg","children_crossing":"1f6b8.svg","chipmunk":"1f43f.svg","chocolate_bar":"1f36b.svg","chopsticks":"1f962.svg","christmas_tree":"1f384.svg","church":"26ea.svg","cinema":"1f3a6.svg","circus_tent":"1f3aa.svg","city_dusk":"1f306.svg","city_sunset":"1f307.svg","cityscape":"1f3d9.svg","cl":"1f191.svg","clap":"1f44f.svg","clap_tone1":"1f44f-1f3fb.svg","clap_tone2":"1f44f-1f3fc.svg","clap_tone3":"1f44f-1f3fd.svg","clap_tone4":"1f44f-1f3fe.svg","clap_tone5":"1f44f-1f3ff.svg","clapper":"1f3ac.svg","classical_building":"1f3db.svg","clipboard":"1f4cb.svg","clock1030":"1f565.svg","clock10":"1f559.svg","clock1130":"1f566.svg","clock11":"1f55a.svg","clock1230":"1f567.svg","clock12":"1f55b.svg","clock130":"1f55c.svg","clock1":"1f550.svg","clock230":"1f55d.svg","clock2":"1f551.svg","clock330":"1f55e.svg","clock3":"1f552.svg","clock430":"1f55f.svg","clock4":"1f553.svg","clock530":"1f560.svg","clock5":"1f554.svg","clock630":"1f561.svg","clock6":"1f555.svg","clock730":"1f562.svg","clock7":"1f556.svg","clock830":"1f563.svg","clock8":"1f557.svg","clock930":"1f564.svg","clock9":"1f558.svg","clock":"1f570.svg","closed_book":"1f4d5.svg","closed_lock_with_key":"1f510.svg","closed_umbrella":"1f302.svg","cloud":"2601.svg","cloud_lightning":"1f329.svg","cloud_rain":"1f327.svg","cloud_snow":"1f328.svg","cloud_tornado":"1f32a.svg","clown":"1f921.svg","clubs":"2663.svg","coat":"1f9e5.svg","cockroach":"1fab3.svg","cocktail":"1f378.svg","coconut":"1f965.svg","coffee":"2615.svg","coffin":"26b0.svg","coin":"1fa99.svg","cold_face":"1f976.svg","cold_sweat":"1f630.svg","comet":"2604.svg","compass":"1f9ed.svg","compression":"1f5dc.svg","computer":"1f4bb.svg","confetti_ball":"1f38a.svg","confounded":"1f616.svg","confused":"1f615.svg","congratulations":"3297.svg","construction":"1f6a7.svg","construction_site":"1f3d7.svg","construction_worker":"1f477.svg","construction_worker_tone1":"1f477-1f3fb.svg","construction_worker_tone2":"1f477-1f3fc.svg","construction_worker_tone3":"1f477-1f3fd.svg","construction_worker_tone4":"1f477-1f3fe.svg","construction_worker_tone5":"1f477-1f3ff.svg","control_knobs":"1f39b.svg","convenience_store":"1f3ea.svg","cook":"1f9d1-200d-1f373.svg","cook_tone1":"1f9d1-1f3fb-200d-1f373.svg","cook_tone2":"1f9d1-1f3fc-200d-1f373.svg","cook_tone3":"1f9d1-1f3fd-200d-1f373.svg","cook_tone4":"1f9d1-1f3fe-200d-1f373.svg","cook_tone5":"1f9d1-1f3ff-200d-1f373.svg","cookie":"1f36a.svg","cooking":"1f373.svg","cool":"1f192.svg","copyright":"a9.svg","corn":"1f33d.svg","couch":"1f6cb.svg","couple":"1f46b.svg","couple_mm":"1f468-200d-2764-fe0f-200d-1f468.svg","couple_with_heart":"1f491.svg","couple_with_heart_man_man_tone1":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone1_tone2":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone1_tone3":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone1_tone4":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone1_tone5":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone2":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone2_tone1":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone2_tone3":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone2_tone4":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone2_tone5":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone3":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone3_tone1":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone3_tone2":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone3_tone4":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone3_tone5":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone4":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone4_tone1":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone4_tone2":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone4_tone3":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone4_tone5":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone5":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone5_tone1":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone5_tone2":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone5_tone3":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone5_tone4":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_person_person_tone1_tone2":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone1_tone3":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone1_tone4":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_person_person_tone1_tone5":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone2_tone1":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone2_tone3":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone2_tone4":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_person_person_tone2_tone5":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone3_tone1":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone3_tone2":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone3_tone4":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_person_person_tone3_tone5":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone4_tone1":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone4_tone2":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone4_tone3":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone4_tone5":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone5_tone1":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone5_tone2":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone5_tone3":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone5_tone4":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_tone1":"1f491-1f3fb.svg","couple_with_heart_tone2":"1f491-1f3fc.svg","couple_with_heart_tone3":"1f491-1f3fd.svg","couple_with_heart_tone4":"1f491-1f3fe.svg","couple_with_heart_tone5":"1f491-1f3ff.svg","couple_with_heart_woman_man":"1f469-200d-2764-fe0f-200d-1f468.svg","couple_with_heart_woman_man_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_woman_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_ww":"1f469-200d-2764-fe0f-200d-1f469.svg","couplekiss":"1f48f.svg","cow2":"1f404.svg","cow":"1f42e.svg","cowboy":"1f920.svg","crab":"1f980.svg","crayon":"1f58d.svg","credit_card":"1f4b3.svg","crescent_moon":"1f319.svg","cricket":"1f997.svg","cricket_game":"1f3cf.svg","crocodile":"1f40a.svg","croissant":"1f950.svg","cross":"271d.svg","crossed_flags":"1f38c.svg","crossed_swords":"2694.svg","crown":"1f451.svg","cruise_ship":"1f6f3.svg","cry":"1f622.svg","crying_cat_face":"1f63f.svg","crystal_ball":"1f52e.svg","cucumber":"1f952.svg","cup_with_straw":"1f964.svg","cupcake":"1f9c1.svg","cupid":"1f498.svg","curling_stone":"1f94c.svg","curly_haired":"1f9b1.svg","curly_loop":"27b0.svg","currency_exchange":"1f4b1.svg","curry":"1f35b.svg","custard":"1f36e.svg","customs":"1f6c3.svg","cut_of_meat":"1f969.svg","cyclone":"1f300.svg","dagger":"1f5e1.svg","dancer":"1f483.svg","dancer_tone1":"1f483-1f3fb.svg","dancer_tone2":"1f483-1f3fc.svg","dancer_tone3":"1f483-1f3fd.svg","dancer_tone4":"1f483-1f3fe.svg","dancer_tone5":"1f483-1f3ff.svg","dango":"1f361.svg","dark_sunglasses":"1f576.svg","dart":"1f3af.svg","dash":"1f4a8.svg","date":"1f4c5.svg","deaf_man":"1f9cf-200d-2642-fe0f.svg","deaf_man_tone1":"1f9cf-1f3fb-200d-2642-fe0f.svg","deaf_man_tone2":"1f9cf-1f3fc-200d-2642-fe0f.svg","deaf_man_tone3":"1f9cf-1f3fd-200d-2642-fe0f.svg","deaf_man_tone4":"1f9cf-1f3fe-200d-2642-fe0f.svg","deaf_man_tone5":"1f9cf-1f3ff-200d-2642-fe0f.svg","deaf_person":"1f9cf.svg","deaf_person_tone1":"1f9cf-1f3fb.svg","deaf_person_tone2":"1f9cf-1f3fc.svg","deaf_person_tone3":"1f9cf-1f3fd.svg","deaf_person_tone4":"1f9cf-1f3fe.svg","deaf_person_tone5":"1f9cf-1f3ff.svg","deaf_woman":"1f9cf-200d-2640-fe0f.svg","deaf_woman_tone1":"1f9cf-1f3fb-200d-2640-fe0f.svg","deaf_woman_tone2":"1f9cf-1f3fc-200d-2640-fe0f.svg","deaf_woman_tone3":"1f9cf-1f3fd-200d-2640-fe0f.svg","deaf_woman_tone4":"1f9cf-1f3fe-200d-2640-fe0f.svg","deaf_woman_tone5":"1f9cf-1f3ff-200d-2640-fe0f.svg","deciduous_tree":"1f333.svg","deer":"1f98c.svg","department_store":"1f3ec.svg","desert":"1f3dc.svg","desktop":"1f5a5.svg","detective":"1f575.svg","detective_tone1":"1f575-1f3fb.svg","detective_tone2":"1f575-1f3fc.svg","detective_tone3":"1f575-1f3fd.svg","detective_tone4":"1f575-1f3fe.svg","detective_tone5":"1f575-1f3ff.svg","diamond_shape_with_a_dot_inside":"1f4a0.svg","diamonds":"2666.svg","disappointed":"1f61e.svg","disappointed_relieved":"1f625.svg","disguised_face":"1f978.svg","dividers":"1f5c2.svg","diving_mask":"1f93f.svg","diya_lamp":"1fa94.svg","dizzy":"1f4ab.svg","dizzy_face":"1f635.svg","dna":"1f9ec.svg","do_not_litter":"1f6af.svg","dodo":"1f9a4.svg","dog2":"1f415.svg","dog":"1f436.svg","dollar":"1f4b5.svg","dolls":"1f38e.svg","dolphin":"1f42c.svg","door":"1f6aa.svg","doughnut":"1f369.svg","dove":"1f54a.svg","dragon":"1f409.svg","dragon_face":"1f432.svg","dress":"1f457.svg","dromedary_camel":"1f42a.svg","drooling_face":"1f924.svg","drop_of_blood":"1fa78.svg","droplet":"1f4a7.svg","drum":"1f941.svg","duck":"1f986.svg","dumpling":"1f95f.svg","dvd":"1f4c0.svg","e-mail":"1f4e7.svg","eagle":"1f985.svg","ear":"1f442.svg","ear_of_rice":"1f33e.svg","ear_tone1":"1f442-1f3fb.svg","ear_tone2":"1f442-1f3fc.svg","ear_tone3":"1f442-1f3fd.svg","ear_tone4":"1f442-1f3fe.svg","ear_tone5":"1f442-1f3ff.svg","ear_with_hearing_aid":"1f9bb.svg","ear_with_hearing_aid_tone1":"1f9bb-1f3fb.svg","ear_with_hearing_aid_tone2":"1f9bb-1f3fc.svg","ear_with_hearing_aid_tone3":"1f9bb-1f3fd.svg","ear_with_hearing_aid_tone4":"1f9bb-1f3fe.svg","ear_with_hearing_aid_tone5":"1f9bb-1f3ff.svg","earth_africa":"1f30d.svg","earth_americas":"1f30e.svg","earth_asia":"1f30f.svg","egg":"1f95a.svg","eggplant":"1f346.svg","eight":"38-20e3.svg","eight_pointed_black_star":"2734.svg","eight_spoked_asterisk":"2733.svg","eject":"23cf.svg","electric_plug":"1f50c.svg","elephant":"1f418.svg","elevator":"1f6d7.svg","elf":"1f9dd.svg","elf_tone1":"1f9dd-1f3fb.svg","elf_tone2":"1f9dd-1f3fc.svg","elf_tone3":"1f9dd-1f3fd.svg","elf_tone4":"1f9dd-1f3fe.svg","elf_tone5":"1f9dd-1f3ff.svg","end":"1f51a.svg","england":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f.svg","envelope":"2709.svg","envelope_with_arrow":"1f4e9.svg","euro":"1f4b6.svg","european_castle":"1f3f0.svg","european_post_office":"1f3e4.svg","evergreen_tree":"1f332.svg","exclamation":"2757.svg","exploding_head":"1f92f.svg","expressionless":"1f611.svg","eye":"1f441.svg","eye_in_speech_bubble":"1f441-200d-1f5e8.svg","eyeglasses":"1f453.svg","eyes":"1f440.svg","face_exhaling":"1f62e-200d-1f4a8.svg","face_in_clouds":"1f636-200d-1f32b-fe0f.svg","face_vomiting":"1f92e.svg","face_with_hand_over_mouth":"1f92d.svg","face_with_monocle":"1f9d0.svg","face_with_raised_eyebrow":"1f928.svg","face_with_spiral_eyes":"1f635-200d-1f4ab.svg","face_with_symbols_over_mouth":"1f92c.svg","factory":"1f3ed.svg","factory_worker":"1f9d1-200d-1f3ed.svg","factory_worker_tone1":"1f9d1-1f3fb-200d-1f3ed.svg","factory_worker_tone2":"1f9d1-1f3fc-200d-1f3ed.svg","factory_worker_tone3":"1f9d1-1f3fd-200d-1f3ed.svg","factory_worker_tone4":"1f9d1-1f3fe-200d-1f3ed.svg","factory_worker_tone5":"1f9d1-1f3ff-200d-1f3ed.svg","fairy":"1f9da.svg","fairy_tone1":"1f9da-1f3fb.svg","fairy_tone2":"1f9da-1f3fc.svg","fairy_tone3":"1f9da-1f3fd.svg","fairy_tone4":"1f9da-1f3fe.svg","fairy_tone5":"1f9da-1f3ff.svg","falafel":"1f9c6.svg","fallen_leaf":"1f342.svg","family":"1f46a.svg","family_man_boy":"1f468-200d-1f466.svg","family_man_boy_boy":"1f468-200d-1f466-200d-1f466.svg","family_man_girl":"1f468-200d-1f467.svg","family_man_girl_boy":"1f468-200d-1f467-200d-1f466.svg","family_man_girl_girl":"1f468-200d-1f467-200d-1f467.svg","family_man_woman_boy":"1f468-200d-1f469-200d-1f466.svg","family_mmb":"1f468-200d-1f468-200d-1f466.svg","family_mmbb":"1f468-200d-1f468-200d-1f466-200d-1f466.svg","family_mmg":"1f468-200d-1f468-200d-1f467.svg","family_mmgb":"1f468-200d-1f468-200d-1f467-200d-1f466.svg","family_mmgg":"1f468-200d-1f468-200d-1f467-200d-1f467.svg","family_mwbb":"1f468-200d-1f469-200d-1f466-200d-1f466.svg","family_mwg":"1f468-200d-1f469-200d-1f467.svg","family_mwgb":"1f468-200d-1f469-200d-1f467-200d-1f466.svg","family_mwgg":"1f468-200d-1f469-200d-1f467-200d-1f467.svg","family_woman_boy":"1f469-200d-1f466.svg","family_woman_boy_boy":"1f469-200d-1f466-200d-1f466.svg","family_woman_girl":"1f469-200d-1f467.svg","family_woman_girl_boy":"1f469-200d-1f467-200d-1f466.svg","family_woman_girl_girl":"1f469-200d-1f467-200d-1f467.svg","family_wwb":"1f469-200d-1f469-200d-1f466.svg","family_wwbb":"1f469-200d-1f469-200d-1f466-200d-1f466.svg","family_wwg":"1f469-200d-1f469-200d-1f467.svg","family_wwgb":"1f469-200d-1f469-200d-1f467-200d-1f466.svg","family_wwgg":"1f469-200d-1f469-200d-1f467-200d-1f467.svg","farmer":"1f9d1-200d-1f33e.svg","farmer_tone1":"1f9d1-1f3fb-200d-1f33e.svg","farmer_tone2":"1f9d1-1f3fc-200d-1f33e.svg","farmer_tone3":"1f9d1-1f3fd-200d-1f33e.svg","farmer_tone4":"1f9d1-1f3fe-200d-1f33e.svg","farmer_tone5":"1f9d1-1f3ff-200d-1f33e.svg","fast_forward":"23e9.svg","fax":"1f4e0.svg","fearful":"1f628.svg","feather":"1fab6.svg","feet":"1f43e.svg","female_sign":"2640.svg","ferris_wheel":"1f3a1.svg","ferry":"26f4.svg","field_hockey":"1f3d1.svg","file_cabinet":"1f5c4.svg","file_folder":"1f4c1.svg","film_frames":"1f39e.svg","fingers_crossed":"1f91e.svg","fingers_crossed_tone1":"1f91e-1f3fb.svg","fingers_crossed_tone2":"1f91e-1f3fc.svg","fingers_crossed_tone3":"1f91e-1f3fd.svg","fingers_crossed_tone4":"1f91e-1f3fe.svg","fingers_crossed_tone5":"1f91e-1f3ff.svg","fire":"1f525.svg","fire_engine":"1f692.svg","fire_extinguisher":"1f9ef.svg","firecracker":"1f9e8.svg","firefighter":"1f9d1-200d-1f692.svg","firefighter_tone1":"1f9d1-1f3fb-200d-1f692.svg","firefighter_tone2":"1f9d1-1f3fc-200d-1f692.svg","firefighter_tone3":"1f9d1-1f3fd-200d-1f692.svg","firefighter_tone4":"1f9d1-1f3fe-200d-1f692.svg","firefighter_tone5":"1f9d1-1f3ff-200d-1f692.svg","fireworks":"1f386.svg","first_place":"1f947.svg","first_quarter_moon":"1f313.svg","first_quarter_moon_with_face":"1f31b.svg","fish":"1f41f.svg","fish_cake":"1f365.svg","fishing_pole_and_fish":"1f3a3.svg","fist":"270a.svg","fist_tone1":"270a-1f3fb.svg","fist_tone2":"270a-1f3fc.svg","fist_tone3":"270a-1f3fd.svg","fist_tone4":"270a-1f3fe.svg","fist_tone5":"270a-1f3ff.svg","five":"35-20e3.svg","flag_ac":"1f1e6-1f1e8.svg","flag_ad":"1f1e6-1f1e9.svg","flag_ae":"1f1e6-1f1ea.svg","flag_af":"1f1e6-1f1eb.svg","flag_ag":"1f1e6-1f1ec.svg","flag_ai":"1f1e6-1f1ee.svg","flag_al":"1f1e6-1f1f1.svg","flag_am":"1f1e6-1f1f2.svg","flag_ao":"1f1e6-1f1f4.svg","flag_aq":"1f1e6-1f1f6.svg","flag_ar":"1f1e6-1f1f7.svg","flag_as":"1f1e6-1f1f8.svg","flag_at":"1f1e6-1f1f9.svg","flag_au":"1f1e6-1f1fa.svg","flag_aw":"1f1e6-1f1fc.svg","flag_ax":"1f1e6-1f1fd.svg","flag_az":"1f1e6-1f1ff.svg","flag_ba":"1f1e7-1f1e6.svg","flag_bb":"1f1e7-1f1e7.svg","flag_bd":"1f1e7-1f1e9.svg","flag_be":"1f1e7-1f1ea.svg","flag_bf":"1f1e7-1f1eb.svg","flag_bg":"1f1e7-1f1ec.svg","flag_bh":"1f1e7-1f1ed.svg","flag_bi":"1f1e7-1f1ee.svg","flag_bj":"1f1e7-1f1ef.svg","flag_bl":"1f1e7-1f1f1.svg","flag_black":"1f3f4.svg","flag_bm":"1f1e7-1f1f2.svg","flag_bn":"1f1e7-1f1f3.svg","flag_bo":"1f1e7-1f1f4.svg","flag_bq":"1f1e7-1f1f6.svg","flag_br":"1f1e7-1f1f7.svg","flag_bs":"1f1e7-1f1f8.svg","flag_bt":"1f1e7-1f1f9.svg","flag_bv":"1f1e7-1f1fb.svg","flag_bw":"1f1e7-1f1fc.svg","flag_by":"1f1e7-1f1fe.svg","flag_bz":"1f1e7-1f1ff.svg","flag_ca":"1f1e8-1f1e6.svg","flag_cc":"1f1e8-1f1e8.svg","flag_cd":"1f1e8-1f1e9.svg","flag_cf":"1f1e8-1f1eb.svg","flag_cg":"1f1e8-1f1ec.svg","flag_ch":"1f1e8-1f1ed.svg","flag_ci":"1f1e8-1f1ee.svg","flag_ck":"1f1e8-1f1f0.svg","flag_cl":"1f1e8-1f1f1.svg","flag_cm":"1f1e8-1f1f2.svg","flag_cn":"1f1e8-1f1f3.svg","flag_co":"1f1e8-1f1f4.svg","flag_cp":"1f1e8-1f1f5.svg","flag_cr":"1f1e8-1f1f7.svg","flag_cu":"1f1e8-1f1fa.svg","flag_cv":"1f1e8-1f1fb.svg","flag_cw":"1f1e8-1f1fc.svg","flag_cx":"1f1e8-1f1fd.svg","flag_cy":"1f1e8-1f1fe.svg","flag_cz":"1f1e8-1f1ff.svg","flag_de":"1f1e9-1f1ea.svg","flag_dg":"1f1e9-1f1ec.svg","flag_dj":"1f1e9-1f1ef.svg","flag_dk":"1f1e9-1f1f0.svg","flag_dm":"1f1e9-1f1f2.svg","flag_do":"1f1e9-1f1f4.svg","flag_dz":"1f1e9-1f1ff.svg","flag_ea":"1f1ea-1f1e6.svg","flag_ec":"1f1ea-1f1e8.svg","flag_ee":"1f1ea-1f1ea.svg","flag_eg":"1f1ea-1f1ec.svg","flag_eh":"1f1ea-1f1ed.svg","flag_er":"1f1ea-1f1f7.svg","flag_es":"1f1ea-1f1f8.svg","flag_et":"1f1ea-1f1f9.svg","flag_eu":"1f1ea-1f1fa.svg","flag_fi":"1f1eb-1f1ee.svg","flag_fj":"1f1eb-1f1ef.svg","flag_fk":"1f1eb-1f1f0.svg","flag_fm":"1f1eb-1f1f2.svg","flag_fo":"1f1eb-1f1f4.svg","flag_fr":"1f1eb-1f1f7.svg","flag_ga":"1f1ec-1f1e6.svg","flag_gb":"1f1ec-1f1e7.svg","flag_gd":"1f1ec-1f1e9.svg","flag_ge":"1f1ec-1f1ea.svg","flag_gf":"1f1ec-1f1eb.svg","flag_gg":"1f1ec-1f1ec.svg","flag_gh":"1f1ec-1f1ed.svg","flag_gi":"1f1ec-1f1ee.svg","flag_gl":"1f1ec-1f1f1.svg","flag_gm":"1f1ec-1f1f2.svg","flag_gn":"1f1ec-1f1f3.svg","flag_gp":"1f1ec-1f1f5.svg","flag_gq":"1f1ec-1f1f6.svg","flag_gr":"1f1ec-1f1f7.svg","flag_gs":"1f1ec-1f1f8.svg","flag_gt":"1f1ec-1f1f9.svg","flag_gu":"1f1ec-1f1fa.svg","flag_gw":"1f1ec-1f1fc.svg","flag_gy":"1f1ec-1f1fe.svg","flag_hk":"1f1ed-1f1f0.svg","flag_hm":"1f1ed-1f1f2.svg","flag_hn":"1f1ed-1f1f3.svg","flag_hr":"1f1ed-1f1f7.svg","flag_ht":"1f1ed-1f1f9.svg","flag_hu":"1f1ed-1f1fa.svg","flag_ic":"1f1ee-1f1e8.svg","flag_id":"1f1ee-1f1e9.svg","flag_ie":"1f1ee-1f1ea.svg","flag_il":"1f1ee-1f1f1.svg","flag_im":"1f1ee-1f1f2.svg","flag_in":"1f1ee-1f1f3.svg","flag_io":"1f1ee-1f1f4.svg","flag_iq":"1f1ee-1f1f6.svg","flag_ir":"1f1ee-1f1f7.svg","flag_is":"1f1ee-1f1f8.svg","flag_it":"1f1ee-1f1f9.svg","flag_je":"1f1ef-1f1ea.svg","flag_jm":"1f1ef-1f1f2.svg","flag_jo":"1f1ef-1f1f4.svg","flag_jp":"1f1ef-1f1f5.svg","flag_ke":"1f1f0-1f1ea.svg","flag_kg":"1f1f0-1f1ec.svg","flag_kh":"1f1f0-1f1ed.svg","flag_ki":"1f1f0-1f1ee.svg","flag_km":"1f1f0-1f1f2.svg","flag_kn":"1f1f0-1f1f3.svg","flag_kp":"1f1f0-1f1f5.svg","flag_kr":"1f1f0-1f1f7.svg","flag_kw":"1f1f0-1f1fc.svg","flag_ky":"1f1f0-1f1fe.svg","flag_kz":"1f1f0-1f1ff.svg","flag_la":"1f1f1-1f1e6.svg","flag_lb":"1f1f1-1f1e7.svg","flag_lc":"1f1f1-1f1e8.svg","flag_li":"1f1f1-1f1ee.svg","flag_lk":"1f1f1-1f1f0.svg","flag_lr":"1f1f1-1f1f7.svg","flag_ls":"1f1f1-1f1f8.svg","flag_lt":"1f1f1-1f1f9.svg","flag_lu":"1f1f1-1f1fa.svg","flag_lv":"1f1f1-1f1fb.svg","flag_ly":"1f1f1-1f1fe.svg","flag_ma":"1f1f2-1f1e6.svg","flag_mc":"1f1f2-1f1e8.svg","flag_md":"1f1f2-1f1e9.svg","flag_me":"1f1f2-1f1ea.svg","flag_mf":"1f1f2-1f1eb.svg","flag_mg":"1f1f2-1f1ec.svg","flag_mh":"1f1f2-1f1ed.svg","flag_mk":"1f1f2-1f1f0.svg","flag_ml":"1f1f2-1f1f1.svg","flag_mm":"1f1f2-1f1f2.svg","flag_mn":"1f1f2-1f1f3.svg","flag_mo":"1f1f2-1f1f4.svg","flag_mp":"1f1f2-1f1f5.svg","flag_mq":"1f1f2-1f1f6.svg","flag_mr":"1f1f2-1f1f7.svg","flag_ms":"1f1f2-1f1f8.svg","flag_mt":"1f1f2-1f1f9.svg","flag_mu":"1f1f2-1f1fa.svg","flag_mv":"1f1f2-1f1fb.svg","flag_mw":"1f1f2-1f1fc.svg","flag_mx":"1f1f2-1f1fd.svg","flag_my":"1f1f2-1f1fe.svg","flag_mz":"1f1f2-1f1ff.svg","flag_na":"1f1f3-1f1e6.svg","flag_nc":"1f1f3-1f1e8.svg","flag_ne":"1f1f3-1f1ea.svg","flag_nf":"1f1f3-1f1eb.svg","flag_ng":"1f1f3-1f1ec.svg","flag_ni":"1f1f3-1f1ee.svg","flag_nl":"1f1f3-1f1f1.svg","flag_no":"1f1f3-1f1f4.svg","flag_np":"1f1f3-1f1f5.svg","flag_nr":"1f1f3-1f1f7.svg","flag_nu":"1f1f3-1f1fa.svg","flag_nz":"1f1f3-1f1ff.svg","flag_om":"1f1f4-1f1f2.svg","flag_pa":"1f1f5-1f1e6.svg","flag_pe":"1f1f5-1f1ea.svg","flag_pf":"1f1f5-1f1eb.svg","flag_pg":"1f1f5-1f1ec.svg","flag_ph":"1f1f5-1f1ed.svg","flag_pk":"1f1f5-1f1f0.svg","flag_pl":"1f1f5-1f1f1.svg","flag_pm":"1f1f5-1f1f2.svg","flag_pn":"1f1f5-1f1f3.svg","flag_pr":"1f1f5-1f1f7.svg","flag_ps":"1f1f5-1f1f8.svg","flag_pt":"1f1f5-1f1f9.svg","flag_pw":"1f1f5-1f1fc.svg","flag_py":"1f1f5-1f1fe.svg","flag_qa":"1f1f6-1f1e6.svg","flag_re":"1f1f7-1f1ea.svg","flag_ro":"1f1f7-1f1f4.svg","flag_rs":"1f1f7-1f1f8.svg","flag_ru":"1f1f7-1f1fa.svg","flag_rw":"1f1f7-1f1fc.svg","flag_sa":"1f1f8-1f1e6.svg","flag_sb":"1f1f8-1f1e7.svg","flag_sc":"1f1f8-1f1e8.svg","flag_sd":"1f1f8-1f1e9.svg","flag_se":"1f1f8-1f1ea.svg","flag_sg":"1f1f8-1f1ec.svg","flag_sh":"1f1f8-1f1ed.svg","flag_si":"1f1f8-1f1ee.svg","flag_sj":"1f1f8-1f1ef.svg","flag_sk":"1f1f8-1f1f0.svg","flag_sl":"1f1f8-1f1f1.svg","flag_sm":"1f1f8-1f1f2.svg","flag_sn":"1f1f8-1f1f3.svg","flag_so":"1f1f8-1f1f4.svg","flag_sr":"1f1f8-1f1f7.svg","flag_ss":"1f1f8-1f1f8.svg","flag_st":"1f1f8-1f1f9.svg","flag_sv":"1f1f8-1f1fb.svg","flag_sx":"1f1f8-1f1fd.svg","flag_sy":"1f1f8-1f1fe.svg","flag_sz":"1f1f8-1f1ff.svg","flag_ta":"1f1f9-1f1e6.svg","flag_tc":"1f1f9-1f1e8.svg","flag_td":"1f1f9-1f1e9.svg","flag_tf":"1f1f9-1f1eb.svg","flag_tg":"1f1f9-1f1ec.svg","flag_th":"1f1f9-1f1ed.svg","flag_tj":"1f1f9-1f1ef.svg","flag_tk":"1f1f9-1f1f0.svg","flag_tl":"1f1f9-1f1f1.svg","flag_tm":"1f1f9-1f1f2.svg","flag_tn":"1f1f9-1f1f3.svg","flag_to":"1f1f9-1f1f4.svg","flag_tr":"1f1f9-1f1f7.svg","flag_tt":"1f1f9-1f1f9.svg","flag_tv":"1f1f9-1f1fb.svg","flag_tw":"1f1f9-1f1fc.svg","flag_tz":"1f1f9-1f1ff.svg","flag_ua":"1f1fa-1f1e6.svg","flag_ug":"1f1fa-1f1ec.svg","flag_um":"1f1fa-1f1f2.svg","flag_us":"1f1fa-1f1f8.svg","flag_uy":"1f1fa-1f1fe.svg","flag_uz":"1f1fa-1f1ff.svg","flag_va":"1f1fb-1f1e6.svg","flag_vc":"1f1fb-1f1e8.svg","flag_ve":"1f1fb-1f1ea.svg","flag_vg":"1f1fb-1f1ec.svg","flag_vi":"1f1fb-1f1ee.svg","flag_vn":"1f1fb-1f1f3.svg","flag_vu":"1f1fb-1f1fa.svg","flag_wf":"1f1fc-1f1eb.svg","flag_white":"1f3f3.svg","flag_ws":"1f1fc-1f1f8.svg","flag_xk":"1f1fd-1f1f0.svg","flag_ye":"1f1fe-1f1ea.svg","flag_yt":"1f1fe-1f1f9.svg","flag_za":"1f1ff-1f1e6.svg","flag_zm":"1f1ff-1f1f2.svg","flag_zw":"1f1ff-1f1fc.svg","flags":"1f38f.svg","flamingo":"1f9a9.svg","flashlight":"1f526.svg","flatbread":"1fad3.svg","fleur-de-lis":"269c.svg","floppy_disk":"1f4be.svg","flower_playing_cards":"1f3b4.svg","flushed":"1f633.svg","fly":"1fab0.svg","flying_disc":"1f94f.svg","flying_saucer":"1f6f8.svg","fog":"1f32b.svg","foggy":"1f301.svg","fondue":"1fad5.svg","foot":"1f9b6.svg","foot_tone1":"1f9b6-1f3fb.svg","foot_tone2":"1f9b6-1f3fc.svg","foot_tone3":"1f9b6-1f3fd.svg","foot_tone4":"1f9b6-1f3fe.svg","foot_tone5":"1f9b6-1f3ff.svg","football":"1f3c8.svg","footprints":"1f463.svg","fork_and_knife":"1f374.svg","fork_knife_plate":"1f37d.svg","fortune_cookie":"1f960.svg","fountain":"26f2.svg","four":"34-20e3.svg","four_leaf_clover":"1f340.svg","fox":"1f98a.svg","frame_photo":"1f5bc.svg","free":"1f193.svg","french_bread":"1f956.svg","fried_shrimp":"1f364.svg","fries":"1f35f.svg","frog":"1f438.svg","frowning2":"2639.svg","frowning":"1f626.svg","fuelpump":"26fd.svg","full_moon":"1f315.svg","full_moon_with_face":"1f31d.svg","game_die":"1f3b2.svg","garlic":"1f9c4.svg","gear":"2699.svg","gem":"1f48e.svg","gemini":"264a.svg","genie":"1f9de.svg","ghost":"1f47b.svg","gift":"1f381.svg","gift_heart":"1f49d.svg","giraffe":"1f992.svg","girl":"1f467.svg","girl_tone1":"1f467-1f3fb.svg","girl_tone2":"1f467-1f3fc.svg","girl_tone3":"1f467-1f3fd.svg","girl_tone4":"1f467-1f3fe.svg","girl_tone5":"1f467-1f3ff.svg","globe_with_meridians":"1f310.svg","gloves":"1f9e4.svg","goal":"1f945.svg","goat":"1f410.svg","goggles":"1f97d.svg","golf":"26f3.svg","gorilla":"1f98d.svg","grapes":"1f347.svg","green_apple":"1f34f.svg","green_book":"1f4d7.svg","green_circle":"1f7e2.svg","green_heart":"1f49a.svg","green_square":"1f7e9.svg","grey_exclamation":"2755.svg","grey_question":"2754.svg","grimacing":"1f62c.svg","grin":"1f601.svg","grinning":"1f600.svg","guard":"1f482.svg","guard_tone1":"1f482-1f3fb.svg","guard_tone2":"1f482-1f3fc.svg","guard_tone3":"1f482-1f3fd.svg","guard_tone4":"1f482-1f3fe.svg","guard_tone5":"1f482-1f3ff.svg","guide_dog":"1f9ae.svg","guitar":"1f3b8.svg","gun":"1f52b.svg","hamburger":"1f354.svg","hammer":"1f528.svg","hammer_pick":"2692.svg","hamster":"1f439.svg","hand_splayed":"1f590.svg","hand_splayed_tone1":"1f590-1f3fb.svg","hand_splayed_tone2":"1f590-1f3fc.svg","hand_splayed_tone3":"1f590-1f3fd.svg","hand_splayed_tone4":"1f590-1f3fe.svg","hand_splayed_tone5":"1f590-1f3ff.svg","handbag":"1f45c.svg","handshake":"1f91d.svg","hash":"23-20e3.svg","hatched_chick":"1f425.svg","hatching_chick":"1f423.svg","head_bandage":"1f915.svg","headphones":"1f3a7.svg","headstone":"1faa6.svg","health_worker":"1f9d1-200d-2695-fe0f.svg","health_worker_tone1":"1f9d1-1f3fb-200d-2695-fe0f.svg","health_worker_tone2":"1f9d1-1f3fc-200d-2695-fe0f.svg","health_worker_tone3":"1f9d1-1f3fd-200d-2695-fe0f.svg","health_worker_tone4":"1f9d1-1f3fe-200d-2695-fe0f.svg","health_worker_tone5":"1f9d1-1f3ff-200d-2695-fe0f.svg","hear_no_evil":"1f649.svg","heart":"2764.svg","heart_decoration":"1f49f.svg","heart_exclamation":"2763.svg","heart_eyes":"1f60d.svg","heart_eyes_cat":"1f63b.svg","heart_on_fire":"2764-fe0f-200d-1f525.svg","heartbeat":"1f493.svg","heartpulse":"1f497.svg","hearts":"2665.svg","heavy_check_mark":"2714.svg","heavy_division_sign":"2797.svg","heavy_dollar_sign":"1f4b2.svg","heavy_minus_sign":"2796.svg","heavy_multiplication_x":"2716.svg","heavy_plus_sign":"2795.svg","hedgehog":"1f994.svg","helicopter":"1f681.svg","helmet_with_cross":"26d1.svg","herb":"1f33f.svg","hibiscus":"1f33a.svg","high_brightness":"1f506.svg","high_heel":"1f460.svg","hiking_boot":"1f97e.svg","hindu_temple":"1f6d5.svg","hippopotamus":"1f99b.svg","hockey":"1f3d2.svg","hole":"1f573.svg","homes":"1f3d8.svg","honey_pot":"1f36f.svg","hook":"1fa9d.svg","horse":"1f434.svg","horse_racing":"1f3c7.svg","horse_racing_tone1":"1f3c7-1f3fb.svg","horse_racing_tone2":"1f3c7-1f3fc.svg","horse_racing_tone3":"1f3c7-1f3fd.svg","horse_racing_tone4":"1f3c7-1f3fe.svg","horse_racing_tone5":"1f3c7-1f3ff.svg","hospital":"1f3e5.svg","hot_face":"1f975.svg","hot_pepper":"1f336.svg","hotdog":"1f32d.svg","hotel":"1f3e8.svg","hotsprings":"2668.svg","hourglass":"231b.svg","hourglass_flowing_sand":"23f3.svg","house":"1f3e0.svg","house_abandoned":"1f3da.svg","house_with_garden":"1f3e1.svg","hugging":"1f917.svg","hushed":"1f62f.svg","hut":"1f6d6.svg","ice_cream":"1f368.svg","ice_cube":"1f9ca.svg","ice_skate":"26f8.svg","icecream":"1f366.svg","id":"1f194.svg","ideograph_advantage":"1f250.svg","imp":"1f47f.svg","inbox_tray":"1f4e5.svg","incoming_envelope":"1f4e8.svg","infinity":"267e.svg","information_source":"2139.svg","innocent":"1f607.svg","interrobang":"2049.svg","island":"1f3dd.svg","izakaya_lantern":"1f3ee.svg","jack_o_lantern":"1f383.svg","japan":"1f5fe.svg","japanese_castle":"1f3ef.svg","japanese_goblin":"1f47a.svg","japanese_ogre":"1f479.svg","jeans":"1f456.svg","jigsaw":"1f9e9.svg","joy":"1f602.svg","joy_cat":"1f639.svg","joystick":"1f579.svg","judge":"1f9d1-200d-2696-fe0f.svg","judge_tone1":"1f9d1-1f3fb-200d-2696-fe0f.svg","judge_tone2":"1f9d1-1f3fc-200d-2696-fe0f.svg","judge_tone3":"1f9d1-1f3fd-200d-2696-fe0f.svg","judge_tone4":"1f9d1-1f3fe-200d-2696-fe0f.svg","judge_tone5":"1f9d1-1f3ff-200d-2696-fe0f.svg","kaaba":"1f54b.svg","kangaroo":"1f998.svg","key2":"1f5dd.svg","key":"1f511.svg","keyboard":"2328.svg","keycap_ten":"1f51f.svg","kimono":"1f458.svg","kiss":"1f48b.svg","kiss_man_man_tone1":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone1_tone2":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone1_tone3":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone1_tone4":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone1_tone5":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone2":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone2_tone1":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone2_tone3":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone2_tone4":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone2_tone5":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone3":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone3_tone1":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone3_tone2":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone3_tone4":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone3_tone5":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone4":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone4_tone1":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone4_tone2":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone4_tone3":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone4_tone5":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone5":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone5_tone1":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone5_tone2":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone5_tone3":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone5_tone4":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_mm":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468.svg","kiss_person_person_tone1_tone2":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone1_tone3":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone1_tone4":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_person_person_tone1_tone5":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone2_tone1":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone2_tone3":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone2_tone4":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_person_person_tone2_tone5":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone3_tone1":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone3_tone2":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone3_tone4":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_person_person_tone3_tone5":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone4_tone1":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone4_tone2":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone4_tone3":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone4_tone5":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone5_tone1":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone5_tone2":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone5_tone3":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone5_tone4":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_tone1":"1f48f-1f3fb.svg","kiss_tone2":"1f48f-1f3fc.svg","kiss_tone3":"1f48f-1f3fd.svg","kiss_tone4":"1f48f-1f3fe.svg","kiss_tone5":"1f48f-1f3ff.svg","kiss_woman_man":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468.svg","kiss_woman_man_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_woman_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_ww":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469.svg","kissing":"1f617.svg","kissing_cat":"1f63d.svg","kissing_closed_eyes":"1f61a.svg","kissing_heart":"1f618.svg","kissing_smiling_eyes":"1f619.svg","kite":"1fa81.svg","kiwi":"1f95d.svg","knife":"1f52a.svg","knot":"1faa2.svg","koala":"1f428.svg","koko":"1f201.svg","lab_coat":"1f97c.svg","label":"1f3f7.svg","lacrosse":"1f94d.svg","ladder":"1fa9c.svg","lady_beetle":"1f41e.svg","large_blue_diamond":"1f537.svg","large_orange_diamond":"1f536.svg","last_quarter_moon":"1f317.svg","last_quarter_moon_with_face":"1f31c.svg","laughing":"1f606.svg","leafy_green":"1f96c.svg","leaves":"1f343.svg","ledger":"1f4d2.svg","left_facing_fist":"1f91b.svg","left_facing_fist_tone1":"1f91b-1f3fb.svg","left_facing_fist_tone2":"1f91b-1f3fc.svg","left_facing_fist_tone3":"1f91b-1f3fd.svg","left_facing_fist_tone4":"1f91b-1f3fe.svg","left_facing_fist_tone5":"1f91b-1f3ff.svg","left_luggage":"1f6c5.svg","left_right_arrow":"2194.svg","leftwards_arrow_with_hook":"21a9.svg","leg":"1f9b5.svg","leg_tone1":"1f9b5-1f3fb.svg","leg_tone2":"1f9b5-1f3fc.svg","leg_tone3":"1f9b5-1f3fd.svg","leg_tone4":"1f9b5-1f3fe.svg","leg_tone5":"1f9b5-1f3ff.svg","lemon":"1f34b.svg","leo":"264c.svg","leopard":"1f406.svg","level_slider":"1f39a.svg","levitate":"1f574.svg","levitate_tone1":"1f574-1f3fb.svg","levitate_tone2":"1f574-1f3fc.svg","levitate_tone3":"1f574-1f3fd.svg","levitate_tone4":"1f574-1f3fe.svg","levitate_tone5":"1f574-1f3ff.svg","libra":"264e.svg","light_rail":"1f688.svg","link":"1f517.svg","lion_face":"1f981.svg","lips":"1f444.svg","lipstick":"1f484.svg","lizard":"1f98e.svg","llama":"1f999.svg","lobster":"1f99e.svg","lock":"1f512.svg","lock_with_ink_pen":"1f50f.svg","lollipop":"1f36d.svg","long_drum":"1fa98.svg","loop":"27bf.svg","loud_sound":"1f50a.svg","loudspeaker":"1f4e2.svg","love_hotel":"1f3e9.svg","love_letter":"1f48c.svg","love_you_gesture":"1f91f.svg","love_you_gesture_tone1":"1f91f-1f3fb.svg","love_you_gesture_tone2":"1f91f-1f3fc.svg","love_you_gesture_tone3":"1f91f-1f3fd.svg","love_you_gesture_tone4":"1f91f-1f3fe.svg","love_you_gesture_tone5":"1f91f-1f3ff.svg","low_brightness":"1f505.svg","luggage":"1f9f3.svg","lungs":"1fac1.svg","lying_face":"1f925.svg","m":"24c2.svg","mag":"1f50d.svg","mag_right":"1f50e.svg","mage":"1f9d9.svg","mage_tone1":"1f9d9-1f3fb.svg","mage_tone2":"1f9d9-1f3fc.svg","mage_tone3":"1f9d9-1f3fd.svg","mage_tone4":"1f9d9-1f3fe.svg","mage_tone5":"1f9d9-1f3ff.svg","magic_wand":"1fa84.svg","magnet":"1f9f2.svg","mahjong":"1f004.svg","mailbox":"1f4eb.svg","mailbox_closed":"1f4ea.svg","mailbox_with_mail":"1f4ec.svg","mailbox_with_no_mail":"1f4ed.svg","male_sign":"2642.svg","mammoth":"1f9a3.svg","man":"1f468.svg","man_artist":"1f468-200d-1f3a8.svg","man_artist_tone1":"1f468-1f3fb-200d-1f3a8.svg","man_artist_tone2":"1f468-1f3fc-200d-1f3a8.svg","man_artist_tone3":"1f468-1f3fd-200d-1f3a8.svg","man_artist_tone4":"1f468-1f3fe-200d-1f3a8.svg","man_artist_tone5":"1f468-1f3ff-200d-1f3a8.svg","man_astronaut":"1f468-200d-1f680.svg","man_astronaut_tone1":"1f468-1f3fb-200d-1f680.svg","man_astronaut_tone2":"1f468-1f3fc-200d-1f680.svg","man_astronaut_tone3":"1f468-1f3fd-200d-1f680.svg","man_astronaut_tone4":"1f468-1f3fe-200d-1f680.svg","man_astronaut_tone5":"1f468-1f3ff-200d-1f680.svg","man_bald":"1f468-200d-1f9b2.svg","man_bald_tone1":"1f468-1f3fb-200d-1f9b2.svg","man_bald_tone2":"1f468-1f3fc-200d-1f9b2.svg","man_bald_tone3":"1f468-1f3fd-200d-1f9b2.svg","man_bald_tone4":"1f468-1f3fe-200d-1f9b2.svg","man_bald_tone5":"1f468-1f3ff-200d-1f9b2.svg","man_beard":"1f9d4-200d-2642-fe0f.svg","man_biking":"1f6b4-200d-2642-fe0f.svg","man_biking_tone1":"1f6b4-1f3fb-200d-2642-fe0f.svg","man_biking_tone2":"1f6b4-1f3fc-200d-2642-fe0f.svg","man_biking_tone3":"1f6b4-1f3fd-200d-2642-fe0f.svg","man_biking_tone4":"1f6b4-1f3fe-200d-2642-fe0f.svg","man_biking_tone5":"1f6b4-1f3ff-200d-2642-fe0f.svg","man_bouncing_ball":"26f9-fe0f-200d-2642-fe0f.svg","man_bouncing_ball_tone1":"26f9-1f3fb-200d-2642-fe0f.svg","man_bouncing_ball_tone2":"26f9-1f3fc-200d-2642-fe0f.svg","man_bouncing_ball_tone3":"26f9-1f3fd-200d-2642-fe0f.svg","man_bouncing_ball_tone4":"26f9-1f3fe-200d-2642-fe0f.svg","man_bouncing_ball_tone5":"26f9-1f3ff-200d-2642-fe0f.svg","man_bowing":"1f647-200d-2642-fe0f.svg","man_bowing_tone1":"1f647-1f3fb-200d-2642-fe0f.svg","man_bowing_tone2":"1f647-1f3fc-200d-2642-fe0f.svg","man_bowing_tone3":"1f647-1f3fd-200d-2642-fe0f.svg","man_bowing_tone4":"1f647-1f3fe-200d-2642-fe0f.svg","man_bowing_tone5":"1f647-1f3ff-200d-2642-fe0f.svg","man_cartwheeling":"1f938-200d-2642-fe0f.svg","man_cartwheeling_tone1":"1f938-1f3fb-200d-2642-fe0f.svg","man_cartwheeling_tone2":"1f938-1f3fc-200d-2642-fe0f.svg","man_cartwheeling_tone3":"1f938-1f3fd-200d-2642-fe0f.svg","man_cartwheeling_tone4":"1f938-1f3fe-200d-2642-fe0f.svg","man_cartwheeling_tone5":"1f938-1f3ff-200d-2642-fe0f.svg","man_climbing":"1f9d7-200d-2642-fe0f.svg","man_climbing_tone1":"1f9d7-1f3fb-200d-2642-fe0f.svg","man_climbing_tone2":"1f9d7-1f3fc-200d-2642-fe0f.svg","man_climbing_tone3":"1f9d7-1f3fd-200d-2642-fe0f.svg","man_climbing_tone4":"1f9d7-1f3fe-200d-2642-fe0f.svg","man_climbing_tone5":"1f9d7-1f3ff-200d-2642-fe0f.svg","man_construction_worker":"1f477-200d-2642-fe0f.svg","man_construction_worker_tone1":"1f477-1f3fb-200d-2642-fe0f.svg","man_construction_worker_tone2":"1f477-1f3fc-200d-2642-fe0f.svg","man_construction_worker_tone3":"1f477-1f3fd-200d-2642-fe0f.svg","man_construction_worker_tone4":"1f477-1f3fe-200d-2642-fe0f.svg","man_construction_worker_tone5":"1f477-1f3ff-200d-2642-fe0f.svg","man_cook":"1f468-200d-1f373.svg","man_cook_tone1":"1f468-1f3fb-200d-1f373.svg","man_cook_tone2":"1f468-1f3fc-200d-1f373.svg","man_cook_tone3":"1f468-1f3fd-200d-1f373.svg","man_cook_tone4":"1f468-1f3fe-200d-1f373.svg","man_cook_tone5":"1f468-1f3ff-200d-1f373.svg","man_curly_haired":"1f468-200d-1f9b1.svg","man_curly_haired_tone1":"1f468-1f3fb-200d-1f9b1.svg","man_curly_haired_tone2":"1f468-1f3fc-200d-1f9b1.svg","man_curly_haired_tone3":"1f468-1f3fd-200d-1f9b1.svg","man_curly_haired_tone4":"1f468-1f3fe-200d-1f9b1.svg","man_curly_haired_tone5":"1f468-1f3ff-200d-1f9b1.svg","man_dancing":"1f57a.svg","man_dancing_tone1":"1f57a-1f3fb.svg","man_dancing_tone2":"1f57a-1f3fc.svg","man_dancing_tone3":"1f57a-1f3fd.svg","man_dancing_tone4":"1f57a-1f3fe.svg","man_dancing_tone5":"1f57a-1f3ff.svg","man_detective":"1f575-fe0f-200d-2642-fe0f.svg","man_detective_tone1":"1f575-1f3fb-200d-2642-fe0f.svg","man_detective_tone2":"1f575-1f3fc-200d-2642-fe0f.svg","man_detective_tone3":"1f575-1f3fd-200d-2642-fe0f.svg","man_detective_tone4":"1f575-1f3fe-200d-2642-fe0f.svg","man_detective_tone5":"1f575-1f3ff-200d-2642-fe0f.svg","man_elf":"1f9dd-200d-2642-fe0f.svg","man_elf_tone1":"1f9dd-1f3fb-200d-2642-fe0f.svg","man_elf_tone2":"1f9dd-1f3fc-200d-2642-fe0f.svg","man_elf_tone3":"1f9dd-1f3fd-200d-2642-fe0f.svg","man_elf_tone4":"1f9dd-1f3fe-200d-2642-fe0f.svg","man_elf_tone5":"1f9dd-1f3ff-200d-2642-fe0f.svg","man_facepalming":"1f926-200d-2642-fe0f.svg","man_facepalming_tone1":"1f926-1f3fb-200d-2642-fe0f.svg","man_facepalming_tone2":"1f926-1f3fc-200d-2642-fe0f.svg","man_facepalming_tone3":"1f926-1f3fd-200d-2642-fe0f.svg","man_facepalming_tone4":"1f926-1f3fe-200d-2642-fe0f.svg","man_facepalming_tone5":"1f926-1f3ff-200d-2642-fe0f.svg","man_factory_worker":"1f468-200d-1f3ed.svg","man_factory_worker_tone1":"1f468-1f3fb-200d-1f3ed.svg","man_factory_worker_tone2":"1f468-1f3fc-200d-1f3ed.svg","man_factory_worker_tone3":"1f468-1f3fd-200d-1f3ed.svg","man_factory_worker_tone4":"1f468-1f3fe-200d-1f3ed.svg","man_factory_worker_tone5":"1f468-1f3ff-200d-1f3ed.svg","man_fairy":"1f9da-200d-2642-fe0f.svg","man_fairy_tone1":"1f9da-1f3fb-200d-2642-fe0f.svg","man_fairy_tone2":"1f9da-1f3fc-200d-2642-fe0f.svg","man_fairy_tone3":"1f9da-1f3fd-200d-2642-fe0f.svg","man_fairy_tone4":"1f9da-1f3fe-200d-2642-fe0f.svg","man_fairy_tone5":"1f9da-1f3ff-200d-2642-fe0f.svg","man_farmer":"1f468-200d-1f33e.svg","man_farmer_tone1":"1f468-1f3fb-200d-1f33e.svg","man_farmer_tone2":"1f468-1f3fc-200d-1f33e.svg","man_farmer_tone3":"1f468-1f3fd-200d-1f33e.svg","man_farmer_tone4":"1f468-1f3fe-200d-1f33e.svg","man_farmer_tone5":"1f468-1f3ff-200d-1f33e.svg","man_feeding_baby":"1f468-200d-1f37c.svg","man_feeding_baby_tone1":"1f468-1f3fb-200d-1f37c.svg","man_feeding_baby_tone2":"1f468-1f3fc-200d-1f37c.svg","man_feeding_baby_tone3":"1f468-1f3fd-200d-1f37c.svg","man_feeding_baby_tone4":"1f468-1f3fe-200d-1f37c.svg","man_feeding_baby_tone5":"1f468-1f3ff-200d-1f37c.svg","man_firefighter":"1f468-200d-1f692.svg","man_firefighter_tone1":"1f468-1f3fb-200d-1f692.svg","man_firefighter_tone2":"1f468-1f3fc-200d-1f692.svg","man_firefighter_tone3":"1f468-1f3fd-200d-1f692.svg","man_firefighter_tone4":"1f468-1f3fe-200d-1f692.svg","man_firefighter_tone5":"1f468-1f3ff-200d-1f692.svg","man_frowning":"1f64d-200d-2642-fe0f.svg","man_frowning_tone1":"1f64d-1f3fb-200d-2642-fe0f.svg","man_frowning_tone2":"1f64d-1f3fc-200d-2642-fe0f.svg","man_frowning_tone3":"1f64d-1f3fd-200d-2642-fe0f.svg","man_frowning_tone4":"1f64d-1f3fe-200d-2642-fe0f.svg","man_frowning_tone5":"1f64d-1f3ff-200d-2642-fe0f.svg","man_genie":"1f9de-200d-2642-fe0f.svg","man_gesturing_no":"1f645-200d-2642-fe0f.svg","man_gesturing_no_tone1":"1f645-1f3fb-200d-2642-fe0f.svg","man_gesturing_no_tone2":"1f645-1f3fc-200d-2642-fe0f.svg","man_gesturing_no_tone3":"1f645-1f3fd-200d-2642-fe0f.svg","man_gesturing_no_tone4":"1f645-1f3fe-200d-2642-fe0f.svg","man_gesturing_no_tone5":"1f645-1f3ff-200d-2642-fe0f.svg","man_gesturing_ok":"1f646-200d-2642-fe0f.svg","man_gesturing_ok_tone1":"1f646-1f3fb-200d-2642-fe0f.svg","man_gesturing_ok_tone2":"1f646-1f3fc-200d-2642-fe0f.svg","man_gesturing_ok_tone3":"1f646-1f3fd-200d-2642-fe0f.svg","man_gesturing_ok_tone4":"1f646-1f3fe-200d-2642-fe0f.svg","man_gesturing_ok_tone5":"1f646-1f3ff-200d-2642-fe0f.svg","man_getting_face_massage":"1f486-200d-2642-fe0f.svg","man_getting_face_massage_tone1":"1f486-1f3fb-200d-2642-fe0f.svg","man_getting_face_massage_tone2":"1f486-1f3fc-200d-2642-fe0f.svg","man_getting_face_massage_tone3":"1f486-1f3fd-200d-2642-fe0f.svg","man_getting_face_massage_tone4":"1f486-1f3fe-200d-2642-fe0f.svg","man_getting_face_massage_tone5":"1f486-1f3ff-200d-2642-fe0f.svg","man_getting_haircut":"1f487-200d-2642-fe0f.svg","man_getting_haircut_tone1":"1f487-1f3fb-200d-2642-fe0f.svg","man_getting_haircut_tone2":"1f487-1f3fc-200d-2642-fe0f.svg","man_getting_haircut_tone3":"1f487-1f3fd-200d-2642-fe0f.svg","man_getting_haircut_tone4":"1f487-1f3fe-200d-2642-fe0f.svg","man_getting_haircut_tone5":"1f487-1f3ff-200d-2642-fe0f.svg","man_golfing":"1f3cc-fe0f-200d-2642-fe0f.svg","man_golfing_tone1":"1f3cc-1f3fb-200d-2642-fe0f.svg","man_golfing_tone2":"1f3cc-1f3fc-200d-2642-fe0f.svg","man_golfing_tone3":"1f3cc-1f3fd-200d-2642-fe0f.svg","man_golfing_tone4":"1f3cc-1f3fe-200d-2642-fe0f.svg","man_golfing_tone5":"1f3cc-1f3ff-200d-2642-fe0f.svg","man_guard":"1f482-200d-2642-fe0f.svg","man_guard_tone1":"1f482-1f3fb-200d-2642-fe0f.svg","man_guard_tone2":"1f482-1f3fc-200d-2642-fe0f.svg","man_guard_tone3":"1f482-1f3fd-200d-2642-fe0f.svg","man_guard_tone4":"1f482-1f3fe-200d-2642-fe0f.svg","man_guard_tone5":"1f482-1f3ff-200d-2642-fe0f.svg","man_health_worker":"1f468-200d-2695-fe0f.svg","man_health_worker_tone1":"1f468-1f3fb-200d-2695-fe0f.svg","man_health_worker_tone2":"1f468-1f3fc-200d-2695-fe0f.svg","man_health_worker_tone3":"1f468-1f3fd-200d-2695-fe0f.svg","man_health_worker_tone4":"1f468-1f3fe-200d-2695-fe0f.svg","man_health_worker_tone5":"1f468-1f3ff-200d-2695-fe0f.svg","man_in_lotus_position":"1f9d8-200d-2642-fe0f.svg","man_in_lotus_position_tone1":"1f9d8-1f3fb-200d-2642-fe0f.svg","man_in_lotus_position_tone2":"1f9d8-1f3fc-200d-2642-fe0f.svg","man_in_lotus_position_tone3":"1f9d8-1f3fd-200d-2642-fe0f.svg","man_in_lotus_position_tone4":"1f9d8-1f3fe-200d-2642-fe0f.svg","man_in_lotus_position_tone5":"1f9d8-1f3ff-200d-2642-fe0f.svg","man_in_manual_wheelchair":"1f468-200d-1f9bd.svg","man_in_manual_wheelchair_tone1":"1f468-1f3fb-200d-1f9bd.svg","man_in_manual_wheelchair_tone2":"1f468-1f3fc-200d-1f9bd.svg","man_in_manual_wheelchair_tone3":"1f468-1f3fd-200d-1f9bd.svg","man_in_manual_wheelchair_tone4":"1f468-1f3fe-200d-1f9bd.svg","man_in_manual_wheelchair_tone5":"1f468-1f3ff-200d-1f9bd.svg","man_in_motorized_wheelchair":"1f468-200d-1f9bc.svg","man_in_motorized_wheelchair_tone1":"1f468-1f3fb-200d-1f9bc.svg","man_in_motorized_wheelchair_tone2":"1f468-1f3fc-200d-1f9bc.svg","man_in_motorized_wheelchair_tone3":"1f468-1f3fd-200d-1f9bc.svg","man_in_motorized_wheelchair_tone4":"1f468-1f3fe-200d-1f9bc.svg","man_in_motorized_wheelchair_tone5":"1f468-1f3ff-200d-1f9bc.svg","man_in_santa_hat":"1f468-200d-1f384.svg","man_in_santa_hat_tone1":"1f468-1f3fb-200d-1f384.svg","man_in_santa_hat_tone2":"1f468-1f3fc-200d-1f384.svg","man_in_santa_hat_tone3":"1f468-1f3fd-200d-1f384.svg","man_in_santa_hat_tone4":"1f468-1f3fe-200d-1f384.svg","man_in_santa_hat_tone5":"1f469-1f3ff-200d-1f384.svg","man_in_steamy_room":"1f9d6-200d-2642-fe0f.svg","man_in_steamy_room_tone1":"1f9d6-1f3fb-200d-2642-fe0f.svg","man_in_steamy_room_tone2":"1f9d6-1f3fc-200d-2642-fe0f.svg","man_in_steamy_room_tone3":"1f9d6-1f3fd-200d-2642-fe0f.svg","man_in_steamy_room_tone4":"1f9d6-1f3fe-200d-2642-fe0f.svg","man_in_steamy_room_tone5":"1f9d6-1f3ff-200d-2642-fe0f.svg","man_in_tuxedo":"1f935-200d-2642-fe0f.svg","man_in_tuxedo_tone1":"1f935-1f3fb-200d-2642-fe0f.svg","man_in_tuxedo_tone2":"1f935-1f3fc-200d-2642-fe0f.svg","man_in_tuxedo_tone3":"1f935-1f3fd-200d-2642-fe0f.svg","man_in_tuxedo_tone4":"1f935-1f3fe-200d-2642-fe0f.svg","man_in_tuxedo_tone5":"1f935-1f3ff-200d-2642-fe0f.svg","man_judge":"1f468-200d-2696-fe0f.svg","man_judge_tone1":"1f468-1f3fb-200d-2696-fe0f.svg","man_judge_tone2":"1f468-1f3fc-200d-2696-fe0f.svg","man_judge_tone3":"1f468-1f3fd-200d-2696-fe0f.svg","man_judge_tone4":"1f468-1f3fe-200d-2696-fe0f.svg","man_judge_tone5":"1f468-1f3ff-200d-2696-fe0f.svg","man_juggling":"1f939-200d-2642-fe0f.svg","man_juggling_tone1":"1f939-1f3fb-200d-2642-fe0f.svg","man_juggling_tone2":"1f939-1f3fc-200d-2642-fe0f.svg","man_juggling_tone3":"1f939-1f3fd-200d-2642-fe0f.svg","man_juggling_tone4":"1f939-1f3fe-200d-2642-fe0f.svg","man_juggling_tone5":"1f939-1f3ff-200d-2642-fe0f.svg","man_kneeling":"1f9ce-200d-2642-fe0f.svg","man_kneeling_tone1":"1f9ce-1f3fb-200d-2642-fe0f.svg","man_kneeling_tone2":"1f9ce-1f3fc-200d-2642-fe0f.svg","man_kneeling_tone3":"1f9ce-1f3fd-200d-2642-fe0f.svg","man_kneeling_tone4":"1f9ce-1f3fe-200d-2642-fe0f.svg","man_kneeling_tone5":"1f9ce-1f3ff-200d-2642-fe0f.svg","man_lifting_weights":"1f3cb-fe0f-200d-2642-fe0f.svg","man_lifting_weights_tone1":"1f3cb-1f3fb-200d-2642-fe0f.svg","man_lifting_weights_tone2":"1f3cb-1f3fc-200d-2642-fe0f.svg","man_lifting_weights_tone3":"1f3cb-1f3fd-200d-2642-fe0f.svg","man_lifting_weights_tone4":"1f3cb-1f3fe-200d-2642-fe0f.svg","man_lifting_weights_tone5":"1f3cb-1f3ff-200d-2642-fe0f.svg","man_mage":"1f9d9-200d-2642-fe0f.svg","man_mage_tone1":"1f9d9-1f3fb-200d-2642-fe0f.svg","man_mage_tone2":"1f9d9-1f3fc-200d-2642-fe0f.svg","man_mage_tone3":"1f9d9-1f3fd-200d-2642-fe0f.svg","man_mage_tone4":"1f9d9-1f3fe-200d-2642-fe0f.svg","man_mage_tone5":"1f9d9-1f3ff-200d-2642-fe0f.svg","man_mechanic":"1f468-200d-1f527.svg","man_mechanic_tone1":"1f468-1f3fb-200d-1f527.svg","man_mechanic_tone2":"1f468-1f3fc-200d-1f527.svg","man_mechanic_tone3":"1f468-1f3fd-200d-1f527.svg","man_mechanic_tone4":"1f468-1f3fe-200d-1f527.svg","man_mechanic_tone5":"1f468-1f3ff-200d-1f527.svg","man_mountain_biking":"1f6b5-200d-2642-fe0f.svg","man_mountain_biking_tone1":"1f6b5-1f3fb-200d-2642-fe0f.svg","man_mountain_biking_tone2":"1f6b5-1f3fc-200d-2642-fe0f.svg","man_mountain_biking_tone3":"1f6b5-1f3fd-200d-2642-fe0f.svg","man_mountain_biking_tone4":"1f6b5-1f3fe-200d-2642-fe0f.svg","man_mountain_biking_tone5":"1f6b5-1f3ff-200d-2642-fe0f.svg","man_office_worker":"1f468-200d-1f4bc.svg","man_office_worker_tone1":"1f468-1f3fb-200d-1f4bc.svg","man_office_worker_tone2":"1f468-1f3fc-200d-1f4bc.svg","man_office_worker_tone3":"1f468-1f3fd-200d-1f4bc.svg","man_office_worker_tone4":"1f468-1f3fe-200d-1f4bc.svg","man_office_worker_tone5":"1f468-1f3ff-200d-1f4bc.svg","man_pilot":"1f468-200d-2708-fe0f.svg","man_pilot_tone1":"1f468-1f3fb-200d-2708-fe0f.svg","man_pilot_tone2":"1f468-1f3fc-200d-2708-fe0f.svg","man_pilot_tone3":"1f468-1f3fd-200d-2708-fe0f.svg","man_pilot_tone4":"1f468-1f3fe-200d-2708-fe0f.svg","man_pilot_tone5":"1f468-1f3ff-200d-2708-fe0f.svg","man_playing_handball":"1f93e-200d-2642-fe0f.svg","man_playing_handball_tone1":"1f93e-1f3fb-200d-2642-fe0f.svg","man_playing_handball_tone2":"1f93e-1f3fc-200d-2642-fe0f.svg","man_playing_handball_tone3":"1f93e-1f3fd-200d-2642-fe0f.svg","man_playing_handball_tone4":"1f93e-1f3fe-200d-2642-fe0f.svg","man_playing_handball_tone5":"1f93e-1f3ff-200d-2642-fe0f.svg","man_playing_water_polo":"1f93d-200d-2642-fe0f.svg","man_playing_water_polo_tone1":"1f93d-1f3fb-200d-2642-fe0f.svg","man_playing_water_polo_tone2":"1f93d-1f3fc-200d-2642-fe0f.svg","man_playing_water_polo_tone3":"1f93d-1f3fd-200d-2642-fe0f.svg","man_playing_water_polo_tone4":"1f93d-1f3fe-200d-2642-fe0f.svg","man_playing_water_polo_tone5":"1f93d-1f3ff-200d-2642-fe0f.svg","man_police_officer":"1f46e-200d-2642-fe0f.svg","man_police_officer_tone1":"1f46e-1f3fb-200d-2642-fe0f.svg","man_police_officer_tone2":"1f46e-1f3fc-200d-2642-fe0f.svg","man_police_officer_tone3":"1f46e-1f3fd-200d-2642-fe0f.svg","man_police_officer_tone4":"1f46e-1f3fe-200d-2642-fe0f.svg","man_police_officer_tone5":"1f46e-1f3ff-200d-2642-fe0f.svg","man_pouting":"1f64e-200d-2642-fe0f.svg","man_pouting_tone1":"1f64e-1f3fb-200d-2642-fe0f.svg","man_pouting_tone2":"1f64e-1f3fc-200d-2642-fe0f.svg","man_pouting_tone3":"1f64e-1f3fd-200d-2642-fe0f.svg","man_pouting_tone4":"1f64e-1f3fe-200d-2642-fe0f.svg","man_pouting_tone5":"1f64e-1f3ff-200d-2642-fe0f.svg","man_raising_hand":"1f64b-200d-2642-fe0f.svg","man_raising_hand_tone1":"1f64b-1f3fb-200d-2642-fe0f.svg","man_raising_hand_tone2":"1f64b-1f3fc-200d-2642-fe0f.svg","man_raising_hand_tone3":"1f64b-1f3fd-200d-2642-fe0f.svg","man_raising_hand_tone4":"1f64b-1f3fe-200d-2642-fe0f.svg","man_raising_hand_tone5":"1f64b-1f3ff-200d-2642-fe0f.svg","man_red_haired":"1f468-200d-1f9b0.svg","man_red_haired_tone1":"1f468-1f3fb-200d-1f9b0.svg","man_red_haired_tone2":"1f468-1f3fc-200d-1f9b0.svg","man_red_haired_tone3":"1f468-1f3fd-200d-1f9b0.svg","man_red_haired_tone4":"1f468-1f3fe-200d-1f9b0.svg","man_red_haired_tone5":"1f468-1f3ff-200d-1f9b0.svg","man_rowing_boat":"1f6a3-200d-2642-fe0f.svg","man_rowing_boat_tone1":"1f6a3-1f3fb-200d-2642-fe0f.svg","man_rowing_boat_tone2":"1f6a3-1f3fc-200d-2642-fe0f.svg","man_rowing_boat_tone3":"1f6a3-1f3fd-200d-2642-fe0f.svg","man_rowing_boat_tone4":"1f6a3-1f3fe-200d-2642-fe0f.svg","man_rowing_boat_tone5":"1f6a3-1f3ff-200d-2642-fe0f.svg","man_running":"1f3c3-200d-2642-fe0f.svg","man_running_tone1":"1f3c3-1f3fb-200d-2642-fe0f.svg","man_running_tone2":"1f3c3-1f3fc-200d-2642-fe0f.svg","man_running_tone3":"1f3c3-1f3fd-200d-2642-fe0f.svg","man_running_tone4":"1f3c3-1f3fe-200d-2642-fe0f.svg","man_running_tone5":"1f3c3-1f3ff-200d-2642-fe0f.svg","man_scientist":"1f468-200d-1f52c.svg","man_scientist_tone1":"1f468-1f3fb-200d-1f52c.svg","man_scientist_tone2":"1f468-1f3fc-200d-1f52c.svg","man_scientist_tone3":"1f468-1f3fd-200d-1f52c.svg","man_scientist_tone4":"1f468-1f3fe-200d-1f52c.svg","man_scientist_tone5":"1f468-1f3ff-200d-1f52c.svg","man_shrugging":"1f937-200d-2642-fe0f.svg","man_shrugging_tone1":"1f937-1f3fb-200d-2642-fe0f.svg","man_shrugging_tone2":"1f937-1f3fc-200d-2642-fe0f.svg","man_shrugging_tone3":"1f937-1f3fd-200d-2642-fe0f.svg","man_shrugging_tone4":"1f937-1f3fe-200d-2642-fe0f.svg","man_shrugging_tone5":"1f937-1f3ff-200d-2642-fe0f.svg","man_singer":"1f468-200d-1f3a4.svg","man_singer_tone1":"1f468-1f3fb-200d-1f3a4.svg","man_singer_tone2":"1f468-1f3fc-200d-1f3a4.svg","man_singer_tone3":"1f468-1f3fd-200d-1f3a4.svg","man_singer_tone4":"1f468-1f3fe-200d-1f3a4.svg","man_singer_tone5":"1f468-1f3ff-200d-1f3a4.svg","man_standing":"1f9cd-200d-2642-fe0f.svg","man_standing_tone1":"1f9cd-1f3fb-200d-2642-fe0f.svg","man_standing_tone2":"1f9cd-1f3fc-200d-2642-fe0f.svg","man_standing_tone3":"1f9cd-1f3fd-200d-2642-fe0f.svg","man_standing_tone4":"1f9cd-1f3fe-200d-2642-fe0f.svg","man_standing_tone5":"1f9cd-1f3ff-200d-2642-fe0f.svg","man_student":"1f468-200d-1f393.svg","man_student_tone1":"1f468-1f3fb-200d-1f393.svg","man_student_tone2":"1f468-1f3fc-200d-1f393.svg","man_student_tone3":"1f468-1f3fd-200d-1f393.svg","man_student_tone4":"1f468-1f3fe-200d-1f393.svg","man_student_tone5":"1f468-1f3ff-200d-1f393.svg","man_superhero":"1f9b8-200d-2642-fe0f.svg","man_superhero_tone1":"1f9b8-1f3fb-200d-2642-fe0f.svg","man_superhero_tone2":"1f9b8-1f3fc-200d-2642-fe0f.svg","man_superhero_tone3":"1f9b8-1f3fd-200d-2642-fe0f.svg","man_superhero_tone4":"1f9b8-1f3fe-200d-2642-fe0f.svg","man_superhero_tone5":"1f9b8-1f3ff-200d-2642-fe0f.svg","man_supervillain":"1f9b9-200d-2642-fe0f.svg","man_supervillain_tone1":"1f9b9-1f3fb-200d-2642-fe0f.svg","man_supervillain_tone2":"1f9b9-1f3fc-200d-2642-fe0f.svg","man_supervillain_tone3":"1f9b9-1f3fd-200d-2642-fe0f.svg","man_supervillain_tone4":"1f9b9-1f3fe-200d-2642-fe0f.svg","man_supervillain_tone5":"1f9b9-1f3ff-200d-2642-fe0f.svg","man_surfing":"1f3c4-200d-2642-fe0f.svg","man_surfing_tone1":"1f3c4-1f3fb-200d-2642-fe0f.svg","man_surfing_tone2":"1f3c4-1f3fc-200d-2642-fe0f.svg","man_surfing_tone3":"1f3c4-1f3fd-200d-2642-fe0f.svg","man_surfing_tone4":"1f3c4-1f3fe-200d-2642-fe0f.svg","man_surfing_tone5":"1f3c4-1f3ff-200d-2642-fe0f.svg","man_swimming":"1f3ca-200d-2642-fe0f.svg","man_swimming_tone1":"1f3ca-1f3fb-200d-2642-fe0f.svg","man_swimming_tone2":"1f3ca-1f3fc-200d-2642-fe0f.svg","man_swimming_tone3":"1f3ca-1f3fd-200d-2642-fe0f.svg","man_swimming_tone4":"1f3ca-1f3fe-200d-2642-fe0f.svg","man_swimming_tone5":"1f3ca-1f3ff-200d-2642-fe0f.svg","man_teacher":"1f468-200d-1f3eb.svg","man_teacher_tone1":"1f468-1f3fb-200d-1f3eb.svg","man_teacher_tone2":"1f468-1f3fc-200d-1f3eb.svg","man_teacher_tone3":"1f468-1f3fd-200d-1f3eb.svg","man_teacher_tone4":"1f468-1f3fe-200d-1f3eb.svg","man_teacher_tone5":"1f468-1f3ff-200d-1f3eb.svg","man_technologist":"1f468-200d-1f4bb.svg","man_technologist_tone1":"1f468-1f3fb-200d-1f4bb.svg","man_technologist_tone2":"1f468-1f3fc-200d-1f4bb.svg","man_technologist_tone3":"1f468-1f3fd-200d-1f4bb.svg","man_technologist_tone4":"1f468-1f3fe-200d-1f4bb.svg","man_technologist_tone5":"1f468-1f3ff-200d-1f4bb.svg","man_tipping_hand":"1f481-200d-2642-fe0f.svg","man_tipping_hand_tone1":"1f481-1f3fb-200d-2642-fe0f.svg","man_tipping_hand_tone2":"1f481-1f3fc-200d-2642-fe0f.svg","man_tipping_hand_tone3":"1f481-1f3fd-200d-2642-fe0f.svg","man_tipping_hand_tone4":"1f481-1f3fe-200d-2642-fe0f.svg","man_tipping_hand_tone5":"1f481-1f3ff-200d-2642-fe0f.svg","man_tone1":"1f468-1f3fb.svg","man_tone1_beard":"1f9d4-1f3fb-200d-2642-fe0f.svg","man_tone2":"1f468-1f3fc.svg","man_tone2_beard":"1f9d4-1f3fc-200d-2642-fe0f.svg","man_tone3":"1f468-1f3fd.svg","man_tone3_beard":"1f9d4-1f3fd-200d-2642-fe0f.svg","man_tone4":"1f468-1f3fe.svg","man_tone4_beard":"1f9d4-1f3fe-200d-2642-fe0f.svg","man_tone5":"1f468-1f3ff.svg","man_tone5_beard":"1f9d4-1f3ff-200d-2642-fe0f.svg","man_vampire":"1f9db-200d-2642-fe0f.svg","man_vampire_tone1":"1f9db-1f3fb-200d-2642-fe0f.svg","man_vampire_tone2":"1f9db-1f3fc-200d-2642-fe0f.svg","man_vampire_tone3":"1f9db-1f3fd-200d-2642-fe0f.svg","man_vampire_tone4":"1f9db-1f3fe-200d-2642-fe0f.svg","man_vampire_tone5":"1f9db-1f3ff-200d-2642-fe0f.svg","man_walking":"1f6b6-200d-2642-fe0f.svg","man_walking_tone1":"1f6b6-1f3fb-200d-2642-fe0f.svg","man_walking_tone2":"1f6b6-1f3fc-200d-2642-fe0f.svg","man_walking_tone3":"1f6b6-1f3fd-200d-2642-fe0f.svg","man_walking_tone4":"1f6b6-1f3fe-200d-2642-fe0f.svg","man_walking_tone5":"1f6b6-1f3ff-200d-2642-fe0f.svg","man_wearing_turban":"1f473-200d-2642-fe0f.svg","man_wearing_turban_tone1":"1f473-1f3fb-200d-2642-fe0f.svg","man_wearing_turban_tone2":"1f473-1f3fc-200d-2642-fe0f.svg","man_wearing_turban_tone3":"1f473-1f3fd-200d-2642-fe0f.svg","man_wearing_turban_tone4":"1f473-1f3fe-200d-2642-fe0f.svg","man_wearing_turban_tone5":"1f473-1f3ff-200d-2642-fe0f.svg","man_white_haired":"1f468-200d-1f9b3.svg","man_white_haired_tone1":"1f468-1f3fb-200d-1f9b3.svg","man_white_haired_tone2":"1f468-1f3fc-200d-1f9b3.svg","man_white_haired_tone3":"1f468-1f3fd-200d-1f9b3.svg","man_white_haired_tone4":"1f468-1f3fe-200d-1f9b3.svg","man_white_haired_tone5":"1f468-1f3ff-200d-1f9b3.svg","man_with_chinese_cap":"1f472.svg","man_with_chinese_cap_tone1":"1f472-1f3fb.svg","man_with_chinese_cap_tone2":"1f472-1f3fc.svg","man_with_chinese_cap_tone3":"1f472-1f3fd.svg","man_with_chinese_cap_tone4":"1f472-1f3fe.svg","man_with_chinese_cap_tone5":"1f472-1f3ff.svg","man_with_probing_cane":"1f468-200d-1f9af.svg","man_with_probing_cane_tone1":"1f468-1f3fb-200d-1f9af.svg","man_with_probing_cane_tone2":"1f468-1f3fc-200d-1f9af.svg","man_with_probing_cane_tone3":"1f468-1f3fd-200d-1f9af.svg","man_with_probing_cane_tone4":"1f468-1f3fe-200d-1f9af.svg","man_with_probing_cane_tone5":"1f468-1f3ff-200d-1f9af.svg","man_with_veil":"1f470-200d-2642-fe0f.svg","man_with_veil_tone1":"1f470-1f3fb-200d-2642-fe0f.svg","man_with_veil_tone2":"1f470-1f3fc-200d-2642-fe0f.svg","man_with_veil_tone3":"1f470-1f3fd-200d-2642-fe0f.svg","man_with_veil_tone4":"1f470-1f3fe-200d-2642-fe0f.svg","man_with_veil_tone5":"1f470-1f3ff-200d-2642-fe0f.svg","man_zombie":"1f9df-200d-2642-fe0f.svg","mango":"1f96d.svg","mans_shoe":"1f45e.svg","manual_wheelchair":"1f9bd.svg","map":"1f5fa.svg","maple_leaf":"1f341.svg","martial_arts_uniform":"1f94b.svg","mask":"1f637.svg","mate":"1f9c9.svg","meat_on_bone":"1f356.svg","mechanic":"1f9d1-200d-1f527.svg","mechanic_tone1":"1f9d1-1f3fb-200d-1f527.svg","mechanic_tone2":"1f9d1-1f3fc-200d-1f527.svg","mechanic_tone3":"1f9d1-1f3fd-200d-1f527.svg","mechanic_tone4":"1f9d1-1f3fe-200d-1f527.svg","mechanic_tone5":"1f9d1-1f3ff-200d-1f527.svg","mechanical_arm":"1f9be.svg","mechanical_leg":"1f9bf.svg","medal":"1f3c5.svg","medical_symbol":"2695.svg","mega":"1f4e3.svg","melon":"1f348.svg","men_holding_hands_tone1":"1f46c-1f3fb.svg","men_holding_hands_tone1_tone2":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone1_tone3":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone1_tone4":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone1_tone5":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone2":"1f46c-1f3fc.svg","men_holding_hands_tone2_tone1":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone2_tone3":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone2_tone4":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone2_tone5":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone3":"1f46c-1f3fd.svg","men_holding_hands_tone3_tone1":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone3_tone2":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone3_tone4":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone3_tone5":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone4":"1f46c-1f3fe.svg","men_holding_hands_tone4_tone1":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone4_tone2":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone4_tone3":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone4_tone5":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone5":"1f46c-1f3ff.svg","men_holding_hands_tone5_tone1":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone5_tone2":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone5_tone3":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone5_tone4":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe.svg","men_with_bunny_ears_partying":"1f46f-200d-2642-fe0f.svg","men_wrestling":"1f93c-200d-2642-fe0f.svg","mending_heart":"2764-fe0f-200d-1fa79.svg","menorah":"1f54e.svg","mens":"1f6b9.svg","mermaid":"1f9dc-200d-2640-fe0f.svg","mermaid_tone1":"1f9dc-1f3fb-200d-2640-fe0f.svg","mermaid_tone2":"1f9dc-1f3fc-200d-2640-fe0f.svg","mermaid_tone3":"1f9dc-1f3fd-200d-2640-fe0f.svg","mermaid_tone4":"1f9dc-1f3fe-200d-2640-fe0f.svg","mermaid_tone5":"1f9dc-1f3ff-200d-2640-fe0f.svg","merman":"1f9dc-200d-2642-fe0f.svg","merman_tone1":"1f9dc-1f3fb-200d-2642-fe0f.svg","merman_tone2":"1f9dc-1f3fc-200d-2642-fe0f.svg","merman_tone3":"1f9dc-1f3fd-200d-2642-fe0f.svg","merman_tone4":"1f9dc-1f3fe-200d-2642-fe0f.svg","merman_tone5":"1f9dc-1f3ff-200d-2642-fe0f.svg","merperson":"1f9dc.svg","merperson_tone1":"1f9dc-1f3fb.svg","merperson_tone2":"1f9dc-1f3fc.svg","merperson_tone3":"1f9dc-1f3fd.svg","merperson_tone4":"1f9dc-1f3fe.svg","merperson_tone5":"1f9dc-1f3ff.svg","metal":"1f918.svg","metal_tone1":"1f918-1f3fb.svg","metal_tone2":"1f918-1f3fc.svg","metal_tone3":"1f918-1f3fd.svg","metal_tone4":"1f918-1f3fe.svg","metal_tone5":"1f918-1f3ff.svg","metro":"1f687.svg","microbe":"1f9a0.svg","microphone2":"1f399.svg","microphone":"1f3a4.svg","microscope":"1f52c.svg","middle_finger":"1f595.svg","middle_finger_tone1":"1f595-1f3fb.svg","middle_finger_tone2":"1f595-1f3fc.svg","middle_finger_tone3":"1f595-1f3fd.svg","middle_finger_tone4":"1f595-1f3fe.svg","middle_finger_tone5":"1f595-1f3ff.svg","military_helmet":"1fa96.svg","military_medal":"1f396.svg","milk":"1f95b.svg","milky_way":"1f30c.svg","minibus":"1f690.svg","minidisc":"1f4bd.svg","mirror":"1fa9e.svg","mobile_phone":"1f4f1.svg","mobile_phone_off":"1f4f4.svg","money_mouth":"1f911.svg","money_with_wings":"1f4b8.svg","moneybag":"1f4b0.svg","monkey":"1f412.svg","monkey_face":"1f435.svg","monorail":"1f69d.svg","moon_cake":"1f96e.svg","mortar_board":"1f393.svg","mosque":"1f54c.svg","mosquito":"1f99f.svg","motor_scooter":"1f6f5.svg","motorboat":"1f6e5.svg","motorcycle":"1f3cd.svg","motorized_wheelchair":"1f9bc.svg","motorway":"1f6e3.svg","mount_fuji":"1f5fb.svg","mountain":"26f0.svg","mountain_cableway":"1f6a0.svg","mountain_railway":"1f69e.svg","mountain_snow":"1f3d4.svg","mouse2":"1f401.svg","mouse":"1f42d.svg","mouse_three_button":"1f5b1.svg","mouse_trap":"1faa4.svg","movie_camera":"1f3a5.svg","moyai":"1f5ff.svg","mrs_claus":"1f936.svg","mrs_claus_tone1":"1f936-1f3fb.svg","mrs_claus_tone2":"1f936-1f3fc.svg","mrs_claus_tone3":"1f936-1f3fd.svg","mrs_claus_tone4":"1f936-1f3fe.svg","mrs_claus_tone5":"1f936-1f3ff.svg","muscle":"1f4aa.svg","muscle_tone1":"1f4aa-1f3fb.svg","muscle_tone2":"1f4aa-1f3fc.svg","muscle_tone3":"1f4aa-1f3fd.svg","muscle_tone4":"1f4aa-1f3fe.svg","muscle_tone5":"1f4aa-1f3ff.svg","mushroom":"1f344.svg","musical_keyboard":"1f3b9.svg","musical_note":"1f3b5.svg","musical_score":"1f3bc.svg","mute":"1f507.svg","mx_claus":"1f9d1-200d-1f384.svg","mx_claus_tone1":"1f9d1-1f3fb-200d-1f384.svg","mx_claus_tone2":"1f9d1-1f3fc-200d-1f384.svg","mx_claus_tone3":"1f9d1-1f3fd-200d-1f384.svg","mx_claus_tone4":"1f9d1-1f3fe-200d-1f384.svg","mx_claus_tone5":"1f9d1-1f3ff-200d-1f384.svg","nail_care":"1f485.svg","nail_care_tone1":"1f485-1f3fb.svg","nail_care_tone2":"1f485-1f3fc.svg","nail_care_tone3":"1f485-1f3fd.svg","nail_care_tone4":"1f485-1f3fe.svg","nail_care_tone5":"1f485-1f3ff.svg","name_badge":"1f4db.svg","nauseated_face":"1f922.svg","nazar_amulet":"1f9ff.svg","necktie":"1f454.svg","negative_squared_cross_mark":"274e.svg","nerd":"1f913.svg","nesting_dolls":"1fa86.svg","neutral_face":"1f610.svg","new":"1f195.svg","new_moon":"1f311.svg","new_moon_with_face":"1f31a.svg","newspaper2":"1f5de.svg","newspaper":"1f4f0.svg","ng":"1f196.svg","night_with_stars":"1f303.svg","nine":"39-20e3.svg","ninja":"1f977.svg","ninja_tone1":"1f977-1f3fb.svg","ninja_tone2":"1f977-1f3fc.svg","ninja_tone3":"1f977-1f3fd.svg","ninja_tone4":"1f977-1f3fe.svg","ninja_tone5":"1f977-1f3ff.svg","no_bell":"1f515.svg","no_bicycles":"1f6b3.svg","no_entry":"26d4.svg","no_entry_sign":"1f6ab.svg","no_mobile_phones":"1f4f5.svg","no_mouth":"1f636.svg","no_pedestrians":"1f6b7.svg","no_smoking":"1f6ad.svg","non-potable_water":"1f6b1.svg","nose":"1f443.svg","nose_tone1":"1f443-1f3fb.svg","nose_tone2":"1f443-1f3fc.svg","nose_tone3":"1f443-1f3fd.svg","nose_tone4":"1f443-1f3fe.svg","nose_tone5":"1f443-1f3ff.svg","notebook":"1f4d3.svg","notebook_with_decorative_cover":"1f4d4.svg","notepad_spiral":"1f5d2.svg","notes":"1f3b6.svg","nut_and_bolt":"1f529.svg","o2":"1f17e.svg","o":"2b55.svg","ocean":"1f30a.svg","octagonal_sign":"1f6d1.svg","octopus":"1f419.svg","oden":"1f362.svg","office":"1f3e2.svg","office_worker":"1f9d1-200d-1f4bc.svg","office_worker_tone1":"1f9d1-1f3fb-200d-1f4bc.svg","office_worker_tone2":"1f9d1-1f3fc-200d-1f4bc.svg","office_worker_tone3":"1f9d1-1f3fd-200d-1f4bc.svg","office_worker_tone4":"1f9d1-1f3fe-200d-1f4bc.svg","office_worker_tone5":"1f9d1-1f3ff-200d-1f4bc.svg","oil":"1f6e2.svg","ok":"1f197.svg","ok_hand":"1f44c.svg","ok_hand_tone1":"1f44c-1f3fb.svg","ok_hand_tone2":"1f44c-1f3fc.svg","ok_hand_tone3":"1f44c-1f3fd.svg","ok_hand_tone4":"1f44c-1f3fe.svg","ok_hand_tone5":"1f44c-1f3ff.svg","older_adult":"1f9d3.svg","older_adult_tone1":"1f9d3-1f3fb.svg","older_adult_tone2":"1f9d3-1f3fc.svg","older_adult_tone3":"1f9d3-1f3fd.svg","older_adult_tone4":"1f9d3-1f3fe.svg","older_adult_tone5":"1f9d3-1f3ff.svg","older_man":"1f474.svg","older_man_tone1":"1f474-1f3fb.svg","older_man_tone2":"1f474-1f3fc.svg","older_man_tone3":"1f474-1f3fd.svg","older_man_tone4":"1f474-1f3fe.svg","older_man_tone5":"1f474-1f3ff.svg","older_woman":"1f475.svg","older_woman_tone1":"1f475-1f3fb.svg","older_woman_tone2":"1f475-1f3fc.svg","older_woman_tone3":"1f475-1f3fd.svg","older_woman_tone4":"1f475-1f3fe.svg","older_woman_tone5":"1f475-1f3ff.svg","olive":"1fad2.svg","om_symbol":"1f549.svg","on":"1f51b.svg","oncoming_automobile":"1f698.svg","oncoming_bus":"1f68d.svg","oncoming_police_car":"1f694.svg","oncoming_taxi":"1f696.svg","one":"31-20e3.svg","one_piece_swimsuit":"1fa71.svg","onion":"1f9c5.svg","open_file_folder":"1f4c2.svg","open_hands":"1f450.svg","open_hands_tone1":"1f450-1f3fb.svg","open_hands_tone2":"1f450-1f3fc.svg","open_hands_tone3":"1f450-1f3fd.svg","open_hands_tone4":"1f450-1f3fe.svg","open_hands_tone5":"1f450-1f3ff.svg","open_mouth":"1f62e.svg","ophiuchus":"26ce.svg","orange_book":"1f4d9.svg","orange_circle":"1f7e0.svg","orange_heart":"1f9e1.svg","orange_square":"1f7e7.svg","orangutan":"1f9a7.svg","orthodox_cross":"2626.svg","otter":"1f9a6.svg","outbox_tray":"1f4e4.svg","owl":"1f989.svg","ox":"1f402.svg","oyster":"1f9aa.svg","package":"1f4e6.svg","page_facing_up":"1f4c4.svg","page_with_curl":"1f4c3.svg","pager":"1f4df.svg","paintbrush":"1f58c.svg","palm_tree":"1f334.svg","palms_up_together":"1f932.svg","palms_up_together_tone1":"1f932-1f3fb.svg","palms_up_together_tone2":"1f932-1f3fc.svg","palms_up_together_tone3":"1f932-1f3fd.svg","palms_up_together_tone4":"1f932-1f3fe.svg","palms_up_together_tone5":"1f932-1f3ff.svg","pancakes":"1f95e.svg","panda_face":"1f43c.svg","paperclip":"1f4ce.svg","paperclips":"1f587.svg","parachute":"1fa82.svg","park":"1f3de.svg","parking":"1f17f.svg","parrot":"1f99c.svg","part_alternation_mark":"303d.svg","partly_sunny":"26c5.svg","partying_face":"1f973.svg","passport_control":"1f6c2.svg","pause_button":"23f8.svg","peace":"262e.svg","peach":"1f351.svg","peacock":"1f99a.svg","peanuts":"1f95c.svg","pear":"1f350.svg","pen_ballpoint":"1f58a.svg","pen_fountain":"1f58b.svg","pencil2":"270f.svg","pencil":"1f4dd.svg","penguin":"1f427.svg","pensive":"1f614.svg","people_holding_hands":"1f9d1-200d-1f91d-200d-1f9d1.svg","people_holding_hands_tone1":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone1_tone2":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone1_tone3":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone1_tone4":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone1_tone5":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone2":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone2_tone1":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone2_tone3":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone2_tone4":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone2_tone5":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone3":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone3_tone1":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone3_tone2":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone3_tone4":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone3_tone5":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone4":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone4_tone1":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone4_tone2":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone4_tone3":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone4_tone5":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone5":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone5_tone1":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone5_tone2":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone5_tone3":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone5_tone4":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe.svg","people_hugging":"1fac2.svg","people_with_bunny_ears_partying":"1f46f.svg","people_wrestling":"1f93c.svg","performing_arts":"1f3ad.svg","persevere":"1f623.svg","person_bald":"1f9d1-200d-1f9b2.svg","person_biking":"1f6b4.svg","person_biking_tone1":"1f6b4-1f3fb.svg","person_biking_tone2":"1f6b4-1f3fc.svg","person_biking_tone3":"1f6b4-1f3fd.svg","person_biking_tone4":"1f6b4-1f3fe.svg","person_biking_tone5":"1f6b4-1f3ff.svg","person_bouncing_ball":"26f9.svg","person_bouncing_ball_tone1":"26f9-1f3fb.svg","person_bouncing_ball_tone2":"26f9-1f3fc.svg","person_bouncing_ball_tone3":"26f9-1f3fd.svg","person_bouncing_ball_tone4":"26f9-1f3fe.svg","person_bouncing_ball_tone5":"26f9-1f3ff.svg","person_bowing":"1f647.svg","person_bowing_tone1":"1f647-1f3fb.svg","person_bowing_tone2":"1f647-1f3fc.svg","person_bowing_tone3":"1f647-1f3fd.svg","person_bowing_tone4":"1f647-1f3fe.svg","person_bowing_tone5":"1f647-1f3ff.svg","person_climbing":"1f9d7.svg","person_climbing_tone1":"1f9d7-1f3fb.svg","person_climbing_tone2":"1f9d7-1f3fc.svg","person_climbing_tone3":"1f9d7-1f3fd.svg","person_climbing_tone4":"1f9d7-1f3fe.svg","person_climbing_tone5":"1f9d7-1f3ff.svg","person_curly_hair":"1f9d1-200d-1f9b1.svg","person_doing_cartwheel":"1f938.svg","person_doing_cartwheel_tone1":"1f938-1f3fb.svg","person_doing_cartwheel_tone2":"1f938-1f3fc.svg","person_doing_cartwheel_tone3":"1f938-1f3fd.svg","person_doing_cartwheel_tone4":"1f938-1f3fe.svg","person_doing_cartwheel_tone5":"1f938-1f3ff.svg","person_facepalming":"1f926.svg","person_facepalming_tone1":"1f926-1f3fb.svg","person_facepalming_tone2":"1f926-1f3fc.svg","person_facepalming_tone3":"1f926-1f3fd.svg","person_facepalming_tone4":"1f926-1f3fe.svg","person_facepalming_tone5":"1f926-1f3ff.svg","person_feeding_baby":"1f9d1-200d-1f37c.svg","person_feeding_baby_tone1":"1f9d1-1f3fb-200d-1f37c.svg","person_feeding_baby_tone2":"1f9d1-1f3fc-200d-1f37c.svg","person_feeding_baby_tone3":"1f9d1-1f3fd-200d-1f37c.svg","person_feeding_baby_tone4":"1f9d1-1f3fe-200d-1f37c.svg","person_feeding_baby_tone5":"1f9d1-1f3ff-200d-1f37c.svg","person_fencing":"1f93a.svg","person_frowning":"1f64d.svg","person_frowning_tone1":"1f64d-1f3fb.svg","person_frowning_tone2":"1f64d-1f3fc.svg","person_frowning_tone3":"1f64d-1f3fd.svg","person_frowning_tone4":"1f64d-1f3fe.svg","person_frowning_tone5":"1f64d-1f3ff.svg","person_gesturing_no":"1f645.svg","person_gesturing_no_tone1":"1f645-1f3fb.svg","person_gesturing_no_tone2":"1f645-1f3fc.svg","person_gesturing_no_tone3":"1f645-1f3fd.svg","person_gesturing_no_tone4":"1f645-1f3fe.svg","person_gesturing_no_tone5":"1f645-1f3ff.svg","person_gesturing_ok":"1f646.svg","person_gesturing_ok_tone1":"1f646-1f3fb.svg","person_gesturing_ok_tone2":"1f646-1f3fc.svg","person_gesturing_ok_tone3":"1f646-1f3fd.svg","person_gesturing_ok_tone4":"1f646-1f3fe.svg","person_gesturing_ok_tone5":"1f646-1f3ff.svg","person_getting_haircut":"1f487.svg","person_getting_haircut_tone1":"1f487-1f3fb.svg","person_getting_haircut_tone2":"1f487-1f3fc.svg","person_getting_haircut_tone3":"1f487-1f3fd.svg","person_getting_haircut_tone4":"1f487-1f3fe.svg","person_getting_haircut_tone5":"1f487-1f3ff.svg","person_getting_massage":"1f486.svg","person_getting_massage_tone1":"1f486-1f3fb.svg","person_getting_massage_tone2":"1f486-1f3fc.svg","person_getting_massage_tone3":"1f486-1f3fd.svg","person_getting_massage_tone4":"1f486-1f3fe.svg","person_getting_massage_tone5":"1f486-1f3ff.svg","person_golfing":"1f3cc.svg","person_golfing_tone1":"1f3cc-1f3fb.svg","person_golfing_tone2":"1f3cc-1f3fc.svg","person_golfing_tone3":"1f3cc-1f3fd.svg","person_golfing_tone4":"1f3cc-1f3fe.svg","person_golfing_tone5":"1f3cc-1f3ff.svg","person_in_bed_tone1":"1f6cc-1f3fb.svg","person_in_bed_tone2":"1f6cc-1f3fc.svg","person_in_bed_tone3":"1f6cc-1f3fd.svg","person_in_bed_tone4":"1f6cc-1f3fe.svg","person_in_bed_tone5":"1f6cc-1f3ff.svg","person_in_lotus_position":"1f9d8.svg","person_in_lotus_position_tone1":"1f9d8-1f3fb.svg","person_in_lotus_position_tone2":"1f9d8-1f3fc.svg","person_in_lotus_position_tone3":"1f9d8-1f3fd.svg","person_in_lotus_position_tone4":"1f9d8-1f3fe.svg","person_in_lotus_position_tone5":"1f9d8-1f3ff.svg","person_in_manual_wheelchair":"1f9d1-200d-1f9bd.svg","person_in_manual_wheelchair_tone1":"1f9d1-1f3fb-200d-1f9bd.svg","person_in_manual_wheelchair_tone2":"1f9d1-1f3fc-200d-1f9bd.svg","person_in_manual_wheelchair_tone3":"1f9d1-1f3fd-200d-1f9bd.svg","person_in_manual_wheelchair_tone4":"1f9d1-1f3fe-200d-1f9bd.svg","person_in_manual_wheelchair_tone5":"1f9d1-1f3ff-200d-1f9bd.svg","person_in_motorized_wheelchair":"1f9d1-200d-1f9bc.svg","person_in_motorized_wheelchair_tone1":"1f9d1-1f3fb-200d-1f9bc.svg","person_in_motorized_wheelchair_tone2":"1f9d1-1f3fc-200d-1f9bc.svg","person_in_motorized_wheelchair_tone3":"1f9d1-1f3fd-200d-1f9bc.svg","person_in_motorized_wheelchair_tone4":"1f9d1-1f3fe-200d-1f9bc.svg","person_in_motorized_wheelchair_tone5":"1f9d1-1f3ff-200d-1f9bc.svg","person_in_steamy_room":"1f9d6.svg","person_in_steamy_room_tone1":"1f9d6-1f3fb.svg","person_in_steamy_room_tone2":"1f9d6-1f3fc.svg","person_in_steamy_room_tone3":"1f9d6-1f3fd.svg","person_in_steamy_room_tone4":"1f9d6-1f3fe.svg","person_in_steamy_room_tone5":"1f9d6-1f3ff.svg","person_in_tuxedo":"1f935.svg","person_in_tuxedo_tone1":"1f935-1f3fb.svg","person_in_tuxedo_tone2":"1f935-1f3fc.svg","person_in_tuxedo_tone3":"1f935-1f3fd.svg","person_in_tuxedo_tone4":"1f935-1f3fe.svg","person_in_tuxedo_tone5":"1f935-1f3ff.svg","person_juggling":"1f939.svg","person_juggling_tone1":"1f939-1f3fb.svg","person_juggling_tone2":"1f939-1f3fc.svg","person_juggling_tone3":"1f939-1f3fd.svg","person_juggling_tone4":"1f939-1f3fe.svg","person_juggling_tone5":"1f939-1f3ff.svg","person_kneeling":"1f9ce.svg","person_kneeling_tone1":"1f9ce-1f3fb.svg","person_kneeling_tone2":"1f9ce-1f3fc.svg","person_kneeling_tone3":"1f9ce-1f3fd.svg","person_kneeling_tone4":"1f9ce-1f3fe.svg","person_kneeling_tone5":"1f9ce-1f3ff.svg","person_lifting_weights":"1f3cb.svg","person_lifting_weights_tone1":"1f3cb-1f3fb.svg","person_lifting_weights_tone2":"1f3cb-1f3fc.svg","person_lifting_weights_tone3":"1f3cb-1f3fd.svg","person_lifting_weights_tone4":"1f3cb-1f3fe.svg","person_lifting_weights_tone5":"1f3cb-1f3ff.svg","person_mountain_biking":"1f6b5.svg","person_mountain_biking_tone1":"1f6b5-1f3fb.svg","person_mountain_biking_tone2":"1f6b5-1f3fc.svg","person_mountain_biking_tone3":"1f6b5-1f3fd.svg","person_mountain_biking_tone4":"1f6b5-1f3fe.svg","person_mountain_biking_tone5":"1f6b5-1f3ff.svg","person_playing_handball":"1f93e.svg","person_playing_handball_tone1":"1f93e-1f3fb.svg","person_playing_handball_tone2":"1f93e-1f3fc.svg","person_playing_handball_tone3":"1f93e-1f3fd.svg","person_playing_handball_tone4":"1f93e-1f3fe.svg","person_playing_handball_tone5":"1f93e-1f3ff.svg","person_playing_water_polo":"1f93d.svg","person_playing_water_polo_tone1":"1f93d-1f3fb.svg","person_playing_water_polo_tone2":"1f93d-1f3fc.svg","person_playing_water_polo_tone3":"1f93d-1f3fd.svg","person_playing_water_polo_tone4":"1f93d-1f3fe.svg","person_playing_water_polo_tone5":"1f93d-1f3ff.svg","person_pouting":"1f64e.svg","person_pouting_tone1":"1f64e-1f3fb.svg","person_pouting_tone2":"1f64e-1f3fc.svg","person_pouting_tone3":"1f64e-1f3fd.svg","person_pouting_tone4":"1f64e-1f3fe.svg","person_pouting_tone5":"1f64e-1f3ff.svg","person_raising_hand":"1f64b.svg","person_raising_hand_tone1":"1f64b-1f3fb.svg","person_raising_hand_tone2":"1f64b-1f3fc.svg","person_raising_hand_tone3":"1f64b-1f3fd.svg","person_raising_hand_tone4":"1f64b-1f3fe.svg","person_raising_hand_tone5":"1f64b-1f3ff.svg","person_red_hair":"1f9d1-200d-1f9b0.svg","person_rowing_boat":"1f6a3.svg","person_rowing_boat_tone1":"1f6a3-1f3fb.svg","person_rowing_boat_tone2":"1f6a3-1f3fc.svg","person_rowing_boat_tone3":"1f6a3-1f3fd.svg","person_rowing_boat_tone4":"1f6a3-1f3fe.svg","person_rowing_boat_tone5":"1f6a3-1f3ff.svg","person_running":"1f3c3.svg","person_running_tone1":"1f3c3-1f3fb.svg","person_running_tone2":"1f3c3-1f3fc.svg","person_running_tone3":"1f3c3-1f3fd.svg","person_running_tone4":"1f3c3-1f3fe.svg","person_running_tone5":"1f3c3-1f3ff.svg","person_shrugging":"1f937.svg","person_shrugging_tone1":"1f937-1f3fb.svg","person_shrugging_tone2":"1f937-1f3fc.svg","person_shrugging_tone3":"1f937-1f3fd.svg","person_shrugging_tone4":"1f937-1f3fe.svg","person_shrugging_tone5":"1f937-1f3ff.svg","person_standing":"1f9cd.svg","person_standing_tone1":"1f9cd-1f3fb.svg","person_standing_tone2":"1f9cd-1f3fc.svg","person_standing_tone3":"1f9cd-1f3fd.svg","person_standing_tone4":"1f9cd-1f3fe.svg","person_standing_tone5":"1f9cd-1f3ff.svg","person_surfing":"1f3c4.svg","person_surfing_tone1":"1f3c4-1f3fb.svg","person_surfing_tone2":"1f3c4-1f3fc.svg","person_surfing_tone3":"1f3c4-1f3fd.svg","person_surfing_tone4":"1f3c4-1f3fe.svg","person_surfing_tone5":"1f3c4-1f3ff.svg","person_swimming":"1f3ca.svg","person_swimming_tone1":"1f3ca-1f3fb.svg","person_swimming_tone2":"1f3ca-1f3fc.svg","person_swimming_tone3":"1f3ca-1f3fd.svg","person_swimming_tone4":"1f3ca-1f3fe.svg","person_swimming_tone5":"1f3ca-1f3ff.svg","person_tipping_hand":"1f481.svg","person_tipping_hand_tone1":"1f481-1f3fb.svg","person_tipping_hand_tone2":"1f481-1f3fc.svg","person_tipping_hand_tone3":"1f481-1f3fd.svg","person_tipping_hand_tone4":"1f481-1f3fe.svg","person_tipping_hand_tone5":"1f481-1f3ff.svg","person_tone1_bald":"1f9d1-1f3fb-200d-1f9b2.svg","person_tone1_curly_hair":"1f9d1-1f3fb-200d-1f9b1.svg","person_tone1_red_hair":"1f9d1-1f3fb-200d-1f9b0.svg","person_tone1_white_hair":"1f9d1-1f3fb-200d-1f9b3.svg","person_tone2_bald":"1f9d1-1f3fc-200d-1f9b2.svg","person_tone2_curly_hair":"1f9d1-1f3fc-200d-1f9b1.svg","person_tone2_red_hair":"1f9d1-1f3fc-200d-1f9b0.svg","person_tone2_white_hair":"1f9d1-1f3fc-200d-1f9b3.svg","person_tone3_bald":"1f9d1-1f3fd-200d-1f9b2.svg","person_tone3_curly_hair":"1f9d1-1f3fd-200d-1f9b1.svg","person_tone3_red_hair":"1f9d1-1f3fd-200d-1f9b0.svg","person_tone3_white_hair":"1f9d1-1f3fd-200d-1f9b3.svg","person_tone4_bald":"1f9d1-1f3fe-200d-1f9b2.svg","person_tone4_curly_hair":"1f9d1-1f3fe-200d-1f9b1.svg","person_tone4_red_hair":"1f9d1-1f3fe-200d-1f9b0.svg","person_tone4_white_hair":"1f9d1-1f3fe-200d-1f9b3.svg","person_tone5_bald":"1f9d1-1f3ff-200d-1f9b2.svg","person_tone5_curly_hair":"1f9d1-1f3ff-200d-1f9b1.svg","person_tone5_red_hair":"1f9d1-1f3ff-200d-1f9b0.svg","person_tone5_white_hair":"1f9d1-1f3ff-200d-1f9b3.svg","person_walking":"1f6b6.svg","person_walking_tone1":"1f6b6-1f3fb.svg","person_walking_tone2":"1f6b6-1f3fc.svg","person_walking_tone3":"1f6b6-1f3fd.svg","person_walking_tone4":"1f6b6-1f3fe.svg","person_walking_tone5":"1f6b6-1f3ff.svg","person_wearing_turban":"1f473.svg","person_wearing_turban_tone1":"1f473-1f3fb.svg","person_wearing_turban_tone2":"1f473-1f3fc.svg","person_wearing_turban_tone3":"1f473-1f3fd.svg","person_wearing_turban_tone4":"1f473-1f3fe.svg","person_wearing_turban_tone5":"1f473-1f3ff.svg","person_white_hair":"1f9d1-200d-1f9b3.svg","person_with_probing_cane":"1f9d1-200d-1f9af.svg","person_with_probing_cane_tone1":"1f9d1-1f3fb-200d-1f9af.svg","person_with_probing_cane_tone2":"1f9d1-1f3fc-200d-1f9af.svg","person_with_probing_cane_tone3":"1f9d1-1f3fd-200d-1f9af.svg","person_with_probing_cane_tone4":"1f9d1-1f3fe-200d-1f9af.svg","person_with_probing_cane_tone5":"1f9d1-1f3ff-200d-1f9af.svg","person_with_veil":"1f470.svg","person_with_veil_tone1":"1f470-1f3fb.svg","person_with_veil_tone2":"1f470-1f3fc.svg","person_with_veil_tone3":"1f470-1f3fd.svg","person_with_veil_tone4":"1f470-1f3fe.svg","person_with_veil_tone5":"1f470-1f3ff.svg","petri_dish":"1f9eb.svg","pick":"26cf.svg","pickup_truck":"1f6fb.svg","pie":"1f967.svg","pig2":"1f416.svg","pig":"1f437.svg","pig_nose":"1f43d.svg","pill":"1f48a.svg","pilot":"1f9d1-200d-2708-fe0f.svg","pilot_tone1":"1f9d1-1f3fb-200d-2708-fe0f.svg","pilot_tone2":"1f9d1-1f3fc-200d-2708-fe0f.svg","pilot_tone3":"1f9d1-1f3fd-200d-2708-fe0f.svg","pilot_tone4":"1f9d1-1f3fe-200d-2708-fe0f.svg","pilot_tone5":"1f9d1-1f3ff-200d-2708-fe0f.svg","pinched_fingers":"1f90c.svg","pinched_fingers_tone1":"1f90c-1f3fb.svg","pinched_fingers_tone2":"1f90c-1f3fc.svg","pinched_fingers_tone3":"1f90c-1f3fd.svg","pinched_fingers_tone4":"1f90c-1f3fe.svg","pinched_fingers_tone5":"1f90c-1f3ff.svg","pinching_hand":"1f90f.svg","pinching_hand_tone1":"1f90f-1f3fb.svg","pinching_hand_tone2":"1f90f-1f3fc.svg","pinching_hand_tone3":"1f90f-1f3fd.svg","pinching_hand_tone4":"1f90f-1f3fe.svg","pinching_hand_tone5":"1f90f-1f3ff.svg","pineapple":"1f34d.svg","ping_pong":"1f3d3.svg","pirate_flag":"1f3f4-200d-2620-fe0f.svg","pisces":"2653.svg","pizza":"1f355.svg","piñata":"1fa85.svg","placard":"1faa7.svg","place_of_worship":"1f6d0.svg","play_pause":"23ef.svg","pleading_face":"1f97a.svg","plunger":"1faa0.svg","point_down":"1f447.svg","point_down_tone1":"1f447-1f3fb.svg","point_down_tone2":"1f447-1f3fc.svg","point_down_tone3":"1f447-1f3fd.svg","point_down_tone4":"1f447-1f3fe.svg","point_down_tone5":"1f447-1f3ff.svg","point_left":"1f448.svg","point_left_tone1":"1f448-1f3fb.svg","point_left_tone2":"1f448-1f3fc.svg","point_left_tone3":"1f448-1f3fd.svg","point_left_tone4":"1f448-1f3fe.svg","point_left_tone5":"1f448-1f3ff.svg","point_right":"1f449.svg","point_right_tone1":"1f449-1f3fb.svg","point_right_tone2":"1f449-1f3fc.svg","point_right_tone3":"1f449-1f3fd.svg","point_right_tone4":"1f449-1f3fe.svg","point_right_tone5":"1f449-1f3ff.svg","point_up":"261d.svg","point_up_2":"1f446.svg","point_up_2_tone1":"1f446-1f3fb.svg","point_up_2_tone2":"1f446-1f3fc.svg","point_up_2_tone3":"1f446-1f3fd.svg","point_up_2_tone4":"1f446-1f3fe.svg","point_up_2_tone5":"1f446-1f3ff.svg","point_up_tone1":"261d-1f3fb.svg","point_up_tone2":"261d-1f3fc.svg","point_up_tone3":"261d-1f3fd.svg","point_up_tone4":"261d-1f3fe.svg","point_up_tone5":"261d-1f3ff.svg","polar_bear":"1f43b-200d-2744-fe0f.svg","police_car":"1f693.svg","police_officer":"1f46e.svg","police_officer_tone1":"1f46e-1f3fb.svg","police_officer_tone2":"1f46e-1f3fc.svg","police_officer_tone3":"1f46e-1f3fd.svg","police_officer_tone4":"1f46e-1f3fe.svg","police_officer_tone5":"1f46e-1f3ff.svg","poodle":"1f429.svg","poop":"1f4a9.svg","popcorn":"1f37f.svg","post_office":"1f3e3.svg","postal_horn":"1f4ef.svg","postbox":"1f4ee.svg","potable_water":"1f6b0.svg","potato":"1f954.svg","potted_plant":"1fab4.svg","pouch":"1f45d.svg","poultry_leg":"1f357.svg","pound":"1f4b7.svg","pouting_cat":"1f63e.svg","pray":"1f64f.svg","pray_tone1":"1f64f-1f3fb.svg","pray_tone2":"1f64f-1f3fc.svg","pray_tone3":"1f64f-1f3fd.svg","pray_tone4":"1f64f-1f3fe.svg","pray_tone5":"1f64f-1f3ff.svg","prayer_beads":"1f4ff.svg","pregnant_woman":"1f930.svg","pregnant_woman_tone1":"1f930-1f3fb.svg","pregnant_woman_tone2":"1f930-1f3fc.svg","pregnant_woman_tone3":"1f930-1f3fd.svg","pregnant_woman_tone4":"1f930-1f3fe.svg","pregnant_woman_tone5":"1f930-1f3ff.svg","pretzel":"1f968.svg","prince":"1f934.svg","prince_tone1":"1f934-1f3fb.svg","prince_tone2":"1f934-1f3fc.svg","prince_tone3":"1f934-1f3fd.svg","prince_tone4":"1f934-1f3fe.svg","prince_tone5":"1f934-1f3ff.svg","princess":"1f478.svg","princess_tone1":"1f478-1f3fb.svg","princess_tone2":"1f478-1f3fc.svg","princess_tone3":"1f478-1f3fd.svg","princess_tone4":"1f478-1f3fe.svg","princess_tone5":"1f478-1f3ff.svg","printer":"1f5a8.svg","probing_cane":"1f9af.svg","projector":"1f4fd.svg","punch":"1f44a.svg","punch_tone1":"1f44a-1f3fb.svg","punch_tone2":"1f44a-1f3fc.svg","punch_tone3":"1f44a-1f3fd.svg","punch_tone4":"1f44a-1f3fe.svg","punch_tone5":"1f44a-1f3ff.svg","purple_circle":"1f7e3.svg","purple_heart":"1f49c.svg","purple_square":"1f7ea.svg","purse":"1f45b.svg","pushpin":"1f4cc.svg","put_litter_in_its_place":"1f6ae.svg","question":"2753.svg","rabbit2":"1f407.svg","rabbit":"1f430.svg","raccoon":"1f99d.svg","race_car":"1f3ce.svg","racehorse":"1f40e.svg","radio":"1f4fb.svg","radio_button":"1f518.svg","radioactive":"2622.svg","rage":"1f621.svg","railway_car":"1f683.svg","railway_track":"1f6e4.svg","rainbow":"1f308.svg","rainbow_flag":"1f3f3-fe0f-200d-1f308.svg","raised_back_of_hand":"1f91a.svg","raised_back_of_hand_tone1":"1f91a-1f3fb.svg","raised_back_of_hand_tone2":"1f91a-1f3fc.svg","raised_back_of_hand_tone3":"1f91a-1f3fd.svg","raised_back_of_hand_tone4":"1f91a-1f3fe.svg","raised_back_of_hand_tone5":"1f91a-1f3ff.svg","raised_hand":"270b.svg","raised_hand_tone1":"270b-1f3fb.svg","raised_hand_tone2":"270b-1f3fc.svg","raised_hand_tone3":"270b-1f3fd.svg","raised_hand_tone4":"270b-1f3fe.svg","raised_hand_tone5":"270b-1f3ff.svg","raised_hands":"1f64c.svg","raised_hands_tone1":"1f64c-1f3fb.svg","raised_hands_tone2":"1f64c-1f3fc.svg","raised_hands_tone3":"1f64c-1f3fd.svg","raised_hands_tone4":"1f64c-1f3fe.svg","raised_hands_tone5":"1f64c-1f3ff.svg","ram":"1f40f.svg","ramen":"1f35c.svg","rat":"1f400.svg","razor":"1fa92.svg","receipt":"1f9fe.svg","record_button":"23fa.svg","recycle":"267b.svg","red_car":"1f697.svg","red_circle":"1f534.svg","red_envelope":"1f9e7.svg","red_haired":"1f9b0.svg","red_square":"1f7e5.svg","regional_indicator_a":"1f1e6.svg","regional_indicator_b":"1f1e7.svg","regional_indicator_c":"1f1e8.svg","regional_indicator_d":"1f1e9.svg","regional_indicator_e":"1f1ea.svg","regional_indicator_f":"1f1eb.svg","regional_indicator_g":"1f1ec.svg","regional_indicator_h":"1f1ed.svg","regional_indicator_i":"1f1ee.svg","regional_indicator_j":"1f1ef.svg","regional_indicator_k":"1f1f0.svg","regional_indicator_l":"1f1f1.svg","regional_indicator_m":"1f1f2.svg","regional_indicator_n":"1f1f3.svg","regional_indicator_o":"1f1f4.svg","regional_indicator_p":"1f1f5.svg","regional_indicator_q":"1f1f6.svg","regional_indicator_r":"1f1f7.svg","regional_indicator_s":"1f1f8.svg","regional_indicator_t":"1f1f9.svg","regional_indicator_u":"1f1fa.svg","regional_indicator_v":"1f1fb.svg","regional_indicator_w":"1f1fc.svg","regional_indicator_x":"1f1fd.svg","regional_indicator_y":"1f1fe.svg","regional_indicator_z":"1f1ff.svg","registered":"ae.svg","relaxed":"263a.svg","relieved":"1f60c.svg","reminder_ribbon":"1f397.svg","repeat":"1f501.svg","repeat_one":"1f502.svg","restroom":"1f6bb.svg","revolving_hearts":"1f49e.svg","rewind":"23ea.svg","rhino":"1f98f.svg","ribbon":"1f380.svg","rice":"1f35a.svg","rice_ball":"1f359.svg","rice_cracker":"1f358.svg","rice_scene":"1f391.svg","right_facing_fist":"1f91c.svg","right_facing_fist_tone1":"1f91c-1f3fb.svg","right_facing_fist_tone2":"1f91c-1f3fc.svg","right_facing_fist_tone3":"1f91c-1f3fd.svg","right_facing_fist_tone4":"1f91c-1f3fe.svg","right_facing_fist_tone5":"1f91c-1f3ff.svg","ring":"1f48d.svg","ringed_planet":"1fa90.svg","robot":"1f916.svg","rock":"1faa8.svg","rocket":"1f680.svg","rofl":"1f923.svg","roll_of_paper":"1f9fb.svg","roller_coaster":"1f3a2.svg","roller_skate":"1f6fc.svg","rolling_eyes":"1f644.svg","rooster":"1f413.svg","rose":"1f339.svg","rosette":"1f3f5.svg","rotating_light":"1f6a8.svg","round_pushpin":"1f4cd.svg","rugby_football":"1f3c9.svg","running_shirt_with_sash":"1f3bd.svg","sa":"1f202.svg","safety_pin":"1f9f7.svg","safety_vest":"1f9ba.svg","sagittarius":"2650.svg","sailboat":"26f5.svg","sake":"1f376.svg","salad":"1f957.svg","salt":"1f9c2.svg","sandal":"1f461.svg","sandwich":"1f96a.svg","santa":"1f385.svg","santa_tone1":"1f385-1f3fb.svg","santa_tone2":"1f385-1f3fc.svg","santa_tone3":"1f385-1f3fd.svg","santa_tone4":"1f385-1f3fe.svg","santa_tone5":"1f385-1f3ff.svg","sari":"1f97b.svg","satellite":"1f4e1.svg","satellite_orbital":"1f6f0.svg","sauropod":"1f995.svg","saxophone":"1f3b7.svg","scales":"2696.svg","scarf":"1f9e3.svg","school":"1f3eb.svg","school_satchel":"1f392.svg","scientist":"1f9d1-200d-1f52c.svg","scientist_tone1":"1f9d1-1f3fb-200d-1f52c.svg","scientist_tone2":"1f9d1-1f3fc-200d-1f52c.svg","scientist_tone3":"1f9d1-1f3fd-200d-1f52c.svg","scientist_tone4":"1f9d1-1f3fe-200d-1f52c.svg","scientist_tone5":"1f9d1-1f3ff-200d-1f52c.svg","scissors":"2702.svg","scooter":"1f6f4.svg","scorpion":"1f982.svg","scorpius":"264f.svg","scotland":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f.svg","scream":"1f631.svg","scream_cat":"1f640.svg","screwdriver":"1fa9b.svg","scroll":"1f4dc.svg","seal":"1f9ad.svg","seat":"1f4ba.svg","second_place":"1f948.svg","secret":"3299.svg","see_no_evil":"1f648.svg","seedling":"1f331.svg","selfie":"1f933.svg","selfie_tone1":"1f933-1f3fb.svg","selfie_tone2":"1f933-1f3fc.svg","selfie_tone3":"1f933-1f3fd.svg","selfie_tone4":"1f933-1f3fe.svg","selfie_tone5":"1f933-1f3ff.svg","service_dog":"1f415-200d-1f9ba.svg","seven":"37-20e3.svg","sewing_needle":"1faa1.svg","shallow_pan_of_food":"1f958.svg","shamrock":"2618.svg","shark":"1f988.svg","shaved_ice":"1f367.svg","sheep":"1f411.svg","shell":"1f41a.svg","shibuya":"e50a.svg","shield":"1f6e1.svg","shinto_shrine":"26e9.svg","ship":"1f6a2.svg","shirt":"1f455.svg","shopping_bags":"1f6cd.svg","shopping_cart":"1f6d2.svg","shorts":"1fa73.svg","shower":"1f6bf.svg","shrimp":"1f990.svg","shushing_face":"1f92b.svg","signal_strength":"1f4f6.svg","singer":"1f9d1-200d-1f3a4.svg","singer_tone1":"1f9d1-1f3fb-200d-1f3a4.svg","singer_tone2":"1f9d1-1f3fc-200d-1f3a4.svg","singer_tone3":"1f9d1-1f3fd-200d-1f3a4.svg","singer_tone4":"1f9d1-1f3fe-200d-1f3a4.svg","singer_tone5":"1f9d1-1f3ff-200d-1f3a4.svg","six":"36-20e3.svg","six_pointed_star":"1f52f.svg","skateboard":"1f6f9.svg","ski":"1f3bf.svg","skier":"26f7.svg","skier_tone1":"26f7-1f3fb.svg","skier_tone2":"26f7-1f3fc.svg","skier_tone3":"26f7-1f3fd.svg","skier_tone4":"26f7-1f3fe.svg","skier_tone5":"26f7-1f3ff.svg","skull":"1f480.svg","skull_crossbones":"2620.svg","skunk":"1f9a8.svg","sled":"1f6f7.svg","sleeping":"1f634.svg","sleeping_accommodation":"1f6cc.svg","sleepy":"1f62a.svg","slight_frown":"1f641.svg","slight_smile":"1f642.svg","slot_machine":"1f3b0.svg","sloth":"1f9a5.svg","small_blue_diamond":"1f539.svg","small_orange_diamond":"1f538.svg","small_red_triangle":"1f53a.svg","small_red_triangle_down":"1f53b.svg","smile":"1f604.svg","smile_cat":"1f638.svg","smiley":"1f603.svg","smiley_cat":"1f63a.svg","smiling_face_with_3_hearts":"1f970.svg","smiling_face_with_tear":"1f972.svg","smiling_imp":"1f608.svg","smirk":"1f60f.svg","smirk_cat":"1f63c.svg","smoking":"1f6ac.svg","snail":"1f40c.svg","snake":"1f40d.svg","sneezing_face":"1f927.svg","snowboarder":"1f3c2.svg","snowboarder_tone1":"1f3c2-1f3fb.svg","snowboarder_tone2":"1f3c2-1f3fc.svg","snowboarder_tone3":"1f3c2-1f3fd.svg","snowboarder_tone4":"1f3c2-1f3fe.svg","snowboarder_tone5":"1f3c2-1f3ff.svg","snowflake":"2744.svg","snowman2":"2603.svg","snowman":"26c4.svg","soap":"1f9fc.svg","sob":"1f62d.svg","soccer":"26bd.svg","socks":"1f9e6.svg","softball":"1f94e.svg","soon":"1f51c.svg","sos":"1f198.svg","sound":"1f509.svg","space_invader":"1f47e.svg","spades":"2660.svg","spaghetti":"1f35d.svg","sparkle":"2747.svg","sparkler":"1f387.svg","sparkles":"2728.svg","sparkling_heart":"1f496.svg","speak_no_evil":"1f64a.svg","speaker":"1f508.svg","speaking_head":"1f5e3.svg","speech_balloon":"1f4ac.svg","speech_left":"1f5e8.svg","speedboat":"1f6a4.svg","spider":"1f577.svg","spider_web":"1f578.svg","sponge":"1f9fd.svg","spoon":"1f944.svg","squeeze_bottle":"1f9f4.svg","squid":"1f991.svg","stadium":"1f3df.svg","star2":"1f31f.svg","star":"2b50.svg","star_and_crescent":"262a.svg","star_of_david":"2721.svg","star_struck":"1f929.svg","stars":"1f320.svg","station":"1f689.svg","statue_of_liberty":"1f5fd.svg","steam_locomotive":"1f682.svg","stethoscope":"1fa7a.svg","stew":"1f372.svg","stop_button":"23f9.svg","stopwatch":"23f1.svg","straight_ruler":"1f4cf.svg","strawberry":"1f353.svg","stuck_out_tongue":"1f61b.svg","stuck_out_tongue_closed_eyes":"1f61d.svg","stuck_out_tongue_winking_eye":"1f61c.svg","student":"1f9d1-200d-1f393.svg","student_tone1":"1f9d1-1f3fb-200d-1f393.svg","student_tone2":"1f9d1-1f3fc-200d-1f393.svg","student_tone3":"1f9d1-1f3fd-200d-1f393.svg","student_tone4":"1f9d1-1f3fe-200d-1f393.svg","student_tone5":"1f9d1-1f3ff-200d-1f393.svg","stuffed_flatbread":"1f959.svg","sun_with_face":"1f31e.svg","sunflower":"1f33b.svg","sunglasses":"1f60e.svg","sunny":"2600.svg","sunrise":"1f305.svg","sunrise_over_mountains":"1f304.svg","superhero":"1f9b8.svg","superhero_tone1":"1f9b8-1f3fb.svg","superhero_tone2":"1f9b8-1f3fc.svg","superhero_tone3":"1f9b8-1f3fd.svg","superhero_tone4":"1f9b8-1f3fe.svg","superhero_tone5":"1f9b8-1f3ff.svg","supervillain":"1f9b9.svg","supervillain_tone1":"1f9b9-1f3fb.svg","supervillain_tone2":"1f9b9-1f3fc.svg","supervillain_tone3":"1f9b9-1f3fd.svg","supervillain_tone4":"1f9b9-1f3fe.svg","supervillain_tone5":"1f9b9-1f3ff.svg","sushi":"1f363.svg","suspension_railway":"1f69f.svg","swan":"1f9a2.svg","sweat":"1f613.svg","sweat_drops":"1f4a6.svg","sweat_smile":"1f605.svg","sweet_potato":"1f360.svg","symbols":"1f523.svg","synagogue":"1f54d.svg","syringe":"1f489.svg","t_rex":"1f996.svg","taco":"1f32e.svg","tada":"1f389.svg","takeout_box":"1f961.svg","tamale":"1fad4.svg","tanabata_tree":"1f38b.svg","tangerine":"1f34a.svg","taurus":"2649.svg","taxi":"1f695.svg","tea":"1f375.svg","teacher":"1f9d1-200d-1f3eb.svg","teacher_tone1":"1f9d1-1f3fb-200d-1f3eb.svg","teacher_tone2":"1f9d1-1f3fc-200d-1f3eb.svg","teacher_tone3":"1f9d1-1f3fd-200d-1f3eb.svg","teacher_tone4":"1f9d1-1f3fe-200d-1f3eb.svg","teacher_tone5":"1f9d1-1f3ff-200d-1f3eb.svg","teapot":"1fad6.svg","technologist":"1f9d1-200d-1f4bb.svg","technologist_tone1":"1f9d1-1f3fb-200d-1f4bb.svg","technologist_tone2":"1f9d1-1f3fc-200d-1f4bb.svg","technologist_tone3":"1f9d1-1f3fd-200d-1f4bb.svg","technologist_tone4":"1f9d1-1f3fe-200d-1f4bb.svg","technologist_tone5":"1f9d1-1f3ff-200d-1f4bb.svg","teddy_bear":"1f9f8.svg","telephone":"260e.svg","telephone_receiver":"1f4de.svg","telescope":"1f52d.svg","tennis":"1f3be.svg","tent":"26fa.svg","test_tube":"1f9ea.svg","thermometer":"1f321.svg","thermometer_face":"1f912.svg","thinking":"1f914.svg","third_place":"1f949.svg","thong_sandal":"1fa74.svg","thought_balloon":"1f4ad.svg","thread":"1f9f5.svg","three":"33-20e3.svg","thumbsdown":"1f44e.svg","thumbsdown_tone1":"1f44e-1f3fb.svg","thumbsdown_tone2":"1f44e-1f3fc.svg","thumbsdown_tone3":"1f44e-1f3fd.svg","thumbsdown_tone4":"1f44e-1f3fe.svg","thumbsdown_tone5":"1f44e-1f3ff.svg","thumbsup":"1f44d.svg","thumbsup_tone1":"1f44d-1f3fb.svg","thumbsup_tone2":"1f44d-1f3fc.svg","thumbsup_tone3":"1f44d-1f3fd.svg","thumbsup_tone4":"1f44d-1f3fe.svg","thumbsup_tone5":"1f44d-1f3ff.svg","thunder_cloud_rain":"26c8.svg","ticket":"1f3ab.svg","tickets":"1f39f.svg","tiger2":"1f405.svg","tiger":"1f42f.svg","timer":"23f2.svg","tired_face":"1f62b.svg","tm":"2122.svg","toilet":"1f6bd.svg","tokyo_tower":"1f5fc.svg","tomato":"1f345.svg","tone1":"1f3fb.svg","tone2":"1f3fc.svg","tone3":"1f3fd.svg","tone4":"1f3fe.svg","tone5":"1f3ff.svg","tongue":"1f445.svg","toolbox":"1f9f0.svg","tools":"1f6e0.svg","tooth":"1f9b7.svg","toothbrush":"1faa5.svg","top":"1f51d.svg","tophat":"1f3a9.svg","track_next":"23ed.svg","track_previous":"23ee.svg","trackball":"1f5b2.svg","tractor":"1f69c.svg","traffic_light":"1f6a5.svg","train2":"1f686.svg","train":"1f68b.svg","tram":"1f68a.svg","transgender_flag":"1f3f3-fe0f-200d-26a7-fe0f.svg","transgender_symbol":"26a7.svg","triangular_flag_on_post":"1f6a9.svg","triangular_ruler":"1f4d0.svg","trident":"1f531.svg","triumph":"1f624.svg","trolleybus":"1f68e.svg","trophy":"1f3c6.svg","tropical_drink":"1f379.svg","tropical_fish":"1f420.svg","truck":"1f69a.svg","trumpet":"1f3ba.svg","tulip":"1f337.svg","tumbler_glass":"1f943.svg","turkey":"1f983.svg","turtle":"1f422.svg","tv":"1f4fa.svg","twisted_rightwards_arrows":"1f500.svg","two":"32-20e3.svg","two_hearts":"1f495.svg","two_men_holding_hands":"1f46c.svg","two_women_holding_hands":"1f46d.svg","u5272":"1f239.svg","u5408":"1f234.svg","u55b6":"1f23a.svg","u6307":"1f22f.svg","u6708":"1f237.svg","u6709":"1f236.svg","u6e80":"1f235.svg","u7121":"1f21a.svg","u7533":"1f238.svg","u7981":"1f232.svg","u7a7a":"1f233.svg","umbrella2":"2602.svg","umbrella":"2614.svg","unamused":"1f612.svg","underage":"1f51e.svg","unicorn":"1f984.svg","united_nations":"1f1fa-1f1f3.svg","unlock":"1f513.svg","up":"1f199.svg","upside_down":"1f643.svg","urn":"26b1.svg","v":"270c.svg","v_tone1":"270c-1f3fb.svg","v_tone2":"270c-1f3fc.svg","v_tone3":"270c-1f3fd.svg","v_tone4":"270c-1f3fe.svg","v_tone5":"270c-1f3ff.svg","vampire":"1f9db.svg","vampire_tone1":"1f9db-1f3fb.svg","vampire_tone2":"1f9db-1f3fc.svg","vampire_tone3":"1f9db-1f3fd.svg","vampire_tone4":"1f9db-1f3fe.svg","vampire_tone5":"1f9db-1f3ff.svg","vertical_traffic_light":"1f6a6.svg","vhs":"1f4fc.svg","vibration_mode":"1f4f3.svg","video_camera":"1f4f9.svg","video_game":"1f3ae.svg","violin":"1f3bb.svg","virgo":"264d.svg","volcano":"1f30b.svg","volleyball":"1f3d0.svg","vs":"1f19a.svg","vulcan":"1f596.svg","vulcan_tone1":"1f596-1f3fb.svg","vulcan_tone2":"1f596-1f3fc.svg","vulcan_tone3":"1f596-1f3fd.svg","vulcan_tone4":"1f596-1f3fe.svg","vulcan_tone5":"1f596-1f3ff.svg","waffle":"1f9c7.svg","wales":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f.svg","waning_crescent_moon":"1f318.svg","waning_gibbous_moon":"1f316.svg","warning":"26a0.svg","wastebasket":"1f5d1.svg","watch":"231a.svg","water_buffalo":"1f403.svg","watermelon":"1f349.svg","wave":"1f44b.svg","wave_tone1":"1f44b-1f3fb.svg","wave_tone2":"1f44b-1f3fc.svg","wave_tone3":"1f44b-1f3fd.svg","wave_tone4":"1f44b-1f3fe.svg","wave_tone5":"1f44b-1f3ff.svg","wavy_dash":"3030.svg","waxing_crescent_moon":"1f312.svg","waxing_gibbous_moon":"1f314.svg","wc":"1f6be.svg","weary":"1f629.svg","wedding":"1f492.svg","whale2":"1f40b.svg","whale":"1f433.svg","wheel_of_dharma":"2638.svg","wheelchair":"267f.svg","white_check_mark":"2705.svg","white_circle":"26aa.svg","white_flower":"1f4ae.svg","white_haired":"1f9b3.svg","white_heart":"1f90d.svg","white_large_square":"2b1c.svg","white_medium_small_square":"25fd.svg","white_medium_square":"25fb.svg","white_small_square":"25ab.svg","white_square_button":"1f533.svg","white_sun_cloud":"1f325.svg","white_sun_rain_cloud":"1f326.svg","white_sun_small_cloud":"1f324.svg","wilted_rose":"1f940.svg","wind_blowing_face":"1f32c.svg","wind_chime":"1f390.svg","window":"1fa9f.svg","wine_glass":"1f377.svg","wink":"1f609.svg","wolf":"1f43a.svg","woman":"1f469.svg","woman_and_man_holding_hands_tone1":"1f46b-1f3fb.svg","woman_and_man_holding_hands_tone1_tone2":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone1_tone3":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone1_tone4":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone1_tone5":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone2":"1f46b-1f3fc.svg","woman_and_man_holding_hands_tone2_tone1":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone2_tone3":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone2_tone4":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone2_tone5":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone3":"1f46b-1f3fd.svg","woman_and_man_holding_hands_tone3_tone1":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone3_tone2":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone3_tone4":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone3_tone5":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone4":"1f46b-1f3fe.svg","woman_and_man_holding_hands_tone4_tone1":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone4_tone2":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone4_tone3":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone4_tone5":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone5":"1f46b-1f3ff.svg","woman_and_man_holding_hands_tone5_tone1":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone5_tone2":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone5_tone3":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone5_tone4":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe.svg","woman_artist":"1f469-200d-1f3a8.svg","woman_artist_tone1":"1f469-1f3fb-200d-1f3a8.svg","woman_artist_tone2":"1f469-1f3fc-200d-1f3a8.svg","woman_artist_tone3":"1f469-1f3fd-200d-1f3a8.svg","woman_artist_tone4":"1f469-1f3fe-200d-1f3a8.svg","woman_artist_tone5":"1f469-1f3ff-200d-1f3a8.svg","woman_astronaut":"1f469-200d-1f680.svg","woman_astronaut_tone1":"1f469-1f3fb-200d-1f680.svg","woman_astronaut_tone2":"1f469-1f3fc-200d-1f680.svg","woman_astronaut_tone3":"1f469-1f3fd-200d-1f680.svg","woman_astronaut_tone4":"1f469-1f3fe-200d-1f680.svg","woman_astronaut_tone5":"1f469-1f3ff-200d-1f680.svg","woman_bald":"1f469-200d-1f9b2.svg","woman_bald_tone1":"1f469-1f3fb-200d-1f9b2.svg","woman_bald_tone2":"1f469-1f3fc-200d-1f9b2.svg","woman_bald_tone3":"1f469-1f3fd-200d-1f9b2.svg","woman_bald_tone4":"1f469-1f3fe-200d-1f9b2.svg","woman_bald_tone5":"1f469-1f3ff-200d-1f9b2.svg","woman_beard":"1f9d4-200d-2640-fe0f.svg","woman_biking":"1f6b4-200d-2640-fe0f.svg","woman_biking_tone1":"1f6b4-1f3fb-200d-2640-fe0f.svg","woman_biking_tone2":"1f6b4-1f3fc-200d-2640-fe0f.svg","woman_biking_tone3":"1f6b4-1f3fd-200d-2640-fe0f.svg","woman_biking_tone4":"1f6b4-1f3fe-200d-2640-fe0f.svg","woman_biking_tone5":"1f6b4-1f3ff-200d-2640-fe0f.svg","woman_bouncing_ball":"26f9-fe0f-200d-2640-fe0f.svg","woman_bouncing_ball_tone1":"26f9-1f3fb-200d-2640-fe0f.svg","woman_bouncing_ball_tone2":"26f9-1f3fc-200d-2640-fe0f.svg","woman_bouncing_ball_tone3":"26f9-1f3fd-200d-2640-fe0f.svg","woman_bouncing_ball_tone4":"26f9-1f3fe-200d-2640-fe0f.svg","woman_bouncing_ball_tone5":"26f9-1f3ff-200d-2640-fe0f.svg","woman_bowing":"1f647-200d-2640-fe0f.svg","woman_bowing_tone1":"1f647-1f3fb-200d-2640-fe0f.svg","woman_bowing_tone2":"1f647-1f3fc-200d-2640-fe0f.svg","woman_bowing_tone3":"1f647-1f3fd-200d-2640-fe0f.svg","woman_bowing_tone4":"1f647-1f3fe-200d-2640-fe0f.svg","woman_bowing_tone5":"1f647-1f3ff-200d-2640-fe0f.svg","woman_cartwheeling":"1f938-200d-2640-fe0f.svg","woman_cartwheeling_tone1":"1f938-1f3fb-200d-2640-fe0f.svg","woman_cartwheeling_tone2":"1f938-1f3fc-200d-2640-fe0f.svg","woman_cartwheeling_tone3":"1f938-1f3fd-200d-2640-fe0f.svg","woman_cartwheeling_tone4":"1f938-1f3fe-200d-2640-fe0f.svg","woman_cartwheeling_tone5":"1f938-1f3ff-200d-2640-fe0f.svg","woman_climbing":"1f9d7-200d-2640-fe0f.svg","woman_climbing_tone1":"1f9d7-1f3fb-200d-2640-fe0f.svg","woman_climbing_tone2":"1f9d7-1f3fc-200d-2640-fe0f.svg","woman_climbing_tone3":"1f9d7-1f3fd-200d-2640-fe0f.svg","woman_climbing_tone4":"1f9d7-1f3fe-200d-2640-fe0f.svg","woman_climbing_tone5":"1f9d7-1f3ff-200d-2640-fe0f.svg","woman_construction_worker":"1f477-200d-2640-fe0f.svg","woman_construction_worker_tone1":"1f477-1f3fb-200d-2640-fe0f.svg","woman_construction_worker_tone2":"1f477-1f3fc-200d-2640-fe0f.svg","woman_construction_worker_tone3":"1f477-1f3fd-200d-2640-fe0f.svg","woman_construction_worker_tone4":"1f477-1f3fe-200d-2640-fe0f.svg","woman_construction_worker_tone5":"1f477-1f3ff-200d-2640-fe0f.svg","woman_cook":"1f469-200d-1f373.svg","woman_cook_tone1":"1f469-1f3fb-200d-1f373.svg","woman_cook_tone2":"1f469-1f3fc-200d-1f373.svg","woman_cook_tone3":"1f469-1f3fd-200d-1f373.svg","woman_cook_tone4":"1f469-1f3fe-200d-1f373.svg","woman_cook_tone5":"1f469-1f3ff-200d-1f373.svg","woman_curly_haired":"1f469-200d-1f9b1.svg","woman_curly_haired_tone1":"1f469-1f3fb-200d-1f9b1.svg","woman_curly_haired_tone2":"1f469-1f3fc-200d-1f9b1.svg","woman_curly_haired_tone3":"1f469-1f3fd-200d-1f9b1.svg","woman_curly_haired_tone4":"1f469-1f3fe-200d-1f9b1.svg","woman_curly_haired_tone5":"1f469-1f3ff-200d-1f9b1.svg","woman_detective":"1f575-fe0f-200d-2640-fe0f.svg","woman_detective_tone1":"1f575-1f3fb-200d-2640-fe0f.svg","woman_detective_tone2":"1f575-1f3fc-200d-2640-fe0f.svg","woman_detective_tone3":"1f575-1f3fd-200d-2640-fe0f.svg","woman_detective_tone4":"1f575-1f3fe-200d-2640-fe0f.svg","woman_detective_tone5":"1f575-1f3ff-200d-2640-fe0f.svg","woman_elf":"1f9dd-200d-2640-fe0f.svg","woman_elf_tone1":"1f9dd-1f3fb-200d-2640-fe0f.svg","woman_elf_tone2":"1f9dd-1f3fc-200d-2640-fe0f.svg","woman_elf_tone3":"1f9dd-1f3fd-200d-2640-fe0f.svg","woman_elf_tone4":"1f9dd-1f3fe-200d-2640-fe0f.svg","woman_elf_tone5":"1f9dd-1f3ff-200d-2640-fe0f.svg","woman_facepalming":"1f926-200d-2640-fe0f.svg","woman_facepalming_tone1":"1f926-1f3fb-200d-2640-fe0f.svg","woman_facepalming_tone2":"1f926-1f3fc-200d-2640-fe0f.svg","woman_facepalming_tone3":"1f926-1f3fd-200d-2640-fe0f.svg","woman_facepalming_tone4":"1f926-1f3fe-200d-2640-fe0f.svg","woman_facepalming_tone5":"1f926-1f3ff-200d-2640-fe0f.svg","woman_factory_worker":"1f469-200d-1f3ed.svg","woman_factory_worker_tone1":"1f469-1f3fb-200d-1f3ed.svg","woman_factory_worker_tone2":"1f469-1f3fc-200d-1f3ed.svg","woman_factory_worker_tone3":"1f469-1f3fd-200d-1f3ed.svg","woman_factory_worker_tone4":"1f469-1f3fe-200d-1f3ed.svg","woman_factory_worker_tone5":"1f469-1f3ff-200d-1f3ed.svg","woman_fairy":"1f9da-200d-2640-fe0f.svg","woman_fairy_tone1":"1f9da-1f3fb-200d-2640-fe0f.svg","woman_fairy_tone2":"1f9da-1f3fc-200d-2640-fe0f.svg","woman_fairy_tone3":"1f9da-1f3fd-200d-2640-fe0f.svg","woman_fairy_tone4":"1f9da-1f3fe-200d-2640-fe0f.svg","woman_fairy_tone5":"1f9da-1f3ff-200d-2640-fe0f.svg","woman_farmer":"1f469-200d-1f33e.svg","woman_farmer_tone1":"1f469-1f3fb-200d-1f33e.svg","woman_farmer_tone2":"1f469-1f3fc-200d-1f33e.svg","woman_farmer_tone3":"1f469-1f3fd-200d-1f33e.svg","woman_farmer_tone4":"1f469-1f3fe-200d-1f33e.svg","woman_farmer_tone5":"1f469-1f3ff-200d-1f33e.svg","woman_feeding_baby":"1f469-200d-1f37c.svg","woman_feeding_baby_tone1":"1f469-1f3fb-200d-1f37c.svg","woman_feeding_baby_tone2":"1f469-1f3fc-200d-1f37c.svg","woman_feeding_baby_tone3":"1f469-1f3fd-200d-1f37c.svg","woman_feeding_baby_tone4":"1f469-1f3fe-200d-1f37c.svg","woman_feeding_baby_tone5":"1f469-1f3ff-200d-1f37c.svg","woman_firefighter":"1f469-200d-1f692.svg","woman_firefighter_tone1":"1f469-1f3fb-200d-1f692.svg","woman_firefighter_tone2":"1f469-1f3fc-200d-1f692.svg","woman_firefighter_tone3":"1f469-1f3fd-200d-1f692.svg","woman_firefighter_tone4":"1f469-1f3fe-200d-1f692.svg","woman_firefighter_tone5":"1f469-1f3ff-200d-1f692.svg","woman_frowning":"1f64d-200d-2640-fe0f.svg","woman_frowning_tone1":"1f64d-1f3fb-200d-2640-fe0f.svg","woman_frowning_tone2":"1f64d-1f3fc-200d-2640-fe0f.svg","woman_frowning_tone3":"1f64d-1f3fd-200d-2640-fe0f.svg","woman_frowning_tone4":"1f64d-1f3fe-200d-2640-fe0f.svg","woman_frowning_tone5":"1f64d-1f3ff-200d-2640-fe0f.svg","woman_genie":"1f9de-200d-2640-fe0f.svg","woman_gesturing_no":"1f645-200d-2640-fe0f.svg","woman_gesturing_no_tone1":"1f645-1f3fb-200d-2640-fe0f.svg","woman_gesturing_no_tone2":"1f645-1f3fc-200d-2640-fe0f.svg","woman_gesturing_no_tone3":"1f645-1f3fd-200d-2640-fe0f.svg","woman_gesturing_no_tone4":"1f645-1f3fe-200d-2640-fe0f.svg","woman_gesturing_no_tone5":"1f645-1f3ff-200d-2640-fe0f.svg","woman_gesturing_ok":"1f646-200d-2640-fe0f.svg","woman_gesturing_ok_tone1":"1f646-1f3fb-200d-2640-fe0f.svg","woman_gesturing_ok_tone2":"1f646-1f3fc-200d-2640-fe0f.svg","woman_gesturing_ok_tone3":"1f646-1f3fd-200d-2640-fe0f.svg","woman_gesturing_ok_tone4":"1f646-1f3fe-200d-2640-fe0f.svg","woman_gesturing_ok_tone5":"1f646-1f3ff-200d-2640-fe0f.svg","woman_getting_face_massage":"1f486-200d-2640-fe0f.svg","woman_getting_face_massage_tone1":"1f486-1f3fb-200d-2640-fe0f.svg","woman_getting_face_massage_tone2":"1f486-1f3fc-200d-2640-fe0f.svg","woman_getting_face_massage_tone3":"1f486-1f3fd-200d-2640-fe0f.svg","woman_getting_face_massage_tone4":"1f486-1f3fe-200d-2640-fe0f.svg","woman_getting_face_massage_tone5":"1f486-1f3ff-200d-2640-fe0f.svg","woman_getting_haircut":"1f487-200d-2640-fe0f.svg","woman_getting_haircut_tone1":"1f487-1f3fb-200d-2640-fe0f.svg","woman_getting_haircut_tone2":"1f487-1f3fc-200d-2640-fe0f.svg","woman_getting_haircut_tone3":"1f487-1f3fd-200d-2640-fe0f.svg","woman_getting_haircut_tone4":"1f487-1f3fe-200d-2640-fe0f.svg","woman_getting_haircut_tone5":"1f487-1f3ff-200d-2640-fe0f.svg","woman_golfing":"1f3cc-fe0f-200d-2640-fe0f.svg","woman_golfing_tone1":"1f3cc-1f3fb-200d-2640-fe0f.svg","woman_golfing_tone2":"1f3cc-1f3fc-200d-2640-fe0f.svg","woman_golfing_tone3":"1f3cc-1f3fd-200d-2640-fe0f.svg","woman_golfing_tone4":"1f3cc-1f3fe-200d-2640-fe0f.svg","woman_golfing_tone5":"1f3cc-1f3ff-200d-2640-fe0f.svg","woman_guard":"1f482-200d-2640-fe0f.svg","woman_guard_tone1":"1f482-1f3fb-200d-2640-fe0f.svg","woman_guard_tone2":"1f482-1f3fc-200d-2640-fe0f.svg","woman_guard_tone3":"1f482-1f3fd-200d-2640-fe0f.svg","woman_guard_tone4":"1f482-1f3fe-200d-2640-fe0f.svg","woman_guard_tone5":"1f482-1f3ff-200d-2640-fe0f.svg","woman_health_worker":"1f469-200d-2695-fe0f.svg","woman_health_worker_tone1":"1f469-1f3fb-200d-2695-fe0f.svg","woman_health_worker_tone2":"1f469-1f3fc-200d-2695-fe0f.svg","woman_health_worker_tone3":"1f469-1f3fd-200d-2695-fe0f.svg","woman_health_worker_tone4":"1f469-1f3fe-200d-2695-fe0f.svg","woman_health_worker_tone5":"1f469-1f3ff-200d-2695-fe0f.svg","woman_in_lotus_position":"1f9d8-200d-2640-fe0f.svg","woman_in_lotus_position_tone1":"1f9d8-1f3fb-200d-2640-fe0f.svg","woman_in_lotus_position_tone2":"1f9d8-1f3fc-200d-2640-fe0f.svg","woman_in_lotus_position_tone3":"1f9d8-1f3fd-200d-2640-fe0f.svg","woman_in_lotus_position_tone4":"1f9d8-1f3fe-200d-2640-fe0f.svg","woman_in_lotus_position_tone5":"1f9d8-1f3ff-200d-2640-fe0f.svg","woman_in_manual_wheelchair":"1f469-200d-1f9bd.svg","woman_in_manual_wheelchair_tone1":"1f469-1f3fb-200d-1f9bd.svg","woman_in_manual_wheelchair_tone2":"1f469-1f3fc-200d-1f9bd.svg","woman_in_manual_wheelchair_tone3":"1f469-1f3fd-200d-1f9bd.svg","woman_in_manual_wheelchair_tone4":"1f469-1f3fe-200d-1f9bd.svg","woman_in_manual_wheelchair_tone5":"1f469-1f3ff-200d-1f9bd.svg","woman_in_motorized_wheelchair":"1f469-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone1":"1f469-1f3fb-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone2":"1f469-1f3fc-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone3":"1f469-1f3fd-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone4":"1f469-1f3fe-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone5":"1f469-1f3ff-200d-1f9bc.svg","woman_in_santa_hat":"1f469-200d-1f384.svg","woman_in_santa_hat_tone1":"1f469-1f3fb-200d-1f384.svg","woman_in_santa_hat_tone2":"1f468-1f3ff-200d-1f384.svg","woman_in_santa_hat_tone3":"1f469-1f3fe-200d-1f384.svg","woman_in_santa_hat_tone4":"1f469-1f3fd-200d-1f384.svg","woman_in_santa_hat_tone5":"1f469-1f3fc-200d-1f384.svg","woman_in_steamy_room":"1f9d6-200d-2640-fe0f.svg","woman_in_steamy_room_tone1":"1f9d6-1f3fb-200d-2640-fe0f.svg","woman_in_steamy_room_tone2":"1f9d6-1f3fc-200d-2640-fe0f.svg","woman_in_steamy_room_tone3":"1f9d6-1f3fd-200d-2640-fe0f.svg","woman_in_steamy_room_tone4":"1f9d6-1f3fe-200d-2640-fe0f.svg","woman_in_steamy_room_tone5":"1f9d6-1f3ff-200d-2640-fe0f.svg","woman_in_tuxedo":"1f935-200d-2640-fe0f.svg","woman_in_tuxedo_tone1":"1f935-1f3fb-200d-2640-fe0f.svg","woman_in_tuxedo_tone2":"1f935-1f3fc-200d-2640-fe0f.svg","woman_in_tuxedo_tone3":"1f935-1f3fd-200d-2640-fe0f.svg","woman_in_tuxedo_tone4":"1f935-1f3fe-200d-2640-fe0f.svg","woman_in_tuxedo_tone5":"1f935-1f3ff-200d-2640-fe0f.svg","woman_judge":"1f469-200d-2696-fe0f.svg","woman_judge_tone1":"1f469-1f3fb-200d-2696-fe0f.svg","woman_judge_tone2":"1f469-1f3fc-200d-2696-fe0f.svg","woman_judge_tone3":"1f469-1f3fd-200d-2696-fe0f.svg","woman_judge_tone4":"1f469-1f3fe-200d-2696-fe0f.svg","woman_judge_tone5":"1f469-1f3ff-200d-2696-fe0f.svg","woman_juggling":"1f939-200d-2640-fe0f.svg","woman_juggling_tone1":"1f939-1f3fb-200d-2640-fe0f.svg","woman_juggling_tone2":"1f939-1f3fc-200d-2640-fe0f.svg","woman_juggling_tone3":"1f939-1f3fd-200d-2640-fe0f.svg","woman_juggling_tone4":"1f939-1f3fe-200d-2640-fe0f.svg","woman_juggling_tone5":"1f939-1f3ff-200d-2640-fe0f.svg","woman_kneeling":"1f9ce-200d-2640-fe0f.svg","woman_kneeling_tone1":"1f9ce-1f3fb-200d-2640-fe0f.svg","woman_kneeling_tone2":"1f9ce-1f3fc-200d-2640-fe0f.svg","woman_kneeling_tone3":"1f9ce-1f3fd-200d-2640-fe0f.svg","woman_kneeling_tone4":"1f9ce-1f3fe-200d-2640-fe0f.svg","woman_kneeling_tone5":"1f9ce-1f3ff-200d-2640-fe0f.svg","woman_leviate_tone2":"1f574-1f3fc-200d-2640-fe0f.svg","woman_leviate_tone3":"1f574-1f3fd-200d-2640-fe0f.svg","woman_leviate_tone4":"1f574-1f3fe-200d-2640-fe0f.svg","woman_leviate_tone5":"1f574-1f3ff-200d-2640-fe0f.svg","woman_levitate":"1f574-fe0f-200d-2640-fe0f.svg","woman_levitate_tone1":"1f574-1f3fb-200d-2640-fe0f.svg","woman_lifting_weights":"1f3cb-fe0f-200d-2640-fe0f.svg","woman_lifting_weights_tone1":"1f3cb-1f3fb-200d-2640-fe0f.svg","woman_lifting_weights_tone2":"1f3cb-1f3fc-200d-2640-fe0f.svg","woman_lifting_weights_tone3":"1f3cb-1f3fd-200d-2640-fe0f.svg","woman_lifting_weights_tone4":"1f3cb-1f3fe-200d-2640-fe0f.svg","woman_lifting_weights_tone5":"1f3cb-1f3ff-200d-2640-fe0f.svg","woman_mage":"1f9d9-200d-2640-fe0f.svg","woman_mage_tone1":"1f9d9-1f3fb-200d-2640-fe0f.svg","woman_mage_tone2":"1f9d9-1f3fc-200d-2640-fe0f.svg","woman_mage_tone3":"1f9d9-1f3fd-200d-2640-fe0f.svg","woman_mage_tone4":"1f9d9-1f3fe-200d-2640-fe0f.svg","woman_mage_tone5":"1f9d9-1f3ff-200d-2640-fe0f.svg","woman_mechanic":"1f469-200d-1f527.svg","woman_mechanic_tone1":"1f469-1f3fb-200d-1f527.svg","woman_mechanic_tone2":"1f469-1f3fc-200d-1f527.svg","woman_mechanic_tone3":"1f469-1f3fd-200d-1f527.svg","woman_mechanic_tone4":"1f469-1f3fe-200d-1f527.svg","woman_mechanic_tone5":"1f469-1f3ff-200d-1f527.svg","woman_mountain_biking":"1f6b5-200d-2640-fe0f.svg","woman_mountain_biking_tone1":"1f6b5-1f3fb-200d-2640-fe0f.svg","woman_mountain_biking_tone2":"1f6b5-1f3fc-200d-2640-fe0f.svg","woman_mountain_biking_tone3":"1f6b5-1f3fd-200d-2640-fe0f.svg","woman_mountain_biking_tone4":"1f6b5-1f3fe-200d-2640-fe0f.svg","woman_mountain_biking_tone5":"1f6b5-1f3ff-200d-2640-fe0f.svg","woman_office_worker":"1f469-200d-1f4bc.svg","woman_office_worker_tone1":"1f469-1f3fb-200d-1f4bc.svg","woman_office_worker_tone2":"1f469-1f3fc-200d-1f4bc.svg","woman_office_worker_tone3":"1f469-1f3fd-200d-1f4bc.svg","woman_office_worker_tone4":"1f469-1f3fe-200d-1f4bc.svg","woman_office_worker_tone5":"1f469-1f3ff-200d-1f4bc.svg","woman_pilot":"1f469-200d-2708-fe0f.svg","woman_pilot_tone1":"1f469-1f3fb-200d-2708-fe0f.svg","woman_pilot_tone2":"1f469-1f3fc-200d-2708-fe0f.svg","woman_pilot_tone3":"1f469-1f3fd-200d-2708-fe0f.svg","woman_pilot_tone4":"1f469-1f3fe-200d-2708-fe0f.svg","woman_pilot_tone5":"1f469-1f3ff-200d-2708-fe0f.svg","woman_playing_handball":"1f93e-200d-2640-fe0f.svg","woman_playing_handball_tone1":"1f93e-1f3fb-200d-2640-fe0f.svg","woman_playing_handball_tone2":"1f93e-1f3fc-200d-2640-fe0f.svg","woman_playing_handball_tone3":"1f93e-1f3fd-200d-2640-fe0f.svg","woman_playing_handball_tone4":"1f93e-1f3fe-200d-2640-fe0f.svg","woman_playing_handball_tone5":"1f93e-1f3ff-200d-2640-fe0f.svg","woman_playing_water_polo":"1f93d-200d-2640-fe0f.svg","woman_playing_water_polo_tone1":"1f93d-1f3fb-200d-2640-fe0f.svg","woman_playing_water_polo_tone2":"1f93d-1f3fc-200d-2640-fe0f.svg","woman_playing_water_polo_tone3":"1f93d-1f3fd-200d-2640-fe0f.svg","woman_playing_water_polo_tone4":"1f93d-1f3fe-200d-2640-fe0f.svg","woman_playing_water_polo_tone5":"1f93d-1f3ff-200d-2640-fe0f.svg","woman_police_officer":"1f46e-200d-2640-fe0f.svg","woman_police_officer_tone1":"1f46e-1f3fb-200d-2640-fe0f.svg","woman_police_officer_tone2":"1f46e-1f3fc-200d-2640-fe0f.svg","woman_police_officer_tone3":"1f46e-1f3fd-200d-2640-fe0f.svg","woman_police_officer_tone4":"1f46e-1f3fe-200d-2640-fe0f.svg","woman_police_officer_tone5":"1f46e-1f3ff-200d-2640-fe0f.svg","woman_pouting":"1f64e-200d-2640-fe0f.svg","woman_pouting_tone1":"1f64e-1f3fb-200d-2640-fe0f.svg","woman_pouting_tone2":"1f64e-1f3fc-200d-2640-fe0f.svg","woman_pouting_tone3":"1f64e-1f3fd-200d-2640-fe0f.svg","woman_pouting_tone4":"1f64e-1f3fe-200d-2640-fe0f.svg","woman_pouting_tone5":"1f64e-1f3ff-200d-2640-fe0f.svg","woman_raising_hand":"1f64b-200d-2640-fe0f.svg","woman_raising_hand_tone1":"1f64b-1f3fb-200d-2640-fe0f.svg","woman_raising_hand_tone2":"1f64b-1f3fc-200d-2640-fe0f.svg","woman_raising_hand_tone3":"1f64b-1f3fd-200d-2640-fe0f.svg","woman_raising_hand_tone4":"1f64b-1f3fe-200d-2640-fe0f.svg","woman_raising_hand_tone5":"1f64b-1f3ff-200d-2640-fe0f.svg","woman_red_haired":"1f469-200d-1f9b0.svg","woman_red_haired_tone1":"1f469-1f3fb-200d-1f9b0.svg","woman_red_haired_tone2":"1f469-1f3fc-200d-1f9b0.svg","woman_red_haired_tone3":"1f469-1f3fd-200d-1f9b0.svg","woman_red_haired_tone4":"1f469-1f3fe-200d-1f9b0.svg","woman_red_haired_tone5":"1f469-1f3ff-200d-1f9b0.svg","woman_rowing_boat":"1f6a3-200d-2640-fe0f.svg","woman_rowing_boat_tone1":"1f6a3-1f3fb-200d-2640-fe0f.svg","woman_rowing_boat_tone2":"1f6a3-1f3fc-200d-2640-fe0f.svg","woman_rowing_boat_tone3":"1f6a3-1f3fd-200d-2640-fe0f.svg","woman_rowing_boat_tone4":"1f6a3-1f3fe-200d-2640-fe0f.svg","woman_rowing_boat_tone5":"1f6a3-1f3ff-200d-2640-fe0f.svg","woman_running":"1f3c3-200d-2640-fe0f.svg","woman_running_tone1":"1f3c3-1f3fb-200d-2640-fe0f.svg","woman_running_tone2":"1f3c3-1f3fc-200d-2640-fe0f.svg","woman_running_tone3":"1f3c3-1f3fd-200d-2640-fe0f.svg","woman_running_tone4":"1f3c3-1f3fe-200d-2640-fe0f.svg","woman_running_tone5":"1f3c3-1f3ff-200d-2640-fe0f.svg","woman_scientist":"1f469-200d-1f52c.svg","woman_scientist_tone1":"1f469-1f3fb-200d-1f52c.svg","woman_scientist_tone2":"1f469-1f3fc-200d-1f52c.svg","woman_scientist_tone3":"1f469-1f3fd-200d-1f52c.svg","woman_scientist_tone4":"1f469-1f3fe-200d-1f52c.svg","woman_scientist_tone5":"1f469-1f3ff-200d-1f52c.svg","woman_shrugging":"1f937-200d-2640-fe0f.svg","woman_shrugging_tone1":"1f937-1f3fb-200d-2640-fe0f.svg","woman_shrugging_tone2":"1f937-1f3fc-200d-2640-fe0f.svg","woman_shrugging_tone3":"1f937-1f3fd-200d-2640-fe0f.svg","woman_shrugging_tone4":"1f937-1f3fe-200d-2640-fe0f.svg","woman_shrugging_tone5":"1f937-1f3ff-200d-2640-fe0f.svg","woman_singer":"1f469-200d-1f3a4.svg","woman_singer_tone1":"1f469-1f3fb-200d-1f3a4.svg","woman_singer_tone2":"1f469-1f3fc-200d-1f3a4.svg","woman_singer_tone3":"1f469-1f3fd-200d-1f3a4.svg","woman_singer_tone4":"1f469-1f3fe-200d-1f3a4.svg","woman_singer_tone5":"1f469-1f3ff-200d-1f3a4.svg","woman_standing":"1f9cd-200d-2640-fe0f.svg","woman_standing_tone1":"1f9cd-1f3fb-200d-2640-fe0f.svg","woman_standing_tone2":"1f9cd-1f3fc-200d-2640-fe0f.svg","woman_standing_tone3":"1f9cd-1f3fd-200d-2640-fe0f.svg","woman_standing_tone4":"1f9cd-1f3fe-200d-2640-fe0f.svg","woman_standing_tone5":"1f9cd-1f3ff-200d-2640-fe0f.svg","woman_student":"1f469-200d-1f393.svg","woman_student_tone1":"1f469-1f3fb-200d-1f393.svg","woman_student_tone2":"1f469-1f3fc-200d-1f393.svg","woman_student_tone3":"1f469-1f3fd-200d-1f393.svg","woman_student_tone4":"1f469-1f3fe-200d-1f393.svg","woman_student_tone5":"1f469-1f3ff-200d-1f393.svg","woman_superhero":"1f9b8-200d-2640-fe0f.svg","woman_superhero_tone1":"1f9b8-1f3fb-200d-2640-fe0f.svg","woman_superhero_tone2":"1f9b8-1f3fc-200d-2640-fe0f.svg","woman_superhero_tone3":"1f9b8-1f3fd-200d-2640-fe0f.svg","woman_superhero_tone4":"1f9b8-1f3fe-200d-2640-fe0f.svg","woman_superhero_tone5":"1f9b8-1f3ff-200d-2640-fe0f.svg","woman_supervillain":"1f9b9-200d-2640-fe0f.svg","woman_supervillain_tone1":"1f9b9-1f3fb-200d-2640-fe0f.svg","woman_supervillain_tone2":"1f9b9-1f3fc-200d-2640-fe0f.svg","woman_supervillain_tone3":"1f9b9-1f3fd-200d-2640-fe0f.svg","woman_supervillain_tone4":"1f9b9-1f3fe-200d-2640-fe0f.svg","woman_supervillain_tone5":"1f9b9-1f3ff-200d-2640-fe0f.svg","woman_surfing":"1f3c4-200d-2640-fe0f.svg","woman_surfing_tone1":"1f3c4-1f3fb-200d-2640-fe0f.svg","woman_surfing_tone2":"1f3c4-1f3fc-200d-2640-fe0f.svg","woman_surfing_tone3":"1f3c4-1f3fd-200d-2640-fe0f.svg","woman_surfing_tone4":"1f3c4-1f3fe-200d-2640-fe0f.svg","woman_surfing_tone5":"1f3c4-1f3ff-200d-2640-fe0f.svg","woman_swimming":"1f3ca-200d-2640-fe0f.svg","woman_swimming_tone1":"1f3ca-1f3fb-200d-2640-fe0f.svg","woman_swimming_tone2":"1f3ca-1f3fc-200d-2640-fe0f.svg","woman_swimming_tone3":"1f3ca-1f3fd-200d-2640-fe0f.svg","woman_swimming_tone4":"1f3ca-1f3fe-200d-2640-fe0f.svg","woman_swimming_tone5":"1f3ca-1f3ff-200d-2640-fe0f.svg","woman_teacher":"1f469-200d-1f3eb.svg","woman_teacher_tone1":"1f469-1f3fb-200d-1f3eb.svg","woman_teacher_tone2":"1f469-1f3fc-200d-1f3eb.svg","woman_teacher_tone3":"1f469-1f3fd-200d-1f3eb.svg","woman_teacher_tone4":"1f469-1f3fe-200d-1f3eb.svg","woman_teacher_tone5":"1f469-1f3ff-200d-1f3eb.svg","woman_technologist":"1f469-200d-1f4bb.svg","woman_technologist_tone1":"1f469-1f3fb-200d-1f4bb.svg","woman_technologist_tone2":"1f469-1f3fc-200d-1f4bb.svg","woman_technologist_tone3":"1f469-1f3fd-200d-1f4bb.svg","woman_technologist_tone4":"1f469-1f3fe-200d-1f4bb.svg","woman_technologist_tone5":"1f469-1f3ff-200d-1f4bb.svg","woman_tipping_hand":"1f481-200d-2640-fe0f.svg","woman_tipping_hand_tone1":"1f481-1f3fb-200d-2640-fe0f.svg","woman_tipping_hand_tone2":"1f481-1f3fc-200d-2640-fe0f.svg","woman_tipping_hand_tone3":"1f481-1f3fd-200d-2640-fe0f.svg","woman_tipping_hand_tone4":"1f481-1f3fe-200d-2640-fe0f.svg","woman_tipping_hand_tone5":"1f481-1f3ff-200d-2640-fe0f.svg","woman_tone1":"1f469-1f3fb.svg","woman_tone1_beard":"1f9d4-1f3fb-200d-2640-fe0f.svg","woman_tone2":"1f469-1f3fc.svg","woman_tone2_beard":"1f9d4-1f3fc-200d-2640-fe0f.svg","woman_tone3":"1f469-1f3fd.svg","woman_tone3_beard":"1f9d4-1f3fd-200d-2640-fe0f.svg","woman_tone4":"1f469-1f3fe.svg","woman_tone4_beard":"1f9d4-1f3fe-200d-2640-fe0f.svg","woman_tone5":"1f469-1f3ff.svg","woman_tone5_beard":"1f9d4-1f3ff-200d-2640-fe0f.svg","woman_vampire":"1f9db-200d-2640-fe0f.svg","woman_vampire_tone1":"1f9db-1f3fb-200d-2640-fe0f.svg","woman_vampire_tone2":"1f9db-1f3fc-200d-2640-fe0f.svg","woman_vampire_tone3":"1f9db-1f3fd-200d-2640-fe0f.svg","woman_vampire_tone4":"1f9db-1f3fe-200d-2640-fe0f.svg","woman_vampire_tone5":"1f9db-1f3ff-200d-2640-fe0f.svg","woman_walking":"1f6b6-200d-2640-fe0f.svg","woman_walking_tone1":"1f6b6-1f3fb-200d-2640-fe0f.svg","woman_walking_tone2":"1f6b6-1f3fc-200d-2640-fe0f.svg","woman_walking_tone3":"1f6b6-1f3fd-200d-2640-fe0f.svg","woman_walking_tone4":"1f6b6-1f3fe-200d-2640-fe0f.svg","woman_walking_tone5":"1f6b6-1f3ff-200d-2640-fe0f.svg","woman_wearing_turban":"1f473-200d-2640-fe0f.svg","woman_wearing_turban_tone1":"1f473-1f3fb-200d-2640-fe0f.svg","woman_wearing_turban_tone2":"1f473-1f3fc-200d-2640-fe0f.svg","woman_wearing_turban_tone3":"1f473-1f3fd-200d-2640-fe0f.svg","woman_wearing_turban_tone4":"1f473-1f3fe-200d-2640-fe0f.svg","woman_wearing_turban_tone5":"1f473-1f3ff-200d-2640-fe0f.svg","woman_white_haired":"1f469-200d-1f9b3.svg","woman_white_haired_tone1":"1f469-1f3fb-200d-1f9b3.svg","woman_white_haired_tone2":"1f469-1f3fc-200d-1f9b3.svg","woman_white_haired_tone3":"1f469-1f3fd-200d-1f9b3.svg","woman_white_haired_tone4":"1f469-1f3fe-200d-1f9b3.svg","woman_white_haired_tone5":"1f469-1f3ff-200d-1f9b3.svg","woman_with_headscarf":"1f9d5.svg","woman_with_headscarf_tone1":"1f9d5-1f3fb.svg","woman_with_headscarf_tone2":"1f9d5-1f3fc.svg","woman_with_headscarf_tone3":"1f9d5-1f3fd.svg","woman_with_headscarf_tone4":"1f9d5-1f3fe.svg","woman_with_headscarf_tone5":"1f9d5-1f3ff.svg","woman_with_probing_cane":"1f469-200d-1f9af.svg","woman_with_probing_cane_tone1":"1f469-1f3fb-200d-1f9af.svg","woman_with_probing_cane_tone2":"1f469-1f3fc-200d-1f9af.svg","woman_with_probing_cane_tone3":"1f469-1f3fd-200d-1f9af.svg","woman_with_probing_cane_tone4":"1f469-1f3fe-200d-1f9af.svg","woman_with_probing_cane_tone5":"1f469-1f3ff-200d-1f9af.svg","woman_with_veil":"1f470-200d-2640-fe0f.svg","woman_with_veil_tone1":"1f470-1f3fb-200d-2640-fe0f.svg","woman_with_veil_tone2":"1f470-1f3fc-200d-2640-fe0f.svg","woman_with_veil_tone3":"1f470-1f3fd-200d-2640-fe0f.svg","woman_with_veil_tone4":"1f470-1f3fe-200d-2640-fe0f.svg","woman_with_veil_tone5":"1f470-1f3ff-200d-2640-fe0f.svg","woman_zombie":"1f9df-200d-2640-fe0f.svg","womans_clothes":"1f45a.svg","womans_flat_shoe":"1f97f.svg","womans_hat":"1f452.svg","women_holding_hands_tone1":"1f46d-1f3fb.svg","women_holding_hands_tone1_tone2":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone1_tone3":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone1_tone4":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone1_tone5":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone2":"1f46d-1f3fc.svg","women_holding_hands_tone2_tone1":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone2_tone3":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone2_tone4":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone2_tone5":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone3":"1f46d-1f3fd.svg","women_holding_hands_tone3_tone1":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone3_tone2":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone3_tone4":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone3_tone5":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone4":"1f46d-1f3fe.svg","women_holding_hands_tone4_tone1":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone4_tone2":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone4_tone3":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone4_tone5":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone5":"1f46d-1f3ff.svg","women_holding_hands_tone5_tone1":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone5_tone2":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone5_tone3":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone5_tone4":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe.svg","women_with_bunny_ears_partying":"1f46f-200d-2640-fe0f.svg","women_wrestling":"1f93c-200d-2640-fe0f.svg","womens":"1f6ba.svg","wood":"1fab5.svg","woozy_face":"1f974.svg","worm":"1fab1.svg","worried":"1f61f.svg","wrench":"1f527.svg","writing_hand":"270d.svg","writing_hand_tone1":"270d-1f3fb.svg","writing_hand_tone2":"270d-1f3fc.svg","writing_hand_tone3":"270d-1f3fd.svg","writing_hand_tone4":"270d-1f3fe.svg","writing_hand_tone5":"270d-1f3ff.svg","x":"274c.svg","yarn":"1f9f6.svg","yawning_face":"1f971.svg","yellow_circle":"1f7e1.svg","yellow_heart":"1f49b.svg","yellow_square":"1f7e8.svg","yen":"1f4b4.svg","yin_yang":"262f.svg","yo_yo":"1fa80.svg","yum":"1f60b.svg","zany_face":"1f92a.svg","zap":"26a1.svg","zebra":"1f993.svg","zero":"30-20e3.svg","zipper_mouth":"1f910.svg","zombie":"1f9df.svg","zzz":"1f4a4.svg"}}} \ No newline at end of file diff --git a/docs/en/theme/overrides/assets/stylesheets/home.def3a648.min.css b/docs/en/theme/overrides/assets/stylesheets/home.def3a648.min.css new file mode 100644 index 0000000..a047783 --- /dev/null +++ b/docs/en/theme/overrides/assets/stylesheets/home.def3a648.min.css @@ -0,0 +1 @@ +.md-typeset{color:var(--md-typeset-color)}.md-typeset h2{font-weight:700;margin-top:.175em}.md-typeset h2+h3{font-size:1em;margin-top:-.8em}.md-typeset :target{--md-scroll-margin:5.2rem}.md-main__inner{margin:0}.md-main__inner>.md-content,.md-main__inner>.md-sidebar--secondary{display:none}.md-content__inner{margin-bottom:0;padding:5.2rem 0}.md-content__inner:before{display:none}.md-content header{display:block;transition:opacity .75s}.js .md-content header[hidden]{opacity:0}.md-typeset .md-button{background-color:#dd2e57;border-width:0;color:var(--md-primary-bg-color);margin-right:.5rem;margin-top:.5rem}.md-typeset .md-button--secondary{background-color:initial}.md-header:not(.md-header--shadow){background-color:initial;transition:background-color 125ms,transform 125ms cubic-bezier(.1,.7,.1,1),box-shadow 0ms}.md-header--shadow{transition:background-color .25s,transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}:root{--md-parallax-perspective:2.5rem}.mdx-parallax{height:100vh;margin-top:-2.4rem;overflow-x:hidden;overflow-y:auto;overscroll-behavior-y:none;perspective:var(--md-parallax-perspective);scroll-behavior:smooth;width:100vw}.mdx-parallax__group{background-color:var(--md-default-bg-color);color:var(--md-typeset-color);display:block;position:relative;transform-style:preserve-3d}.mdx-parallax__group:first-child{background-color:initial;contain:strict;height:140vh}.safari .mdx-parallax__group:first-child{contain:none}@media (min-width:125vh){.mdx-parallax__group:first-child{height:120vw}}@media (min-width:137.5vh){.mdx-parallax__group:first-child{height:125vw}}@media (min-width:150vh){.mdx-parallax__group:first-child{height:130vw}}@media (min-width:162.5vh){.mdx-parallax__group:first-child{height:135vw}}@media (min-width:175vh){.mdx-parallax__group:first-child{height:140vw}}@media (min-width:187.5vh){.mdx-parallax__group:first-child{height:145vw}}@media (min-width:200vh){.mdx-parallax__group:first-child{height:150vw}}.mdx-parallax__group:last-child{background-color:var(--md-default-bg-color)}.mdx-parallax__layer{height:max(120vh,100vw);pointer-events:none;position:absolute;top:0;transform:translateZ(calc(var(--md-parallax-perspective)*var(--md-parallax-depth)*-1)) scale(calc(var(--md-parallax-depth) + 1));transform-origin:50vw 50vh;width:100vw;z-index:calc(10 - var(--md-parallax-depth, 0))}.mdx-parallax__image{display:block;height:100%;object-fit:cover;object-position:var(--md-image-position,50%);position:absolute;width:100%;z-index:-1}.mdx-parallax__blend{background-image:linear-gradient(to bottom,transparent,var(--md-default-bg-color));bottom:0;height:min(100vh,100vw);top:auto}.mdx-content__column:last-child{margin-top:2.4rem}.mdx-content__column p:last-child{margin-bottom:0}@media screen and (min-width:60em){.mdx-content__inner{display:flex;flex-wrap:nowrap;gap:6.4rem}.mdx-content__column{margin-top:0}.mdx-content__column:first-child{flex:2 0}.mdx-content__column:last-child{flex:1 0;margin-top:0}}.mdx-connect{display:block;transition:transform .75s cubic-bezier(.075,.85,.175,1) 125ms,opacity .75s 125ms}.js .mdx-connect[hidden]{opacity:0;transform:translateY(1.6rem)}.mdx-connect .mdx-connect__link{color:var(--md-default-fg-color);display:block}.mdx-connect .mdx-connect__link span{margin-right:.2rem}.mdx-expect{margin:2.4rem 0}.mdx-expect__list{display:flex;flex-flow:row wrap;gap:1.6rem;padding:0}.mdx-expect__item{display:flex;flex:1 0 48%;gap:.6rem;margin:0;transition:transform .75s cubic-bezier(.075,.85,.175,1),opacity .75s}.mdx-expect__item:first-child{transition-delay:.2s}.mdx-expect__item:nth-child(2){transition-delay:275ms}.mdx-expect__item:nth-child(3){transition-delay:.35s}.mdx-expect__item:nth-child(4){transition-delay:425ms}.mdx-expect__item:nth-child(5){transition-delay:.5s}.mdx-expect__item:nth-child(6){transition-delay:575ms}.js .mdx-expect__item[hidden]{opacity:0;transform:translate(-.8rem,.4rem)}.js .mdx-expect__item[hidden]:nth-child(2n){transform:translate(.8rem,.4rem)}.mdx-expect__icon{fill:currentcolor;background-color:var(--md-default-fg-color--lightest);border-radius:100%;flex-shrink:0;height:2.2rem;padding:.4rem;width:2.2rem}.mdx-expect__description>:last-child{margin-bottom:0}@media screen and (max-width:76.1875em){.mdx-expect__description>:last-child{margin-left:-2.8rem}}.mdx-hero{display:block;height:inherit}.js .mdx-hero[hidden]>*{opacity:0;transform:translateY(16px);transition:transform 0ms .1s,opacity .1s}.mdx-hero__scrollwrap{height:100vh;margin-bottom:-100vh;position:-webkit-sticky;position:sticky;top:0;z-index:9}.mdx-hero__inner{bottom:3.2rem;display:block;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s;width:100%}@media screen and (max-width:44.9375em){.mdx-hero__inner{bottom:6.4rem}}.mdx-hero__teaser{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-primary-bg-color);margin:0 .8rem;max-width:24rem}.mdx-hero__teaser h1{color:inherit;font-weight:700;margin-bottom:0}.mdx-hero__teaser :not(.md-button){text-shadow:0 0 .2rem rgba(33,29,45,.8)}.mdx-hero .mdx-hero__attribution{background-color:var(--md-default-bg-color--light);border-radius:.1rem;bottom:-2.4rem;color:var(--md-default-fg-color);font-size:.5rem;padding:.1rem .4rem;position:absolute;right:.8rem;transition:color 125ms,background-color 125ms}.mdx-hero .mdx-hero__attribution:focus,.mdx-hero .mdx-hero__attribution:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.mdx-hero__more{bottom:-2.4rem;display:block;left:50%;margin-left:-.6rem;pointer-events:none;position:absolute;text-align:center}.mdx-hero__more svg{fill:#fff;height:1.2rem;width:1.2rem}.mdx-spotlight{margin:2em 0}.mdx-spotlight__feature{display:flex;flex:1 0 48%;flex-flow:row nowrap;gap:3.2rem;margin:0 0 3.2rem}@media screen and (max-width:59.9375em){.mdx-spotlight__feature{flex-direction:column;gap:0}}@media screen and (min-width:60em){.mdx-spotlight__feature:nth-child(odd){flex-direction:row-reverse}}.mdx-spotlight__feature:last-child{margin-bottom:1em}.mdx-spotlight__feature>a{display:block;flex-shrink:0;transition:transform .5s cubic-bezier(.075,.85,.175,1)}@media screen and (max-width:59.9375em){.mdx-spotlight__feature>a{margin-left:auto;margin-right:auto}}.mdx-spotlight__feature>a:hover{transform:scale(1.025)}.mdx-spotlight__feature a>img{border-radius:.2rem;box-shadow:var(--md-shadow-z2);display:block;height:auto;max-width:100%;width:25rem}.mdx-spotlight__feature a>img,.mdx-spotlight__feature figcaption{transition:transform .75s cubic-bezier(.075,.85,.175,1) 125ms,opacity .75s 125ms}.mdx-spotlight__feature figcaption{margin-top:.8rem}.js .mdx-spotlight__feature[hidden]>a>img{opacity:0;transform:translateY(1.6rem)}.js .mdx-spotlight__feature[hidden]>figcaption{opacity:0;transform:translateX(1.6rem)}.js .mdx-spotlight__feature[hidden]:nth-child(2n)>figcaption{transform:translateX(-1.6rem)}.mdx-trust{display:block;max-width:40rem;transition:transform .75s cubic-bezier(.075,.85,.175,1) 125ms,opacity .75s 125ms}.js .mdx-trust[hidden]{opacity:0;transform:translateY(1.6rem)}.mdx-users{display:flex;gap:3.2rem;margin:2.4rem 0}@media screen and (max-width:59.9375em){.mdx-users{flex-direction:column}}.mdx-users__testimonial{display:flex;flex:1;flex-direction:column;gap:1.2rem;margin:0;text-align:center}.mdx-users__testimonial:first-child{transition-delay:.2s}.mdx-users__testimonial:nth-child(2){transition-delay:275ms}.mdx-users__testimonial:nth-child(3){transition-delay:.35s}.mdx-users__testimonial img{border-radius:5rem;height:auto;margin-left:auto;margin-right:auto;width:10rem}.mdx-users__testimonial figcaption,.mdx-users__testimonial img{transition:transform .75s cubic-bezier(.075,.85,.175,1),opacity .75s;transition-delay:inherit}.mdx-users__testimonial figcaption{display:block}.mdx-users__testimonial hr{margin-left:auto;margin-right:auto;width:5rem}.mdx-users__testimonial cite{display:block;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;text-align:justify}.js .mdx-users__testimonial[hidden] img{opacity:0;transform:scale(.75)}.js .mdx-users__testimonial[hidden] figcaption{opacity:0;transform:translateY(1.6rem)}@media screen and (min-width:60em){.md-sidebar--secondary{display:none}}@media screen and (min-width:76.25em){.md-sidebar--primary{display:none}}.md-tabs{background-color:initial;position:absolute;top:2.4rem} \ No newline at end of file diff --git a/docs/en/theme/overrides/assets/stylesheets/main.e13ced4c.min.css b/docs/en/theme/overrides/assets/stylesheets/main.e13ced4c.min.css new file mode 100644 index 0000000..671294a --- /dev/null +++ b/docs/en/theme/overrides/assets/stylesheets/main.e13ced4c.min.css @@ -0,0 +1 @@ +@-webkit-keyframes heart{0%,40%,80%,to{transform:scale(1)}20%,60%{transform:scale(1.15)}}@keyframes heart{0%,40%,80%,to{transform:scale(1)}20%,60%{transform:scale(1.15)}}@-webkit-keyframes new{0%,to{transform:scale(1) rotate(0deg)}50%{transform:scale(1.15) rotate(10deg)}}@keyframes new{0%,to{transform:scale(1) rotate(0deg)}50%{transform:scale(1.15) rotate(10deg)}}.md-typeset .twitter{color:#00acee}.md-typeset .mdx-video{width:auto}.md-typeset .mdx-video__inner{height:0;padding-bottom:56.138%;position:relative;width:100%}.md-typeset .mdx-video iframe{border:none;height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}.md-typeset .mdx-heart{-webkit-animation:heart 1s infinite;animation:heart 1s infinite}.md-typeset .mdx-pulse{-webkit-animation:new 2s infinite;animation:new 2s infinite}.md-typeset .mdx-pulse svg{fill:var(--md-accent-fg-color)}.md-typeset .mdx-insiders{color:#e91e63}.md-typeset .mdx-switch button{cursor:pointer;transition:opacity .25s}.md-typeset .mdx-switch button:focus,.md-typeset .mdx-switch button:hover{opacity:.75}.md-typeset .mdx-switch button>code{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block}.md-typeset .mdx-deprecated{opacity:.5;transition:opacity .25s}.md-typeset .mdx-deprecated:focus-within,.md-typeset .mdx-deprecated:hover{opacity:1}.md-typeset .mdx-columns ol,.md-typeset .mdx-columns ul{column-count:2}@media screen and (max-width:29.9375em){.md-typeset .mdx-columns ol,.md-typeset .mdx-columns ul{columns:initial}}.md-typeset .mdx-columns li{break-inside:avoid}.md-typeset .mdx-author{display:flex;font-size:.68rem}.md-typeset .mdx-author img{border-radius:100%;height:2rem}.md-typeset .mdx-author p:first-child{flex-shrink:0;margin-right:.8rem}.md-typeset .mdx-author p>span{display:block}.md-banner a,.md-banner a:focus,.md-banner a:hover{color:currentcolor}.md-banner strong{white-space:nowrap}[dir=ltr] .md-banner .twitter{margin-left:.2em}[dir=rtl] .md-banner .twitter{margin-right:.2em}.md-typeset .mdx-iconsearch{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z1);position:relative;transition:box-shadow 125ms}.md-typeset .mdx-iconsearch:focus-within,.md-typeset .mdx-iconsearch:hover{box-shadow:var(--md-shadow-z2)}.md-typeset .mdx-iconsearch .md-input{background:var(--md-default-bg-color);box-shadow:none}[data-md-color-scheme=slate] .md-typeset .mdx-iconsearch .md-input{background:var(--md-code-bg-color)}.md-typeset .mdx-iconsearch-result{-webkit-backface-visibility:hidden;backface-visibility:hidden;max-height:50vh;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin;touch-action:pan-y}.md-tooltip .md-typeset .mdx-iconsearch-result{max-height:10.25rem}.md-typeset .mdx-iconsearch-result::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset .mdx-iconsearch-result::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset .mdx-iconsearch-result::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset .mdx-iconsearch-result__meta{color:var(--md-default-fg-color--lighter);font-size:.64rem;position:absolute;right:.6rem;top:.4rem}[dir=ltr] .md-typeset .mdx-iconsearch-result__list{margin-left:0}[dir=rtl] .md-typeset .mdx-iconsearch-result__list{margin-right:0}.md-typeset .mdx-iconsearch-result__list{list-style:none;margin:0;padding:0}[dir=ltr] .md-typeset .mdx-iconsearch-result__item{margin-left:0}[dir=rtl] .md-typeset .mdx-iconsearch-result__item{margin-right:0}.md-typeset .mdx-iconsearch-result__item{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin:0;padding:.2rem .6rem}.md-typeset .mdx-iconsearch-result__item:last-child{border-bottom:none}.md-typeset .mdx-iconsearch-result__item>*{margin-right:.6rem}.md-typeset .mdx-iconsearch-result__item img{height:.9rem;width:.9rem}[data-md-color-scheme=slate] .md-typeset .mdx-iconsearch-result__item img[src*=squidfunk]{filter:invert(1)}.md-typeset .mdx-premium p{margin:2em 0;text-align:center}.md-typeset .mdx-premium img{height:3.25rem}.md-typeset .mdx-premium p:last-child{display:flex;flex-wrap:wrap;justify-content:center}.md-typeset .mdx-premium p:last-child>a{display:block;flex-shrink:0}.md-typeset .mdx-sponsorship__list{margin:2em 0}.md-typeset .mdx-sponsorship__list:after{clear:both;content:"";display:block}.md-typeset .mdx-sponsorship__item{border-radius:100%;display:block;float:left;height:1.6rem;margin:.2rem;overflow:hidden;transform:scale(1);transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .mdx-sponsorship__item:focus,.md-typeset .mdx-sponsorship__item:hover{transform:scale(1.1)}.md-typeset .mdx-sponsorship__item:focus img,.md-typeset .mdx-sponsorship__item:hover img{filter:grayscale(0)}.md-typeset .mdx-sponsorship__item--private{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .mdx-sponsorship__item img{display:block;filter:grayscale(100%) opacity(75%);height:auto;transition:filter 125ms;width:100%}.md-typeset .mdx-sponsorship-button{font-weight:400}.md-typeset .mdx-sponsorship-count,.md-typeset .mdx-sponsorship-total{font-weight:700} \ No newline at end of file diff --git a/docs/en/theme/overrides/home.html b/docs/en/theme/overrides/home.html new file mode 100644 index 0000000..0645d63 --- /dev/null +++ b/docs/en/theme/overrides/home.html @@ -0,0 +1,26 @@ +{#- + This file was automatically generated - do not edit +-#} +{% extends "overrides/main.html" %} + +{% block htmltitle %} + {{ config.site_name }} +{% endblock %} +{% block styles %} + {{ super() }} + + +{% endblock %} +{% block announce %}{% endblock %} +{% block hero %} + {% include "overrides/partials/parallax.html" %} +{% endblock %} + +{% block tabs %}{% endblock %} + +{#- +{% block content %}{% endblock %} + +{% block footer %}{% endblock %} + +-#} diff --git a/docs/en/theme/overrides/main.html b/docs/en/theme/overrides/main.html new file mode 100644 index 0000000..bed2df4 --- /dev/null +++ b/docs/en/theme/overrides/main.html @@ -0,0 +1,22 @@ +{#- + This file was automatically generated - do not edit +-#} +{% extends "base.html" %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block announce %} + + DaoCloud 第五代产品 全新上线咯!点击链接,免费体验! + + +{% endblock %} +{% block content %} + {% include "overrides/partials/content.html" %} +{% endblock %} + +{% block scripts %} + {{ super() }} + +{% endblock %} \ No newline at end of file diff --git a/docs/en/theme/overrides/partials/comments.html b/docs/en/theme/overrides/partials/comments.html new file mode 100644 index 0000000..fd0586b --- /dev/null +++ b/docs/en/theme/overrides/partials/comments.html @@ -0,0 +1,49 @@ + +

{{ lang.t("meta.comments") }}

+ + + + + \ No newline at end of file diff --git a/docs/en/theme/overrides/partials/content.html b/docs/en/theme/overrides/partials/content.html new file mode 100644 index 0000000..5da0603 --- /dev/null +++ b/docs/en/theme/overrides/partials/content.html @@ -0,0 +1,28 @@ +{#- + This file was automatically generated - do not edit +-#} +{% if page.edit_url %} + {% set hisrtory = "https://github.com/DaoCloud/DaoCloud-docs/commits/" %} + {% set edit = "https://github.com/DaoCloud/DaoCloud-docs/edit/" %} + {% set view = "https://raw.githubusercontent.com/DaoCloud/DaoCloud-docs/" %} + + {% include ".icons/material/history.svg" %} + + + {% include ".icons/material/file-edit-outline.svg" %} + + + {% include ".icons/material/file-eye-outline.svg" %} + +{% endif %} +{% if "tags" in config.plugins %} + {% include "partials/tags.html" %} +{% endif %} +{% if not "\x3ch1" in page.content %} +

{{ page.title | d(config.site_name, true)}}

+{% endif %} +{{ page.content }} + +{% block comments %} + {% include "overrides/partials/comments.html" %} +{% endblock %} diff --git a/docs/en/theme/overrides/partials/parallax.html b/docs/en/theme/overrides/partials/parallax.html new file mode 100644 index 0000000..4e160f8 --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax.html @@ -0,0 +1,15 @@ +{#- + This file was automatically generated - do not edit +-#} +
+ {% include "overrides/partials/parallax/hero.html" %} + {% include "overrides/partials/parallax/expect.html" %} + {% include "overrides/partials/parallax/spotlight.html" %} + {% include "overrides/partials/parallax/trust.html" %} + {% include "overrides/partials/parallax/users.html" %} + {% include "overrides/partials/parallax/connect.html" %} +
+ {% include "partials/footer.html" %} +
+
+ diff --git a/docs/en/theme/overrides/partials/parallax/connect.html b/docs/en/theme/overrides/partials/parallax/connect.html new file mode 100644 index 0000000..cb5ead2 --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax/connect.html @@ -0,0 +1,84 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+
+ + +
+ +
+
diff --git a/docs/en/theme/overrides/partials/parallax/expect.html b/docs/en/theme/overrides/partials/parallax/expect.html new file mode 100644 index 0000000..10e61fe --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax/expect.html @@ -0,0 +1,97 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+ +
+
    + + + + + + +
+
+
+
+
diff --git a/docs/en/theme/overrides/partials/parallax/hero.html b/docs/en/theme/overrides/partials/parallax/hero.html new file mode 100644 index 0000000..8713558 --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax/hero.html @@ -0,0 +1,49 @@ +{#- + This file was automatically generated - do not edit +-#} +
+ {% for layer in [ + { "depth": 8, "position": "70%", "image": "1-landscape" }, + { "depth": 5, "position": "25%", "image": "2-plateau" }, + { "depth": 4, "position": "20%", "image": "3-astronaut-1" }, + { "depth": 3, "position": "30%", "image": "4-astronaut-2" }, + { "depth": 2, "position": "40%", "image": "5-plants-1" }, + { "depth": 1, "position": "50%", "image": "6-plants-2" }, + ] %} + {% set image = "overrides/assets/images/layers/" ~ layer["image"] %} + {% set style = "style=\"" ~ [ + "--md-parallax-depth: " ~ layer["depth"], + "--md-image-position: " ~ layer["position"] + ] | join(";") ~ "\"" %} + + {% for type in ["avif", "webp"] %} + + {% endfor %} + + + {% endfor %} +
+
+
+ {% include "partials/tabs.html" %} +
+
+

The DigitalX Formula

+

{{ config.site_description }}

+ + Quick Start + + + Learn More + + + © DaoCloud + +
+
+ {% include ".icons/material/arrow-down.svg" %} +
+
+
+
+
diff --git a/docs/en/theme/overrides/partials/parallax/spotlight.html b/docs/en/theme/overrides/partials/parallax/spotlight.html new file mode 100644 index 0000000..d7a0254 --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax/spotlight.html @@ -0,0 +1,119 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+ +
+ + + + +
+
+
+
diff --git a/docs/en/theme/overrides/partials/parallax/trust.html b/docs/en/theme/overrides/partials/parallax/trust.html new file mode 100644 index 0000000..6f3e2bf --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax/trust.html @@ -0,0 +1,29 @@ +{#- + This file was automatically generated - do not edit +-#} +
+ Trusted in the industry +
+
+ + +
+
+
diff --git a/docs/en/theme/overrides/partials/parallax/users.html b/docs/en/theme/overrides/partials/parallax/users.html new file mode 100644 index 0000000..e408e5c --- /dev/null +++ b/docs/en/theme/overrides/partials/parallax/users.html @@ -0,0 +1,74 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+ +
+ + + +
+
+
+
diff --git a/docs/zh/docs/admin/baize/best-practice/add-scheduler.md b/docs/zh/docs/admin/baize/best-practice/add-scheduler.md new file mode 100644 index 0000000..364e8bc --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/add-scheduler.md @@ -0,0 +1,73 @@ +# 增加任务调度器 + +5.0 AI Lab 提供了任务调度器,可以帮助您更好地管理任务,除了提供基础的调度器之外,目前也支持用户自定义调度器。 + +## 任务调度器介绍 + +在 Kubernetes 中,任务调度器负责决定将 Pod 分配到哪个节点上运行。它考虑多种因素,如资源需求、硬件/软件约束、亲和性/反亲和性规则、数据局部性等。 + +默认调度器是 Kubernetes 集群中的一个核心组件,负责决定将 Pod 分配到哪个节点上运行。让我们深入了解它的工作原理、特性和配置方法。 + +### 调度器的工作流程 + +默认调度器的工作流程可以分为两个主要阶段:过滤(Filtering)和评分(Scoring)。 + +#### 过滤阶段 + +调度器会遍历所有节点,排除不满足 Pod 要求的节点,考虑的因素包括: + +- 资源需求 +- 节点选择器 +- 节点亲和性 +- 污点和容忍 + +以上参数,我们可以通过创建任务时的高级配置来设置,如下图所示: + +![scheduler01](./images/scheduler01.png) + +#### 评分阶段 + +对通过过滤的节点进行打分,选择得分最高的节点来运行 Pod,考虑因素包括: + +- 资源使用率 +- Pod 亲和性/反亲和性 +- 节点亲和性等。 + +## 调度器插件 + +除了基础的一些任务调度能力之外,我们还支持使用 `Scheduler Plugins:Kubernetes SIG Scheduling` +维护的一组调度器插件,包括 `Coscheduling (Gang Scheduling)` 等功能。 + +### 部署调度器插件 + +在工作集群中部署第二调度器插件,请参考[部署第二调度器插件](../../kpanda/clusters/cluster-scheduler-plugin.md)。 + +### 在 AI Lab 中启用调度器插件 + +!!! danger + + 增加调度器插件若操作不当,可能会影响到整个集群的稳定性,建议在测试环境中进行测试;或者联系我们的技术支持团队。 + +注意,如果希望在训练任务中使用更多的调度器插件,需要事先手工在工作集群中成功安装,然后在集群中部署 `baize-agent` 时,增加对应的调度器插件配置。 + +通过容器管理提供的界面 **Helm 应用** 管理能力,可以方便地在集群中部署调度器插件,如下图所示: + +![scheduler03](./images/scheduler03.png) + +然后,在右上角点击 **安装** ,(若已部署了 `baize-agent`,可以到 Helm 应用列表去更新),根据如下图所示的配置,增加调度器。 + +![scheduler02](./images/scheduler02.png) + +注意调度器的参数层级,添加完成后,点击 **确定** 即可。 + +> 注意以后在更新 `baize-agent` 时,不要遗漏这个配置。 + +## 在创建任务时指定调度器 + +当您在集群中成功部署了对应的调度器插件,并且在 `baize-agent` 也正确增加了对应的调度器配置后,可以在创建任务时,指定调度器。 + +一切正常的情况下,您可以在调度器下拉框中看到您部署的调度器插件。 + +![scheduler04](./images/scheduler04.png) + +以上,就是我们在 AI Lab 中,为任务增加调度器选项的配置使用说明。 diff --git a/docs/zh/docs/admin/baize/best-practice/change-notebook-image.md b/docs/zh/docs/admin/baize/best-practice/change-notebook-image.md new file mode 100644 index 0000000..f4333bc --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/change-notebook-image.md @@ -0,0 +1,193 @@ +# 更新 Notebook 内置镜像 + +在 Notebook 中,默认提供了多个可用的基础镜像,供开发者选择;大部分情况下,这会满足开发者的使用。 + +![创建 notebook 界面](../images/notebook-images.png) + +算丰提供了一个默认的 Notebook 镜像,包含了所需的任何开发工具和资料。 + +```markdown +baize/baize-notebook +``` + +这个 Notebook 里面包含了基础的开发工具,以 `baize-notebook:v0.5.0` (2024 年 5 月 30 日)为例,相关依赖及版本如下: + +| 依赖 | 版本编号 | 介绍 | +| ------------ | -------- | ------------------------------------------------------------ | +| Ubuntu | 22.04.3 | 默认 OS | +| Python | 3.11.6 | 默认 Python 版本 | +| pip | 23.3.1 | | +| conda(mamba) | 23.3.1 | | +| jupyterlab | 3.6.6 | JupyterLab 镜像,提供完整的 Notebook 开发体验 | +| codeserver | v4.89.1 | 主流 Code 开发工具,方便用户使用熟悉的工具进行开发体验 | +| *baizectl | v0.5.0 | 算丰内置 CLI 任务管理工具 | +| *SSH | - | 支持本地 SSH 直接访问到 Notebook 容器内 | +| *kubectl | v1.27 | Kubernetes CLI,可以使用 kubectl 在 Notebook 内 管理容器资源 | + +但有时用户可能需要自定义镜像,本文介绍了如何更新镜像,并增加到 Notebook 创建界面中进行选择。 + +## 构建自定义镜像(仅供参考) + +!!! note + + 注意,构建新镜像 **需要以 `baize-notebook` 作为基础镜像**,以保证 Notebook 的正常运行。 + +在构建自定义镜像时,建议先了解 baize-notebook 镜像的 Dockerfile,以便更好地理解如何构建自定义镜像。 + +### baize-noteboook 的 Dockerfile + +```dockerfile +ARG BASE_IMG=docker.m.daocloud.io/kubeflownotebookswg/jupyter:v1.8.0 + +FROM $BASE_IMG + +USER root + +# install - useful linux packages +RUN export DEBIAN_FRONTEND=noninteractive \ + && apt-get -yq update \ + && apt-get -yq install --no-install-recommends \ + openssh-server git git-lfs bash-completion \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# remove default s6 jupyterlab run script +RUN rm -rf /etc/services.d/jupyterlab + +# install - useful jupyter plugins +RUN mamba install -n base -y jupyterlab-language-pack-zh-cn \ + && mamba clean --all -y + +ARG CODESERVER_VERSION=4.89.1 +ARG TARGETARCH + +RUN curl -fsSL "https://github.com/coder/code-server/releases/download/v$CODESERVER_VERSION/code-server_${CODESERVER_VERSION}_$TARGETARCH.deb" -o /tmp/code-server.deb \ + && dpkg -i /tmp/code-server.deb \ + && rm -f /tmp/code-server.deb + +ARG CODESERVER_PYTHON_VERSION=2024.4.1 +ARG CODESERVER_JUPYTER_VERSION=2024.3.1 +ARG CODESERVER_LANGUAGE_PACK_ZH_CN=1.89.0 +ARG CODESERVER_YAML=1.14.0 +ARG CODESERVER_DOTENV=1.0.1 +ARG CODESERVER_EDITORCONFIG=0.16.6 +ARG CODESERVER_TOML=0.19.1 +ARG CODESERVER_GITLENS=15.0.4 + +# configure for code-server extensions +# # https://github.com/kubeflow/kubeflow/blob/709254159986d2cc99e675d0fad5a128ddeb0917/components/example-notebook-servers/codeserver-python/Dockerfile +# # and +# # https://github.com/kubeflow/kubeflow/blob/709254159986d2cc99e675d0fad5a128ddeb0917/components/example-notebook-servers/codeserver/Dockerfile +RUN code-server --list-extensions --show-versions \ + && code-server --list-extensions --show-versions \ + && code-server \ + --install-extension MS-CEINTL.vscode-language-pack-zh-hans@$CODESERVER_LANGUAGE_PACK_ZH_CN \ + --install-extension ms-python.python@$CODESERVER_PYTHON_VERSION \ + --install-extension ms-toolsai.jupyter@$CODESERVER_JUPYTER_VERSION \ + --install-extension redhat.vscode-yaml@$CODESERVER_YAML \ + --install-extension mikestead.dotenv@$CODESERVER_DOTENV \ + --install-extension EditorConfig.EditorConfig@$CODESERVER_EDITORCONFIG \ + --install-extension tamasfe.even-better-toml@$CODESERVER_TOML \ + --install-extension eamodio.gitlens@$CODESERVER_GITLENS \ + --install-extension catppuccin.catppuccin-vsc-pack \ + --force \ + && code-server --list-extensions --show-versions + +# configure for code-server +RUN mkdir -p /home/${NB_USER}/.local/share/code-server/User \ + && chown -R ${NB_USER}:users /home/${NB_USER} \ + && cat < /home/${NB_USER}/.local/share/code-server/User/settings.json +{ + "gitlens.showWelcomeOnInstall": false, + "workbench.colorTheme": "Catppuccin Mocha", +} +EOF + +RUN mkdir -p /tmp_home/${NB_USER}/.local/share \ + && mv /home/${NB_USER}/.local/share/code-server /tmp_home/${NB_USER}/.local/share + +# set ssh configuration +RUN mkdir -p /run/sshd \ + && chown -R ${NB_USER}:users /etc/ssh \ + && chown -R ${NB_USER}:users /run/sshd \ + && sed -i "/#\?Port/s/^.*$/Port 2222/g" /etc/ssh/sshd_config \ + && sed -i "/#\?PasswordAuthentication/s/^.*$/PasswordAuthentication no/g" /etc/ssh/sshd_config \ + && sed -i "/#\?PubkeyAuthentication/s/^.*$/PubkeyAuthentication yes/g" /etc/ssh/sshd_config \ + && rclone_version=v1.65.0 && \ + arch=$(uname -m | sed -E 's/x86_64/amd64/g;s/aarch64/arm64/g') && \ + filename=rclone-${rclone_version}-linux-${arch} && \ + curl -fsSL https://github.com/rclone/rclone/releases/download/${rclone_version}/${filename}.zip -o ${filename}.zip && \ + unzip ${filename}.zip && mv ${filename}/rclone /usr/local/bin && rm -rf ${filename} ${filename}.zip + +# Init mamba +RUN mamba init --system + +# init baize-base environment for essential python packages +RUN mamba create -n baize-base -y python \ + && /opt/conda/envs/baize-base/bin/pip install tensorboard \ + && mamba clean --all -y \ + && ln -s /opt/conda/envs/baize-base/bin/tensorboard /usr/local/bin/tensorboard + +# prepare baize-runtime-env directory +RUN mkdir -p /opt/baize-runtime-env \ + && chown -R ${NB_USER}:users /opt/baize-runtime-env + +ARG APP +ARG PROD_NAME +ARG TARGETOS + +COPY out/$TARGETOS/$TARGETARCH/data-loader /usr/local/bin/ +COPY out/$TARGETOS/$TARGETARCH/baizectl /usr/local/bin/ + +RUN chmod +x /usr/local/bin/baizectl /usr/local/bin/data-loader && \ + echo "source /etc/bash_completion" >> /opt/conda/etc/profile.d/conda.sh && \ + echo "source <(baizectl completion bash)" >> /opt/conda/etc/profile.d/conda.sh && \ + echo "source <(kubectl completion bash)" >> /opt/conda/etc/profile.d/conda.sh && \ + echo '[ -f /run/baize-env ] && export $(cat /run/baize-env | xargs)' >> /opt/conda/etc/profile.d/conda.sh && \ + echo 'alias conda="mamba"' >> /opt/conda/etc/profile.d/conda.sh + +USER ${NB_UID} +``` + +### 构建你的镜像 + +```dockerfile +ARG BASE_IMG=release.daocloud.io/baize/baize-notebook:v0.5.0 + +FROM $BASE_IMG +USER root + +# Do Customization +RUN mamba install -n baize-base -y pytorch torchvision torchaudio cpuonly -c pytorch \ + && mamba install -n baize-base -y tensorflow \ + && mamba clean --all -y + +USER ${NB_UID} +``` + +## 增加到 Notebook 镜像列表(Helm) + +!!! warning + + 注意,必须由平台管理员操作,谨慎变更。 + +目前,镜像选择器需要通过更新 `baize` 的 `Helm` 参数来修改,具体步骤如下: + +在 kpanda-global-cluster 全局服务集群的 `Helm 应用`列表,找到 baize,进入更新页面,在 `YAML` 参数中修改 Notebook 镜像: + +![Update Baize](../images/update-baize.png) + +注意参数修改的路径如下 `global.config.notebook_images`: + +```yaml +... +global: + ... + config: + notebook_images: + ... + names: release.daocloud.io/baize/baize-notebook:v0.5.0 + # 在这里增加你的镜像信息 +``` + +更新完成之后,待 Helm 应用重启成功之后,可以在 Notebook 创建界面中的选择镜像看到新的镜像。 diff --git a/docs/zh/docs/admin/baize/best-practice/checkpoint.md b/docs/zh/docs/admin/baize/best-practice/checkpoint.md new file mode 100644 index 0000000..2b34a3d --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/checkpoint.md @@ -0,0 +1,201 @@ +# Checkpoint 机制及使用介绍 + +在深度学习的实际场景中,模型训练一般都会持续一段时间,这对分布式训练任务的稳定性和效率提出了更高的要求。 +而且,在实际训练的过程中,异常中断会导致训练过程中的模型状态丢失,需要重新开始训练, +这不仅浪费了时间和资源,这在 LLM 训练中尤为明显,而且也会影响模型的训练效果。 + +能够在训练过程中保存模型的状态,以便在训练过程中出现异常时能够恢复模型状态,变得至关重要。 +Checkpoint 就是目前主流的解决方案,本文将介绍 Checkpoint 机制的基本概念和在 PyTorch 和 TensorFlow 中的使用方法。 + +## 什么是 Checkpoint? + +Checkpoint 是在模型训练过程中保存模型状态的机制。通过定期保存 Checkpoint,可以在以下情况下恢复模型: + +- 训练过程中断(如系统崩溃或手动中断) +- 需要在某个训练阶段进行评估 +- 希望在不同的实验中复用模型 + +## PyTorch + +在 PyTorch 中,`torch.save` 和 `torch.load` 是用于保存和加载模型的基本函数。 + +### PyTorch 保存 Checkpoint + +在 PyTorch 中,通常使用 `state_dict` 保存模型的参数。以下是一个简单的示例: + +```python +import torch +import torch.nn as nn + +# 假设我们有一个简单的神经网络 +class SimpleModel(nn.Module): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = nn.Linear(10, 2) + + def forward(self, x): + return self.fc(x) + +# 初始化模型和优化器 +model = SimpleModel() +optimizer = torch.optim.Adam(model.parameters(), lr=0.001) + +# 训练模型... +# 保存 Checkpoint +checkpoint_path = 'model_checkpoint.pth' +torch.save({ + 'epoch': 10, + 'model_state_dict': model.state_dict(), + 'optimizer_state_dict': optimizer.state_dict(), + 'loss': 0.02, +}, checkpoint_path) +``` + +### PyTorch 恢复 Checkpoint + +加载模型时,需要恢复模型参数和优化器状态,并继续训练或推理: + +```python +# 恢复 Checkpoint +checkpoint = torch.load('model_checkpoint.pth') +model.load_state_dict(checkpoint['model_state_dict']) +optimizer.load_state_dict(checkpoint['optimizer_state_dict']) +epoch = checkpoint['epoch'] +loss = checkpoint['loss'] + +# 继续训练或推理... +``` + +- `model_state_dict`: 模型参数 +- `optimizer_state_dict`: 优化器状态 +- `epoch`: 当前训练轮数 +- `loss`: 损失值 +- `learning_rate`: 学习率 +- `best_accuracy`: 最佳准确率 + +## TensorFlow + +TensorFlow 提供了 `tf.train.Checkpoint` 类来管理模型和优化器的保存和恢复。 + +### TensorFlow 保存 Checkpoint + +以下是一个在 TensorFlow 中保存 Checkpoint 的示例: + +```python +import tensorflow as tf + +# 假设我们有一个简单的模型 +model = tf.keras.Sequential([ + tf.keras.layers.Dense(2, input_shape=(10,)) +]) +optimizer = tf.keras.optimizers.Adam(learning_rate=0.001) + +# 定义 Checkpoint +checkpoint = tf.train.Checkpoint(optimizer=optimizer, model=model) +checkpoint_dir = './checkpoints' +checkpoint_prefix = f'{checkpoint_dir}/ckpt' + +# 训练模型... +# 保存 Checkpoint +checkpoint.save(file_prefix=checkpoint_prefix) +``` + +!!!note + + 使用 AI Lab 的用户,可以直接将高性能存储挂载为 Checkpoint 目录,以提高 Checkpoint 保存和恢复的速度。 + +### TensorFlow 恢复 Checkpoint + +加载 Checkpoint 并恢复模型和优化器状态: + +```python +# 恢复 Checkpoint +latest_checkpoint = tf.train.latest_checkpoint(checkpoint_dir) +checkpoint.restore(latest_checkpoint) + +# 继续训练或推理... +``` + +### TensorFlow 在分布式训练的 Checkpoint 管理 + +TensorFlow 在分布式训练中管理 Checkpoint 的主要方法如下: + +- 使用 `tf.train.Checkpoint` 和 `tf.train.CheckpointManager` + + ```python + checkpoint = tf.train.Checkpoint(model=model, optimizer=optimizer) + manager = tf.train.CheckpointManager(checkpoint, directory='/tmp/model', max_to_keep=3) + ``` + +- 在分布式策略中保存 Checkpoint + + ```python + strategy = tf.distribute.MirroredStrategy() + with strategy.scope(): + checkpoint = tf.train.Checkpoint(model=model, optimizer=optimizer) + manager = tf.train.CheckpointManager(checkpoint, directory='/tmp/model', max_to_keep=3) + ``` + +- 只在主节点 (chief worker) 保存 Checkpoint + + ```python + if strategy.cluster_resolver.task_type == 'chief': + manager.save() + ``` + +- 使用 MultiWorkerMirroredStrategy 时的特殊处理 + + ```python + strategy = tf.distribute.MultiWorkerMirroredStrategy() + with strategy.scope(): + # 模型定义 + ... + checkpoint = tf.train.Checkpoint(model=model, optimizer=optimizer) + manager = tf.train.CheckpointManager(checkpoint, '/tmp/model', max_to_keep=3) + + def _chief_worker(task_type, task_id): + return task_type is None or task_type == 'chief' or (task_type == 'worker' and task_id == 0) + + if _chief_worker(strategy.cluster_resolver.task_type, strategy.cluster_resolver.task_id): + manager.save() + ``` + +- 使用分布式文件系统 + + 确保所有工作节点都能访问到同一个 Checkpoint 目录,通常使用分布式文件系统如 HDFS 或 GCS。 + +- 异步保存 + + 使用 `tf.keras.callbacks.ModelCheckpoint` 并设置 `save_freq` 参数可以在训练过程中异步保存 Checkpoint。 + +- Checkpoint 恢复 + + ```python + status = checkpoint.restore(manager.latest_checkpoint) + status.assert_consumed() # (1)! + ``` + + 1. 确保所有变量都被恢复 + +- 性能优化 + + - 使用 `tf.train.experimental.enable_mixed_precision_graph_rewrite()` 启用混合精度训练 + - 调整保存频率,避免过于频繁的 I/O 操作 + - 考虑使用 `tf.saved_model.save()` 保存整个模型,而不仅仅是权重 + +## 注意事项 + +1. **定期保存**:根据训练时间和资源消耗,决定合适的保存频率。如每个 epoch 或每隔一定的训练步数。 + +2. **保存多个 Checkpoint**:保留最新的几个 Checkpoint 以防止文件损坏或不适用的情况。 + +3. **记录元数据**:在 Checkpoint 中保存额外的信息,如 epoch 数、损失值等,以便更好地恢复训练状态。 + +4. **使用版本控制**:保存不同实验的 Checkpoint,便于对比和复用。 + +5. **验证和测试**:在训练的不同阶段使用 Checkpoint 进行验证和测试,确保模型性能和稳定性。 + +## 结论 + +Checkpoint 机制在深度学习训练中起到了关键作用。通过合理使用 PyTorch 和 TensorFlow 中的 Checkpoint 功能, +可以有效提高训练的可靠性和效率。希望本文所述的方法和最佳实践能帮助你更好地管理深度学习模型的训练过程。 diff --git a/docs/zh/docs/admin/baize/best-practice/deploy-nfs-in-worker.md b/docs/zh/docs/admin/baize/best-practice/deploy-nfs-in-worker.md new file mode 100644 index 0000000..58057b6 --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/deploy-nfs-in-worker.md @@ -0,0 +1,208 @@ +# 部署 NFS 做数据集预热 + +**网络文件系统 (NFS)** 允许远程主机通过网络挂载文件,并像本地文件系统一样进行交互。 +这使系统管理员能够将资源集中到网络服务器上进行管理。 + +**数据集** 是 AI Lab 中的核心数据管理功能,将 MLOps 生命周期中对于数据的依赖统一抽象为数据集; +支持用户将各类数据纳管到数据集内,以便训练任务可以直接使用数据集中的数据。 + +当远端数据不在工作集群内时,数据集提供了自动进行预热的能力,支持 `Git`、`S3`、`HTTP` 等数据提前预热到集群本地。 + +数据集需要一个支持 `ReadWriteMany` 模式的存储服务对远端数据进行预热,推荐在集群内部署 NFS。 + +本文主要介绍了如何快速部署一个 NFS 服务,并将其添加为集群的`存储类`。 + +## 准备工作 + +* NFS 默认使用节点的存储作为数据缓存点,因此需要确认磁盘本身有足够的磁盘空间。 +* 安装方式使用 `Helm` 与 `Kubectl`,请确保已经安装好。 + +## 部署过程 + +一共需要安装几个组件: + +* NFS Server +* csi-driver-nfs +* StorageClass + +### 初始化命名空间 + +所有系统组件会安装到 `nfs` 命名空间内,因此需要先创建此命名空间。 + +```bash +kubectl create namespace nfs +``` + +### 安装 NFS Server + +这里是一个简单的 YAML 部署文件,可以直接使用。 + +!!! note + + 注意检查 `image:`,根据集群所在位置情况,可能需要修改为国内镜像。 + +```yaml title="nfs-server.yaml" +kind: Service +apiVersion: v1 +metadata: + name: nfs-server + namespace: nfs + labels: + app: nfs-server +spec: + type: ClusterIP + selector: + app: nfs-server + ports: + - name: tcp-2049 + port: 2049 + protocol: TCP + - name: udp-111 + port: 111 + protocol: UDP +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: nfs-server + namespace: nfs +spec: + replicas: 1 + selector: + matchLabels: + app: nfs-server + template: + metadata: + name: nfs-server + labels: + app: nfs-server + spec: + nodeSelector: + "kubernetes.io/os": linux + containers: + - name: nfs-server + image: itsthenetwork/nfs-server-alpine:latest + env: + - name: SHARED_DIRECTORY + value: "/exports" + volumeMounts: + - mountPath: /exports + name: nfs-vol + securityContext: + privileged: true + ports: + - name: tcp-2049 + containerPort: 2049 + protocol: TCP + - name: udp-111 + containerPort: 111 + protocol: UDP + volumes: + - name: nfs-vol + hostPath: + path: /nfsdata # (1)! + type: DirectoryOrCreate +``` + +1. 修改此处以指定另一个路径来存储 NFS 共享数据 + +将上述 `YAML` 保存为 `nfs-server.yaml`,然后执行以下命令进行部署: + +```bash +kubectl -n nfs apply -f nfs-server.yaml + +# 检查部署结果 +kubectl -n nfs get pod,svc +``` + +### 安装 csi-driver-nfs + +安装 `csi-driver-nfs` 需要使用 `Helm`,请注意提前安装。 + +```bash +# 添加 Helm 仓库 +helm repo add csi-driver-nfs https://mirror.ghproxy.com/https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts +helm repo update csi-driver-nfs + +# 部署 csi-driver-nfs +# 这里参数主要优化了镜像地址,加速国内下载 +helm upgrade --install csi-driver-nfs csi-driver-nfs/csi-driver-nfs \ + --set image.nfs.repository=k8s.m.daocloud.io/sig-storage/nfsplugin \ + --set image.csiProvisioner.repository=k8s.m.daocloud.io/sig-storage/csi-provisioner \ + --set image.livenessProbe.repository=k8s.m.daocloud.io/sig-storage/livenessprobe \ + --set image.nodeDriverRegistrar.repository=k8s.m.daocloud.io/sig-storage/csi-node-driver-registrar \ + --namespace nfs \ + --version v4.5.0 +``` + +!!! warning + + `csi-nfs-controller` 的镜像并未全部支持 `helm` 参数,需要手工修改 `deployment` 的 `image` 字段。 + 将 `image: registry.k8s.io` 改为 `image: k8s.dockerproxy.com` 以加速国内下载。 + +### 创建 StorageClass + +将以下 `YAML` 保存为 `nfs-sc.yaml`: + +```yaml title="nfs-sc.yaml" +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: nfs-csi +provisioner: nfs.csi.k8s.io +parameters: + server: nfs-server.nfs.svc.cluster.local + share: / + # csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume + # csi.storage.k8s.io/provisioner-secret-name: "mount-options" + # csi.storage.k8s.io/provisioner-secret-namespace: "default" +reclaimPolicy: Retain +volumeBindingMode: Immediate +mountOptions: + - nfsvers=4.1 +``` + +然后执行以下命令进行部署: + +```bash +kubectl apply -f nfs-sc.yaml +``` + +## 测试 + +创建数据集,并将数据集的 **关联存储类** ,`预热方式` 设置为 `NFS`,即可将远端数据预热到集群内。 + +数据集创建成功后,可以看到数据集的状态为 `预热中`,等待预热完成后即可使用。 + +## 常见问题 + +### 缺少必要的 NFS 客户端软件 `/sbin/mount` + +```bash +bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount. helper program. +``` + +在运行 Kubernetes 的节点机器上,确保已安装 NFS 客户端: + +=== "Ubuntu/Debian" + + 运行以下命令安装 NFS 客户端: + + ```bash + sudo apt-get update + sudo apt-get install nfs-common + ``` +=== "CentOS/RHEL" + + 运行以下命令安装 NFS 客户端: + + ```bash + sudo yum install nfs-utils + ``` + +检查 NFS 服务器配置,确保 NFS 服务器正在运行且配置正确。你可以尝试运行以下命令手动挂载来测试: + +```bash +sudo mkdir -p /mnt/test +sudo mount -t nfs :/nfsdata /mnt/test +``` diff --git a/docs/zh/docs/admin/baize/best-practice/finetunel-llm.md b/docs/zh/docs/admin/baize/best-practice/finetunel-llm.md new file mode 100644 index 0000000..7c22aff --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/finetunel-llm.md @@ -0,0 +1,305 @@ +# 使用 AI Lab 微调 ChatGLM3 模型 + +本文以 `ChatGLM3` 模型为例,演示如何在 AI Lab 中使用 LoRA(Low-Rank Adaptation,低秩自适应)微调 ChatGLM3 模型。 +Demo 程序来自 [ChatGLM3](https://github.com/THUDM/ChatGLM3/blob/main/finetune_demo/lora_finetune.ipynb) 官方案例。 + +微调的大致流程为: + +![流程](./images/fine-tunel-chatglm3-01.png) + +## 环境依赖 + +- GPU 显存至少 20GB,推荐使用 RTX4090、NVIDIA A/H 系列显卡 +- 可用磁盘空间至少 200GB +- CPU 至少 8 核,推荐 16 核 +- 内存 64GB,推荐 128GB + +!!! info + + 在开始体验之前,请检查 AI 算力平台以及 AI Lab 部署正确,GPU 队列资源初始化成功,且算力资源充足。 + +## 数据准备 + +利用 AI Lab 提供的数据集管理功能,快速将微调大模型所需的数据进行预热及持久化,减少因为准备数据导致的 GPU 资源占用,提高资源利用效率。 + +![数据集列表](./images/fine-tunel-chatglm3-02.png) + +在数据集列表页面,创建需要的数据资源,这些资源包含了 ChatGLM3 代码,也可以是数据文件,所有这些数据都可以通过数据集列表来统一管理。 + +### 代码及模型文件 + +[ChatGLM3](https://github.com/THUDM/ChatGLM3) 是[智谱 AI](https://www.zhipuai.cn/) 和清华大学 KEG 实验室联合发布的对话预训练模型。 + +先拉取 ChatGLM3 代码仓库,下载预训练模型,用于后续的微调任务。 + +![image](./images/fine-tunel-chatglm3-03.png) + +AI Lab 会在后台进行全自动数据预热,以便后续的任务能够快速访问数据。 + +### AdvertiseGen 数据集 + +国内数据可以从 [Tsinghua Cloud](https://cloud.tsinghua.edu.cn/f/b3f119a008264b1cabd1/?dl=1) 直接获取,这里使用 `HTTP` 的数据源方式。 + +注意创建完成后,需要等待数据集预热完成,一般很快,根据您的网络情况而定。 + +### 微调输出数据 + +同时,您需要准备一个空的数据集,用于存放微调任务完成后输出的模型文件,这里创建一个空的数据集,以 `PVC` 为例。 + +!!! warning + + 注意需要使用支持 `ReadWriteMany` 的存储类型,以便后续的任务能够快速访问数据。 + +## 环境准备 + +对于模型开发者来说,准备模型开发需要的 Python 环境依赖是非常重要的,传统做法将环境依赖直接打包到开发工具的镜像中, +或者直接在本地环境中安装,但是这样做会导致环境依赖的不一致,而且不利于环境的管理和依赖更新及同步。 + +AI Lab 提供了环境管理的能力,将 Python 环境依赖包管理和开发工具、任务镜像等进行解耦,解决了依赖管理混乱,环境不一致等问题。 + +这里使用 AI Lab 提供的环境管理功能,创建 ChatGLM3 微调所需的环境,以备后续使用。 + +!!! warning + + 1. ChatGLM 仓库内有 `requirements.txt` 文件,里面包含了 ChatGLM3 微调所需的环境依赖 + 2. 本次微调没有用到 `deepspeed` 和 `mpi4py` 包,建议从 `requirements.txt` 文件中将其注释掉,否则可能出现包编译不通过的情况 + +![创建环境](./images/fine-tunel-chatglm3-05.png) + +在环境管理列表,您可以快速创建一个 Python 环境,并通过简单的表单配置来完成环境的创建;这里需要一个 Python 3.11.x 环境, + +![环境配置](./images/fine-tunel-chatglm3-06.png) + +因为本实验需要使用 CUDA,所以在这里需要配置 GPU 资源,用于预热需要资源的依赖库。 + +创建环境,需要去下载一系列的 Python 依赖,根据您的实际位置不同,可能会有不同的下载速度,这里使用了国内的镜像加速,可以加快下载速度。 + +## 使用 Notebook 作为 IDE + +AI Lab 提供了 Notebook 作为 IDE 的功能,可以让用户在浏览器中直接编写代码,运行代码,查看代码运行结果,非常适合于数据分析、机器学习、深度学习等领域的开发。 + +您可以使用 AI Lab 提供的 JupyterLab Notebook 来进行 ChatGLM3 的微调任务。 + +### 创建 JupyterLab Notebook + +![创建 Notebook](./images/fine-tunel-chatglm3-07.png) + +在 Notebook 列表中,可以根据页面操作指引,创建一个 Notebook。注意您需要根据前文提到的资源要求来配置对应的 Notebook 资源参数, +避免后续因为资源问题,影响微调过程。 + +![资源配置](./images/fine-tunel-chatglm3-08.png) + +!!! note + + 在创建 Notebook 时,可以将之前预加载的模型代码数据集和环境,直接挂载到 Notebook 中,极大节省了数据准备的时间。 + +#### 挂载数据集和代码 + +注意:ChatGLM3 的代码文件挂载到了 `/home/jovyan/ChatGLM3` 目录下,同时您也需要将 `AdvertiseGen` 数据集挂载到 +`/home/jovyan/ChatGLM3/finetune_demo/data/AdvertiseGen` 目录下,以便后续的微调任务能够访问数据。 + +![挂载代码文件](./images/fine-tunel-chatglm3-09.png) + +#### 挂载 PVC 到模型输出文件夹 + +本次使用的模型输出位置在 `/home/jovyan/ChatGLM3/finetune_demo/output` 目录下,可以将之前创建的 `PVC` 数据集挂载到这个目录下, +这样训练输出的模型就可以保存到数据集中,后续模型推理等任务可以直接访问。 + +创建完成后,可以看到 Notebook 的界面,您可以直接在 Notebook 中编写代码,运行代码,查看代码运行结果。 + +![挂载 PVC 到模型输出](./images/fine-tunel-chatglm3-10.png) + +### 微调 ChatGLM3 + +当您进入到 Notebook 中后,可以在 Notebook 侧边栏会发现有一个 `File Browser` 的选项,可以看到之前挂载的数据集和代码,在这里找到 ChatGLM3 的文件夹。 + +您可以看到 ChatGLM3 的微调代码在 `finetune_demo` 文件夹中,这里可以直接打开 `lora_finetune.ipynb` 文件,这是 ChatGLM3 的微调代码。 + +![文件夹](./images/fine-tunel-chatglm3-11.png) + +首先,根据 `README.md` 的说明,您可以了解到整个微调的过程,建议先阅读一遍,确保基础的环境依赖和数据准备工作都已经完成。 + +![readme](./images/fine-tunel-chatglm3-12.png) + +打开终端,并使用 `conda` 切换到您提前预热的环境中,此环境与 JupyterLab Kernel 保持一致,以便后续的代码运行。 + +![打开终端切换环境](./images/fine-tunel-chatglm3-13.png) + +### 数据预处理 + +首先,您需要将 `AdvertiseGen` 数据集进行预处理,对数据进行标准化处理,使其符合 `Lora` 预训练的标准格式要求; +这里将处理后的数据保存到 `AdvertiseGen_fix` 文件夹中。 + +```python +import json +from typing import Union +from pathlib import Path + +def _resolve_path(path: Union[str, Path]) -> Path: + return Path(path).expanduser().resolve() + +def _mkdir(dir_name: Union[str, Path]): + dir_name = _resolve_path(dir_name) + if not dir_name.is_dir(): + dir_name.mkdir(parents=True, exist_ok=False) + +def convert_adgen(data_dir: Union[str, Path], save_dir: Union[str, Path]): + def _convert(in_file: Path, out_file: Path): + _mkdir(out_file.parent) + with open(in_file, encoding='utf-8') as fin: + with open(out_file, 'wt', encoding='utf-8') as fout: + for line in fin: + dct = json.loads(line) + sample = {'conversations': [{'role': 'user', 'content': dct['content']}, + {'role': 'assistant', 'content': dct['summary']}]} + fout.write(json.dumps(sample, ensure_ascii=False) + '\n') + + data_dir = _resolve_path(data_dir) + save_dir = _resolve_path(save_dir) + + train_file = data_dir / 'train.json' + if train_file.is_file(): + out_file = save_dir / train_file.relative_to(data_dir) + _convert(train_file, out_file) + + dev_file = data_dir / 'dev.json' + if dev_file.is_file(): + out_file = save_dir / dev_file.relative_to(data_dir) + _convert(dev_file, out_file) + +convert_adgen('data/AdvertiseGen', 'data/AdvertiseGen_fix') +``` + +为了节省调试的时间,您可以将 `/home/jovyan/ChatGLM3/finetune_demo/data/AdvertiseGen_fix/dev.json` +中的数据量缩减到 50 条,这里的数据是 JSON 格式,处理起来也是比较方便的。 + +![代码和数据](./images/fine-tunel-chatglm3-14.png) + +### 本地 LoRA 微调测试 + +完成数据的预处理之后,基本上您就可以直接微调测试了,可以在 +`/home/jovyan/ChatGLM3/finetune_demo/configs/lora.yaml` 文件中配置微调的参数,一般需要关注的参数基本如下: + +![要关注的参数](./images/fine-tunel-chatglm3-15.png) + +新开一个终端窗口,使用如下命令即可进行本地微调测试,请确保参数配置和路径正确: + +```bash +!CUDA_VISIBLE_DEVICES=0 NCCL_P2P_DISABLE="1" NCCL_IB_DISABLE="1" python finetune_hf.py data/AdvertiseGen_fix ./chatglm3-6b configs/lora.yaml +``` + +在这条命令中, + +- `finetune_hf.py` 是 ChatGLM3 代码中的微调脚本 +- `data/AdvertiseGen_fix` 是您预处理后的数据集 +- `./chatglm3-6b` 是您预训练模型的路径 +- `configs/lora.yaml` 是微调的配置文件 + +![运行命令](./images/fine-tunel-chatglm3-16.png) + +微调过程中可以使用 `nvidia-smi` 命令查看 GPU 显存使用情况: + +![查看显存使用情况](./images/fine-tunel-chatglm3-17.png) + +在微调完成后,在 `finetune_demo` 目录下会生成一个 `output` 目录,里面包含了微调的模型文件, +这样微调的模型文件就直接保存到您之前创建的 `PVC` 数据集中了。 + +## 微调任务提交 + +在本地微调测试完成后,确保您的代码和数据没有问题,接下来可以将微调任务提交到AI Lab 中,进行大规模的训练和微调任务。 + +> 这也是推荐的模型开发和微调流程,先在本地进行微调测试,确保代码和数据没有问题。 + +### 使用界面提交微调任务 + +![任务列表](./images/fine-tunel-chatglm3-18.png) + +这里使用 `Pytorch` 来创建微调任务,根据您的实际情况,选择需要使用哪个集群的资源,注意需要满足前面资源准备中提及的资源要求。 + +![任务资源配置](./images/fine-tunel-chatglm3-19.png) + +- 镜像:可直接使用 baizectl 提供的模型镜像 +- 启动命令,根据您在 Notebook 中使用 LoRA 微调的经验,代码文件和数据在 `/home/jovyan/ChatGLM3/finetune_demo` 目录下,所以您可以直接使用这个路径: + + ```bash + bash -c "cd /home/jovyan/ChatGLM3/finetune_demo && CUDA_VISIBLE_DEVICES=0 NCCL_P2P_DISABLE="1" NCCL_IB_DISABLE="1" python finetune_hf.py data/AdvertiseGen_fix ./chatglm3-6b configs/lora.yaml" + ``` + +- 挂载环境,这样之前预加载的环境依赖不仅可以在 Notebook 中使用,同时也可以在任务中使用 +- 数据集:直接使用之前预热的数据集 + - 将模型输出路径设置为之前创建的 PVC 数据集 + - 将 `AdvertiseGen` 数据集挂载到 `/home/jovyan/ChatGLM3/finetune_demo/data/AdvertiseGen` 目录下 +- 配置足够的 GPU 资源,确保微调任务能够正常运行 + +![提交微调任务](./images/fine-tunel-chatglm3-20.png) + +### 查看任务状态 + +任务成功提交后,您可以在任务列表中实时查看任务的训练进展,这里您可以看到任务的状态、资源使用情况、日志等信息。 + +> 查看任务日志 + +![任务日志](./images/fine-tunel-chatglm3-21.png) + +任务运行完成后,您可以在数据输出的数据集中查看微调的模型文件,这样就可以使用这个模型文件进行后续的推理任务。 + +### 使用 `baizectl` 提交任务 + +AI Lab 的 Notebook 支持免认证直接使用 `baizectl` 命令行工具, +如果您喜欢使用 CLI,那么可以直接使用 `baizectl` 提供的命令行工具,提交任务。 + +```bash +baizectl job submit --name finetunel-chatglm3 -t PYTORCH \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --resources cpu=8,memory=16Gi,nvidia.com/gpu=1 \ + --workers 1 \ + --queue default \ + --working-dir /home/jovyan/ChatGLM3 \ + --datasets AdvertiseGen:/home/jovyan/ChatGLM3/finetune_demo/data/AdvertiseGen \ + --datasets output:/home/jovyan/ChatGLM3/finetune_demo/output \ + --labels job_type=pytorch \ + --restart-policy on-failure \ + -- bash -c "cd /home/jovyan/ChatGLM3/finetune_demo && CUDA_VISIBLE_DEVICES=0 NCCL_P2P_DISABLE="1" NCCL_IB_DISABLE="1" python finetune_hf.py data/AdvertiseGen_fix ./chatglm3-6b configs/lora.yaml" +``` + +如果希望了解更多 `baizectl` 的使用说明,可以查看 [baizectl 使用文档](../developer/notebooks/baizectl.md)。 + +## 模型推理 + +在微调任务完成后,您可以使用微调的模型进行推理任务,这里您可以使用AI Lab 提供的推理服务,将输出后的模型创建为推理服务。 + +![推理任务](./images/fine-tunel-chatglm3-22.png) + +在推理服务列表中,您可以创建一个新的推理服务,在选择模型的位置,选择之前推理输出的数据集,并配置模型路径。 + +![创建推理服务](./images/fine-tunel-chatglm3-23.png) + +有关模型资源要求、推理服务的 GPU 资源要求,需要根据模型的大小和推理的并发量来配置,这里您可以根据之前微调任务的资源配置来配置。 + +### 配置模型运行时 + +配置模型的运行时尤为重要,目前 AI Lab 已经支持 `vLLM` 作为模型推理服务的运行时,可以直接选择 `vLLM`。 + +> vLLM 支持非常丰富的大语言模型,建议访问 [vLLM](https://docs.vllm.ai) 了解更多信息,这些模型都可以很方便地在 AI Lab 中使用。 + +![模型配置](./images/fine-tunel-chatglm3-24.png) + +创建完成后,您可以在推理服务列表中看到您创建的推理服务,在模型服务列表,您可以直接获取模型的访问地址 + +### 使用模型服务测试 + +简单在终端中尝试,使用 `curl` 命令来测试模型服务,这里您可以看到返回的结果,这样就可以使用模型服务进行推理任务了。 + +```bash +curl -X POST http://10.20.100.210:31118/v2/models/chatglm3-6b/generate \ + -d '{"text_input": "hello", "stream": false, "sampling_parameters": "{\"temperature\": 0.7, \"top_p\": 0.95, \'max_tokens\": 1024}"}' +``` + +![curl 命令结果](./images/fine-tunel-chatglm3-25.png) + +## 结语 + +本文以 `ChatGLM3` 为例,带您快速了解和上手 **AI Lab** 的模型微调,使用 `LoRA` 微调了 ChatGLM3 模型。 + +AI Lab 提供了非常丰富的功能,可以帮助模型开发者快速进行模型开发、微调、推理等任务,同时也提供了丰富的 OpenAPI 接口,可以方便地与第三方应用生态进行结合。 diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-01.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-01.png new file mode 100644 index 0000000..34b514b Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-01.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-02.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-02.png new file mode 100644 index 0000000..d88f583 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-02.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-03.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-03.png new file mode 100644 index 0000000..d2c3784 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-03.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-04.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-04.png new file mode 100644 index 0000000..6e94bcf Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-04.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-05.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-05.png new file mode 100644 index 0000000..80241ae Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-05.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-06.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-06.png new file mode 100644 index 0000000..1506e23 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-06.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-07.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-07.png new file mode 100644 index 0000000..415ea9e Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-07.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-08.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-08.png new file mode 100644 index 0000000..ef0f370 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-08.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-09.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-09.png new file mode 100644 index 0000000..67240eb Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-09.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-10.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-10.png new file mode 100644 index 0000000..99a11a1 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-10.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-11.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-11.png new file mode 100644 index 0000000..779a58d Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-11.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-12.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-12.png new file mode 100644 index 0000000..c63b78b Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-12.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-13.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-13.png new file mode 100644 index 0000000..bb514c6 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-13.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-14.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-14.png new file mode 100644 index 0000000..27c71f0 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-14.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-15.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-15.png new file mode 100644 index 0000000..e4cfa9b Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-15.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-16.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-16.png new file mode 100644 index 0000000..172eda6 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-16.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-17.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-17.png new file mode 100644 index 0000000..1df3b1f Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-17.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-18.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-18.png new file mode 100644 index 0000000..b1b28a2 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-18.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-19.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-19.png new file mode 100644 index 0000000..9c49893 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-19.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-20.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-20.png new file mode 100644 index 0000000..9c49893 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-20.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-21.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-21.png new file mode 100644 index 0000000..69cc577 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-21.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-22.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-22.png new file mode 100644 index 0000000..3491bc7 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-22.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-23.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-23.png new file mode 100644 index 0000000..eb70283 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-23.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-24.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-24.png new file mode 100644 index 0000000..2829c5d Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-24.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-25.png b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-25.png new file mode 100644 index 0000000..1be2c97 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/fine-tunel-chatglm3-25.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/lbs01.png b/docs/zh/docs/admin/baize/best-practice/images/lbs01.png new file mode 100644 index 0000000..33c285b Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/lbs01.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/lbs02.png b/docs/zh/docs/admin/baize/best-practice/images/lbs02.png new file mode 100644 index 0000000..21f5b30 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/lbs02.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/lbs03.png b/docs/zh/docs/admin/baize/best-practice/images/lbs03.png new file mode 100644 index 0000000..68d0ef4 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/lbs03.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/lbs04.png b/docs/zh/docs/admin/baize/best-practice/images/lbs04.png new file mode 100644 index 0000000..34fa4e3 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/lbs04.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/lbs05.png b/docs/zh/docs/admin/baize/best-practice/images/lbs05.png new file mode 100644 index 0000000..6c1ab7c Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/lbs05.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/scheduler01.png b/docs/zh/docs/admin/baize/best-practice/images/scheduler01.png new file mode 100644 index 0000000..90e97f5 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/scheduler01.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/scheduler02.png b/docs/zh/docs/admin/baize/best-practice/images/scheduler02.png new file mode 100644 index 0000000..e9b482f Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/scheduler02.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/scheduler03.png b/docs/zh/docs/admin/baize/best-practice/images/scheduler03.png new file mode 100644 index 0000000..12353b7 Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/scheduler03.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/images/scheduler04.png b/docs/zh/docs/admin/baize/best-practice/images/scheduler04.png new file mode 100644 index 0000000..1d1f3eb Binary files /dev/null and b/docs/zh/docs/admin/baize/best-practice/images/scheduler04.png differ diff --git a/docs/zh/docs/admin/baize/best-practice/label-studio.md b/docs/zh/docs/admin/baize/best-practice/label-studio.md new file mode 100644 index 0000000..16d898a --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/label-studio.md @@ -0,0 +1,176 @@ +# 部署 Label Studio + +[Label Studio](https://labelstud.io/) 是一个开源的数据标注工具,用于各种机器学习和人工智能任务。 +以下是 Label Studio 的简要介绍: + +- 支持图像、音频、视频、文本等多种数据类型的标注 +- 可用于目标检测、图像分类、语音转录、命名实体识别等多种任务 +- 提供可定制的标注界面 +- 支持多种标注格式和导出选项 + +Label Studio 通过其灵活性和功能丰富性,为数据科学家和机器学习工程师提供了强大的数据标注解决方案。 + +## 部署到 AI 算力平台 + +要想在 AI Lab 中使用 Label Studio,需将其部署到[全局服务集群](../../kpanda/clusters/cluster-role.md#_2), +你可以通过 Helm 的方式快速部署。 + +!!! note + + 更多部署详情,请参阅 [Deploy Label Studio on Kubernetes](https://labelstud.io/guide/install_k8s)。 + +1. 打开全局服务集群界面,从左侧导航栏找到 __Helm 应用__ -> __Helm 仓库__ ,选择 __创建仓库__ 按钮,填写如下参数: + + ![创建按钮](./images/lbs01.png) + +1. 添加成功后,点击列表右侧的 __┇__ ,选择 __同步仓库__ ,稍等片刻后完成同步。(后续更新 Label Studio 也会用到这个同步操作)。 + + ![同步仓库](./images/lbs02.png) + +1. 然后跳转到 __Helm 模板__ 页面,你可以搜索找到 `label-studio`,点击卡片。 + + ![点击卡片安装](./images/lbs03.png) + +1. 选择最新的版本,如下图配置安装参数,名称为 `label-stuio`,建议创建新的命令空间,配置参数切换到 `YAML` ,根据说明修改其中配置。 + + ```yaml + global: + image: + repository: heartexlabs/label-studio # 如果无法访问 docker.io,在此处配置代理地址 + extraEnvironmentVars: + LABEL_STUDIO_HOST: https://{访问地址}/label-studio # 使用的登录地址,请参阅当前网页 URL + LABEL_STUDIO_USERNAME: {用户邮箱} # 必须是邮箱,替换为自己的 + LABEL_STUDIO_PASSWORD: {用户密码} + app: + nginx: + livenessProbe: + path: /label-studio/nginx_health + readinessProbe: + path: /label-studio/version + ``` + + ![yaml 配置示例](./images/lbs04.png) + +至此,完成了 Label studio 的安装。 + +!!! warning + + 默认会安装 PostgreSQL 作为数据服务中间件,如果镜像拉取失败,可能是 `docker.io` 无法访问,注意切换到可用代理即可。 + +> 如果你有自己的 PostgreSQL 数据服务中间件,可以使用如下参数配置: + +```yaml +global: + image: + repository: heartexlabs/label-studio # 如果无法访问 docker.io,在此处配置代理地址 + extraEnvironmentVars: + LABEL_STUDIO_HOST: https://{访问地址}/label-studio # 使用的登录地址,参阅当前网页 URL + LABEL_STUDIO_USERNAME: {用户邮箱} # 必须是邮箱,替换为自己的 + LABEL_STUDIO_PASSWORD: {用户密码} +app: + nginx: + livenessProbe: + path: /label-studio/nginx_health + readinessProbe: + path: /label-studio/version +postgresql: + enabled: false # 禁用内置的 PostgreSQL +externalPostgresql: + host: "postgres-postgresql" # PostgreSQL 地址 + port: 5432 + username: "label_studio" # PostgreSQL 用户名 + password: "your_label_studio_password" # PostgreSQL 密码 + database: "label_studio" # PostgreSQL 数据库名 +``` + +## 添加 GProduct 到导航栏 + +如果要添加 Label Studio 到导航栏,可以参考[全局管理 OEM IN](../../ghippo/best-practice/oem/oem-in.md) 的方式。 +以下案例是增加到 AI Lab 二级导航的添加方式。 + +### 添加代理访问 + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: GProductProxy +metadata: + name: label-studio +spec: + gproduct: label-studio + proxies: + - authnCheck: false + destination: + host: label-studio-ls-app.label-studio.svc.cluster.local + port: 80 + match: + uri: + prefix: /label-studio +``` + +### 添加到 AI Lab + +修改 CRD 为 `GProductNavigator` 的 CR `baize` ,然后在现有配置中进行如下变更: + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: GProductNavigator +metadata: + annotations: + meta.helm.sh/release-name: baize + meta.helm.sh/release-namespace: baize-system + labels: + app.kubernetes.io/managed-by: Helm + gProductName: baize + name: baize +spec: + category: cloudnativeai + gproduct: baize + iconUrl: ./ui/baize/logo.svg + isCustom: false + localizedName: + en-US: AI Lab + zh-CN: AI Lab + menus: + - iconUrl: '' + isCustom: false + localizedName: + en-US: AI Lab + zh-CN: AI Lab + name: workspace-view + order: 1 + url: ./baize + visible: true + - iconUrl: '' + isCustom: false + localizedName: + en-US: Operator + zh-CN: 运维管理 + name: admin-view + order: 1 + url: ./baize/admin + visible: true + # 添加开始 + - iconUrl: '' + localizedName: + en-US: Data Annotation + zh-CN: 数据标注 + name: label-studio + order: 1 + target: blank # 控制新开页 + url: https://{访问地址}/label-studio # 访问地址 + visible: true + # 添加结束 + name: AI Lab + order: 10 + url: ./baize + visible: true +``` + +### 添加效果 + +![oem 效果](./images/lbs05.png) + +## 结语 + +以上,就是如何添加 Label Studio 并将其作为 AI Lab 的标注组件,通过将标注后的数据添加到 AI Lab 的数据集中, +联动算法开发,完善算法开发流程,后续如何使用请关注其他文档参考。 diff --git a/docs/zh/docs/admin/baize/best-practice/train-with-deepspeed.md b/docs/zh/docs/admin/baize/best-practice/train-with-deepspeed.md new file mode 100644 index 0000000..3ca985e --- /dev/null +++ b/docs/zh/docs/admin/baize/best-practice/train-with-deepspeed.md @@ -0,0 +1,80 @@ +--- +hide: + - toc +--- + +# 如何提交 DeepSpeed 训练任务 + +根据 [DeepSpeed 官方文档](https://www.deepspeed.ai/getting-started/),我们推荐使用修改代码的方式实现。 + +即使用 `deepspeed.init_distributed()` 代替 `torch.distributed.init_process_group(...)`。 +然后运行命令使用 `torchrun`,提交为 Pytorch 分布式任务,既可运行 DeepSpeed 任务。 + +是的,你可以使用 `torchrun` 运行你的 DeepSpeed 训练脚本。 +`torchrun` 是 PyTorch 提供的一个实用工具,用于分布式训练。你可以结合 `torchrun` 和 DeepSpeed API 来启动你的训练任务。 + +以下是一个使用 `torchrun` 运行 DeepSpeed 训练脚本的示例: + +1. 编写训练脚本: + + ```python title="train.py" + import torch + import deepspeed + from torch.utils.data import DataLoader + + # 模型和数据加载 + model = YourModel() + train_dataset = YourDataset() + train_dataloader = DataLoader(train_dataset, batch_size=32) + + # 配置文件路径 + deepspeed_config = "deepspeed_config.json" + + # 创建 DeepSpeed 训练引擎 + model_engine, optimizer, _, _ = deepspeed.initialize( + model=model, + model_parameters=model.parameters(), + config_params=deepspeed_config + ) + + # 训练循环 + for batch in train_dataloader: + loss = model_engine(batch) + model_engine.backward(loss) + model_engine.step() + ``` + +2. 创建 DeepSpeed 配置文件: + + ```json title="deepspeed_config.json" + { + "train_batch_size": 32, + "gradient_accumulation_steps": 1, + "fp16": { + "enabled": true, + "loss_scale": 0 + }, + "optimizer": { + "type": "Adam", + "params": { + "lr": 0.00015, + "betas": [0.9, 0.999], + "eps": 1e-08, + "weight_decay": 0 + } + } + } + ``` + +3. 使用 `torchrun` 或者 `baizectl` 运行训练脚本: + + ```bash + torchrun train.py + ``` + + 通过这种方式,你可以结合 PyTorch 的分布式训练功能和 DeepSpeed 的优化技术,从而实现更高效的训练。 + 您可以在 Notebook 中,使用 `baizectl` 提交命令: + + ```bash + baizectl job submit --pytorch --workers 2 -- torchrun train.py + ``` diff --git a/docs/zh/docs/admin/baize/developer/dataset/create-use-delete.md b/docs/zh/docs/admin/baize/developer/dataset/create-use-delete.md new file mode 100644 index 0000000..65a7628 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/dataset/create-use-delete.md @@ -0,0 +1,80 @@ +# 数据集列表 + +AI Lab 提供模型开发、训练以及推理过程所有需要的数据集管理功能。目前支持将多种数据源统一接入能力。 + +通过简单配置即可将数据源接入到 AI Lab 中,实现数据的统一纳管、预热、数据集管理等功能。 + +## 创建数据集 + +1. 在左侧导航栏中点击 **数据管理** -> **数据集列表** ,点击右侧的 **创建** 按钮。 + + ![点击创建](../../images/dataset01.png) + +2. 选择数据集归属的工作集群、命名空间 **下一步** 。 + + ![填写参数](../../images/dataset02.png) + +3. 配置目标数据的数据源类型,然后点击 **确定** 。 + + ![任务资源配置](../../images/dataset03.png) + + 目前支持这几种数据源: + + - GIT:支持 GitHub、GitLab、Gitee 等仓库 + - S3:支持 Amazon 云等对象存储 + - HTTP:直接输入一个有效的 HTTP 网址 + - PVC:支持预先创建的 Kubernetes PersistentVolumeClaim + - NFS:支持 NFS 共享存储 + +4. 数据集创建成功将返回数据集列表。你可以通过右侧的 **┇** 执行更多操作。 + + ![数据集列表](../../images/dataset04.png) + +!!! info + + 系统自动会在数据集创建成功后,立即进行一次性的数据预加载;在预加载完成之前,数据集不可以使用。 + +## 数据集使用 + +数据集创建成功后,可以在模型训练、推理等任务中使用。 + +### 在 Notebook 中使用 + +在创建 Notebook 中,可以直接使用数据集;使用方式如下: + +- 使用数据集做训练数据挂载 +- 使用数据集做代码挂载 + +![数据集列表](../../images/dataset05.png) + +### 在 训练任务 中使用 + +- 使用数据集指定任务输出 +- 使用数据集指定任务输入 +- 使用数据集指定 TensorBoard 输出 + +![任务管理](../../images/dataset06.png) + +### 在推理服务 中使用 + +- 使用数据集挂载模型 + +![推理服务](../../images/dataset07.png) + +## 删除数据集 + +如果发现数据集冗余、过期或因其他缘故不再需要,可以从数据集列表中删除。 + +1. 在数据集列表右侧点击 **┇** ,在弹出菜单中选择 **删除** 。 + + ![删除](../../images/ds-delete01.png) + +1. 在弹窗中确认要删除的数据集,输入数据集名称后点击 **删除** 。 + + ![确认删除](../../images/ds-delete02.png) + +1. 屏幕提示删除成功,该数据集从列表中消失。 + +!!! caution + + 数据集一旦删除将不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/admin/baize/developer/dataset/environments.md b/docs/zh/docs/admin/baize/developer/dataset/environments.md new file mode 100644 index 0000000..ee9111c --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/dataset/environments.md @@ -0,0 +1,79 @@ +# 管理环境 + +本文说明如何在 AI Lab 中管理你的环境依赖库,以下是具体操作步骤和注意事项。 + +1. [环境管理概述](#_2) +2. [创建新环境](#_3) +3. [配置环境](#_4) +4. [故障排除](#_5) + +## 环境管理概述 + +传统方式,一般会将 Python 环境依赖在镜像中构建,镜像带有 Python 版本和依赖包的镜像,维护成本较高且更新不方便,往往需要重新构建镜像。 + +而在 AI Lab 中,用户可以通过 **环境管理** 模块来管理纯粹的环境依赖,将这部分从镜像中解耦,带来的优势有: + +- 一份环境多处使用,同时可以在 Notebook、分布式训练任务、乃至推理服务中使用。 +- 更新依赖包更加方便,只需要更新环境依赖即可,无需重新构建镜像。 + +以下为环境管理的主要组成部分: + +- **集群** :选择需要操作的集群。 +- **命名空间** :选择命名空间以限定操作范围。 +- **环境列表** :展示当前集群和命名空间下的所有环境及其状态。 + +![环境管理概述](../../images/conda01.png) + +| 字段 | 描述 | 举例值 | +|-----|------|-------| +| 名称 | 环境的名称 | my-environment | +| 状态 | 环境当前的状态(正常或失败),新创建环境有一个预热过程,预热成功后即可在其他任务中使用 | 正常 | +| 创建时间 | 环境创建的时间 | 2023-10-01 10:00:00 | + +## 创建新环境 + +在 **环境管理** 界面,点击右上角的 **创建** 按钮,进入创建环境的流程。 + +![创建新环境](../../images/conda02.png) + +| 字段 | 描述 | 举例值 | +|-----|------|------| +| 名称 | 输入环境的名称,长度为 2-63 个字符,必须以小写字母、数字开头和结尾。 | my-environment | +| 部署位置 | **集群** :选择需要部署的集群 | `gpu-cluster` | +| | **命名空间** :选择命名空间 | `default` | +| 备注 | 填写备注信息。 | 这是一个测试环境 | +| 标签 | 为环境添加标签。 | env:test | +| 注解 | 为环境添加注解。填写完成后,点击 **下一步** 进入环境配置。 | 注解示例 | + +## 配置环境 + +在环境配置步骤中,用户需要配置 Python 版本和依赖包管理工具。 + +![配置环境](../../images/conda03.png) + +| 字段 | 描述 | 举例值 | +|-----|-----|--------| +| Python 版本 | 选择所需的 Python 版本 | 3.12.3 | +| 包管理器 | 选择包管理工具,可选 `PIP` 或 `CONDA` | PIP | +| Environment Data | 如果选择 `PIP`:在下方编辑器中输入 `requirements.txt` 格式的依赖包列表。 | numpy==1.21.0 | +| | 如果选择 `CONDA`:在下方编辑器中输入 `environment.yaml` 格式的依赖包列表。 | | +| 其他选项 | **pip 额外索引地址** :配置 pip 额外的索引地址;适用于企业内部有自己的私有仓库或者 PIP 加速站点。 | `https://pypi.example.com` | +| | **GPU 配置** :启用或禁用 GPU 配置;部分涉及到 GPU 的依赖包需要在预加载时配置 GPU 资源。 | 启用 | +| | **关联存储** :选择关联的存储配置;环境依赖包会存储在关联存储中。注意:需要使用支持 `ReadWriteMany` 的存储。 | my-storage-config | + +配置完成后,点击 **创建** 按钮,系统会自动创建并配置新的 Python 环境。 + +## 故障排除 + +- 如果环境创建失败: + - 检查网络连接是否正常。 + - 确认填写的 Python 版本和包管理器配置无误。 + - 确保所选集群和命名空间可用。 + +- 如果依赖预热失败: + - 检查 `requirements.txt` 或 `environment.yaml` 文件格式是否正确。 + - 确认依赖包名称和版本是否正确无误。如遇到其他问题,请联系平台管理员或查看平台帮助文档获取更多支持。 + +--- + +以上即为在 AI Lab 中管理 Python 依赖库的基本操作步骤和注意事项。 diff --git a/docs/zh/docs/admin/baize/developer/index.md b/docs/zh/docs/admin/baize/developer/index.md new file mode 100644 index 0000000..9f50c00 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/index.md @@ -0,0 +1,12 @@ +--- +hide: + - toc +--- + +# 开发控制台 + +开发控制台是开发者日常执行 AI 推理、大模型训练等任务的控制台。 + +![开发者概览](../images/dev-view.png) + +方便用户通过概览快速了解,当前工作空间的资源及用量情况,包含了GPU资源、Notebook、任务以及数据集的数量信息。 diff --git a/docs/zh/docs/admin/baize/developer/inference/models.md b/docs/zh/docs/admin/baize/developer/inference/models.md new file mode 100644 index 0000000..0ae8f99 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/inference/models.md @@ -0,0 +1,45 @@ +# 了解模型支持情况 + +随着 AI Lab 的快速迭代,我们已经支持了多种模型的推理服务,您可以在这里看到所支持的模型信息。 + +- AI Lab v0.3.0 上线了模型推理服务,针对传统的深度学习模型,方便用户可以直接使用AI Lab 的推理服务,无需关心模型的部署和维护。 +- AI Lab v0.6.0 支持了完整版本的 vLLM 推理能力,支持诸多大语言模型,如 `LLama`、`Qwen`、`ChatGLM` 等。 + +您可以在 AI Lab 中使用经过算丰 AI 算力平台验证过的 GPU 类型; +更多细节参阅 [GPU 支持矩阵](../../../kpanda/gpu/gpu_matrix.md)。 + +![点击创建](../../images/inference-interface.png) + +## Triton Inference Server + +通过 Triton Inference Server 可以很好的支持传统的深度学习模型,我们目前支持主流的推理后端服务: + +| Backend | 支持模型格式 | 介绍 | +| ------- | ---------- | --- | +| pytorch | TorchScript、PyTorch 2.0 格式的模型 | [triton-inference-server/pytorch_backend](https://github.com/triton-inference-server/pytorch_backend) | +| tensorflow | TensorFlow 2.x | [triton-inference-server/tensorflow_backend](https://github.com/triton-inference-server/tensorflow_backend) | +| vLLM(Deprecated) | 与 vLLM 一致 | 支持的模型和 vLLM support Model 一致 | + +!!! danger + + 使用 Triton 的 Backend vLLM 的方式已被弃用,推荐使用最新支持 vLLM 来部署您的大语言模型。 + +## vLLM + +通过 vLLM 我们可以很快的使用大语言模型,您可以在这里看到我们支持的模型列表,这通常和 `vLLM Support Models` 保持一致。 + +- HuggingFace 模型:我们支持了 HuggingFace 的大部分模型,您可以在 [HuggingFace Model Hub](https://huggingface.co/models) 查看更多模型。 +- [vLLM 支持模型](https://docs.vllm.ai/en/stable/models/supported_models.html)列出了支持的大语言模型和视觉语言模型。 +- 使用 vLLM 支持框架的模型进行微调后的模型。 + +### vLLM 新特性 + +目前,AI Lab 还支持在使用 vLLM 作为推理工具时的一些新特性: + +- 在推理模型时,启用 `Lora Adapter` 来优化模型推理服务 +- 提供兼容 `OpenAI` 的 `OpenAPI` 接口,方便用户切换到本地推理服务时,可以低成本的快速切换 + +## 下一步 + +- [创建 Triton 推理服务](./triton-inference.md) +- [创建 vLLM 推理服务](./vllm-inference.md) diff --git a/docs/zh/docs/admin/baize/developer/inference/triton-inference.md b/docs/zh/docs/admin/baize/developer/inference/triton-inference.md new file mode 100644 index 0000000..7605cbc --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/inference/triton-inference.md @@ -0,0 +1,181 @@ +# 创建 Triton 推理服务 + +AI Lab 目前提供以 Triton、vLLM 作为推理框架,用户只需简单配置即可快速启动一个高性能的推理服务。 + +!!! danger + + 使用 Triton 的 Backend vLLM 的方式已被弃用,推荐使用最新支持 vLLM 来部署您的大语言模型。 + +## Triton介绍 + +Triton 是由 NVIDIA 开发的一个开源推理服务器,旨在简化机器学习模型的部署和推理服务。它支持多种深度学习框架,包括 TensorFlow、PyTorch 等,使得用户能够轻松管理和部署不同类型的模型。 + +## 前提条件 + +准备模型数据:在数据集管理中纳管模型代码,并保证数据成功预加载,下面以 mnist 手写数字识别的 PyTorch 模型为例。 + +!!! note + + 待推理的模型在数据集中需要遵以下目录格式: + + ```bash + + └── + └── + └── + ``` + +本例中的目录格式为: + +```bash + model-repo + └── mnist-cnn + └── 1 + └── model.pt +``` + +## 创建推理服务 + +目前已经支持表单创建,可以界面字段提示,进行服务创建。 + +![点击创建](../../images/triton-infer-0.png) + +### 配置模型路径 + +模型路径 `model-repo/mnist-cnn/1/model.pt` 需要和数据集中的模型目录格式一致。 + +## 模型配置 + +![点击创建](../../images/triton-infer-1.png) + +### 配置输入和输出参数 + +!!! note + + 输入和输出参数的第一个维度默认为 `batchsize` 的大小,设置为 `-1` 可以根据输入的推理数据自动计算 batchsize。参数其余维度和数据类型需要与模型输入匹配。 + +### 配置环境 + +可以导入 [环境管理](../dataset/environments.md) 中创建的环境作为推理时的运行环境。 + +## 高级配置 + +![点击创建](../../images/triton-infer-2.png) + +### 配置认证策略 + +支持 `API key` 的请求方式认证,用户可以自定义增加认证参数。 + +### 亲和性调度 + +支持 根据 GPU 资源等节点配置实现自动化的亲和性调度,同时也方便用户自定义调度策略。 + +## 访问 + +![点击创建](../../images/triton-infer-3.png) + + + +### API 访问 + +- Triton 提供了一个基于 REST 的 API,允许客户端通过 HTTP POST 请求进行模型推理。 +- 客户端可以发送 JSON 格式的请求体,其中包含输入数据和相关的元数据。 + +#### HTTP 访问 + +1. **发送 HTTP POST 请求**:使用工具如 `curl` 或 HTTP 客户端库(如 Python 的 `requests` 库)向 Triton Server 发送 POST 请求。 + +2. **设置 HTTP 头**:根据用户配置项自动生成的配置,包含模型输入和输出的元数据。 + +3. **构建请求体**:请求体通常包含要进行推理的输入数据,以及模型特定的元数据。 + +##### 示例 curl 命令 + +```bash + curl -X POST "http://:/v2/models//infer" \ + -H "Content-Type: application/json" \ + -d '{ + "inputs": [ + { + "name": "model_input", + "shape": [1, 1, 32, 32], + "datatype": "FP32", + "data": [ + [0.1234, 0.5678, 0.9101, ... ] + ] + } + ] + }' +``` + +- `` 是 Triton Inference Server 运行的主机地址。 +- `` 是 Triton Inference Server 运行的主机端口号。 +- `` 是所创建的推理服务的名称。 +- `"name"` 要与模型配置中的输入参数的 `name` 一致。 +- `"shape"` 要与模型配置中的输入参数的 `dims` 一致。 +- `"datatype"` 要与模型配置中的输入参数的 `Data Type` 一致。 +- `"data"` 替换为实际的推理数据。 + + + +请注意,上述示例代码需要根据你的具体模型和环境进行调整,输入数据的格式和内容也需要符合模型的要求。 + + diff --git a/docs/zh/docs/admin/baize/developer/inference/vllm-inference.md b/docs/zh/docs/admin/baize/developer/inference/vllm-inference.md new file mode 100644 index 0000000..7620e31 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/inference/vllm-inference.md @@ -0,0 +1,49 @@ +# 创建 vLLM 推理服务 + +AI Lab 支持以 vLLM 作为推理服务,提供全部 vLLM 的能力,同时提供了完全适配 OpenAI 接口定义。 + +## vLLM 介绍 + +vLLM 是一个快速且易于使用的用于推理和服务的库,vLLM 旨在极大地提升实时场景下的语言模型服务的吞吐与内存使用效率。vLLM 在速度、灵活性方面具有以下部分特点: + +- 连续批处理传入请求; +- 使用 PagedAttention 高效管理注意力键和值内存; +- 与流行的 HuggingFace 型号无缝集成; +- 兼容 OpenAI 的 API 服务器。 + +## 前提条件 + +准备模型数据:在数据集管理中纳管模型代码,并保证数据成功预加载。 + +## 创建推理服务 + +1. 选择 `vLLM` 推理框架,并在选择模型模块选择提前创建好的模型数据集 `hdd-models` 并填写数据集中模型所在的`路径`信息。 + + 本文推理服务的创建使用 ChatGLM3 模型。 + + ![模型选择](../../images/vllm-infer-0.png) + +2. 配置推理服务的资源,并调整推理服务运行的参数。 + + ![数据选择](../../images/vllm-infer-1.png) + + | 参数名 | 描述 | + | -- | -- | + | GPU 资源 | 根据模型规模以及集群资源可以为推理配置 GPU 资源。| + | 允许远程代码 | 控制 vLLM 是否信任并执行来自远程源的代码 | + | LoRA | **LoRA** 是一种针对深度学习模型的参数高效调整技术。它通过将原始模型参数矩阵分解为低秩矩阵,从而减少参数数量和计算复杂度。

1. `--lora-modules`:用来指定特定模块或层进行低秩近似
2. `max_loras_rank`:用来指定 LoRA 模型中每个适配层的最大秩,对于简单的任务,可以选择较小的秩值,而对于复杂任务,可能需要较大的秩值来保证模型性能。
3. `max_loras`:表示模型中可以包含的 LoRA 层的最大数量,根据模型大小、推理复杂度等因素自定
4. `max_cpu_loras`:用于指定在 CPU 环境中可以处理的 LoRA 层的最大数。 | + | 关联环境 | 通过选择环境预定义推理时所需的环境依赖。| + + !!! info + + 支持配置 LoRA 参数的模型可参考 [vLLM 支持的模型](https://docs.vllm.ai/en/latest/models/supported_models.html)。 + +3. 在 **高级配置** 中,支持根据 GPU 资源等节点配置实现自动化的亲和性调度,同时也方便用户自定义调度策略。 + +## 验证推理服务 + +推理服务创建完成之后,点击推理服务名称进入详情,查看 API 调用方法。通过使用 Curl、Python、Nodejs 等方式验证执行结果。 + +拷贝详情中的 `curl` 命令,并在终端中执行命令发送一条模型推理请求,预期输出: + +![推理接口](../../images/vllm-infer-2.png) diff --git a/docs/zh/docs/admin/baize/developer/jobs/create.md b/docs/zh/docs/admin/baize/developer/jobs/create.md new file mode 100644 index 0000000..7ecdddb --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/create.md @@ -0,0 +1,39 @@ +# 创建任务(Job) + +任务管理是指通过作业调度和管控组件来创建和管理任务生命周期的功能。 + +AI Lab 采用 Kubernetes 的 Job 机制来调度各项 AI 推理、训练任务。 + +## 通用步骤 + +1. 在左侧导航栏中点击 **任务中心** -> **训练任务** ,点击右侧的 **创建** 按钮。 + + ![点击创建](../../images/job01.png) + +1. 系统会预先填充基础配置数据,包括要部署的集群、命名空间、任务类型、队列、优先级等。 + 调整这些参数后点击 **下一步** 。 + + ![填写参数](../../images/job02.png) + +1. 配置镜像地址、运行参数以及关联的数据集、环境和资源后,点击 **下一步** 。 + + ![任务资源配置](../../images/job03.png) + +1. 按需添加标签、注解、环境变量等任务参数,选择调度策略后点击 **确定** 。 + + ![高级配置](../../images/job04.png) + +1. 任务创建成功后,会有几种运行状态: + + - 运行中 + - 排队中 + - 提交成功、提交失败 + - 任务成功、任务失败 + +## 创建特定任务 + +- [创建 Pytorch 任务](./pytorch.md) +- [创建 TensorFlow 任务](./tensorflow.md) +- [创建 MPI 任务](./mpi.md) +- [创建 MXNet 任务](./mxnet.md) +- [创建 PaddlePaddle 任务](./paddle.md) diff --git a/docs/zh/docs/admin/baize/developer/jobs/delete.md b/docs/zh/docs/admin/baize/developer/jobs/delete.md new file mode 100644 index 0000000..4341c34 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/delete.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 删除任务(Job) + +如果发现任务冗余、过期或因其他缘故不再需要,可以从训练任务列表中删除。 + +1. 在训练任务列表右侧点击 **┇** ,在弹出菜单中选择 **删除** 。 + + ![删除](../../images/delete01.png) + +1. 在弹窗中确认要删除的任务,输入任务名称后点击 **删除** 。 + + ![确认删除](../../images/delete02.png) + +1. 屏幕提示删除成功,该任务从列表中消失。 + + ![已删除](../../images/delete03.png) + +!!! caution + + 任务一旦删除将不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/admin/baize/developer/jobs/mpi.md b/docs/zh/docs/admin/baize/developer/jobs/mpi.md new file mode 100644 index 0000000..f55dc69 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/mpi.md @@ -0,0 +1,224 @@ +# MPI 任务 + +MPI(Message Passing Interface)是一种用于并行计算的通信协议,它允许多个计算节点之间进行消息传递和协作。 +MPI 任务是使用 MPI 协议进行并行计算的任务,适用于需要大规模并行处理的应用场景,例如分布式训练、科学计算等。 + +在 AI Lab 中,我们提供了 MPI 任务的支持,您可以通过界面化操作,快速创建 MPI 任务,进行高性能的并行计算。 +本教程将指导您如何在 AI Lab 中创建和运行一个 MPI 任务。 + +## 任务配置介绍 + +- **任务类型** :`MPI`,用于运行并行计算任务。 +- **运行环境** :选用预装了 MPI 环境的镜像,或者在任务中指定安装必要的依赖。 +- **MPIJob 配置** :理解并配置 MPIJob 的各项参数,如副本数、资源请求等。 + +## 任务运行环境 + +在这里我们使用 `baize-notebook` 基础镜像和 **关联环境** 的方式来作为任务的基础运行环境。 +确保运行环境中包含 MPI 及相关库,如 OpenMPI、`mpi4py` 等。 + +> **注意** :了解如何创建环境,请参考[环境列表](../dataset/environments.md)。 + +## 创建 MPI 任务 + +### MPI 任务创建步骤 + +![MPI 任务](../../images/job-mpi01.png) + +1. **登录平台** :登录 AI Lab 平台,点击左侧导航栏中的 **任务中心**,进入 **训练任务** 页面。 +2. **创建任务** :点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型** :在弹出的窗口中,选择任务类型为 `MPI`,然后点击 **下一步**。 +4. **填写任务信息** :填写任务名称和描述,例如 “benchmarks-mpi”,然后点击 **下一步**。 +5. **配置任务参数** :根据您的需求,配置任务的运行参数、镜像、资源等信息。 + +#### 运行参数 + +- **启动命令** :使用 `mpirun`,这是运行 MPI 程序的命令。 +- **命令参数** :输入您要运行的 MPI 程序的参数。 + +**示例:运行 TensorFlow Benchmarks** + +在本示例中,我们将运行一个 TensorFlow 的基准测试程序,使用 Horovod 进行分布式训练。 +首先,确保您使用的镜像中包含所需的依赖项,例如 TensorFlow、Horovod、Open MPI 等。 + +**镜像选择** :使用包含 TensorFlow 和 MPI 的镜像,例如 `mai.daocloud.io/docker.io/mpioperator/tensorflow-benchmarks:latest`。 + +**命令参数** : + +```bash +mpirun --allow-run-as-root -np 2 -bind-to none -map-by slot \ + -x NCCL_DEBUG=INFO -x LD_LIBRARY_PATH -x PATH \ + -mca pml ob1 -mca btl ^openib \ + python scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py \ + --model=resnet101 --batch_size=64 --variable_update=horovod +``` + +**说明** : + +- `mpirun`:MPI 的启动命令。 +- `--allow-run-as-root`:允许以 root 用户运行(在容器中通常是 root 用户)。 +- `-np 2`:指定运行的进程数为 2。 +- `-bind-to none`,`-map-by slot`:MPI 进程绑定和映射的配置。 +- `-x NCCL_DEBUG=INFO`:设置 NCCL(NVIDIA Collective Communication Library)的调试信息级别。 +- `-x LD_LIBRARY_PATH`,`-x PATH`:在 MPI 环境中传递必要的环境变量。 +- `-mca pml ob1 -mca btl ^openib`:MPI 的配置参数,指定传输层和消息层协议。 +- `python scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py`:运行 TensorFlow 基准测试脚本。 +- `--model=resnet101`,`--batch_size=64`,`--variable_update=horovod`:TensorFlow 脚本的参数,指定模型、批量大小和使用 Horovod 进行参数更新。 + +#### 资源配置 + +在任务配置中,需要为每个节点(Launcher 和 Worker)分配适当的资源,例如 CPU、内存和 GPU。 + +**资源示例** : + +- **Launcher(启动器)** : + + - **副本数** :1 + - **资源请求** : + - CPU:2 核 + - 内存:4 GiB + +- **Worker(工作节点)** : + + - **副本数** :2 + - **资源请求** : + - CPU:2 核 + - 内存:4 GiB + - GPU:根据需求分配 + +#### 完整的 MPIJob 配置示例 + +以下是完整的 MPIJob 配置示例,供您参考。 + +```yaml +apiVersion: kubeflow.org/v1 +kind: MPIJob +metadata: + name: tensorflow-benchmarks +spec: + slotsPerWorker: 1 + runPolicy: + cleanPodPolicy: Running + mpiReplicaSpecs: + Launcher: + replicas: 1 + template: + spec: + containers: + - name: tensorflow-benchmarks + image: mai.daocloud.io/docker.io/mpioperator/tensorflow-benchmarks:latest + command: + - mpirun + - --allow-run-as-root + - -np + - "2" + - -bind-to + - none + - -map-by + - slot + - -x + - NCCL_DEBUG=INFO + - -x + - LD_LIBRARY_PATH + - -x + - PATH + - -mca + - pml + - ob1 + - -mca + - btl + - ^openib + - python + - scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py + - --model=resnet101 + - --batch_size=64 + - --variable_update=horovod + resources: + limits: + cpu: "2" + memory: 4Gi + requests: + cpu: "2" + memory: 4Gi + Worker: + replicas: 2 + template: + spec: + containers: + - name: tensorflow-benchmarks + image: mai.daocloud.io/docker.io/mpioperator/tensorflow-benchmarks:latest + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpumem: 1k + nvidia.com/vgpu: "1" + requests: + cpu: "2" + memory: 4Gi +``` + +**配置解析** : + +- `apiVersion` 和 `kind`:表示资源的 API 版本和类型,`MPIJob` 是 Kubeflow 定义的自定义资源,用于创建 MPI 类型的任务。 +- `metadata`:元数据,包含任务的名称等信息。 +- `spec`:任务的详细配置。 + - `slotsPerWorker`:每个 Worker 节点的槽位数量,通常设置为 1。 + - `runPolicy`:运行策略,例如任务完成后是否清理 Pod。 + - `mpiReplicaSpecs`:MPI 任务的副本配置。 + - `Launcher`:启动器,负责启动 MPI 任务。 + - `replicas`:副本数,通常为 1。 + - `template`:Pod 模板,定义容器运行的镜像、命令、资源等。 + - `Worker`:工作节点,实际执行任务的计算节点。 + - `replicas`:副本数,根据并行需求设置,这里设置为 2。 + - `template`:Pod 模板,同样定义容器的运行环境和资源。 + +#### 设置任务副本数 + +在创建 MPI 任务时,需要根据 `mpiReplicaSpecs` 中配置的副本数,正确设置 **任务副本数**。 + +- **总副本数** = `Launcher` 副本数 + `Worker` 副本数 +- 本示例中: + + - `Launcher` 副本数:1 + - `Worker` 副本数:2 + - **总副本数** :1 + 2 = 3 + +因此,在任务配置中,您需要将 **任务副本数** 设置为 **3**。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 MPI 任务。 + +## 查看运行结果 + +任务提交成功后,您可以进入 **任务详情** 页面,查看资源的使用情况和任务的运行状态。 +从右上角进入 **工作负载详情**,可以查看运行过程中每个节点的日志输出。 + +**示例输出**: + +```bash +TensorFlow: 1.13 +Model: resnet101 +Mode: training +Batch size: 64 +... + +Total images/sec: 125.67 +``` + +这表示 MPI 任务成功运行,TensorFlow 基准测试程序完成了分布式训练。 + +--- + +## 小结 + +通过本教程,您学习了如何在 AI Lab 平台上创建和运行一个 MPI 任务。我们详细介绍了 MPIJob 的配置方式, +以及如何在任务中指定运行的命令和资源需求。希望本教程对您有所帮助,如有任何问题,请参考平台提供的其他文档或联系技术支持。 + +--- + +**附录** : + +- 如果您的运行环境未预装所需的库(如 `mpi4py`、Horovod 等),请在任务中添加安装命令,或者使用预装了相关依赖的镜像。 +- 在实际应用中,您可以根据需求修改 MPIJob 的配置,例如更改镜像、命令参数、资源请求等。 diff --git a/docs/zh/docs/admin/baize/developer/jobs/mxnet.md b/docs/zh/docs/admin/baize/developer/jobs/mxnet.md new file mode 100644 index 0000000..07f4c14 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/mxnet.md @@ -0,0 +1,334 @@ +# MXNet 任务 + +!!! warning + + 由于 Apache MXNet 项目已存档,因此 Kubeflow MXJob 将在未来的 Training Operator 1.9 版本中弃用和删除。 + +Apache MXNet 是一个高性能的深度学习框架,支持多种编程语言。MXNet 任务可以使用多种方式进行训练,包括单机模式和分布式模式。在 AI Lab 中,我们提供了对 MXNet 任务的支持,您可以通过界面化操作,快速创建 MXNet 任务,进行模型训练。 + +本教程将指导您如何在 AI Lab 平台上创建和运行 MXNet 的单机和分布式任务。 + +## 任务配置介绍 + +- **任务类型**:`MXNet`,支持单机和分布式两种模式。 +- **运行环境**:选择包含 MXNet 框架的镜像,或在任务中安装必要的依赖。 + +## 任务运行环境 + +我们使用 `release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest` 镜像作为任务的基础运行环境。该镜像预装了 MXNet 及其相关依赖,支持 GPU 加速。 + +> **注意**:了解如何创建和管理环境,请参考 [环境列表](../dataset/environments.md)。 + +## 创建 MXNet 任务 + +![mxnet](../../images/mxnet_job.png) + +### MXNet 单机任务 + +#### 创建步骤 + +1. **登录平台**:登录 AI Lab 平台,点击左侧导航栏中的 **任务中心**,进入 **训练任务** 页面。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:在弹出的窗口中,选择任务类型为 `MXNet`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “MXNet 单机训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据您的需求,配置任务的运行参数、镜像、资源等信息。 + +#### 运行参数 + +- **启动命令**:`python3` +- **命令参数**: + + ```bash + /mxnet/mxnet/example/gluon/mnist/mnist.py --epochs 10 --cuda + ``` + + **说明**: + + - `/mxnet/mxnet/example/gluon/mnist/mnist.py`:MXNet 提供的 MNIST 手写数字识别示例脚本。 + - `--epochs 10`:设置训练轮数为 10。 + - `--cuda`:使用 CUDA 进行 GPU 加速。 + +#### 资源配置 + +- **副本数**:1(单机任务) +- **资源请求**: + - **CPU**:2 核 + - **内存**:4 GiB + - **GPU**:1 块 + +#### 完整的 MXJob 配置示例 + +以下是单机 MXJob 的 YAML 配置: + +```yaml +apiVersion: "kubeflow.org/v1" +kind: "MXJob" +metadata: + name: "mxnet-single-job" +spec: + jobMode: MXTrain + mxReplicaSpecs: + Worker: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + command: ["python3"] + args: + [ + "/mxnet/mxnet/example/gluon/mnist/mnist.py", + "--epochs", + "10", + "--cuda", + ] + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 +``` + +**配置解析**: + +- `apiVersion` 和 `kind`:指定资源的 API 版本和类型,这里是 `MXJob`。 +- `metadata`:元数据,包括任务名称等信息。 +- `spec`:任务的详细配置。 + - `jobMode`:设置为 `MXTrain`,表示训练任务。 + - `mxReplicaSpecs`:MXNet 任务的副本配置。 + - `Worker`:指定工作节点的配置。 + - `replicas`:副本数,这里为 1。 + - `restartPolicy`:重启策略,设为 `Never`,表示任务失败时不重启。 + - `template`:Pod 模板,定义容器的运行环境和资源。 + - `containers`:容器列表。 + - `name`:容器名称。 + - `image`:使用的镜像。 + - `command` 和 `args`:启动命令和参数。 + - `ports`:容器端口配置。 + - `resources`:资源请求和限制。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 MXNet 单机任务。 + +#### 查看运行结果 + +任务提交成功后,您可以进入 **任务详情** 页面,查看资源的使用情况和任务的运行状态。从右上角进入 **工作负载详情**,可以查看运行过程中的日志输出。 + +**示例输出**: + +```bash +Epoch 1: accuracy=0.95 +Epoch 2: accuracy=0.97 +... +Epoch 10: accuracy=0.98 +Training completed. +``` + +这表示 MXNet 单机任务成功运行,模型训练完成。 + +--- + +### MXNet 分布式任务 + +在分布式模式下,MXNet 任务可以使用多台计算节点共同完成训练,提高训练效率。 + +#### 创建步骤 + +1. **登录平台**:同上。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:选择任务类型为 `MXNet`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “MXNet 分布式训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据需求,配置运行参数、镜像、资源等。 + +#### 运行参数 + +- **启动命令**:`python3` +- **命令参数**: + + ```bash + /mxnet/mxnet/example/image-classification/train_mnist.py --num-epochs 10 --num-layers 2 --kv-store dist_device_sync --gpus 0 + ``` + + **说明**: + + - `/mxnet/mxnet/example/image-classification/train_mnist.py`:MXNet 提供的图像分类示例脚本。 + - `--num-epochs 10`:训练轮数为 10。 + - `--num-layers 2`:模型的层数为 2。 + - `--kv-store dist_device_sync`:使用分布式设备同步模式。 + - `--gpus 0`:使用 GPU 进行加速。 + +#### 资源配置 + +- **任务副本数**:3(包括 Scheduler、Server 和 Worker) +- **各角色资源请求**: + - **Scheduler**(调度器): + - **副本数**:1 + - **资源请求**: + - CPU:2 核 + - 内存:4 GiB + - GPU:1 块 + - **Server**(参数服务器): + - **副本数**:1 + - **资源请求**: + - CPU:2 核 + - 内存:4 GiB + - GPU:1 块 + - **Worker**(工作节点): + - **副本数**:1 + - **资源请求**: + - CPU:2 核 + - 内存:4 GiB + - GPU:1 块 + +#### 完整的 MXJob 配置示例 + +以下是分布式 MXJob 的 YAML 配置: + +```yaml +apiVersion: "kubeflow.org/v1" +kind: "MXJob" +metadata: + name: "mxnet-job" +spec: + jobMode: MXTrain + mxReplicaSpecs: + Scheduler: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi + Server: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi + Worker: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + command: ["python3"] + args: + [ + "/mxnet/mxnet/example/image-classification/train_mnist.py", + "--num-epochs", + "10", + "--num-layers", + "2", + "--kv-store", + "dist_device_sync", + "--gpus", + "0", + ] + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi +``` + +**配置解析**: + +- **Scheduler(调度器)**:负责协调集群中各节点的任务调度。 +- **Server(参数服务器)**:用于存储和更新模型参数,实现分布式参数同步。 +- **Worker(工作节点)**:实际执行训练任务。 +- **资源配置**:为各角色分配适当的资源,确保任务顺利运行。 + +#### 设置任务副本数 + +在创建 MXNet 分布式任务时,需要根据 `mxReplicaSpecs` 中配置的副本数,正确设置 **任务副本数**。 + +- **总副本数** = Scheduler 副本数 + Server 副本数 + Worker 副本数 +- 本示例中: + - Scheduler 副本数:1 + - Server 副本数:1 + - Worker 副本数:1 + - **总副本数**:1 + 1 + 1 = 3 + +因此,在任务配置中,需要将 **任务副本数** 设置为 **3**。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 MXNet 分布式任务。 + +#### 查看运行结果 + +进入 **任务详情** 页面,查看任务的运行状态和资源使用情况。您可以查看每个角色(Scheduler、Server、Worker)的日志输出。 + +**示例输出**: + +```bash +INFO:root:Epoch[0] Batch [50] Speed: 1000 samples/sec accuracy=0.85 +INFO:root:Epoch[0] Batch [100] Speed: 1200 samples/sec accuracy=0.87 +... +INFO:root:Epoch[9] Batch [100] Speed: 1300 samples/sec accuracy=0.98 +Training completed. +``` + +这表示 MXNet 分布式任务成功运行,模型训练完成。 + +--- + +## 小结 + +通过本教程,您学习了如何在 AI Lab 平台上创建和运行 MXNet 的单机和分布式任务。我们详细介绍了 MXJob 的配置方式,以及如何在任务中指定运行的命令和资源需求。希望本教程对您有所帮助,如有任何问题,请参考平台提供的其他文档或联系技术支持。 + +--- + +## 附录 + +- **注意事项**: + - 确保您使用的镜像包含所需的 MXNet 版本和依赖。 + - 根据实际需求调整资源配置,避免资源不足或浪费。 + - 如需使用自定义的训练脚本,请修改启动命令和参数。 + +- **参考文档**: + - [MXNet 官方文档](https://mxnet.apache.org/) + - [Kubeflow MXJob 指南](https://v1-8-branch.kubeflow.org/docs/components/training/mxnet/) diff --git a/docs/zh/docs/admin/baize/developer/jobs/paddle.md b/docs/zh/docs/admin/baize/developer/jobs/paddle.md new file mode 100644 index 0000000..9d5fd3c --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/paddle.md @@ -0,0 +1,235 @@ +# PaddlePaddle 任务 + +PaddlePaddle(飞桨)是百度开源的深度学习平台,支持丰富的神经网络模型和分布式训练方式。PaddlePaddle 任务可以通过单机或分布式模式进行训练。在 AI Lab 平台中,我们提供了对 PaddlePaddle 任务的支持,您可以通过界面化操作,快速创建 PaddlePaddle 任务,进行模型训练。 + +本教程将指导您如何在 AI Lab 平台上创建和运行 PaddlePaddle 的单机和分布式任务。 + +## 任务配置介绍 + +- **任务类型**:`PaddlePaddle`,支持单机和分布式两种模式。 +- **运行环境**:选择包含 PaddlePaddle 框架的镜像,或在任务中安装必要的依赖。 + +## 任务运行环境 + +我们使用 `registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-cpu` 镜像作为任务的基础运行环境。该镜像预装了 PaddlePaddle 框架,适用于 CPU 计算。如果需要使用 GPU,请选择对应的 GPU 版本镜像。 + +> **注意**:了解如何创建和管理环境,请参考 [环境列表](../dataset/environments.md)。 + +## 创建 PaddlePaddle 任务 + +![paddle](../../images/paddle_job.png) + +### PaddlePaddle 单机训练任务 + +#### 创建步骤 + +1. **登录平台**:登录 AI Lab 平台,点击左侧导航栏中的 **任务中心**,进入 **训练任务** 页面。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:在弹出的窗口中,选择任务类型为 `PaddlePaddle`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “PaddlePaddle 单机训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据您的需求,配置任务的运行参数、镜像、资源等信息。 + +#### 运行参数 + +- **启动命令**:`python` +- **命令参数**: + + ```bash + -m paddle.distributed.launch run_check + ``` + + **说明**: + + - `-m paddle.distributed.launch`:使用 PaddlePaddle 提供的分布式启动模块,即使在单机模式下也可以使用,方便将来迁移到分布式。 + - `run_check`:PaddlePaddle 提供的测试脚本,用于检查分布式环境是否正常。 + +#### 资源配置 + +- **副本数**:1(单机任务) +- **资源请求**: + - **CPU**:根据需求设置,建议至少 1 核 + - **内存**:根据需求设置,建议至少 2 GiB + - **GPU**:如果需要使用 GPU,选择 GPU 版本的镜像,并分配相应的 GPU 资源 + +#### 完整的 PaddleJob 配置示例 + +以下是单机 PaddleJob 的 YAML 配置: + +```yaml +apiVersion: kubeflow.org/v1 +kind: PaddleJob +metadata: + name: paddle-simple-cpu + namespace: kubeflow +spec: + paddleReplicaSpecs: + Worker: + replicas: 1 + restartPolicy: OnFailure + template: + spec: + containers: + - name: paddle + image: registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-cpu + command: + [ + 'python', + '-m', + 'paddle.distributed.launch', + 'run_check', + ] +``` + +**配置解析**: + +- `apiVersion` 和 `kind`:指定资源的 API 版本和类型,这里是 `PaddleJob`。 +- `metadata`:元数据,包括任务名称和命名空间。 +- `spec`:任务的详细配置。 + - `paddleReplicaSpecs`:PaddlePaddle 任务的副本配置。 + - `Worker`:指定工作节点的配置。 + - `replicas`:副本数,这里为 1,表示单机训练。 + - `restartPolicy`:重启策略,设为 `OnFailure`,表示任务失败时自动重启。 + - `template`:Pod 模板,定义容器的运行环境和资源。 + - `containers`:容器列表。 + - `name`:容器名称。 + - `image`:使用的镜像。 + - `command`:启动命令和参数。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 PaddlePaddle 单机任务。 + +#### 查看运行结果 + +任务提交成功后,您可以进入 **任务详情** 页面,查看资源的使用情况和任务的运行状态。从右上角进入 **工作负载详情**,可以查看运行过程中的日志输出。 + +**示例输出**: + +```bash +run check success, PaddlePaddle is installed correctly on this node :) +``` + +这表示 PaddlePaddle 单机任务成功运行,环境配置正常。 + +--- + +### PaddlePaddle 分布式训练任务 + +在分布式模式下,PaddlePaddle 任务可以使用多台计算节点共同完成训练,提高训练效率。 + +#### 创建步骤 + +1. **登录平台**:同上。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:选择任务类型为 `PaddlePaddle`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “PaddlePaddle 分布式训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据需求,配置运行参数、镜像、资源等。 + +#### 运行参数 + +- **启动命令**:`python` +- **命令参数**: + + ```bash + -m paddle.distributed.launch train.py --epochs=10 + ``` + + **说明**: + + - `-m paddle.distributed.launch`:使用 PaddlePaddle 提供的分布式启动模块。 + - `train.py`:您的训练脚本,需要放在镜像中或挂载到容器内。 + - `--epochs=10`:训练的轮数,这里设置为 10。 + +#### 资源配置 + +- **任务副本数**:根据 `Worker` 副本数设置,这里为 2。 +- **资源请求**: + - **CPU**:根据需求设置,建议至少 1 核 + - **内存**:根据需求设置,建议至少 2 GiB + - **GPU**:如果需要使用 GPU,选择 GPU 版本的镜像,并分配相应的 GPU 资源 + +#### 完整的 PaddleJob 配置示例 + +以下是分布式 PaddleJob 的 YAML 配置: + +```yaml +apiVersion: kubeflow.org/v1 +kind: PaddleJob +metadata: + name: paddle-distributed-job + namespace: kubeflow +spec: + paddleReplicaSpecs: + Worker: + replicas: 2 + restartPolicy: OnFailure + template: + spec: + containers: + - name: paddle + image: registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-cpu + command: + [ + 'python', + '-m', + 'paddle.distributed.launch', + 'train.py', + ] + args: + - '--epochs=10' +``` + +**配置解析**: + +- `Worker`: + - `replicas`:副本数,设置为 2,表示使用 2 个工作节点进行分布式训练。 + - 其他配置与单机模式类似。 + +#### 设置任务副本数 + +在创建 PaddlePaddle 分布式任务时,需要根据 `paddleReplicaSpecs` 中配置的副本数,正确设置 **任务副本数**。 + +- **总副本数** = `Worker` 副本数 +- 本示例中: + - `Worker` 副本数:2 + - **总副本数**:2 + +因此,在任务配置中,需要将 **任务副本数** 设置为 **2**。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 PaddlePaddle 分布式任务。 + +#### 查看运行结果 + +进入 **任务详情** 页面,查看任务的运行状态和资源使用情况。您可以查看每个工作节点的日志输出,确认分布式训练是否正常运行。 + +**示例输出**: + +```bash +Worker 0: Epoch 1, Batch 100, Loss 0.5 +Worker 1: Epoch 1, Batch 100, Loss 0.6 +... +Training completed. +``` + +这表示 PaddlePaddle 分布式任务成功运行,模型训练完成。 + +--- + +## 小结 + +通过本教程,您学习了如何在 AI Lab 平台上创建和运行 PaddlePaddle 的单机和分布式任务。我们详细介绍了 PaddleJob 的配置方式,以及如何在任务中指定运行的命令和资源需求。希望本教程对您有所帮助,如有任何问题,请参考平台提供的其他文档或联系技术支持。 + +--- + +## 附录 + +- **注意事项**: + - **训练脚本**:确保 `train.py`(或其他训练脚本)在容器内存在。您可以通过自定义镜像、挂载持久化存储等方式将脚本放入容器。 + - **镜像选择**:根据您的需求选择合适的镜像,例如使用 GPU 时选择 `paddle:2.4.0rc0-gpu` 等。 + - **参数调整**:可以通过修改 `command` 和 `args` 来传递不同的训练参数。 + +- **参考文档**: + - [PaddlePaddle 官方文档](https://www.paddlepaddle.org.cn/documentation/docs/zh/2.6/guides/index_cn.html) + - [Kubeflow PaddleJob 指南](https://www.kubeflow.org/docs/components/training/user-guides/paddle/) diff --git a/docs/zh/docs/admin/baize/developer/jobs/pytorch.md b/docs/zh/docs/admin/baize/developer/jobs/pytorch.md new file mode 100644 index 0000000..8667d6d --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/pytorch.md @@ -0,0 +1,227 @@ +# Pytorch 任务 + +Pytorch 是一个开源的深度学习框架,它提供了一个灵活的训练和部署环境。 +Pytorch 任务是一个使用 Pytorch 框架的任务。 + +在 AI Lab 中,我们提供了 Pytorch 任务支持和适配,您可以通过界面化操作, +快速创建 Pytorch 任务,进行模型训练。 + +## 任务配置介绍 + +- 任务类型同时支持 `Pytorch 单机` 和 `Pytorch 分布式` 两种模式。 +- 运行镜像内已经默认支持 Pytorch 框架,无需额外安装。 + +## 任务运行环境 + +在这里我们使用 `baize-notebook` 基础镜像 和 `关联环境` 的方式来作为任务基础运行环境。 + +> 了解如何创建环境,请参考 [环境列表](../dataset/environments.md)。 + +## 创建任务 + +### Pytorch 单机任务 + +![Pytorch 单机任务](../../images/job05.png) + +1. 登录 AI Lab 平台,点击左侧导航栏中的 **任务中心** ,进入 **训练任务** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Pytorch 单机`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 + +```python +import torch +import torch.nn as nn +import torch.optim as optim + +# 定义一个简单的神经网络 +class SimpleNet(nn.Module): + def __init__(self): + super(SimpleNet, self).__init__() + self.fc = nn.Linear(10, 1) + + def forward(self, x): + return self.fc(x) + +# 创建模型、损失函数和优化器 +model = SimpleNet() +criterion = nn.MSELoss() +optimizer = optim.SGD(model.parameters(), lr=0.01) + +# 生成一些随机数据 +x = torch.randn(100, 10) +y = torch.randn(100, 1) + +# 训练模型 +for epoch in range(100): + # 前向传播 + outputs = model(x) + loss = criterion(outputs, y) + + # 反向传播和优化 + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if (epoch + 1) % 10 == 0: + print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}') + +print('Training finished.') +``` + +#### 运行结果 + +任务提交成功,我们可以进入任务详情查看到资源的使用情况,从右上角去往 **工作负载详情** ,可以查看训练过程中的日志输出 + +```bash +[HAMI-core Warn(1:140244541377408:utils.c:183)]: get default cuda from (null) +[HAMI-core Msg(1:140244541377408:libvgpu.c:855)]: Initialized +Epoch [10/100], Loss: 1.1248 +Epoch [20/100], Loss: 1.0486 +Epoch [30/100], Loss: 0.9969 +Epoch [40/100], Loss: 0.9611 +Epoch [50/100], Loss: 0.9360 +Epoch [60/100], Loss: 0.9182 +Epoch [70/100], Loss: 0.9053 +Epoch [80/100], Loss: 0.8960 +Epoch [90/100], Loss: 0.8891 +Epoch [100/100], Loss: 0.8841 +Training finished. +[HAMI-core Msg(1:140244541377408:multiprocess_memory_limit.c:468)]: Calling exit handler 1 +``` + +### Pytorch 分布式任务 + +1. 登录 AI Lab 平台,点击左侧导航栏中的 **任务中心** ,进入 **任务列表** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Pytorch 分布式`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 + +```python +import os +import torch +import torch.distributed as dist +import torch.nn as nn +import torch.optim as optim +from torch.nn.parallel import DistributedDataParallel as DDP + +class SimpleModel(nn.Module): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = nn.Linear(10, 1) + + def forward(self, x): + return self.fc(x) + +def train(): + # 打印环境信息 + print(f'PyTorch version: {torch.__version__}') + print(f'CUDA available: {torch.cuda.is_available()}') + if torch.cuda.is_available(): + print(f'CUDA version: {torch.version.cuda}') + print(f'CUDA device count: {torch.cuda.device_count()}') + + rank = int(os.environ.get('RANK', '0')) + world_size = int(os.environ.get('WORLD_SIZE', '1')) + + print(f'Rank: {rank}, World Size: {world_size}') + + # 初始化分布式环境 + try: + if world_size > 1: + dist.init_process_group('nccl') + print('Distributed process group initialized successfully') + else: + print('Running in non-distributed mode') + except Exception as e: + print(f'Error initializing process group: {e}') + return + + # 设置设备 + try: + if torch.cuda.is_available(): + device = torch.device(f'cuda:{rank % torch.cuda.device_count()}') + print(f'Using CUDA device: {device}') + else: + device = torch.device('cpu') + print('CUDA not available, using CPU') + except Exception as e: + print(f'Error setting device: {e}') + device = torch.device('cpu') + print('Falling back to CPU') + + try: + model = SimpleModel().to(device) + print('Model moved to device successfully') + except Exception as e: + print(f'Error moving model to device: {e}') + return + + try: + if world_size > 1: + ddp_model = DDP(model, device_ids=[rank % torch.cuda.device_count()] if torch.cuda.is_available() else None) + print('DDP model created successfully') + else: + ddp_model = model + print('Using non-distributed model') + except Exception as e: + print(f'Error creating DDP model: {e}') + return + + loss_fn = nn.MSELoss() + optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) + + # 生成一些随机数据 + try: + data = torch.randn(100, 10, device=device) + labels = torch.randn(100, 1, device=device) + print('Data generated and moved to device successfully') + except Exception as e: + print(f'Error generating or moving data to device: {e}') + return + + for epoch in range(10): + try: + ddp_model.train() + outputs = ddp_model(data) + loss = loss_fn(outputs, labels) + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if rank == 0: + print(f'Epoch {epoch}, Loss: {loss.item():.4f}') + except Exception as e: + print(f'Error during training epoch {epoch}: {e}') + break + + if world_size > 1: + dist.destroy_process_group() + +if __name__ == '__main__': + train() +``` + +#### 任务副本数 + +注意 `Pytorch 分布式` 训练任务会创建一组 `Master` 和 `Worker` 的训练 Pod, +`Master` 负责协调训练任务,`Worker` 负责实际的训练工作。 + +!!! note + + 本次演示中:`Master` 副本数为 1,`Worker` 副本数为 2; + 所以我们需要在 **任务配置** 中设置副本数为 3,即 `Master` 副本数 + `Worker` 副本数。 + Pytorch 会自动调谐 `Master` 和 `Worker` 的角色。 + +#### 运行结果 + +同样,我们可以进入任务详情,查看资源的使用情况,以及每个 Pod 的日志输出。 diff --git a/docs/zh/docs/admin/baize/developer/jobs/tensorboard.md b/docs/zh/docs/admin/baize/developer/jobs/tensorboard.md new file mode 100644 index 0000000..f1bc240 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/tensorboard.md @@ -0,0 +1,122 @@ +# 任务分析介绍 + +在 AI Lab 模块中,提供了模型开发过程重要的可视化分析工具,用于展示机器学习模型的训练过程和结果。 +本文将介绍 任务分析(Tensorboard)的基本概念、在 AI Lab 系统中的使用方法,以及如何配置数据集的日志内容。 + +!!! note + + Tensorboard 是 TensorFlow 提供的一个可视化工具,用于展示机器学习模型的训练过程和结果。 + 它可以帮助开发者更直观地理解模型的训练动态,分析模型性能,调试模型问题等。 + +![Tensorboard](../../images/tensorboard.png) + +Tensorboard 在模型开发过程中的作用及优势: + +- **可视化训练过程**:通过图表展示训练和验证的损失、精度等指标,帮助开发者直观地观察模型的训练效果。 +- **调试和优化模型**:通过查看不同层的权重、梯度分布等,帮助开发者发现和修正模型中的问题。 +- **对比不同实验**:可以同时展示多个实验的结果,方便开发者对比不同模型和超参数配置的效果。 +- **追踪训练数据**:记录训练过程中使用的数据集和参数,确保实验的可复现性。 + +## 如何创建 Tensorboard + +在 AI Lab 系统中,我们提供了便捷的方式来创建和管理 Tensorboard。以下是具体步骤: + +### 在创建时 Notebook 启用 Tensorboard + +1. **创建 Notebook**:在 AI Lab 平台上创建一个新的 Notebook。 +2. **启用 Tensorboard**:在创建 Notebook 的页面中,启用 **Tensorboard** 选项,并指定数据集和日志路径。 + + ![Tensorboard](../../images/tensorboard-03.png) + +### 在分布式任务创建及完成后启用 Tensorboard + +1. **创建分布式任务**:在 AI Lab 平台上创建一个新的分布式训练任务。 +2. **配置 Tensorboard**:在任务配置页面中,启用 **Tensorboard** 选项,并指定数据集和日志路径。 +3. **任务完成后查看 Tensorboard**:任务完成后,可以在任务详情页面中查看 Tensorboard 的链接,点击链接即可查看训练过程的可视化结果。 + + ![Tensorboard](../../images/tensorboard-02.png) + +### 在 Notebook 中直接引用 Tensorboard + +在 Notebook 中,可以通过代码直接启动 Tensorboard。以下是一个示例代码: + +```python +# 导入必要的库 +import tensorflow as tf +import datetime + +# 定义日志目录 +log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + +# 创建 Tensorboard 回调 +tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1) + +# 构建并编译模型 +model = tf.keras.models.Sequential([ + tf.keras.layers.Flatten(input_shape=(28, 28)), + tf.keras.layers.Dense(512, activation='relu'), + tf.keras.layers.Dropout(0.2), + tf.keras.layers.Dense(10, activation='softmax') +]) + +model.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + +# 训练模型并启用 Tensorboard 回调 +model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test), callbacks=[tensorboard_callback]) +``` + +## 如何配置数据集的日志内容 + +在使用 Tensorboard 时,可以记录和配置不同的数据集和日志内容。以下是一些常见的配置方式: + +### 配置训练和验证数据集的日志 + +在训练模型时,可以通过 TensorFlow 的 `tf.summary` API 来记录训练和验证数据集的日志。以下是一个示例代码: + +```python +# 导入必要的库 +import tensorflow as tf + +# 创建日志目录 +train_log_dir = 'logs/gradient_tape/train' +val_log_dir = 'logs/gradient_tape/val' +train_summary_writer = tf.summary.create_file_writer(train_log_dir) +val_summary_writer = tf.summary.create_file_writer(val_log_dir) + +# 训练模型并记录日志 +for epoch in range(EPOCHS): + for (x_train, y_train) in train_dataset: + # 训练步骤 + train_step(x_train, y_train) + with train_summary_writer.as_default(): + tf.summary.scalar('loss', train_loss.result(), step=epoch) + tf.summary.scalar('accuracy', train_accuracy.result(), step=epoch) + + for (x_val, y_val) in val_dataset: + # 验证步骤 + val_step(x_val, y_val) + with val_summary_writer.as_default(): + tf.summary.scalar('loss', val_loss.result(), step=epoch) + tf.summary.scalar('accuracy', val_accuracy.result(), step=epoch) +``` + +### 配置自定义日志 + +除了训练和验证数据集的日志外,还可以记录其他自定义的日志内容,例如学习率、梯度分布等。以下是一个示例代码: + +```python +# 记录自定义日志 +with train_summary_writer.as_default(): + tf.summary.scalar('learning_rate', learning_rate, step=epoch) + tf.summary.histogram('gradients', gradients, step=epoch) +``` + +## Tensorboard 管理 + +在 AI Lab 中,通过各种方式创建出来的 Tensorboard 会统一展示在任务分析的页面中,方便用户查看和管理。 + +![Tensorboard](../../images/tensorboard-01.png) + +用户可以在任务分析页面中查看 Tensorboard 的链接、状态、创建时间等信息,并通过链接直接访问 Tensorboard 的可视化结果。 diff --git a/docs/zh/docs/admin/baize/developer/jobs/tensorflow.md b/docs/zh/docs/admin/baize/developer/jobs/tensorflow.md new file mode 100644 index 0000000..af13dc8 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/tensorflow.md @@ -0,0 +1,160 @@ +# Tensorflow 任务 + +Tensorflow 是除了 Pytorch 另外一个非常活跃的开源的深度学习框架,它提供了一个灵活的训练和部署环境。 + +在 AI Lab 中,我们同样提供了 Tensorflow 框架的支持和适配,您可以通过界面化操作,快速创建 Tensorflow 任务,进行模型训练。 + +## 任务配置介绍 + +- 任务类型同时支持 `Tensorflow 单机` 和 `Tensorflow 分布式` 两种模式。 +- 运行镜像内已经默认支持 Tensorflow 框架,无需额外安装。 + +## 任务运行环境 + +在这里我们使用 `baize-notebook` 基础镜像 和 `关联环境` 的方式来作为任务基础运行环境。 + +> 了解如何创建环境,请参考 [环境列表](../dataset/environments.md)。 + +## 创建任务 + +### 示例 TFJob 单机任务 + +![Tensorflow 单机任务](../../images/job06.png) + +1. 登录 AI Lab 平台,点击左侧导航栏中的 **任务中心** ,进入 **训练任务** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Tensorflow 单机`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 提前预热代码仓库 + +使用 **AI Lab** -> **数据集列表** ,创建一个数据集,并将远端 Github 的代码拉取到数据集中, +这样在创建任务时,可以直接选择数据集,将代码挂载到任务中。 + +演示代码仓库地址:[https://github.com/d-run/training-sample-code/](https://github.com/d-run/training-sample-code/) + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 `python /code/tensorflow/tf-single.py` + +```python +""" + pip install tensorflow numpy +""" + +import tensorflow as tf +import numpy as np + +# 创建一些随机数据 +x = np.random.rand(100, 1) +y = 2 * x + 1 + np.random.rand(100, 1) * 0.1 + +# 创建一个简单的模型 +model = tf.keras.Sequential([ + tf.keras.layers.Dense(1, input_shape=(1,)) +]) + +# 编译模型 +model.compile(optimizer='adam', loss='mse') + +# 训练模型,将 epochs 改为 10 +history = model.fit(x, y, epochs=10, verbose=1) + +# 打印最终损失 +print('Final loss: {' + str(history.history['loss'][-1]) +'}') + +# 使用模型进行预测 +test_x = np.array([[0.5]]) +prediction = model.predict(test_x) +print(f'Prediction for x=0.5: {prediction[0][0]}') +``` + +#### 运行结果 + +任务提交成功后,可以进入任务详情查看到资源的使用情况,从右上角去往 **工作负载详情** ,可以查看训练过程中的日志输出。 + +### TFJob 分布式任务 + +1. 登录 **AI Lab** ,点击左侧导航栏中的 **任务中心** ,进入 **任务列表** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Tensorflow 分布式`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 示例任务介绍 + +![Tensorflow 单机任务](../../images/job07.png) + +本次包含了三种角色:`Chief`、`Worker` 和 `Parameter Server (PS)`。 + +- Chief: 主要负责协调训练过程和模型检查点的保存。 +- Worker: 执行实际的模型训练。 +- PS: 在异步训练中用于存储和更新模型参数。 + +为不同的角色分配了不同的资源。`Chief` 和 `Worker` 使用 GPU,而 `PS` 使用 CPU 和较大的内存。 + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 `python /code/tensorflow/tensorflow-distributed.py` + +```python +import os +import json +import tensorflow as tf + +class SimpleModel(tf.keras.Model): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = tf.keras.layers.Dense(1, input_shape=(10,)) + + def call(self, x): + return self.fc(x) + +def train(): + # 打印环境信息 + print(f"TensorFlow version: {tf.__version__}") + print(f"GPU available: {tf.test.is_gpu_available()}") + if tf.test.is_gpu_available(): + print(f"GPU device count: {len(tf.config.list_physical_devices('GPU'))}") + + # 获取分布式训练信息 + tf_config = json.loads(os.environ.get('TF_CONFIG') or '{}') + task_type = tf_config.get('task', {}).get('type') + task_id = tf_config.get('task', {}).get('index') + + print(f"Task type: {task_type}, Task ID: {task_id}") + + # 设置分布式策略 + strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy() + + with strategy.scope(): + model = SimpleModel() + loss_fn = tf.keras.losses.MeanSquaredError() + optimizer = tf.keras.optimizers.SGD(learning_rate=0.001) + + # 生成一些随机数据 + data = tf.random.normal((100, 10)) + labels = tf.random.normal((100, 1)) + + @tf.function + def train_step(inputs, labels): + with tf.GradientTape() as tape: + predictions = model(inputs) + loss = loss_fn(labels, predictions) + gradients = tape.gradient(loss, model.trainable_variables) + optimizer.apply_gradients(zip(gradients, model.trainable_variables)) + return loss + + for epoch in range(10): + loss = train_step(data, labels) + if task_type == 'chief': + print(f'Epoch {epoch}, Loss: {loss.numpy():.4f}') + +if __name__ == '__main__': + train() +``` + +#### 运行结果 + +同样,我们可以进入任务详情,查看资源的使用情况,以及每个 Pod 的日志输出。 diff --git a/docs/zh/docs/admin/baize/developer/jobs/view.md b/docs/zh/docs/admin/baize/developer/jobs/view.md new file mode 100644 index 0000000..af4df1f --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/jobs/view.md @@ -0,0 +1,207 @@ +# 查看任务(Job)工作负载 + +任务创建好后,都会显示在训练任务列表中。 + +1. 在训练训练任务列表中,点击某个任务右侧的 **┇** -> **任务负载详情** 。 + + ![点击菜单项](../../images/view-wl01.png) + +1. 出现一个弹窗选择要查看哪个 Pod 后,点击 **进入** 。 + + ![弹窗进入](../../images/view-wl02.png) + +1. 跳转到容器管理界面,可以查看容器的工作状态、标签与注解以及发生的事件。 + + ![查看详情](../../images/view-wl03.png) + +1. 你还可以查看当前 Pod 最近一段时间的详细日志。 + 此处默认展示 100 行日志,如果要查看更详细的日志活下载日志,请点击顶部的蓝色 **可观测性** 文字。 + + ![日志](../../images/view-wl04.png) + +1. 当然你还可以通过右上角的 **...** ,查看当前 Pod 的 YAML、上传和下载文件。 + 以下是一个 Pod 的 YAML 示例。 + +```yaml +kind: Pod +apiVersion: v1 +metadata: + name: neko-tensorboard-job-test-202404181843-skxivllb-worker-0 + namespace: default + uid: ddedb6ff-c278-47eb-ae1e-0de9b7c62f8c + resourceVersion: '41092552' + creationTimestamp: '2024-04-18T10:43:36Z' + labels: + training.kubeflow.org/job-name: neko-tensorboard-job-test-202404181843-skxivllb + training.kubeflow.org/operator-name: pytorchjob-controller + training.kubeflow.org/replica-index: '0' + training.kubeflow.org/replica-type: worker + annotations: + cni.projectcalico.org/containerID: 0cfbb9af257d5e69027c603c6cb2d3890a17c4ae1a145748d5aef73a10d7fbe1 + cni.projectcalico.org/podIP: '' + cni.projectcalico.org/podIPs: '' + hami.io/bind-phase: success + hami.io/bind-time: '1713437016' + hami.io/vgpu-devices-allocated: GPU-29d5fa0d-935b-2966-aff8-483a174d61d1,NVIDIA,1024,20:; + hami.io/vgpu-devices-to-allocate: ; + hami.io/vgpu-node: worker-a800-1 + hami.io/vgpu-time: '1713437016' + k8s.v1.cni.cncf.io/network-status: |- + [{ + "name": "kube-system/calico", + "ips": [ + "10.233.97.184" + ], + "default": true, + "dns": {} + }] + k8s.v1.cni.cncf.io/networks-status: |- + [{ + "name": "kube-system/calico", + "ips": [ + "10.233.97.184" + ], + "default": true, + "dns": {} + }] + ownerReferences: + - apiVersion: kubeflow.org/v1 + kind: PyTorchJob + name: neko-tensorboard-job-test-202404181843-skxivllb + uid: e5a8b05d-1f03-4717-8e1c-4ec928014b7b + controller: true + blockOwnerDeletion: true +spec: + volumes: + - name: 0-dataset-pytorch-examples + persistentVolumeClaim: + claimName: pytorch-examples + - name: kube-api-access-wh9rh + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + defaultMode: 420 + containers: + - name: pytorch + image: m.daocloud.io/docker.io/pytorch/pytorch + command: + - bash + args: + - '-c' + - >- + ls -la /root && which pip && pip install pytorch_lightning tensorboard + && python /root/Git/pytorch/examples/mnist/main.py + ports: + - name: pytorchjob-port + containerPort: 23456 + protocol: TCP + env: + - name: PYTHONUNBUFFERED + value: '1' + - name: PET_NNODES + value: '1' + resources: + limits: + cpu: '4' + memory: 8Gi + nvidia.com/gpucores: '20' + nvidia.com/gpumem: '1024' + nvidia.com/vgpu: '1' + requests: + cpu: '4' + memory: 8Gi + nvidia.com/gpucores: '20' + nvidia.com/gpumem: '1024' + nvidia.com/vgpu: '1' + volumeMounts: + - name: 0-dataset-pytorch-examples + mountPath: /root/Git/pytorch/examples + - name: kube-api-access-wh9rh + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + restartPolicy: Never + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + nodeName: worker-a800-1 + securityContext: {} + affinity: {} + schedulerName: hami-scheduler + tolerations: + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + priorityClassName: baize-high-priority + priority: 100000 + enableServiceLinks: true + preemptionPolicy: PreemptLowerPriority +status: + phase: Succeeded + conditions: + - type: Initialized + status: 'True' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:43:36Z' + reason: PodCompleted + - type: Ready + status: 'False' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:46:34Z' + reason: PodCompleted + - type: ContainersReady + status: 'False' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:46:34Z' + reason: PodCompleted + - type: PodScheduled + status: 'True' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:43:36Z' + hostIP: 10.20.100.211 + podIP: 10.233.97.184 + podIPs: + - ip: 10.233.97.184 + startTime: '2024-04-18T10:43:36Z' + containerStatuses: + - name: pytorch + state: + terminated: + exitCode: 0 + reason: Completed + startedAt: '2024-04-18T10:43:39Z' + finishedAt: '2024-04-18T10:46:34Z' + containerID: >- + containerd://09010214bcf3315e81d38fba50de3943c9d2b48f50a6cc2e83f8ef0e5c6eeec1 + lastState: {} + ready: false + restartCount: 0 + image: m.daocloud.io/docker.io/pytorch/pytorch:latest + imageID: >- + m.daocloud.io/docker.io/pytorch/pytorch@sha256:11691e035a3651d25a87116b4f6adc113a27a29d8f5a6a583f8569e0ee5ff897 + containerID: >- + containerd://09010214bcf3315e81d38fba50de3943c9d2b48f50a6cc2e83f8ef0e5c6eeec1 + started: false + qosClass: Guaranteed +``` diff --git a/docs/zh/docs/admin/baize/developer/notebooks/baizectl.md b/docs/zh/docs/admin/baize/developer/notebooks/baizectl.md new file mode 100644 index 0000000..db313c8 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/baizectl.md @@ -0,0 +1,641 @@ +# baizectl 命令行工具使用指南 + +`baizectl` 是在 AI Lab 模块中专门服务于模型开发者与数据科学家们使用的命令行工具。 +它提供了一系列命令来帮助用户管理分布式训练作业、查看任务状态、管理数据集等操作,同时支持连接 +Kubernetes 工作集群和算丰 AI 算力平台工作空间,帮助用户更高效地使用和管理 Kubernetes 平台资源。 + +## 安装 + +目前,`baizectl` 已经集成在 AI Lab 中。 +你在创建 Notebook 后,即可在 Notebook 中直接使用 `baizectl`。 + +--- + +## 快速上手 + +### 基本信息 + +`baizectl` 命令的基本格式如下: + +```bash +jovyan@19d0197587cc:/$ baizectl +AI platform management tool + +Usage: + baizectl [command] + +Available Commands: + completion Generate the autocompletion script for the specified shell + data Management datasets + help Help about any command + job Manage jobs + login Login to the platform + version Show cli version + +Flags: + --cluster string Cluster name to operate + -h, --help help for baizectl + --mode string Connection mode: auto, api, notebook (default "auto") + -n, --namespace string Namespace to use for the operation. If not set, the default Namespace will be used. + -s, --server string 算丰 AI 算力平台 access base url + --skip-tls-verify Skip TLS certificate verification + --token string 算丰 AI 算力平台 access token + -w, --workspace int32 Workspace ID to use for the operation + +Use "baizectl [command] --help" for more information about a command. +``` + +以上是 `baizectl` 的基本信息,用户可以通过 `baizectl --help` 查看帮助信息, +或者通过 `baizectl [command] --help` 查看具体命令的帮助信息。 + +### 查看版本信息 + +`baizectl` 支持通过 `version` 命令查看版本信息。 + +```bash +(base) jovyan@den-0:~$ baizectl version +baizectl version: v0.5.0, commit sha: ac0837c4 +``` + +### 命令格式 + +`baizectl` 命令的基本格式如下: + +```bash +baizectl [command] [flags] +``` + +其中,`[command]` 是具体的操作命令,如 `data`、`job` 等,`[flags]` 是可选的参数,用于指定操作的详细信息。 + +### 常用选项 + +- `--cluster string`:指定要操作的集群名称 +- `-h, --help`:显示帮助信息 +- `--mode string`:连接模式,可选值为 `auto`、`api`、`notebook`(默认值为 `auto`) +- `-n, --namespace string`:指定操作的命名空间。如果未设置,将使用默认命名空间 +- `-s, --server string`:算丰 AI 算力平台访问基础 URL +- `--skip-tls-verify`:跳过 TLS 证书验证 +- `--token string`:算丰 AI 算力平台访问令牌 +- `-w, --workspace int32`:指定操作的工作区 ID + +--- + +## 功能介绍 + +### 任务管理 + +baizectl 提供了一系列命令来管理分布式训练任务,包含了查看任务列表,提交任务、查看日志、重启任务、删除任务等。 + +```bash +jovyan@19d0197587cc:/$ baizectl job +Manage jobs + +Usage: + baizectl job [command] + +Available Commands: + delete Delete a job + logs Show logs of a job + ls List jobs + restart restart a job + submit Submit a job + +Flags: + -h, --help help for job + -o, --output string Output format. One of: table, json, yaml (default "table") + --page int Page number (default 1) + --page-size int Page size (default -1) + --search string Search query + --sort string Sort order + --truncate int Truncate output to the given length, 0 means no truncation (default 50) + +Use "baizectl job [command] --help" for more information about a command. +``` + +#### 提交训练任务 + +`baizectl` 支持使用 `submit` 命令提交一个任务,用户可以通过 `baizectl job submit --help` 查看详细信息。 + +```bash +(base) jovyan@den-0:~$ baizectl job submit --help +Submit a job + +Usage: + baizectl job submit [flags] -- command ... + +Aliases: + submit, create + +Examples: +# Submit a job to run the command "torchrun python train.py" +baizectl job submit -- torchrun python train.py +# Submit a job with 2 workers(each pod use 4 gpus) to run the command "torchrun python train.py" and use the image "pytorch/pytorch:1.8.1-cuda11.1-cudnn8-runtime" +baizectl job submit --image pytorch/pytorch:1.8.1-cuda11.1-cudnn8-runtime --workers 2 --resources nvidia.com/gpu=4 -- torchrun python train.py +# Submit a tensorflow job to run the command "python train.py" +baizectl job submit --tensorflow -- python train.py + + +Flags: + --annotations stringArray The annotations of the job, the format is key=value + --auto-load-env It only takes effect when executed in Notebook, the environment variables of the current environment will be automatically read and set to the environment variables of the Job, the specific environment variables to be read can be specified using the BAIZE_MAPPING_ENVS environment variable, the default is PATH,CONDA_*,*PYTHON*,NCCL_*, if set to false, the environment variables of the current environment will not be read. (default true) + --commands stringArray The default command of the job + -d, --datasets stringArray The dataset bind to the job, the format is datasetName:mountPath, e.g. mnist:/data/mnist + -e, --envs stringArray The environment variables of the job, the format is key=value + -x, --from-notebook string Define whether to read the configuration of the current Notebook and directly create tasks, including images, resources, Dataset, etc. + auto: Automatically determine the mode according to the current environment. If the current environment is a Notebook, it will be set to notebook mode. + false: Do not read the configuration of the current Notebook. + true: Read the configuration of the current Notebook. (default "auto") + -h, --help help for submit + --image string The image of the job, it must be specified if fromNotebook is false. + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --labels stringArray The labels of the job, the format is key=value + --max-retries int32 number of retries before marking this job failed + --max-run-duration int Specifies the duration in seconds relative to the startTime that the job may be active before the system tries to terminate it + --name string The name of the job, if empty, the name will be generated automatically. + --paddle PaddlePaddle Job, has higher priority than --job-type + --priority string The priority of the job, current support baize-medium-priority, baize-low-priority, baize-high-priority + --pvcs stringArray The pvcs bind to the job, the format is pvcName:mountPath, e.g. mnist:/data/mnist + --pytorch Pytorch Job, has higher priority than --job-type + --queue string The queue to used + --requests-resources stringArray Similar to resources, but sets the resources of requests + --resources stringArray The resources of the job, it is a string in the format of cpu=1,memory=1Gi,nvidia.com/gpu=1, it will be set to the limits and requests of the container. + --restart-policy string The job restart policy (default "on-failure") + --runtime-envs baizectl data ls --runtime-env The runtime environment to use for the job, you can use baizectl data ls --runtime-env to get the runtime environment + --shm-size int32 The shared memory size of the job, default is 0, which means no shared memory, if set to more than 0, the job will use the shared memory, the unit is MiB + --tensorboard-log-dir string The tensorboard log directory, if set, the job will automatically start tensorboard, else not. The format is /path/to/log, you can use relative path in notebook. + --tensorflow Tensorflow Job, has higher priority than --job-type + --workers int The workers of the job, default is 1, which means single worker, if set to more than 1, the job will be distributed. (default 1) + --working-dir string The working directory of job container, if in notebook mode, the default is the directory of the current file +``` + +!!! note + + 提交任务的命令参数说明: + + - --name: 任务名称,如果为空,则会自动生成 + - --image: 镜像名称,必须指定 + - --priority: 任务优先级,支持 高=`baize-high-priority`、中=`baize-medium-priority`、低=`baize-low-priority` + - --resources: 任务资源,格式为 `cpu=1 memory=1Gi,nvidia.com/gpu=1` + - --workers: 任务工作节点数,默认为 1,当设置大于 1 时,任务将会分布式运行 + - --queue: 任务队列,需要提前创建队列资源 + - --working-dir: 工作目录,如果在 Notebook 模式下,会默认使用当前文件目录 + - --datasets: 数据集,格式为 `datasetName:mountPath`,例如 `mnist:/data/mnist` + - --shm-size: 共享内存大小,在分布式训练任务时,可以启用,表示使用共享内存,单位为 MiB + - --labels: 任务标签,格式为 `key=value` + - --max-retries: 最大重试次数,任务失败后重试次数,失败后会重启任务,默认不限制 + - --max-run-duration: 最大运行时间,任务运行时间超过指定时间后,会被系统终止,默认不限制 + - --restart-policy: 重启策略,支持 `on-failure`、`never`、`always`,默认为 `on-failure` + - --from-notebook: 是否从 Notebook 中读取配置,支持 `auto`、`true`、`false`,默认为 `auto` + +##### PyTorch 单机任务示例 + +提交训练任务示例,用户可以根据实际需求修改参数,以下为创建一个 PyTorch 任务的示例: + +```bash +baizectl job submit --name demojob-v2 -t PYTORCH \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --resources cpu=1,memory=1Gi \ + --workers 1 \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +##### PyTorch 分布式任务示例 + +提交训练任务示例,用户可以根据实际需求修改参数,以下为创建一个 PyTorch 任务的示例: + +```bash +baizectl job submit --name demojob-v2 -t PYTORCH \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --resources cpu=1,memory=1Gi \ + --workers 2 \ # 多任务副本会自动创建分布式任务 + --shm-size 1024 \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +##### Tensorflow 任务示例 + +使用 `-t` 参数指定任务类型,以下为创建一个 Tensorflow 任务的示例: + +```bash +baizectl job submit --name demojob-v2 -t TENSORFLOW \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --from-notebook auto \ + --workers 1 \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +也可以使用 `--job-type` 或者 `--tensorflow` 参数指定任务类型 + +##### Paddle 任务示例 + +```bash +baizectl job submit --name demojob-v2 -t PADDLE \ + --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --priority baize-high-priority \ + --queue default \ + --working-dir /data \ + --datasets fashion-mnist:/data/mnist \ + --labels job_type=pytorch \ + --max-retries 3 \ + --max-run-duration 60 \ + --restart-policy on-failure \ + -- sleep 1000 +``` + +#### 查看任务列表 + +`baizectl job` 支持通过 `ls` 命令查看任务列表,默认显示 `pytroch` 任务,用户可以通过 `-t` 指定任务类型。 + +```bash +(base) jovyan@den-0:~$ baizectl job ls # 默认查看 pytorch 任务 + NAME TYPE PHASE DURATION COMMAND + demong PYTORCH SUCCEEDED 1m2s sleep 60 + demo-sleep PYTORCH RUNNING 1h25m28s sleep 7200 +(base) jovyan@den-0:~$ baizectl job ls demo-sleep # 查看指定任务 + NAME TYPE PHASE DURATION COMMAND + demo-sleep PYTORCH RUNNING 1h25m28s sleep 7200 +(base) jovyan@den-0:~$ baizectl job ls -t TENSORFLOW # 查看 tensorflow 任务 + NAME TYPE PHASE DURATION COMMAND + demotfjob TENSORFLOW CREATED 0s sleep 1000 +``` + +任务列表默认情况下使用 `table` 作为展示形式,如果希望查看更多信息,可使用 `json` 或 `yaml` 格式展示,可以通过 `-o` 参数指定。 + +```bash +(base) jovyan@den-0:~$ baizectl job ls -t TENSORFLOW -o yaml +- baseConfig: + args: + - sleep + - "1000" + image: release.daocloud.io/baize/baize-notebook:v0.5.0 + labels: + app: den + podConfig: + affinity: {} + kubeEnvs: + - name: CONDA_EXE + value: /opt/conda/bin/conda + - name: CONDA_PREFIX + value: /opt/conda + - name: CONDA_PROMPT_MODIFIER + value: '(base) ' + - name: CONDA_SHLVL + value: "1" + - name: CONDA_DIR + value: /opt/conda + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_DEFAULT_ENV + value: base + - name: PATH + value: /opt/conda/bin:/opt/conda/condabin:/command:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + priorityClass: baize-high-priority + queue: default + creationTimestamp: "2024-06-16T07:47:27Z" + jobSpec: + runPolicy: + suspend: true + tfReplicaSpecs: + Worker: + replicas: 1 + restartPolicy: OnFailure + template: + metadata: + creationTimestamp: null + spec: + affinity: {} + containers: + - args: + - sleep + - "1000" + env: + - name: CONDA_EXE + value: /opt/conda/bin/conda + - name: CONDA_PREFIX + value: /opt/conda + - name: CONDA_PROMPT_MODIFIER + value: '(base) ' + - name: CONDA_SHLVL + value: "1" + - name: CONDA_DIR + value: /opt/conda + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_PYTHON_EXE + value: /opt/conda/bin/python + - name: CONDA_DEFAULT_ENV + value: base + - name: PATH + value: /opt/conda/bin:/opt/conda/condabin:/command:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + image: release.daocloud.io/baize/baize-notebook:v0.5.0 + name: tensorflow + resources: + limits: + memory: 1Gi + requests: + cpu: "1" + memory: 2Gi + workingDir: /home/jovyan + priorityClassName: baize-high-priority + name: demotfjob + namespace: ns-chuanjia-ndx + phase: CREATED + roleConfig: + TF_WORKER: + replicas: 1 + resources: + limits: + memory: 1Gi + requests: + cpu: "1" + memory: 2Gi + totalResources: + limits: + memory: "1073741824" + requests: + cpu: "1" + memory: "2147483648" + trainingConfig: + restartPolicy: RESTART_POLICY_ON_FAILURE + trainingMode: SINGLE + type: TENSORFLOW +``` + +#### 查看任务日志 + +`baizectl job` 支持使用 `logs` 命令查看任务日志,用户可以通过 `baizectl job logs --help` 查看详细信息。 + +```bash +(base) jovyan@den-0:~$ baizectl job logs --help +Show logs of a job + +Usage: + baizectl job logs [pod-name] [flags] + +Aliases: + logs, log + +Flags: + -f, --follow Specify if the logs should be streamed. + -h, --help help for logs + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --paddle PaddlePaddle Job, has higher priority than --job-type + --pytorch Pytorch Job, has higher priority than --job-type + --tail int Lines of recent log file to display. + --tensorflow Tensorflow Job, has higher priority than --job-type + --timestamps Show timestamps +``` + +!!! note + + - `--follow` 参数实时查看日志 + - `--tail` 参数指定查看日志的行数,默认为 50 行 + - `--timestamps` 参数显示时间戳 + +示例查看任务日志: + +```bash +(base) jovyan@den-0:~$ baizectl job log -t TENSORFLOW tf-sample-job-v2-202406161632-evgrbrhn -f +2024-06-16 08:33:06.083766: I tensorflow/core/util/port.cc:110] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`. +2024-06-16 08:33:06.086189: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used. +2024-06-16 08:33:06.132416: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used. +2024-06-16 08:33:06.132903: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations. +To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags. +2024-06-16 08:33:07.223046: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT +Model: "sequential" +_________________________________________________________________ + Layer (type) Output Shape Param # +================================================================= + Conv1 (Conv2D) (None, 13, 13, 8) 80 + + flatten (Flatten) (None, 1352) 0 + + Softmax (Dense) (None, 10) 13530 + +================================================================= +Total params: 13610 (53.16 KB) +Trainable params: 13610 (53.16 KB) +Non-trainable params: 0 (0.00 Byte) +... +``` + +#### 删除任务 + +`baizectl job` 支持使用 `delete` 命令删除任务,并且同时支持删除多个任务。 + +```bash +(base) jovyan@den-0:~$ baizectl job delete --help +Delete a job + +Usage: + baizectl job delete [flags] + +Aliases: + delete, del, remove, rm + +Flags: + -h, --help help for delete + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --paddle PaddlePaddle Job, has higher priority than --job-type + --pytorch Pytorch Job, has higher priority than --job-type + --tensorflow Tensorflow Job, has higher priority than --job-type +``` + +示例删除任务: + +```bash +(base) jovyan@den-0:~$ baizectl job ls + NAME TYPE PHASE DURATION COMMAND + demong PYTORCH SUCCEEDED 1m2s sleep 60 + demo-sleep PYTORCH RUNNING 1h20m51s sleep 7200 + demojob PYTORCH FAILED 16m46s sleep 1000 + demojob-v2 PYTORCH RUNNING 3m13s sleep 1000 + demojob-v3 PYTORCH CREATED 0s sleep 1000 +(base) jovyan@den-0:~$ baizectl job delete demojob # 删除单个任务 +Delete job demojob in ns-chuanjia-ndx successfully +(base) jovyan@den-0:~$ baizectl job delete demojob-v2 demojob-v3 # 删除多个任务 +Delete job demojob-v2 in ns-chuanjia-ndx successfully +Delete job demojob-v3 in ns-chuanjia-ndx successfully +``` + +#### 重启任务 + +`baizectl job` 支持使用 `restart` 命令重启任务,用户可以通过 `baizectl job restart --help` 查看详细信息。 + +```bash +(base) jovyan@den-0:~$ baizectl job restart --help +restart a job + +Usage: + baizectl job restart [flags] job + +Aliases: + restart, rerun + +Flags: + -h, --help help for restart + -t, --job-type string Job type: PYTORCH, TENSORFLOW, PADDLE (default "PYTORCH") + --paddle PaddlePaddle Job, has higher priority than --job-type + --pytorch Pytorch Job, has higher priority than --job-type + --tensorflow Tensorflow Job, has higher priority than --job-type +``` + +### 数据集管理 + +`baizectl` 支持管理数据集,目前支持查看数据集列表,方便在任务训练时,快速绑定数据集。 + +```bash +(base) jovyan@den-0:~$ baizectl data +Management datasets + +Usage: + baizectl data [flags] + baizectl data [command] + +Aliases: + data, dataset, datasets, envs, runtime-envs + +Available Commands: + ls List datasets + +Flags: + -h, --help help for data + -o, --output string Output format. One of: table, json, yaml (default "table") + --page int Page number (default 1) + --page-size int Page size (default -1) + --search string Search query + --sort string Sort order + --truncate int Truncate output to the given length, 0 means no truncation (default 50) + +Use "baizectl data [command] --help" for more information about a command. +``` + +#### 查看数据集列表 + +`baizectl data` 支持通过 `ls` 命令查看数据集列表,默认显示 `table` 格式,用户可以通过 `-o` 参数指定输出格式。 + +```bash +(base) jovyan@den-0:~$ baizectl data ls + NAME TYPE URI PHASE + fashion-mnist GIT https://gitee.com/samzong_lu/fashion-mnist.git READY + sample-code GIT https://gitee.com/samzong_lu/training-sample-code.... READY + training-output PVC pvc://training-output READY +``` + +在提交训练任务时,可以使用 `-d` 或者 `--datasets` 参数指定数据集,例如: + +```bash +baizectl job submit --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --datasets sample-code:/home/jovyan/code \ + -- sleep 1000 +``` + +同时挂载多个数据集,可以按照如下格式: + +```bash +baizectl job submit --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --datasets sample-code:/home/jovyan/code fashion-mnist:/home/jovyan/data \ + -- sleep 1000 +``` + +#### 查看依赖库(环境) + +环境 `runtime-env` 是算丰 AI 算力平台的特色环境管理能力,通过将模型开发、训练任务以及推理中所需的依赖库解耦, +提供了一种更加灵活的依赖库管理方式,无需重复构建复杂的 Docker 镜像,只需选择合适的环境即可。 + +同时 `runtime-env` 支持热更新,动态升级,无需重新构建镜像,即可更新环境依赖库。 + +`baizectl data` 支持通过 `runtime-env` 命令查看环境列表,默认显示 `table` 格式,用户可以通过 `-o` 参数指定输出格式。 + +```bash +(base) jovyan@den-0:~$ baizectl data ls --runtime-env + NAME TYPE URI PHASE + fashion-mnist GIT https://gitee.com/samzong_lu/fashion-mnist.git READY + sample-code GIT https://gitee.com/samzong_lu/training-sample-code.... READY + training-output PVC pvc://training-output READY + tensorflow-sample CONDA conda://python?version=3.12.3 PROCESSING +``` + +在提交训练任务时,可以使用 `--runtime-env` 参数指定环境,例如: + +```bash +baizectl job submit --image release.daocloud.io/baize/baize-notebook:v0.5.0 \ + --runtime-env tensorflow-sample \ + -- sleep 1000 +``` + +--- + +## 高级用法 + +baizectl 支持更多高级用法,例如自动补全脚本生成、使用特定集群和命名空间、使用特定工作空间等。 + +### 自动补全脚本生成 + +```bash +baizectl completion bash > /etc/bash_completion.d/baizectl +``` + +上述命令生成 `bash` 的自动补全脚本,并将其保存到 `/etc/bash_completion.d/baizectl` 目录中,用户可以通过 `source /etc/bash_completion.d/baizectl` 加载自动补全脚本。 + +### 使用特定集群和命名空间 + +```bash +baizectl job ls --cluster my-cluster --namespace my-namespace +``` + +该命令将列出 `my-cluster` 集群中 `my-namespace` 命名空间下的所有作业。 + +### 使用特定工作空间 + +```bash +baizectl job ls --workspace 123 +``` + +## 常见问题 + +- **问题**:为什么无法连接到服务器? + + **解决方法**:检查 `--server` 参数是否正确设置,并确保网络连接正常。 + 如果服务器使用自签名证书,可以使用 `--skip-tls-verify` 跳过 TLS 证书验证。 + +- **问题**:如何解决权限不足的问题? + + **解决方法**:确保使用正确的 `--token` 参数登录,并检查当前用户是否具有相应的操作权限。 + +- **问题**:为什么无法列出数据集? + + **解决方法**:检查命名空间和工作区是否正确设置,确保当前用户有权限访问这些资源。 + +--- + +## 结语 + +通过以上指南,用户可以快速上手 `baizectl` 命令,并在实际应用中高效地管理 AI 平台资源。 +如果有任何疑问或问题,建议参考 `baizectl [command] --help` 获取更多详细信息。 diff --git a/docs/zh/docs/admin/baize/developer/notebooks/baizess.md b/docs/zh/docs/admin/baize/developer/notebooks/baizess.md new file mode 100644 index 0000000..ee0eace --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/baizess.md @@ -0,0 +1,53 @@ +# baizess 换源工具使用指南 + +`baizess` 是 AI Lab 模块中 Notebook 内置的开箱即用的换源小工具。它提供了简洁的命令行界面,方便用户管理各种编程环境的包管理器源。 +通过 baizess,用户可以轻松切换常用包管理器的源,确保顺利访问最新的库和依赖项。该工具通过简化包源管理流程,提升了开发者和数据科学家的工作效率。 + +## 安装 + +目前,`baizess` 已经集成在 AI Lab 中。 +你在创建 Notebook 后,即可在 Notebook 中直接使用 `baizess`。 + +## 快速上手 + +### 基本信息 + +`baizess` 命令的基本信息如下: + +```bash +jovyan@19d0197587cc:/$ baizess +source switch tool + +Usage: + baizess [command] [package-manager] + +Available Commands: + set Switch the source of specified package manager to current fastest source + reset Reset the source of specified package manager to default source + +Available Package-managers: + apt (require root privilege) + conda + pip +``` + +### 命令格式 + +`baizess` 命令的基本格式如下: + +```bash +baizess [command] [package-manager] +``` + +其中,`[command]` 是具体的操作命令,`[package-manager]` 用于指定操作对应的包管理器。 + +#### command + +- `set`:备份源,测速,将所指定的包管理器的源切换为测速结果最快的国内源。 +- `reset`:将所指定的包管理器重置为默认源。 + +#### 目前支持的 package-manager + +- `apt` (源的切换与重置需要`root`权限) +- `conda` (原先的源将被备份在`/etc/apt/backup/`) +- `pip` (更新后源信息将被写入`~/.condarc`) diff --git a/docs/zh/docs/admin/baize/developer/notebooks/create.md b/docs/zh/docs/admin/baize/developer/notebooks/create.md new file mode 100644 index 0000000..a86e88b --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/create.md @@ -0,0 +1,33 @@ +--- +hide: + - toc +--- + +# 创建 Notebook + +Notebook 提供了一个在线的 Web 交互式编程环境,方便开发者快速进行数据科学和机器学习实验。 + +进入开发者控制台后,开发者可以在不同集群、命名空间中创建和管理 Notebook。 + +1. 在左侧导航栏中点击 **Notebooks** ,进入 Notebook 列表。点击右侧的 **创建** 按钮。 + + ![点击创建](../../images/notebook01.png) + +1. 系统会预先填充基础配置数据,包括要部署的集群、命名空间、Notebook 镜像地址、队列、资源、用户目录等。 + 调整这些参数后点击 **确定** 。 + + ![填写参数](../../images/notebook02.png) + +1. 刚创建的 Notebook 状态为 **等待中** ,片刻后将变为 **运行中** ,默认最新的位于列表顶部。 + + ![创建成功](../../images/notebook03.png) + +1. 点击右侧的 **┇** ,可以执行更多操作:更新参数、启动/暂停、克隆 Notebook 、查看工作负载详情和删除。 + +!!! note + + 如果选择纯 CPU 资源后,发现挂载了节点上的所有 GPU 卡,可以尝试添加 container env 来解决此问题: + + ```config + NVIDIA_VISIBLE_DEVICES="" + ``` diff --git a/docs/zh/docs/admin/baize/developer/notebooks/delete.md b/docs/zh/docs/admin/baize/developer/notebooks/delete.md new file mode 100644 index 0000000..14ece50 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/delete.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 删除 Notebook + +如果发现 Notebook 冗余、过期或因其他缘故不再需要,可以从 Notebook 列表中删除。 + +1. 在 Notebook 列表右侧点击 **┇** ,在弹出菜单中选择 **删除** 。 + + ![删除](../../images/nb-delete01.png) + +1. 在弹窗中确认要删除的任务,输入 Notebook 名称后点击 **删除** 。 + + ![确认删除](../../images/nb-delete02.png) + +1. 屏幕提示删除成功,该 Notebook 从列表中消失。 + + ![已删除](../../images/nb-delete03.png) + +!!! caution + + Notebook 一旦删除将不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/admin/baize/developer/notebooks/notebook-auto-close.md b/docs/zh/docs/admin/baize/developer/notebooks/notebook-auto-close.md new file mode 100644 index 0000000..2951917 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/notebook-auto-close.md @@ -0,0 +1,62 @@ +# Notebook 闲置超时自动关机 + +在默认情况下,为优化资源利用率,AI Lab 启用了 Notebook 闲置超时自动关机功能; +当 Notebook 长时间无操作时,系统会自动关机 Notebook,释放资源。 + +- 优点:通过这个方式,可以极大减少因为长时间无操作导致的资源浪费,提高资源利用效率。 +- 缺点:如果 Notebook 未配置相关备份策略,可能导致数据丢失。 + +!!! note + + 当前,此功能为集群级别配置,默认开启,默认超时时长为 30 分钟。 + +## 配置变更 + +目前配置修改方式为手动修改,后续会提供更加便捷的配置方式。 + +修改工作集群中 `baize-agent` 的部署参数,正确的修改方式为更新 Helm 应用, + +### 界面化修改 + +1. 在集群管理界面找到对应的工作集群,进入集群详情,选择 __Helm 应用__ ,在 `baize-system` + 命名空间下找到 `baize-agent`,在右上角点击 __更新__ 按钮: + + ![baize-agent](../../images/notebook-idle.png) + +1. 如图修改 YAML 代码: + + ![baize-agent](../../images/notebook-idle02.png) + + ```yaml + ... + notebook-controller: + culling_enabled: false + cull_idle_time: 120 + idleness_check_period: 1 + ... + ``` + +1. 确认参数修改成功后,点击 **下一步** 和 **确定** 。 + +### 命令行修改 + +进入控制台以后,使用 `helm upgrade` 命令更改配置: + +```bash +# 设定版本号 +export VERSION=0.8.0 + +# 更新 Helm Chart +helm upgrade --install baize-agent baize/baize-agent \ + --namespace baize-system \ + --create-namespace \ + --set global.imageRegistry=release.daocloud.io \ + --set notebook-controller.culling_enabled=true \ # 开启自动关机,默认为 true + --set notebook-controller.cull_idle_time=120 \ # 设置闲置超时时间为 120 分钟,默认为 30 分钟 + --set notebook-controller.idleness_check_period=1 \ # 设置检查间隔为 1 分钟,默认为 1 分钟 + --version=$VERSION +``` + +!!! note + + 为了避免自动关机后丢失数据,您可以将 AI Lab 升级到 v0.8.0 及更高版本,在 Notebook 配置中启用关机自动保存功能。 diff --git a/docs/zh/docs/admin/baize/developer/notebooks/notebook-with-envs.md b/docs/zh/docs/admin/baize/developer/notebooks/notebook-with-envs.md new file mode 100644 index 0000000..fb0511c --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/notebook-with-envs.md @@ -0,0 +1,122 @@ +# 在 Notebook 中使用环境 + +环境管理是 AI Lab 的重要功能之一,通过在 **Notebook** 中关联对应的环境,可以快速切换不同的环境,方便用户进行开发和调试。 + +## 创建 Notebook 时选择环境 + +在创建 **Notebook** 时,可以选择一个或多个的环境 **Envs** 。如果没有合适的环境,可以去 **环境管理** 中创建一个新的环境。 + +![Attach-Envs](../../images/notebook04.png) + +> 如何创建环境,请参考[环境管理](../dataset/environments.md)。 + +## 在 Notebook 使用环境 + +!!! note + + 在 Notebook 中,我们同时提供了 `conda` 和 `mamba` 两种,用户可以根据自己的需求选择合适的环境管理工具。 + +AI Lab 中,我们采用了 `conda` 环境管理工具,用户可以在 Notebook 中通过 `!conda env list` 命令查看当前环境列表。 + +```bash +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ conda env list +# conda environments: +# +dkj-python312-pure /opt/baize-runtime-env/dkj-python312-pure/conda/envs/dkj-python312-pure +python-3.10 /opt/baize-runtime-env/python-3.10/conda/envs/python-3.10 +torch-smaple /opt/baize-runtime-env/torch-smaple/conda/envs/torch-smaple +base * /opt/conda # 当前激活的环境 +baize-base /opt/conda/envs/baize-base +``` + +这个命令会列出所有的 `conda` 环境,并在当前激活的环境前面加上一个星号(*)。 + +## JupyterLab 的 Kernel 环境管理 + +在 Jupyterlab 中,我们自动将 Notebook 关联的环境绑定到 Kernel 列表中,用户可以通过 Kernel 快速切换环境。 + +![Switch-Envs](../../images/notebook05.png) + +通过以上办法,可以同时在一个 Notebook 中使用不同编写和调试算法。 + +## Terminal 切换环境 + +> AI Lab 的 Notebook 目前也已经支持了 VSCode。 + +如果您更喜欢在 Terminal 中管理和切换环境,可以安装如下步骤: + +在首次启动并使用 Notebook 时,需要先执行 `conda init`,然后再执行 `conda activate ` 切换到对应的环境。 + +```bash +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ conda init bash# 初始化 bash 环境, 仅首次使用需要执行 +no change /opt/conda/condabin/conda + change /opt/conda/bin/conda + change /opt/conda/bin/conda-env + change /opt/conda/bin/activate + change /opt/conda/bin/deactivate + change /opt/conda/etc/profile.d/conda.sh + change /opt/conda/etc/fish/conf.d/conda.fish + change /opt/conda/shell/condabin/Conda.psm1 + change /opt/conda/shell/condabin/conda-hook.ps1 + change /opt/conda/lib/python3.11/site-packages/xontrib/conda.xsh + change /opt/conda/etc/profile.d/conda.csh + change /home/jovyan/.bashrc + action taken. +Added mamba to /home/jovyan/.bashrc + +==> For changes to take effect, close and re-open your current shell. <== + +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ source ~/.bashrc # 重新加载 bash 环境 +(base) jovyan@chuanjia-jupyter-0:~/yolov8$ conda activate python-3.10 # 切换到 python-3.10 环境 +(python-3.10) jovyan@chuanjia-jupyter-0:~/yolov8$ conda env list + + mamba version : 1.5.1 +# conda environments: +# +dkj-python312-pure /opt/baize-runtime-env/dkj-python312-pure/conda/envs/dkj-python312-pure +python-3.10 * /opt/baize-runtime-env/python-3.10/conda/envs/python-3.10 # 当前激活的环境 +torch-smaple /opt/baize-runtime-env/torch-smaple/conda/envs/torch-smaple +base /opt/conda +baize-base /opt/conda/envs/baize-base +``` + +> 如果您更喜欢使用 `mamba` ,这里需要使用 `mamaba init` 和 `mamba activate `。 + +## 查看环境中的包 + +通过不同环境管理的一个很重要的功能是,可以在一个 Notebook 中通过快速切换环境,使用不用的包。 + +我们可以通过下方的命令来使用 `conda` 查看当前环境中的所有包。 + +```bash +(python-3.10) jovyan@chuanjia-jupyter-0:~/yolov8$ conda list +# packages in environment at /opt/baize-runtime-env/python-3.10/conda/envs/python-3.10: +# +# Name Version Build Channel +_libgcc_mutex 0.1 main defaults +_openmp_mutex 5.1 1_gnu defaults +... # 省略部分输出 +idna 3.7 py310h06a4308_0 defaults +ipykernel 6.28.0 py310h06a4308_0 defaults +ipython 8.20.0 py310h06a4308_0 defaults +ipython_genutils 0.2.0 pyhd3eb1b0_1 defaults +jedi 0.18.1 py310h06a4308_1 defaults +jinja2 3.1.4 py310h06a4308_0 defaults +jsonschema 4.19.2 py310h06a4308_0 defaults +jsonschema-specifications 2023.7.1 py310h06a4308_0 defaults +jupyter_client 7.4.9 py310h06a4308_0 defaults +jupyter_core 5.5.0 py310h06a4308_0 defaults +jupyter_events 0.8.0 py310h06a4308_0 defaults +jupyter_server 2.10.0 py310h06a4308_0 defaults +jupyter_server_terminals 0.4.4 py310h06a4308_1 defaults +jupyterlab_pygments 0.2.2 py310h06a4308_0 defaults +... # 省略部分输出 +xz 5.4.6 h5eee18b_1 defaults +yaml 0.2.5 h7b6447c_0 defaults +zeromq 4.3.5 h6a678d5_0 defaults +zlib 1.2.13 h5eee18b_1 defaults +``` + +## 更新环境的包 + +目前,可以通过在 AI Lab 的界面中 **环境管理** 来更新环境中的包。 diff --git a/docs/zh/docs/admin/baize/developer/notebooks/notebook-with-ssh.md b/docs/zh/docs/admin/baize/developer/notebooks/notebook-with-ssh.md new file mode 100644 index 0000000..13e3717 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/notebook-with-ssh.md @@ -0,0 +1,160 @@ +# Notebook SSH 访问指南 + +AI Lab 提供的 Notebook 支持在本地通过 SSH 的方式访问; + +通过简单的配置,即可使用 SSH 访问 Jupyter Notebook 的功能。 +无论您是使用 Windows、Mac 还是 Linux 操作系统,都可以按照以下步骤进行操作。 + +## 配置 SSH 访问凭证 + +### 生成 SSH 密钥对 + +首先,您需要在您的计算机上生成 SSH 公钥和私钥对。这个密钥对将用于认证过程,确保安全访问。 + +=== "Mac/Linux" + + 1. 打开终端 + 2. 输入命令: + + ```bash + ssh-keygen -t rsa -b 4096 + ``` + + 3. 当系统提示您“Enter a file in which to save the key”,您可以直接敲击 Enter 键使用默认路径,或者指定一个新的路径。 + 4. 接下来,系统会提示您输入密码(可选),这将增加一个额外的安全层。如果选择输入密码,请记住这个密码,因为每次使用密钥时都会需要它。 + +=== "Windows" + + 1. 安装 Git Bash(如果您尚未安装) + 2. 打开 Git Bash + 3. 输入命令: + + ```bash + ssh-keygen -t rsa -b 4096 + ``` + + 4. 同 Mac/Linux 步骤 + +### 添加 SSH 公钥到个人中心 + +!!! note + + 具体操作可以参考:[配置 SSH 公钥](../../../ghippo/personal-center/ssh-key.md) + +1. 打开生成的公钥文件,通常位于 `~/.ssh/id_rsa.pub`(如果您没有更改默认路径) +2. 复制公钥内容 +3. 登录到算丰 AI 算力平台, 然后右上角帐号点开,选择个人中心 +4. 在 SSH 公钥配置页,添加你本地生成的公钥文件 +5. 保存更改 + +## 在 Notebook 中开启 SSH 访问 + +1. 登录到 Jupyter Notebook 的 Web 界面。 +2. 寻找您想要启用 SSH 访问的 Notebook。 +3. 在 Notebook 的设置或详情页面,找到 **开启 SSH 访问** 的选项并启用它。 +4. 记录或复制显示的 SSH 访问命令。这个命令将用于后续步骤中的 SSH 连接。 + +## 不同环境下的 SSH 访问方式 + +### 访问示例 + +假设您获得的 SSH 访问命令如下: + +```bash + # ssh {USERNAME}@{CLUSTER}.{NAMESPACE}.{NOTEBOOK_NAME}@{UI_LOGIN_IP} -p {UI_LOGIN_IP} + ssh baizeuser01@gpu-cluster.demo.demo-notebook@10.20.100.201 -p 80 -i private_key +``` + +请将 `USERNAME` 替换为您的用户名,`UI_LOGIN_IP` 替换为实际的主机名,`UI_LOGIN_IP` 替换为实际的端口号。 + +### Windows + +推荐使用 PuTTY 或 Git Bash 进行 SSH 连接。 + +=== "PuTTY" + + 1. 打开 PuTTY + 2. 在 **Host Name (or IP address)** 栏输入 `mockhost`(实际的主机名) + 3. 输入端口号 `2222`(实际的端口号) + 4. 点击 **Open** 开始连接 + 5. 第一次连接时,可能会提示验证服务器的身份,点击 **Yes** + +=== "Git Bash" + + 1. 打开 Git Bash + 2. 输入访问命令: + + ```bash + # ssh {USERNAME}@{CLUSTER}.{NAMESPACE}.{NOTEBOOK_NAME}@{UI_LOGIN_IP} -p {UI_LOGIN_IP} + ssh baizeuser01@gpu-cluster.demo.demo-notebook@10.20.100.201 -p 80 -i private_key + ``` + + 3. 按 Enter 键 + +### Mac/Linux + +1. 打开终端。 +2. 输入访问命令: + + ```bash + # ssh {USERNAME}@{CLUSTER}.{NAMESPACE}.{NOTEBOOK_NAME}@{UI_LOGIN_IP} -p {UI_LOGIN_IP} + ssh baizeuser01@gpu-cluster.demo.demo-notebook@10.20.100.201 -p 80 -i private_key + ``` + +3. 如果系统提示您接受主机的身份,请输入`yes`。 + +## 配合 IDE 实现远程开发 + +除了使用命令行工具进行 SSH 连接,您还可以利用现代 IDE 如 Visual Studio Code (VSCode) 和 PyCharm 的 SSH 远程连接功能, +直接在本地 IDE 中开发并利用远程服务器的资源。 + +=== "在 VSCode 中使用 SSH 远程连接" + + VSCode 通过 **Remote - SSH** 扩展支持 SSH 远程连接,允许您直接在本地 VSCode 环境中编辑远程服务器上的文件,并运行命令。 + + 操作步骤为: + + 1. 确保您已安装 VSCode 和 **Remote - SSH** 扩展。 + 2. 打开 VSCode,点击左侧活动栏底部的远程资源管理器图标。 + 3. 选择 **Remote-SSH: Connect to Host...** 选项,然后点击 **+ Add New SSH Host...** + 4. 输入 SSH 连接命令,例如: + + ```bash + # ssh {USERNAME}@{CLUSTER}.{NAMESPACE}.{NOTEBOOK_NAME}@{UI_LOGIN_IP} -p {UI_LOGIN_IP} + ssh baizeuser01@gpu-cluster.demo.demo-notebook@10.20.100.201 -p 80 -i private_key + ``` + + 5. 敲击 Enter 键。请将 username、mockhost 和 2222 替换为实际的用户名、主机名和端口号。 + 6. 选择一个配置文件来保存此 SSH 主机,通常选择默认即可。 + + 完成后,您的 SSH 主机将添加到 SSH 目标列表中。点击您的主机进行连接。 + 如果是第一次连接,可能会提示您验证主机的指纹。接受后,您将被要求输入密码(如果 SSH 密钥设置了密码)。 + 连接成功后,您可以像在本地开发一样在 VSCode 中编辑远程文件,并利用远程资源。 + +=== "在 PyCharm 中使用 SSH 远程连接" + + PyCharm Professional 版支持通过 SSH 连接到远程服务器,并在本地 PyCharm 中直接开发。 + + 操作步骤为: + + 1. 打开 PyCharm,并打开或创建一个项目 + 2. 选择 **File** -> **Settings** (在 Mac 上是 **PyCharm** -> **Preferences** + 3. 在设置窗口中,导航到 **Project: YourProjectName** -> **Python Interpreter** + 4. 点击右上角的齿轮图标,选择 **Add...** + - 在弹出的窗口中,选择 **SSH Interpreter** + - 输入远程主机的信息:主机名(mockhost)、端口号(2222)、用户名(username)。 + 请使用您的实际信息替换这些占位符。 + - 点击 **Next** ,PyCharm 将尝试连接到远程服务器。如果连接成功,您将被要求输入密码或选择私钥文件。 + + 5. 配置完成后,点击 **Finish** 。现在,您的 PyCharm 将使用远程服务器上的 Python 解释器。 + +## 安全限制 + +在同一个 Workspace 内,任意用户都可以通过自己的 SSH 访问凭证来登录到启用了 SSH 的 Notebook。 +这意味着,只要用户配置了自己的 SSH 公钥到个人中心,并且 Notebook 启用了 SSH 访问,就可以使用 SSH 进行安全连接。 + +请注意,不同用户的访问权限可能会根据 Workspace 的配置而有所不同。确保您了解并遵守您所在组织的安全和访问策略。 + +--- + +通过遵循上述步骤,您应该能够成功配置并使用 SSH 访问 Jupyter Notebook。如果遇到任何问题,请参考系统帮助文档或联系系统管理员。 diff --git a/docs/zh/docs/admin/baize/developer/notebooks/start-pause.md b/docs/zh/docs/admin/baize/developer/notebooks/start-pause.md new file mode 100644 index 0000000..6d37d88 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/start-pause.md @@ -0,0 +1,20 @@ +--- +hide: + - toc +--- + +# 启动和暂停 Notebook + +Notebook 创建成功后,通常会有几个状态: + +- 等待中 +- 运行中 +- 已停止 + +如果某个 Notebook 的状态为 **已停止** ,在列表右侧点击 **┇** ,在弹出菜单中选择 **启动** 。 + +![启动](../../images/nb-start01.png) + +此 Notebook 将进入运行队列中,状态变为 **等待中** ,如果一切正常,片刻后其状态将变为 **运行中** 。 + +如果使用结束,可以从菜单中选择 **暂停** ,将其状态变为 **已停止** 。 diff --git a/docs/zh/docs/admin/baize/developer/notebooks/view.md b/docs/zh/docs/admin/baize/developer/notebooks/view.md new file mode 100644 index 0000000..635b416 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/notebooks/view.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# Notebook 工作负载 + +如果想要查看某个 Notebook 的工作负载,可以执行以下操作: + +1. 在 Notebook 列表右侧点击 **┇** ,在弹出菜单中选择 **工作负载详情** 。 + + ![删除](../../images/nb-workload01.png) + +1. 跳转到有状态工作负载(StatefulSet)列表,可以查看: + + - 容器组 Pod 的运行状态、IP、资源请求和使用情况 + - 容器配置信息 + - 访问方式:ClusterIP、NodePort + - 调度策略:节点和工作负载的亲和性、反亲和性 + - 标签与注解:工作负载、Pod 的标签与注解键值对 + - 弹性伸缩:支持 HPA、CronHPA、VPA 等方式 + - 事件列表:警告、通知等消息 + + ![确认删除](../../images/nb-workload02.png) + +1. 在 StatefulSet 列表,点击右侧的 **┇**,可以针对 Pod 执行更多操作。 + + ![已删除](../../images/nb-workload03.png) diff --git a/docs/zh/docs/admin/baize/developer/quick-start.md b/docs/zh/docs/admin/baize/developer/quick-start.md new file mode 100644 index 0000000..ab806c0 --- /dev/null +++ b/docs/zh/docs/admin/baize/developer/quick-start.md @@ -0,0 +1,113 @@ +# 快速入门 + +本文提供了简单的操作手册以便用户使用 AI Lab 进行数据集、Notebook、任务训练的整个开发、训练流程。 + +## 准备数据集 + +点击 **数据管理** -> **数据集** ,选择 **创建** 按钮,分别创建以下三个数据集。 + +### 数据集:训练代码 + +- 代码数据源:[https://github.com/samzong/training-sample-code.git](https://github.com/samzong/training-sample-code.git),主要是一个简单的 Tensorflow 代码。 +- 如果是中国境内的用户,可以使用 Gitee 加速:[https://gitee.com/samzong_lu/training-sample-code.git](https://gitee.com/samzong_lu/training-sample-code.git) +- 代码路径为 `tensorflow/tf-fashion-mnist-sample` + +![训练代码的数据集](../images/baize-01.png) + +!!! note + + 目前仅支持读写模式为 `ReadWriteMany` 的 `StorageClass`,请使用 NFS 或者推荐的 [JuiceFS](https://juicefs.com/zh-cn/)。 + +### 数据集:训练数据 + +本次训练使用的数据为 [https://github.com/zalandoresearch/fashion-mnist.git](https://github.com/zalandoresearch/fashion-mnist.git), +这是 Fashion-MNIST 数据集。 + +如果是中国境内的用户,可以使用 Gitee 加速:[https://gitee.com/samzong_lu/fashion-mnist.git](https://gitee.com/samzong_lu/fashion-mnist.git) + +![训练数据的数据集](../images/baize-02.png) + +!!! note + + 如果未创建训练数据的数据集,通过训练脚本也会自动下载;提前准备训练数据可以提高训练速度。 + +### 数据集:空数据集 + +AI Lab 支持将 `PVC` 作为数据集的数据源类型,所以创建一个空 PVC 绑定到数据集后,可将空数据集作为存放后续训练任务的输出数据集,存放模型和日志。 + +![空数据集](../images/baize-03.png) + +## 环境依赖: tensorflow + +脚本在运行时,需要依赖 `Tensorflow` 的 Python 库,可以使用 AI Lab 的环境依赖管理功能,提前将需要的 Python 库下载和准备完成,无需依赖镜像构建 + +> 参考 [环境依赖](../developer/dataset/environments.md) 的操作方式,添加一个 `CONDA` 环境. + +```yaml +name: tensorflow +channels: + - defaults + - conda-forge +dependencies: + - python=3.12 + - tensorflow +prefix: /opt/conda/envs/tensorflow +``` + +![创建环境依赖](../images/baize-08.png) + +!!! note + + 等待环境预热成功后,只需要将此环境挂载到 Notebook、训练任务中,使用 AI Lab 提供的基础镜像就可以 + +## 使用 Notebook 调试脚本 + +准备开发环境,点击导航栏的 **Notebooks** ,点击 **创建** 。 + +- 将[准备好的三个数据集](#_2)进行关联,挂载路径请参照下图填写,注意将需要使用的空数据集在 输出数据集位置配置 + + ![挂载路径](../images/baize-06.png) + +- 选择并绑定[环境依赖包](#tensorflow) + + 等待 Notebook 创建成功,点击列表中的访问地址,进入 Notebook。并在 Notebook 的终端中执行以下命令进行任务训练。 + + ![进入 notebook](../images/baize-05.png) + + !!! note + + 脚本使用 Tensorflow,如果忘记关联依赖库,也可以临时用 `pip install tensorflow` 安装。 + + ```shell + python /home/jovyan/code/tensorflow/tf-fashion-mnist-sample/train.py + ``` + +## 创建训练任务 + +1. 点击导航栏的 **任务中心** -> **训练任务** ,创建一个 `Tensorflow` 单机任务 +1. 先填写基本参数后,点击 **下一步** +1. 在任务资源配置中,正确配置任务资源后,点击 **下一步** + + - 镜像:如果前序环境依赖包准备好了,使用默认镜像即可; 如果未准备,要确认镜像内有 `tensorflow` 的 Python 库 + - shell:使用 `bash` 即可 + - 启用命令: + + ```bash + /home/jovyan/code/tensorflow/tf-fashion-mnist-sample/train.py + ``` + +1. 在高级配置中,启用 **任务分析(Tensorboard)** ,点击 **确定** 。 + + !!! note + + 日志所在位置为输出数据集的 `/home/jovyan/model/train/logs/` + + ![高级配置](../images/enable-analy.png) + +1. 返回训练任务列表,等到状态变为 **成功** 。点击列表右侧的 **┇** ,可以查看详情、克隆任务、更新优先级、查看日志和删除等操作。 + + ![提交训练任务](../images/othera.png) + +1. 成功创建任务后,在左侧导航栏点击 **任务分析** ,可以查看任务状态并对任务训练进行调优。 + + ![查看任务](../images/baize-07.png) diff --git a/docs/zh/docs/admin/baize/images/agent-helm.png b/docs/zh/docs/admin/baize/images/agent-helm.png new file mode 100644 index 0000000..30fb946 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/agent-helm.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-01.png b/docs/zh/docs/admin/baize/images/baize-01.png new file mode 100644 index 0000000..b515142 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-01.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-02.png b/docs/zh/docs/admin/baize/images/baize-02.png new file mode 100644 index 0000000..de75df4 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-02.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-03.png b/docs/zh/docs/admin/baize/images/baize-03.png new file mode 100644 index 0000000..bae2181 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-03.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-04.png b/docs/zh/docs/admin/baize/images/baize-04.png new file mode 100644 index 0000000..8e31919 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-04.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-05.png b/docs/zh/docs/admin/baize/images/baize-05.png new file mode 100644 index 0000000..b360c85 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-05.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-06.png b/docs/zh/docs/admin/baize/images/baize-06.png new file mode 100644 index 0000000..50dd98f Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-06.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-07.png b/docs/zh/docs/admin/baize/images/baize-07.png new file mode 100644 index 0000000..2d9c1a4 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-07.png differ diff --git a/docs/zh/docs/admin/baize/images/baize-08.png b/docs/zh/docs/admin/baize/images/baize-08.png new file mode 100644 index 0000000..b2c9b88 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/baize-08.png differ diff --git a/docs/zh/docs/admin/baize/images/bind01.png b/docs/zh/docs/admin/baize/images/bind01.png new file mode 100644 index 0000000..e4b8d90 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/bind01.png differ diff --git a/docs/zh/docs/admin/baize/images/bind02.png b/docs/zh/docs/admin/baize/images/bind02.png new file mode 100644 index 0000000..c8273ea Binary files /dev/null and b/docs/zh/docs/admin/baize/images/bind02.png differ diff --git a/docs/zh/docs/admin/baize/images/bind03.png b/docs/zh/docs/admin/baize/images/bind03.png new file mode 100644 index 0000000..5b2f0f7 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/bind03.png differ diff --git a/docs/zh/docs/admin/baize/images/bind04.png b/docs/zh/docs/admin/baize/images/bind04.png new file mode 100644 index 0000000..29db3cb Binary files /dev/null and b/docs/zh/docs/admin/baize/images/bind04.png differ diff --git a/docs/zh/docs/admin/baize/images/change-ws.png b/docs/zh/docs/admin/baize/images/change-ws.png new file mode 100644 index 0000000..8299ea2 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/change-ws.png differ diff --git a/docs/zh/docs/admin/baize/images/cluster.png b/docs/zh/docs/admin/baize/images/cluster.png new file mode 100644 index 0000000..3ea2aa8 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/cluster.png differ diff --git a/docs/zh/docs/admin/baize/images/conda01.png b/docs/zh/docs/admin/baize/images/conda01.png new file mode 100644 index 0000000..f8e6f09 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/conda01.png differ diff --git a/docs/zh/docs/admin/baize/images/conda02.png b/docs/zh/docs/admin/baize/images/conda02.png new file mode 100644 index 0000000..1af809e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/conda02.png differ diff --git a/docs/zh/docs/admin/baize/images/conda03.png b/docs/zh/docs/admin/baize/images/conda03.png new file mode 100644 index 0000000..e2d196c Binary files /dev/null and b/docs/zh/docs/admin/baize/images/conda03.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset01.png b/docs/zh/docs/admin/baize/images/dataset01.png new file mode 100644 index 0000000..5f585de Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset01.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset02.png b/docs/zh/docs/admin/baize/images/dataset02.png new file mode 100644 index 0000000..187d157 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset02.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset03.png b/docs/zh/docs/admin/baize/images/dataset03.png new file mode 100644 index 0000000..1087fe5 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset03.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset04.png b/docs/zh/docs/admin/baize/images/dataset04.png new file mode 100644 index 0000000..eb44eb2 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset04.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset05.png b/docs/zh/docs/admin/baize/images/dataset05.png new file mode 100644 index 0000000..cea3afb Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset05.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset06.png b/docs/zh/docs/admin/baize/images/dataset06.png new file mode 100644 index 0000000..bfb04b8 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset06.png differ diff --git a/docs/zh/docs/admin/baize/images/dataset07.png b/docs/zh/docs/admin/baize/images/dataset07.png new file mode 100644 index 0000000..69e04a0 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dataset07.png differ diff --git a/docs/zh/docs/admin/baize/images/delete01.png b/docs/zh/docs/admin/baize/images/delete01.png new file mode 100644 index 0000000..5602ed4 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/delete01.png differ diff --git a/docs/zh/docs/admin/baize/images/delete02.png b/docs/zh/docs/admin/baize/images/delete02.png new file mode 100644 index 0000000..c661e2d Binary files /dev/null and b/docs/zh/docs/admin/baize/images/delete02.png differ diff --git a/docs/zh/docs/admin/baize/images/delete03.png b/docs/zh/docs/admin/baize/images/delete03.png new file mode 100644 index 0000000..655a640 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/delete03.png differ diff --git a/docs/zh/docs/admin/baize/images/dev-view.png b/docs/zh/docs/admin/baize/images/dev-view.png new file mode 100644 index 0000000..5ab7ca0 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/dev-view.png differ diff --git a/docs/zh/docs/admin/baize/images/ds-delete01.png b/docs/zh/docs/admin/baize/images/ds-delete01.png new file mode 100644 index 0000000..38a3896 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/ds-delete01.png differ diff --git a/docs/zh/docs/admin/baize/images/ds-delete02.png b/docs/zh/docs/admin/baize/images/ds-delete02.png new file mode 100644 index 0000000..63f8426 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/ds-delete02.png differ diff --git a/docs/zh/docs/admin/baize/images/ds-delete03.png b/docs/zh/docs/admin/baize/images/ds-delete03.png new file mode 100644 index 0000000..fcca8ac Binary files /dev/null and b/docs/zh/docs/admin/baize/images/ds-delete03.png differ diff --git a/docs/zh/docs/admin/baize/images/enable-analy.png b/docs/zh/docs/admin/baize/images/enable-analy.png new file mode 100644 index 0000000..aba5c22 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/enable-analy.png differ diff --git a/docs/zh/docs/admin/baize/images/image01.png b/docs/zh/docs/admin/baize/images/image01.png new file mode 100644 index 0000000..ac52a69 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/image01.png differ diff --git a/docs/zh/docs/admin/baize/images/inference-interface.png b/docs/zh/docs/admin/baize/images/inference-interface.png new file mode 100644 index 0000000..199f08e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/inference-interface.png differ diff --git a/docs/zh/docs/admin/baize/images/job-mpi01.png b/docs/zh/docs/admin/baize/images/job-mpi01.png new file mode 100644 index 0000000..77335a8 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job-mpi01.png differ diff --git a/docs/zh/docs/admin/baize/images/job01.png b/docs/zh/docs/admin/baize/images/job01.png new file mode 100644 index 0000000..7660646 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job01.png differ diff --git a/docs/zh/docs/admin/baize/images/job02.png b/docs/zh/docs/admin/baize/images/job02.png new file mode 100644 index 0000000..3eb3eba Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job02.png differ diff --git a/docs/zh/docs/admin/baize/images/job03.png b/docs/zh/docs/admin/baize/images/job03.png new file mode 100644 index 0000000..be5ba4b Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job03.png differ diff --git a/docs/zh/docs/admin/baize/images/job04.png b/docs/zh/docs/admin/baize/images/job04.png new file mode 100644 index 0000000..a5e8651 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job04.png differ diff --git a/docs/zh/docs/admin/baize/images/job05.png b/docs/zh/docs/admin/baize/images/job05.png new file mode 100644 index 0000000..f98d434 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job05.png differ diff --git a/docs/zh/docs/admin/baize/images/job06.png b/docs/zh/docs/admin/baize/images/job06.png new file mode 100644 index 0000000..ec230d0 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job06.png differ diff --git a/docs/zh/docs/admin/baize/images/job07.png b/docs/zh/docs/admin/baize/images/job07.png new file mode 100644 index 0000000..a038540 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/job07.png differ diff --git a/docs/zh/docs/admin/baize/images/mxnet_job.png b/docs/zh/docs/admin/baize/images/mxnet_job.png new file mode 100644 index 0000000..e431c2e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/mxnet_job.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-delete01.png b/docs/zh/docs/admin/baize/images/nb-delete01.png new file mode 100644 index 0000000..ac097be Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-delete01.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-delete02.png b/docs/zh/docs/admin/baize/images/nb-delete02.png new file mode 100644 index 0000000..4aa5ac2 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-delete02.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-delete03.png b/docs/zh/docs/admin/baize/images/nb-delete03.png new file mode 100644 index 0000000..44c5b74 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-delete03.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-start01.png b/docs/zh/docs/admin/baize/images/nb-start01.png new file mode 100644 index 0000000..c0b2995 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-start01.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-workload01.png b/docs/zh/docs/admin/baize/images/nb-workload01.png new file mode 100644 index 0000000..08e11a2 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-workload01.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-workload02.png b/docs/zh/docs/admin/baize/images/nb-workload02.png new file mode 100644 index 0000000..a3be64e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-workload02.png differ diff --git a/docs/zh/docs/admin/baize/images/nb-workload03.png b/docs/zh/docs/admin/baize/images/nb-workload03.png new file mode 100644 index 0000000..97e4447 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/nb-workload03.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook-idle.png b/docs/zh/docs/admin/baize/images/notebook-idle.png new file mode 100644 index 0000000..91e9e6e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook-idle.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook-idle02.png b/docs/zh/docs/admin/baize/images/notebook-idle02.png new file mode 100644 index 0000000..722d870 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook-idle02.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook-images.png b/docs/zh/docs/admin/baize/images/notebook-images.png new file mode 100644 index 0000000..e96841e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook-images.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook01.png b/docs/zh/docs/admin/baize/images/notebook01.png new file mode 100644 index 0000000..99855ae Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook01.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook02.png b/docs/zh/docs/admin/baize/images/notebook02.png new file mode 100644 index 0000000..951a289 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook02.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook03.png b/docs/zh/docs/admin/baize/images/notebook03.png new file mode 100644 index 0000000..8500c0c Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook03.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook04.png b/docs/zh/docs/admin/baize/images/notebook04.png new file mode 100644 index 0000000..1545522 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook04.png differ diff --git a/docs/zh/docs/admin/baize/images/notebook05.png b/docs/zh/docs/admin/baize/images/notebook05.png new file mode 100644 index 0000000..d34f8e7 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/notebook05.png differ diff --git a/docs/zh/docs/admin/baize/images/oam-overview.png b/docs/zh/docs/admin/baize/images/oam-overview.png new file mode 100644 index 0000000..03a6dab Binary files /dev/null and b/docs/zh/docs/admin/baize/images/oam-overview.png differ diff --git a/docs/zh/docs/admin/baize/images/othera.png b/docs/zh/docs/admin/baize/images/othera.png new file mode 100644 index 0000000..a70eb7f Binary files /dev/null and b/docs/zh/docs/admin/baize/images/othera.png differ diff --git a/docs/zh/docs/admin/baize/images/paddle_job.png b/docs/zh/docs/admin/baize/images/paddle_job.png new file mode 100644 index 0000000..6c88c66 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/paddle_job.png differ diff --git a/docs/zh/docs/admin/baize/images/q-delete01.png b/docs/zh/docs/admin/baize/images/q-delete01.png new file mode 100644 index 0000000..cca9c84 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/q-delete01.png differ diff --git a/docs/zh/docs/admin/baize/images/q-delete02.png b/docs/zh/docs/admin/baize/images/q-delete02.png new file mode 100644 index 0000000..5abd4c1 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/q-delete02.png differ diff --git a/docs/zh/docs/admin/baize/images/queue01.png b/docs/zh/docs/admin/baize/images/queue01.png new file mode 100644 index 0000000..8bb910b Binary files /dev/null and b/docs/zh/docs/admin/baize/images/queue01.png differ diff --git a/docs/zh/docs/admin/baize/images/queue02.png b/docs/zh/docs/admin/baize/images/queue02.png new file mode 100644 index 0000000..2822456 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/queue02.png differ diff --git a/docs/zh/docs/admin/baize/images/queue03.png b/docs/zh/docs/admin/baize/images/queue03.png new file mode 100644 index 0000000..a42b286 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/queue03.png differ diff --git a/docs/zh/docs/admin/baize/images/resource.png b/docs/zh/docs/admin/baize/images/resource.png new file mode 100644 index 0000000..f648647 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/resource.png differ diff --git a/docs/zh/docs/admin/baize/images/tensorboard-01.png b/docs/zh/docs/admin/baize/images/tensorboard-01.png new file mode 100644 index 0000000..2679fac Binary files /dev/null and b/docs/zh/docs/admin/baize/images/tensorboard-01.png differ diff --git a/docs/zh/docs/admin/baize/images/tensorboard-02.png b/docs/zh/docs/admin/baize/images/tensorboard-02.png new file mode 100644 index 0000000..29b0488 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/tensorboard-02.png differ diff --git a/docs/zh/docs/admin/baize/images/tensorboard-03.png b/docs/zh/docs/admin/baize/images/tensorboard-03.png new file mode 100644 index 0000000..3ba9d9e Binary files /dev/null and b/docs/zh/docs/admin/baize/images/tensorboard-03.png differ diff --git a/docs/zh/docs/admin/baize/images/tensorboard.png b/docs/zh/docs/admin/baize/images/tensorboard.png new file mode 100644 index 0000000..ae63654 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/tensorboard.png differ diff --git a/docs/zh/docs/admin/baize/images/triton-infer-0.png b/docs/zh/docs/admin/baize/images/triton-infer-0.png new file mode 100644 index 0000000..6d77950 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/triton-infer-0.png differ diff --git a/docs/zh/docs/admin/baize/images/triton-infer-1.png b/docs/zh/docs/admin/baize/images/triton-infer-1.png new file mode 100644 index 0000000..e1298e4 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/triton-infer-1.png differ diff --git a/docs/zh/docs/admin/baize/images/triton-infer-2.png b/docs/zh/docs/admin/baize/images/triton-infer-2.png new file mode 100644 index 0000000..df4bdde Binary files /dev/null and b/docs/zh/docs/admin/baize/images/triton-infer-2.png differ diff --git a/docs/zh/docs/admin/baize/images/triton-infer-3.png b/docs/zh/docs/admin/baize/images/triton-infer-3.png new file mode 100644 index 0000000..937cdfb Binary files /dev/null and b/docs/zh/docs/admin/baize/images/triton-infer-3.png differ diff --git a/docs/zh/docs/admin/baize/images/update-baize.png b/docs/zh/docs/admin/baize/images/update-baize.png new file mode 100644 index 0000000..d22c9f5 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/update-baize.png differ diff --git a/docs/zh/docs/admin/baize/images/view-wl01.png b/docs/zh/docs/admin/baize/images/view-wl01.png new file mode 100644 index 0000000..ba30542 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/view-wl01.png differ diff --git a/docs/zh/docs/admin/baize/images/view-wl02.png b/docs/zh/docs/admin/baize/images/view-wl02.png new file mode 100644 index 0000000..d5ddbe3 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/view-wl02.png differ diff --git a/docs/zh/docs/admin/baize/images/view-wl03.png b/docs/zh/docs/admin/baize/images/view-wl03.png new file mode 100644 index 0000000..c6a21d4 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/view-wl03.png differ diff --git a/docs/zh/docs/admin/baize/images/view-wl04.png b/docs/zh/docs/admin/baize/images/view-wl04.png new file mode 100644 index 0000000..d8b783b Binary files /dev/null and b/docs/zh/docs/admin/baize/images/view-wl04.png differ diff --git a/docs/zh/docs/admin/baize/images/vllm-infer-0.png b/docs/zh/docs/admin/baize/images/vllm-infer-0.png new file mode 100644 index 0000000..142b965 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/vllm-infer-0.png differ diff --git a/docs/zh/docs/admin/baize/images/vllm-infer-1.png b/docs/zh/docs/admin/baize/images/vllm-infer-1.png new file mode 100644 index 0000000..8aaa198 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/vllm-infer-1.png differ diff --git a/docs/zh/docs/admin/baize/images/vllm-infer-2.png b/docs/zh/docs/admin/baize/images/vllm-infer-2.png new file mode 100644 index 0000000..ac22933 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/vllm-infer-2.png differ diff --git a/docs/zh/docs/admin/baize/images/workspace.png b/docs/zh/docs/admin/baize/images/workspace.png new file mode 100644 index 0000000..019a1b3 Binary files /dev/null and b/docs/zh/docs/admin/baize/images/workspace.png differ diff --git a/docs/zh/docs/admin/baize/oam/index.md b/docs/zh/docs/admin/baize/oam/index.md new file mode 100644 index 0000000..e820a2a --- /dev/null +++ b/docs/zh/docs/admin/baize/oam/index.md @@ -0,0 +1,17 @@ +--- +hide: + - toc +--- + +# 运维管理 + +运维管理是 IT 运维人员日常管理 IT 资源,处理工作的空间。 + +![运维管理概览](../images/oam-overview.png) + +在这里可以直观地了解当前集群、节点、CPU、GPU、vGPU 等资源的使用状况。 + +## 常见术语 + +- GPU 分配率:统计当前集群内所有未完成的任务的 GPU 分配情况,统计请求的 GPU(Request)与总资源量(Total)之间的比例。 +- GPU 利用率:统计当前集群中所有运行中的任务的实际资源利用情况,统计实际使用的 GPU(Usage)与总资源量(Total)之间的比例。 diff --git a/docs/zh/docs/admin/baize/oam/queue/create.md b/docs/zh/docs/admin/baize/oam/queue/create.md new file mode 100644 index 0000000..584d714 --- /dev/null +++ b/docs/zh/docs/admin/baize/oam/queue/create.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 创建队列 + +在运维管理模式中,队列可用于调度和优化批处理工作负载,它可以有效地管理在集群上运行的多个任务,通过队列系统来优化资源利用率。 + +1. 在左侧导航栏中点击 **队列管理** ,点击右侧的 **创建** 按钮。 + + ![点击创建](../../images/queue01.png) + +1. 系统会预先填充基础设置数据,包括要部署的集群、工作空间、排队策略等。 + 调整这些参数后点击 **确定** 。 + + ![填写参数](../../images/queue02.png) + +1. 屏幕提示创建,返回队列管理列表。点击列表右侧的 **┇** ,可以执行更新、删除等更多操作。 + + ![更多操作](../../images/queue03.png) diff --git a/docs/zh/docs/admin/baize/oam/queue/delete.md b/docs/zh/docs/admin/baize/oam/queue/delete.md new file mode 100644 index 0000000..3d4c318 --- /dev/null +++ b/docs/zh/docs/admin/baize/oam/queue/delete.md @@ -0,0 +1,22 @@ +--- +hide: + - toc +--- + +# 删除队列 + +在运维管理模式中,如果发现队列冗余、过期或因其他缘故不再需要,可以从队列列表中删除。 + +1. 在队列列表右侧点击 **┇** ,在弹出菜单中选择 **删除** 。 + + ![删除](../../images/q-delete01.png) + +1. 在弹窗中确认要删除的队列,输入队列名称后点击 **删除** 。 + + ![确认删除](../../images/delete02.png) + +1. 屏幕提示删除成功,该队列从列表中消失。 + +!!! caution + + 队列一旦删除将不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/admin/baize/oam/resource.md b/docs/zh/docs/admin/baize/oam/resource.md new file mode 100644 index 0000000..3ce607c --- /dev/null +++ b/docs/zh/docs/admin/baize/oam/resource.md @@ -0,0 +1,12 @@ +--- +hide: + - toc +--- + +# GPU 列表 + +自动化汇总整个平台中的 GPU 资源信息,提供详尽的 GPU 设备信息展示,可查看各种 GPU 卡的负载统计和任务运行信息。 + +进入 **运维管理** 后,点击左侧导航栏的 **资源管理** -> **GPU 管理** ,可以查看 GPU 卡和任务信息。 + +![GPU 管理](../images/resource.png) diff --git a/docs/zh/docs/admin/baize/troubleshoot/cluster-not-found.md b/docs/zh/docs/admin/baize/troubleshoot/cluster-not-found.md new file mode 100644 index 0000000..a653193 --- /dev/null +++ b/docs/zh/docs/admin/baize/troubleshoot/cluster-not-found.md @@ -0,0 +1,42 @@ +# 集群下拉列表中找不到集群 + +## 问题现象 + +在 AI Lab 开发控制台、运维控制台,功能模块的集群搜索条件的下拉列表找不到想要的集群。 + +## 问题分析 + +在 AI Lab 中,集群下拉列表如果缺少了想要的集群,可能是由于以下原因导致的: + +- `baize-agent` 未安装或安装不成功,导致 AI Lab 无法获取集群信息 +- 安装 `baize-agent` 未配置集群名称,导致 AI Lab 无法获取集群信息 +- 工作集群内可观测组件异常,导致无法采集集群内的指标信息 + +## 解决办法 + +### `baize-agent` 未安装或安装不成功 + +AI Lab 有一些基础组件需要在每个工作集群内进行安装,如果工作集群内未安装 `baize-agent` 时,可以在界面上选择安装,可能会导致一些非预期的报错等问题。 + +所以,为了保障使用体验,可选择的集群范围仅包含了已经成功安装了 `baize-agent` 的集群。 + +如果是因为 `baize-agent` 未安装或安装失败,则使用 +**容器管理** -> **集群管理** -> **Helm 应用** -> **Helm 模板** ,找到 `baize-agent` 并安装。 + +!!! note + + 此地址快速跳转 `https:///kpanda/clusters//helm/charts/addon/baize-agent`。 + 注意将 `` 替换为实际的 AI 算力中心控制台地址,`` 替换为实际的集群名称。 + +### 安装 `baize-agent` 时未配置集群名称 + +在安装 `baize-agent` 时,需要注意配置集群的名称,这个名称会用于可观测指标采集, **默认为空,需手工配置** 。 + +![baize-agent-install](./images/baize-agent01.png) + +### 工作集群内可观测组件异常 + +如果集群内可观测组件异常,可能会导致 AI Lab 无法获取集群信息,请检查平台的可观测服务是否正常运行及配置。 + +- 检查[全局服务集群](../../kpanda/clusters/cluster-role.md#_2)内 insight-server 组件是否正常运行 +- 检查[工作集群](../../kpanda/clusters/cluster-role.md#_4)内 insight-agent 组件是否正常运行 diff --git a/docs/zh/docs/admin/baize/troubleshoot/images/baize-agent01.png b/docs/zh/docs/admin/baize/troubleshoot/images/baize-agent01.png new file mode 100644 index 0000000..2525687 Binary files /dev/null and b/docs/zh/docs/admin/baize/troubleshoot/images/baize-agent01.png differ diff --git a/docs/zh/docs/admin/baize/troubleshoot/images/kueue-init-localqueue.png b/docs/zh/docs/admin/baize/troubleshoot/images/kueue-init-localqueue.png new file mode 100644 index 0000000..bec6464 Binary files /dev/null and b/docs/zh/docs/admin/baize/troubleshoot/images/kueue-init-localqueue.png differ diff --git a/docs/zh/docs/admin/baize/troubleshoot/images/kueue-k8s127.png b/docs/zh/docs/admin/baize/troubleshoot/images/kueue-k8s127.png new file mode 100644 index 0000000..d611028 Binary files /dev/null and b/docs/zh/docs/admin/baize/troubleshoot/images/kueue-k8s127.png differ diff --git a/docs/zh/docs/admin/baize/troubleshoot/images/kueue-plainpod.png b/docs/zh/docs/admin/baize/troubleshoot/images/kueue-plainpod.png new file mode 100644 index 0000000..d6bfb74 Binary files /dev/null and b/docs/zh/docs/admin/baize/troubleshoot/images/kueue-plainpod.png differ diff --git a/docs/zh/docs/admin/baize/troubleshoot/index.md b/docs/zh/docs/admin/baize/troubleshoot/index.md new file mode 100644 index 0000000..b6d4a23 --- /dev/null +++ b/docs/zh/docs/admin/baize/troubleshoot/index.md @@ -0,0 +1,20 @@ +--- +hide: + - toc +--- + +# 故障排查 + +本文将持续统计和梳理 AI Lab 使用过程可能因环境或操作不规范引起的报错,以及在使用过程中遇到某些报错的问题分析、解决方案。 + +!!! warning + + 本文档仅适用于 AI 算力中心版本,若遇到 AI Lab 的使用问题,请优先查看此排障手册。 + +AI Lab 在 AI 算力中心中模块名称 `baize`,提供了一站式的模型训练、推理、模型管理等功能。 + +## 常见故障案例 + +- [集群下拉列表中找不到集群](./cluster-not-found.md) +- [Notebook 不受队列配额控制](./notebook-not-controlled-by-quotas.md) +- [队列初始化失败](./local-queue-initialization-failed.md) diff --git a/docs/zh/docs/admin/baize/troubleshoot/local-queue-initialization-failed.md b/docs/zh/docs/admin/baize/troubleshoot/local-queue-initialization-failed.md new file mode 100644 index 0000000..ebe5b9b --- /dev/null +++ b/docs/zh/docs/admin/baize/troubleshoot/local-queue-initialization-failed.md @@ -0,0 +1,34 @@ +# 本地队列初始化失败 + +## 问题现象 + +在创建 Notebook、训练任务或者推理服务时,当队列是首次在该命名空间使用时,会提示需要一键初始化队列,但是初始化失败。 + +![local-queue-initialization-failed](./images/kueue-init-localqueue.png) + +## 问题分析 + +在 AI Lab 中,队列管理能力由 [Kueue](https://kueue.sigs.k8s.io/) 提供, +而 Kueue 提供了 两种队列管理资源: + +- ClusterQueue 是集群级别的队列,主要用于管理队列中的资源配额,包含了 CPU、内存、GPU 等资源 +- LocalQueue 是命名空间级别的队列,需要指向到一个 ClusterQueue,用于使用队列中的资源分配 + +在 AI Lab 中,如果创建服务时,发现指定的命名空间不存在 `LocalQueue`,则会提示需要初始化队列。 + +在极少数情况下,可能由于特殊原因会导致 `LocalQueue` 初始化失败。 + +### 解决办法 + +检查 Kueue 是否正常运行,如果 `kueue-controller-manager` 未运行,可以通过以下命令查看。 + +```bash +kubectl get deploy kueue-controller-manager -n baize-sysatem +``` + +如果 `kueue-controller-manager` 未正常运行,请先修复 Kueue。 + +### 参考资料 + +- [ClusterQueue](https://kueue.sigs.k8s.io/docs/concepts/cluster_queue/) +- [LocalQueue](https://kueue.sigs.k8s.io/docs/concepts/local_queue/) diff --git a/docs/zh/docs/admin/baize/troubleshoot/notebook-not-controlled-by-quotas.md b/docs/zh/docs/admin/baize/troubleshoot/notebook-not-controlled-by-quotas.md new file mode 100644 index 0000000..2023c8f --- /dev/null +++ b/docs/zh/docs/admin/baize/troubleshoot/notebook-not-controlled-by-quotas.md @@ -0,0 +1,32 @@ +# Notebook 不受队列配额控制 + +在 AI Lab 中,用户在创建 Notebook 时,发现选择的队列即使资源不足,Notebook 依然可以创建成功。 + +## 问题 01: Kubernetes 版本不支持 + +- 分析: + + AI Lab 中的队列管理能力由 [Kueue](https://kueue.sigs.k8s.io/) 提供, + Notebook 服务是通过 [JupyterHub](https://jupyter.org/hub) 提供的。 + JupyterHub 对 Kubernetes 的版本要求较高,对于低于 v1.27 的版本,即使在 AI 算力中心中设置了队列配额, + 用户在创建 Notebook 时也选择了配额,但 Notebook 实际也不会受到队列配额的限制。 + + ![local-queue-initialization-failed](./images/kueue-k8s127.png) + +- 解决办法:提前规划,生产环境中建议使用 Kubernetes 版本 `v1.27` 以上。 + +- 参考资料:[Jupyter Notebook Documentation](https://jupyter-notebook.readthedocs.io/en/latest/) + +## 问题 02: 配置未启用 + +- 分析: + + 当 Kubernetes 集群版本 大于 v1.27 时,Notebook 仍无法受到队列配额的限制。 + + 这是因为,Kueue 需要启用对 `enablePlainPod` 支持,才会对 Notebook 服务生效。 + + ![local-queue-initialization-failed](./images/kueue-plainpod.png) + +- 解决办法:在工作集群中部署 `baize-agent` 时,启用 Kueue 对 `enablePlainPod` 的支持。 + +- 参考资料:[Run Plain Pods as a Kueue-Managed Job](https://kueue.sigs.k8s.io/docs/tasks/run/plain_pods/) diff --git a/docs/zh/docs/admin/ghippo/access-control/custom-role.md b/docs/zh/docs/admin/ghippo/access-control/custom-role.md new file mode 100644 index 0000000..e3d03be --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/custom-role.md @@ -0,0 +1,62 @@ +# 自定义角色 + +算丰 AI 算力平台支持创建三种范围的自定义角色: + +- **平台角色** 的权限对平台所有相关资源生效 +- **工作空间角色** 的权限对该用户所在的工作空间下的资源生效 +- **文件夹角色** 的权限对该用户所在的文件夹及其下的子文件夹和工作空间资源生效 + +## 创建平台角色 + +平台角色是粗粒度角色,能够对所选权限内的所有资源生效。如授权后用户可以拥有所有工作空间的查看权限、所有集群的编辑权限等,而不能针对某个工作空间或某个集群生效。平台角色创建完成后可以在用户/用户组列表中进行授权。 + +1. 从左侧导航栏点击 __全局管理__ -> __用户与访问控制__ -> __角色__ ,点击 __创建自定义角色__ 。 + + ![创建自定义角色](../../../images/custom01.png) + +1. 输入名称、描述,选择 __平台角色__ ,勾选角色权限后点击 __确定__ 。 + + ![平台角色](../../../images/custom02.png) + +1. 返回角色列表,搜索刚创建的自定义角色,点击右侧的 __┇__ ,可以执行复制、编辑和删除等操作。 + + ![更多操作](../../../images/custom03.png) + +1. 平台角色创建成功后,可以去[用户](./user.md)/[用户组](./group.md)授权,为这个角色添加用户和用户组。 + +## 创建工作空间角色 + +工作空间角色是细粒度角色,针对某个工作空间生效。如在该角色中选择应用工作台的全部权限,给用户在某个工作空间下授予该角色后,该用户将仅能在该工作空间下使用应用工作台相关的功能,而无法使用如微服务引擎、中间件等其他模块的能力。工作空间角色创建完成后,可以在工作空间与层级中选择工作空间后进行授权。 + +1. 从左侧导航栏点击 __全局管理__ -> __用户与访问控制__ -> __角色__ ,点击 __创建自定义角色__ 。 + + ![创建自定义角色](../../../images/custom01.png) + +1. 输入名称、描述,选择 __工作空间角色__ ,勾选角色权限后点击 __确定__ 。 + + ![工作空间角色](../../../images/custom04.png) + +1. 返回角色列表,搜索刚创建的自定义角色,点击右侧的 __┇__ ,可以执行复制、编辑和删除等操作。 + + ![更多操作](../../../images/custom05.png) + +1. 工作空间角色创建成功后,可以去[工作空间](../workspace/workspace.md)授权,设定这个角色可以管理哪些工作空间。 + +## 创建文件夹角色 + +文件夹角色针对某个文件夹和该文件夹下的所有子文件夹及工作空间生效。如在该角色中选择全局管理-工作空间和应用工作台,给用户在某个文件夹下授予该角色后,该用户将能够在其下的所有工作空间中使用应用工作台的相关功能,而无法使用如微服务引擎、中间件等其他模块的能力。文件夹角色创建完成后,可以在工作空间与层级中选择文件夹后进行授权。 +请注意:应用工作台、多云编排、镜像仓库、微服务引擎、服务网格和中间件均依赖于工作空间,因此在创建文件夹角色时大部分场景下需要用到工作空间,请注意在全局管理-工作空间下勾选。 + +1. 从左侧导航栏点击 __全局管理__ -> __用户与访问控制__ -> __角色__ ,点击 __创建自定义角色__ 。 + + ![创建自定义角色](../../../images/custom01.png) + +1. 输入名称、描述,选择 __文件夹角色__ ,勾选角色权限后点击 __确定__ 。 + + ![文件夹角色](../../../images/custom06.png) + +1. 返回角色列表,搜索刚创建的自定义角色,点击右侧的 __┇__ ,可以执行复制、编辑和删除等操作。 + + ![更多操作](../../../images/custom07.png) + +1. 文件夹角色创建成功后,可以去[文件夹](../workspace/folders.md)授权,设定这个角色可以管理哪些文件夹。 diff --git a/docs/zh/docs/admin/ghippo/access-control/docking.md b/docs/zh/docs/admin/ghippo/access-control/docking.md new file mode 100644 index 0000000..1339960 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/docking.md @@ -0,0 +1,35 @@ +--- +hide: + - toc +--- + +# 接入管理 + +当两个或两个以上平台相互对接或嵌入时,通常需要进行用户体系打通。 +在用户打通过程中, __接入管理__ 主要提供 SSO 接入能力,当您需要将算丰 AI 算力平台作为用户源接入客户系统时, +您可以通过 __接入管理__ 创建 SSO 接入来实现。 + +## 创建 SSO 接入 + +前提:拥有平台管理员 Admin 权限或者用户与访问控制管理员 IAM Owner 权限。 + +1. 管理员进入 __用户与访问控制__ ,选择 __接入管理__ ,进入接入管理列表,点击右上方的 __创建 SSO 接入__ 。 + + ![创建 SSO 接入按钮](../../../images/sso1.png) + +2. 在 __创建 SSO 接入__ 页面填写客户端 ID。 + + - 客户端 ID:对应 client 名称 + - 客户端访问地址:用户完成登录并通过身份验证后,认证服务器用来重定向用户的地址,即 Callback URL + + ![创建 SSO 接入](../../images/sso2.png) + +3. 创建 SSO 接入成功后,在 __接入管理__ 管理列表,点击刚创建的客户端 ID 进入详情, + 复制客户端 ID、密钥和单点登录 URL 信息,填写至客户系统完成用户体系打通。 + + !!! note + + realm 名称为 ghippo。 + + + ![接入管理详情](../../../images/sso3.png) diff --git a/docs/zh/docs/admin/ghippo/access-control/global.md b/docs/zh/docs/admin/ghippo/access-control/global.md new file mode 100644 index 0000000..eb0e8f6 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/global.md @@ -0,0 +1,45 @@ +# 系统角色 + +## 适用场景 + +算丰 AI 算力平台提供了预置的系统角色,帮助用户简化角色权限的使用步骤。 + +!!! note + + 算丰 AI 算力平台提供了三种类型的系统角色,分别为平台角色、工作空间角色和文件夹角色。 + + - 平台角色:对平台上所有相关资源具有相应权限,请前往用户/用户组授权。 + - 工作空间角色:对某个工作空间具有相应权限,请前往具体工作空间授权。 + - 文件夹角色:对某个文件夹、子文件夹及其工作空间下的资源具有相应权限,请前往具体文件夹授权。 + +## 平台角色 + +在用户与访问控制中预定义了 5 个系统角色,分别是:Admin、IAM Owner、Audit Owner、 Kpanda Owner 和 Workspace and Folder Owner 。这 5 个角色由系统创建,用户只能使用不能修改。角色对应的权限如下: + +| 角色名称 | 角色类型 | 所属模块 | 角色权限 | +| -------------------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Admin | 系统角色 | 全部 | 平台管理员,管理所有平台资源,代表平台的最高权限 | +| IAM Owner | 系统角色 | 用户与访问控制 | 用户与访问控制的管理员,拥有该服务下的所有权限,如管理用户/用户组及授权 | +| Audit Owner | 系统角色 | 审计日志 | 审计日志的管理员,拥有该服务下的所有权限,如设置审计日志策略,导出审计日志 | +| Kpanda Owner | 系统角色 | 容器管理 | 容器管理的管理员,拥有该服务下的所有权限,如创建/接入集群,部署应用,给用户/用户组授予集群/命名空间相关的权限 | +| Workspace and Folder Owner | 系统角色 | 工作空间与层级 | 工作空间与层级管理员,拥有该服务下的所有权限,如创建文件夹/工作空间,给用户/用户组授权文件夹/工作空间的相关权限,在工作空间下使用应用工作台、微服务引擎等功能 | + +## 工作空间角色 + +在用户与访问控制中预定义了 3 个系统角色,分别是:Workspace Admin、Workspace Editor、Workspace Viewer。这 3 个角色由系统创建,用户只能使用不能修改。角色对应的权限如下: + +| 角色名称 | 角色类型 | 所属模块 | 角色权限 | +| ---------------- | -------- | -------- | ------------------ | +| Workspace Admin | 系统角色 | 工作空间 | 工作空间的管理权限 | +| Workspace Editor | 系统角色 | 工作空间 | 工作空间的编辑权限 | +| Workspace Viewer | 系统角色 | 工作空间 | 工作空间的只读权限 | + +## 文件夹角色 + +在用户与访问控制中预定义了 3 个系统角色,分别是:Folder Admin、Folder Editor、Folder Viewer。这 3 个角色由系统创建,用户只能使用不能修改。角色对应的权限如下: + +| 角色名称 | 角色类型 | 所属模块 | 角色权限 | +| ------------- | -------- | -------- | ---------------------------------------- | +| Folder Admin | 系统角色 | 工作空间 | 文件夹及其下子文件夹、工作空间的管理权限 | +| Folder Editor | 系统角色 | 工作空间 | 文件夹及其下子文件夹、工作空间的编辑权限 | +| Folder Viewer | 系统角色 | 工作空间 | 文件夹及其下子文件夹、工作空间的只读权限 | diff --git a/docs/zh/docs/admin/ghippo/access-control/group.md b/docs/zh/docs/admin/ghippo/access-control/group.md new file mode 100644 index 0000000..5410265 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/group.md @@ -0,0 +1,75 @@ +# 用户组 + +用户组是用户的集合,用户可以通过加入用户组,继承用户组的角色权限。通过用户组批量地给用户进行授权,可以更好地管理用户及其权限。 + +## 适用场景 + +当用户权限发生变化时,只需将其移到相应的用户组下,不会对其他用户产生影响。 + +当用户组的权限发生变化时,只需修改用户组的角色权限,即可应用到组内的所有用户。 + +## 创建用户组 + +前提:拥有平台管理员 Admin 权限或者用户与访问控制管理员 IAM Owner 权限。 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户组__ ,进入用户组列表,点击右上方的 __创建用户组__ 。 + + ![创建用户组](../../../images/group00.png) + +2. 在 __创建用户组__ 页面填写用户组信息。 + + ![创建用户组](../../../images/group01.png) + +3. 点击 __确定__ ,创建用户组成功,返回用户组列表页面。列表中的第一行是新创建的用户组。 + +## 为用户组授权 + +前提:该用户组已存在。 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户组__ ,进入用户组列表,点击 __...__ -> __授权__ 。 + + ![创建用户组按钮](../../../images/group02.png) + +2. 在 __授权__ 页面勾选需要的角色权限(可多选)。 + + ![创建用户组按钮](../../../images/group03.png) + +3. 点击 __确定__ 完成为用户组的授权。自动返回用户组列表,点击某个用户组,可以查看用户组被授予的权限。 + + ![创建用户组按钮](../../../images/group04.png) + +## 给用户组添加用户 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户组__ 进入用户组列表,在某个用户组右侧,点击 __...__ -> __添加用户__ 。 + + ![添加用户](../../../images/group05.png) + +2. 在 __添加用户__ 页面点选需要添加的用户(可多选)。若没有可选的用户,点击 __前往创建新用户__ ,先前往创建用户,再返回该页面点击 __刷新__ 按钮,显示刚创建的用户。 + + ![选择用户](../../../images/group06.png) + +3. 点击 __确定__ 完成给用户组添加用户。 + +!!! note + + 用户组中的用户会继承用户组的权限;可以在用户组详情中查看加入该组的用户。 + +## 删除用户组 + +说明:删除用户组,不会删除组内的用户,但组内用户将无法再继承该组的权限 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户组__ 进入用户组列表,在某个用户组右侧,点击 __...__ -> __删除__ 。 + + ![删除按钮](../../../images/deletegroup01.png) + +2. 点击 __移除__ 删除用户组。 + + ![确认删除](../../../images/deletegroup02.png) + +3. 返回用户组列表,屏幕上方将提示删除成功。 + + ![删除提示](../../../images/deletegroup03.png) + +!!! note + + 说明:删除用户组,不会删除组内的用户,但组内用户将无法再继承该组的权限。 diff --git a/docs/zh/docs/admin/ghippo/access-control/iam.md b/docs/zh/docs/admin/ghippo/access-control/iam.md new file mode 100644 index 0000000..6545f19 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/iam.md @@ -0,0 +1,44 @@ +# 什么是用户与访问控制 + +IAM(Identity and Access Management,用户与访问控制)是全局管理的一个重要模块,您可以通过用户与访问控制模块创建、管理和销毁用户(用户组),并使用系统角色和自定义角色控制其他用户使用算丰 AI 算力平台的权限。 + +![IAM 定义](../../../images/iam.png) + +## 优势 + +- 简洁流畅 + + 企业内部的结构和角色可能非常复杂,项目、工作小组及授权的管理都在不断地变化。用户与访问控制采用清晰整洁的页面,打通用户、用户组、角色之间的授权关系,以最短链路实现对用户(用户组)的授权。 + +- 适当的角色 + + 用户与访问控制为每个子模块预定义了一个管理员角色,无需用户维护,您可以直接将平台预定义的系统角色授权给用户,实现平台的模块化管理(细粒度权限请参阅[权限管理](role.md)。 + +- 企业级访问控制 + + 当您希望本企业员工可以使用企业内部的认证系统登录算丰 AI 算力平台,而不需要在算丰 AI 算力平台创建对应的用户,您可以使用用户与访问控制的身份提供商功能,建立您所在企业与算丰 AI 算力平台的信任关系,通过联合认证使员工使用企业已有账号直接登录算丰 AI 算力平台,实现单点登录。 + +## 使用流程 + +有关访问控制的常规流程为: + +```mermaid +graph TD + login[登录] --> user[创建用户] + user --> auth[为用户授权] + auth --> group[创建用户组] + group --> role[创建自定义角色] + role --> id[创建身份提供商] + + classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; + classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; + classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + class login,user,auth,group,role,id cluster; + +click login "https://docs.daocloud.io/ghippo/install/login.html" +click user "https://docs.daocloud.io/ghippo/access-control/user.html" +click auth "https://docs.daocloud.io/ghippo/access-control/role.html" +click group "https://docs.daocloud.io/ghippo/access-control/group.html" +click role "https://docs.daocloud.io/ghippo/access-control/custom-role.html" +click id "https://docs.daocloud.io/ghippo/access-control/idprovider.html" +``` diff --git a/docs/zh/docs/admin/ghippo/access-control/idprovider.md b/docs/zh/docs/admin/ghippo/access-control/idprovider.md new file mode 100644 index 0000000..d561a15 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/idprovider.md @@ -0,0 +1,35 @@ +# 身份提供商 + +全局管理支持基于 LDAP 和 OIDC 协议的单点登录,如果您的企业或组织已有自己的账号体系,同时希望管理组织内的成员使用算丰 AI 算力平台资源,您可以使用全局管理提供的身份提供商功能,而不必在您的算丰 AI 算力平台中为每一位组织成员创建用户名/密码。您可以向这些外部用户身份授予使用算丰 AI 算力平台资源的权限。 + +## 基本概念 + +- 身份提供商(Identity Provider,简称 IdP) + + 负责收集和存储用户身份信息、用户名、密码等,在用户登录时负责认证用户的服务。在企业与算丰 AI 算力平台进行身份认证的过程中,身份提供商指企业自身的身份提供商。 + +- 服务提供商(Service Provider,简称 SP) + + 服务提供商通过与身份提供商 IdP 建立信任关系,使用 IDP 提供的用户信息,为用户提供具体的服务。在企业与算丰 AI 算力平台进行身份认证的过程中,服务提供商指 算丰 AI 算力平台。 + +- LDAP + + LDAP 指轻型目录访问协议(Lightweight Directory Access Protocol),常用于单点登录,即用户可以在多个服务中使用一个账号密码进行登录。全局管理支持 LDAP 进行身份认证,因此与算丰 AI 算力平台通过 LDAP 协议建立身份认证的企业 IdP 必须支持 LDAP 协议。关于 LDAP 的详细描述请参见:[欢迎使用 LDAP](ldap.md)。 + +- OIDC + + OIDC 是 OpenID Connect 的简称,是一个基于 OAuth 2.0 协议的身份认证标准协议。全局管理支持使用 OIDC 协议进行身份认证,因此与算丰 AI 算力平台通过 OIDC 协议建立身份认证的企业 IdP 必须支持 OIDC 协议。关于 OIDC 的详细描述请参见:[欢迎使用 OpenID Connect](https://openid.net/connect/)。 + +- OAuth 2.0 + + OAuth 2.0 是 Open Authorization 2.0 的简称,是一种开放授权协议,授权框架支持第三方应用程序以自己的名义获取访问权限。 + +## 功能特性 + +- 管理员无需重新创建算丰 AI 算力平台用户 + + 使用身份提供商进行身份认证前,管理员需要在企业管理系统和算丰 AI 算力平台中分别为用户创建账号;使用身份提供商进行身份认证后,企业管理员只需要在企业管理系统中为用户创建账号,用户即可同时访问两个系统,降低了人员管理成本。 + +- 用户无需记住两套平台账号 + + 使用身份提供商进行身份认证前,用户访问企业管理系统和算丰 AI 算力平台需要使用两个系统的账号登录;使用身份提供商进行身份认证后,用户在本企业管理系统中登录即可访问两个系统。 diff --git a/docs/zh/docs/admin/ghippo/access-control/ldap.md b/docs/zh/docs/admin/ghippo/access-control/ldap.md new file mode 100644 index 0000000..df14031 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/ldap.md @@ -0,0 +1,71 @@ +--- +hide: + - toc +--- + +# LDAP + +LDAP 英文全称为 Lightweight Directory Access Protocol,即轻型目录访问协议,这是一个开放的、中立的工业标准应用协议, +通过 IP 协议提供访问控制和维护分布式信息的目录信息。 + +如果您的企业或组织已有自己的账号体系,同时您的企业用户管理系统支持 LDAP 协议,就可以使用全局管理提供的基于 +LDAP 协议的身份提供商功能,而不必在算丰 AI 算力平台中为每一位组织成员创建用户名/密码。 +您可以向这些外部用户身份授予使用算丰 AI 算力平台资源的权限。 + +在全局管理中,其操作步骤如下: + +1. 使用具有 __admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏左下角的 __全局管理__ -> __用户与访问控制__ 。 + + ![global](../../../images/ws01_2.png) + +2. 在左侧导航栏点击 __身份提供商__ ,点击 __创建身份提供商__ 按钮。 + + ![身份提供商](../images/ldap00.png) + +3. 在 __LDAP__ 页签中,填写以下字段后点击 __保存__ ,建立与身份提供商的信任关系及用户的映射关系。 + + ![ldap](../images/ldap01.png) + + | 字段 | 描述 | + | --- | ---- | + | 类型(Vendor) | 支持 LDAP (Lightweight Directory Access Protocol) 和 AD (Active Directory) | + | 身份提供商名称(UI display name) | 用于区分不同的身份提供商 | + | 服务器(Connection URL) | LDAP 服务的地址和端口号,如 ldap://10.6.165.2:30061 | + | 用户名称(Bind DN) | LDAP 管理员的 DN,Keycloak 将使用该 DN 来访问 LDAP 服务器 | cn=admin,dn=daocloud,dc=com | + | 密码(Bind credentials) | LDAP 管理员的密码。该字段可以从 vault 中获取其值,使用 ${vault.ID} 格式。 | + | 用户 DN(Users DN) | 您的用户所在的 LDAP 树的完整 DN。此 DN 是 LDAP 用户的父级。例如,假设您的典型用户的 DN 类似于“uid='john',ou=users,dc=example,dc=com”,则可以是“ou=users,dc=example,dc=com”。 | dc=daocloud,dc=io | + | 用户对象类(User object classes) | LDAP 中用户的 LDAP objectClass 属性的所有值,以逗号分隔。例如:“inetOrgPerson,organizationalPerson”。新创建的 Keycloak 用户将与所有这些对象类一起写入 L​​DAP,并且只要现有 LDAP 用户记录包含所有这些对象类,就会找到它们。 | + | 是否启用TLS(Enable StartTLS) | 启用后将加密算丰 AI 算力平台与 LDAP 的连接 | + | 预设权限(Default permission) | 同步后的用户/用户组默认没有任何权限 | + | 全名映射(First/Last name mapping) | 对应 First name 和 Last Name | + | 用户名映射(User name mapping) | 用户唯一的用户名 | + | 邮箱映射(Mailbox mapping) | 用户的邮箱 | + + **高级配置** + + | 字段 | 描述 | + | --- | --- | + | 是否启用(Enable or not) | 默认启用,关闭后该 LDAP 配置不生效 | + | 自动同步用户(Periodic full sync) | 默认不启用,启用后可配置同步周期,如每小时同步一次 | + | 数据同步模式(Edit mode) | 只读模式不会修改 LDAP 的源数据;写入模式在平台编辑用户信息后,数据将同步回LDAP | + | 读取超时(Read timeout) |当LDAP数据量较大时,调整该数值可以有效避免接口超时 | + | 用户对象过滤器(User LDAP filter) | 用于过滤搜索用户的附加 LDAP 过滤器。如果您不需要额外的过滤器,请将其留空。确保它以“(”开头,并以“)”结尾。 | + |用户名属性(Username LDAP attribute) | LDAP 属性的名称,映射为 Keycloak 用户名。对于许多 LDAP 服务器供应商来说,它可以是“uid”。对于 Active Directory,它可以是“sAMAccountName”或“cn”。应为您想要从 LDAP 导入到 Keycloak 的所有 LDAP 用户记录填写该属性。 | + | RDN属性(RDN LDAP attribute) | LDAP 属性名称,作为典型用户DN的RDN(顶级属性)。通常它与用户名 LDAP 属性相同,但这不是必需的。例如,对于 Active Directory,当用户名属性可能是“sAMAccountName”时,通常使用“cn”作为 RDN 属性。 | + | UUID属性(UUID LDAP attribute) | LDAP 属性的名称,用作 LDAP 中对象的唯一对象标识符 (UUID)。对于许多 LDAP 服务器供应商来说,它是“entryUUID”;然而有些是不同的。例如,对于 Active Directory,它应该是“objectGUID”。如果您的 LDAP 服务器不支持 UUID 概念,您可以使用在树中的 LDAP 用户之间应该唯一的任何其他属性。例如“uid”或“entryDN”。 | + + +4. 在 __同步用户组__ 页签中,填写以下字段配置用户组的映射关系后,再次点击 __保存__ 。 + + ![身份提供商](../../../images/ldap02.png) + + | 字段 | 描述 | 举例值 | + | --- | ---- | ------ | + | 基准 DN | 用户组在 LDAP 树状结构中的位置 | ou=groups,dc=example,dc=org | + | 用户组对象过滤器 | 用户组的对象类,如果需要更多类,则用逗号分隔。在典型的 LDAP 部署中,通常是 “groupOfNames”,系统已自动填入,如需更改请直接编辑。* 表示所有。 | * | + | 用户组名 | cn | 不可更改 | + +!!! note + + 1. 当您通过 LDAP 协议将企业用户管理系统与算丰 AI 算力平台建立信任关系后,可通过手动同步或自动同步的方式,将企业用户管理系统中的用户或用户组一次性同步至 算丰 AI 算力平台。 + 1. 同步后管理员可对用户组/用户组进行批量授权,同时用户可通过在企业用户管理系统中的账号/密码登录 AI 算力平台。 diff --git a/docs/zh/docs/admin/ghippo/access-control/oauth2.0.md b/docs/zh/docs/admin/ghippo/access-control/oauth2.0.md new file mode 100644 index 0000000..d014148 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/oauth2.0.md @@ -0,0 +1,39 @@ +--- +hide: + - toc +--- + +# OAuth 2.0 - 企业微信 + +如果您的企业或组织中的成员均管理在企业微信中,您可以使用全局管理提供的基于 OAuth 2.0 协议的身份提供商功能, +而不必在算丰 AI 算力平台中为每一位组织成员创建用户名/密码。 您可以向这些外部用户身份授予使用算丰 AI 算力平台资源的权限。 + +## 操作步骤 + +1. 使用具有 **Admin** 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 **全局管理** -> **用户与访问控制** 。 + + ![用户与访问控制](../../images/access.png) + +2. 在左侧导航栏选择 **身份提供商** ,点击 **OAuth2.0** 页签。填写表单字段,建立与企业微信的信任关系后,点击 **保存** 。 + + ![Oauth2.0](../../images/oauth2.png) + +## 企业微信中对应的字段 + +!!! note + + 对接前需要在企业微信管理后台中创建自建应用,参阅[如何创建自建应用链接](https://open.work.weixin.qq.com/help2/pc/16892?person_id=1&searchData=)。 + + | 字段 | 描述 | + | ----------- | ---------------| + | 企业 ID | 企业微信的 ID | + | Agent ID | 自建应用的 ID | + | ClientSecret | 自建应用的 Secret | + +企业微信 ID: + +![Oauth2.0](../../images/mybusiness.png) + +Agent ID 和 ClientSecret: + +![agent](../../images/selfapplication.png) diff --git a/docs/zh/docs/admin/ghippo/access-control/oidc.md b/docs/zh/docs/admin/ghippo/access-control/oidc.md new file mode 100644 index 0000000..fdb2280 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/oidc.md @@ -0,0 +1,52 @@ +# 创建和管理 OIDC + +OIDC(OpenID Connect)是建立在 OAuth 2.0 基础上的一个身份层,是基于 OAuth2 协议的身份认证标准协议。 + +如果您的企业或组织已有自己的账号体系,同时您的企业用户管理系统支持 OIDC 协议, +可以使用全局管理提供的基于 OIDC 协议的身份提供商功能,而不必在算丰 AI 算力平台中为每一位组织成员创建用户名/密码。 +您可以向这些外部用户身份授予使用算丰 AI 算力平台资源的权限。 + +具体操作步骤如下。 + +1. 使用具有 __admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ -> __用户与访问控制__ 。 + + ![全局管理](../images/access.png) + +2. 在左侧导航栏选择 __身份提供商__ ,点击 __OIDC__ 页签 -> **创建身份提供商** 按钮。 + + ![点击创建按钮](../images/oidc-button.png) + +3. 填写表单字段,建立与身份提供商的信任关系后,点击 __确定__ 。 + + ![填写表单](../images/oidc02.png) + + | 字段 | 描述 | + | ---------- | ------------------------------------------------------------ | + | 提供商名称 | 显示在登录页上,是身份提供商的入口 | + | 认证方式 | 客户端身份验证方法。如果 JWT 使用私钥签名,请下拉选择 __JWT signed with private key__ 。具体参阅 [Client Authentication](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication)。 | + | 客户端 ID | 客户端的 ID | + | 客户端密钥 | 客户端密码 | + | 客户端 URL | 可通过身份提供商 well-known 接口一键获取登录 URL、Token URL、用户信息 URL 和登出 URL | + | 自动关联 | 开启后当身份提供商用户名/邮箱与算丰 AI 算力平台用户名/邮箱重复时将自动使二者关联 | + +!!! note + + 1. 当用户通过企业用户管理系统完成第一次登录算丰 AI 算力平台后,用户信息才会被同步至算丰 AI 算力平台的 __用户与访问控制__ -> __用户列表__ 。 + 1. 初次登录的用户不会被赋予任何默认权限,需要有管理员给其赋权(管理员可以是平台管理员、子模块管理员或资源管理员)。 + 1. 参考 + [Azure OpenID Connect (OIDC) 接入流程](https://learn.microsoft.com/zh-cn/azure/active-directory/develop/v2-protocols-oidc)。 + +## 用户身份认证交互流程 + +用户身份认证的交互流程为: + +![oidc](../../../images/oidc01.png) + +1. 使用浏览器发起单点登录算丰 AI 算力平台的请求。 +1.算丰 AI 算力平台根据登录链接中携带的信息,查找 __全局管理__ -> __用户与访问控制__ -> __身份提供商__ 中对应的配置信息, + 构建 OIDC 授权 Request,发送给浏览器。 +1. 浏览器收到请求后,转发 OIDC 授权 Request 给企业 IdP。 +1. 在企业 IdP 的登录页面中输入用户名和密码,企业 IdP 对提供的身份信息进行验证,并构建携带用户信息的 ID Token,向浏览器发送 OIDC 授权 Response。 +1. 浏览器响应后转发 OIDC 授权 Response 给 算丰 AI 算力平台。 +1.算丰 AI 算力平台从 OIDC 授权 Response 中取出 ID Token,并根据已配置的身份转换规则映射到具体的用户列表,颁发 Token。 +1. 完成单点登录,访问 算丰 AI 算力平台。 diff --git a/docs/zh/docs/admin/ghippo/access-control/role.md b/docs/zh/docs/admin/ghippo/access-control/role.md new file mode 100644 index 0000000..666e4c6 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/role.md @@ -0,0 +1,104 @@ +# 角色和权限管理 + +一个角色对应一组权限。权限决定了可以对资源执行的操作。向用户授予某角色,即授予该角色所包含的所有权限。 + +算丰 AI 算力平台存在三种角色范围,能够灵活、有效地解决您在权限上的使用问题: + +- [平台角色](#_2) +- [工作空间角色](#_4) +- [文件夹角色](#_6) + +## 平台角色 + +平台角色是粗粒度权限,对平台上所有相关资源具有相应权限。通过平台角色可以赋予用户对所有集群、所有工作空间等的增删改查权限, +而不能具体到某一个集群或某一个工作空间。算丰 AI 算力平台提供了 5 个预置的、用户可直接使用的平台角色: + +- Admin +- Kpanda Owner +- Workspace and Folder Owner +- IAM Owner +- Audit Owner + +![5 个预置平台角色](../../../images/newrole01.png) + +同时,算丰 AI 算力平台还支持用户创建自定义平台角色,可根据需要自定义角色内容。 +如创建一个平台角色,包含应用工作台的所有功能权限,由于应用工作台依赖于工作空间, +因此平台会帮助用户默认勾选工作空间的查看权限,请不要手动取消勾选。 +若用户 A 被授予该 Workbench(应用工作台)角色,将自动拥有所有工作空间下的应用工作台相关功能的增删改查等权限。 + +![权限列表](../../../images/newrole02.png) + +### 平台角色授权方式 + +给平台角色授权共有三种方式: + +- 在 __全局管理__ -> __用户与访问控制__ -> __用户__ 的用户列表中,找到该用户,点击 __...__ ,选择 __授权__ ,为该用户赋予平台角色权限。 + + ![点击授权](../../../images/newrole03.png) + +- 在 __全局管理__ -> __用户与访问控制__ -> __用户组__ 的用户组列表中创建用户组,将该用户加入用户组,并给用户组授权 + (具体操作为:在用户组列表找到该用户组,点击 __...__ ,选择 __授权__ ,为该用户组赋予平台角色)。 + + ![点击授权](../../../images/newrole04.png) + +- 在 __全局管理__ -> __用户与访问控制__ -> __角色__ 的角色列表中,找到相应的平台角色, + 点击角色名称进入详情,点击 __关联成员__ 按钮,选中该用户或用户所在的用户组,点击 __确定__ 。 + + ![关联成员按钮](../../../images/newrole05.png) + +## 工作空间角色 + +工作空间角色是细粒度角色,通过工作空间角色可以赋予用户某个工作空间的管理权限、查看权限或该工作空间应用工作台相关的权限等。 +获得该角色权限的用户只能管理该工作空间,而无法访问其他工作空间。算丰 AI 算力平台提供了 3 个预置的、用户可直接使用的工作空间角色: + +- Workspace Admin +- Workspace Editor +- Workspace Viewer + +![3 种工作空间预置角色](../../../images/newrole06.png) + +同时,算丰 AI 算力平台还支持用户创建自定义工作空间角色,可根据需要自定义角色内容。如创建一个工作空间角色, +包含应用工作台的所有功能权限,由于应用工作台依赖于工作空间,因此平台会帮助用户默认勾选工作空间的查看权限, +请不要手动取消勾选。若用户 A 在工作空间 01 中被授予该角色,将拥有工作空间 01 下的应用工作台相关功能的增删改查权限。 + +!!! note + + 与平台角色不同,工作空间角色被创建后需要前往工作空间使用,被授权后用户仅在该工作空间下拥有该角色中的功能权限。 + +### 工作空间角色授权方式 + +在 __全局管理__ -> __工作空间与层级__ 列表中,找到该工作空间,点击 __添加授权__ ,为该用户赋予工作空间角色权限。 + +![添加授权按钮](../../../images/newrole07.png) + +![填写和选择](../../../images/newrole08.png) + +## 文件夹角色 + +文件夹角色的权限粒度介于平台角色与工作空间角色之间,通过文件夹角色可以赋予用户某个文件夹及其子文件夹和该文件夹下所有工作空间的管理权限、查看权限等, +常适用于企业中的部门场景。比如用户 B 是一级部门的 Leader,通常用户 B 能够管理该一级部门、其下的所有二级部门和部门中的项目等, +在此场景中给用户 B 授予一级文件夹的管理员权限,用户 B 也将拥有其下的二级文件夹和工作空间的相应权限。 +算丰 AI 算力平台提供了 3 个预置的、用户可直接使用文件夹角色: + +- Folder Admin +- Folder Editor +- Folder Viewer + +![3 种预置文件夹角色](../../../images/newrole09.png) + +同时,算丰 AI 算力平台还支持用户创建自定义文件夹角色,可根据需要自定义角色内容。 +如创建一个文件夹角色,包含应用工作台的所有功能权限。若用户 A 在文件夹 01 中被授予该角色, +将拥有该文件夹下所有工作空间中应用工作台相关功能的增删改查权限。 + +!!! note + + 功能模块本身依赖的是工作空间,文件夹是工作空间上的进一步分组机制且具有权限继承能力, + 因此文件夹权限不光包含文件夹本身,还包括其下的子文件夹和工作空间。 + +### 文件夹角色授权方式 + +在 __全局管理__ -> __工作空间与层级__ 列表中,找到该文件夹,点击 __添加授权__ ,为该用户赋予文件夹角色权限。 + +![添加授权按钮](../../../images/newrole10.png) + +![填写和选择](../../../images/newrole11.png) diff --git a/docs/zh/docs/admin/ghippo/access-control/user.md b/docs/zh/docs/admin/ghippo/access-control/user.md new file mode 100644 index 0000000..815d1ce --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/user.md @@ -0,0 +1,107 @@ +# 用户 + +用户指的是由平台管理员 admin 或者用户与访问控制管理员 IAM Owner 在 __全局管理__ -> __用户与访问控制__ -> __用户__ 页面创建的用户,或者通过 LDAP / OIDC 对接过来的用户。 +用户名代表账号,用户通过用户名和密码登录算丰 AI 算力平台。 + +拥有一个用户账号是用户访问平台的前提。新建的用户默认没有任何权限,例如您需要给用户赋予相应的角色权限,比如在 __用户列表__ 或 __用户详情__ 授予子模块的管理员权限。 +子模块管理员拥有该子模块的最高权限,能够创建、管理、删除该模块的所有资源。 +如果用户需要被授予具体资源的权限,比如某个资源的使用权限,请查看[资源授权说明](#grant-admin-permissions)。 + +本页介绍用户的创建、授权、禁用、启用、删除等操作。 + +## 创建用户 + +前提:拥有平台管理员 Admin 权限或者用户与访问控制管理员 IAM Owner 权限。 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户__ ,进入用户列表,点击右上方的 __创建用户__ 。 + + ![创建用户按钮](../../../images/createuser01.png) + +2. 在 __创建用户__ 页面填写用户名和登录密码。如需一次性创建多个用户,可以点击 __创建用户__ 后进行批量创建,一次性最多创建 5 个用户。根据您的实际情况确定是否设置用户在首次登录时重置密码。 + + ![设置用户名和密码](../../../images/createuser02.png) + +3. 点击 __确定__ ,创建用户成功,返回用户列表页。 + +!!! note + + 此处设置的用户名和密码将用于登录平台。 + +## 为用户授予子模块管理员权限 {#grant-admin-permissions} + +前提:该用户已存在。 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户__ ,进入用户列表,点击 __┇__ -> __授权__ 。 + + ![授权菜单](../../../images/authorize01.png) + +2. 在 __授权__ 页面勾选需要的角色权限(可多选)。 + + ![授权界面](../../../images/authorize02.png) + +3. 点击 __确定__ 完成为用户的授权。 + +!!! note + + 在用户列表中,点击某个用户,可以进入用户详情页面。 + +## 将用户加入用户组 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户__ ,进入用户列表,点击 __┇__ -> __加入用户组__ 。 + + ![加入用户组菜单](../../../images/joingroup01.png) + +2. 在 __加入用户组__ 页面勾选需要加入的用户组(可多选)。若没有可选的用户组,点击 __创建用户组__ 创建用户组,再返回该页面点击 __刷新__ 按钮,显示刚创建的用户组。 + + ![加入用户组界面](../../../images/joingroup02.png) + +3. 点击 __确定__ 将用户加入用户组。 + +!!! note + + 用户会继承用户组的权限,可以在 __用户详情__ 中查看该用户已加入的用户组。 + +## 启用/禁用用户 + +禁用用户后,该用户将无法再访问平台。与删除用户不同,禁用的用户可以根据需要再次启用,建议删除用户前先禁用,以确保没有关键服务在使用该用户创建的密钥。 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户__ ,进入用户列表,点击一个用户名进入用户详情。 + + ![用户详情](../../../images/createuser03.png) + +2. 点击右上方的 __编辑__ ,关闭状态按钮,使按钮置灰且处于未启用状态。 + + ![编辑](../../../images/enableuser.png) + +3. 点击 __确定__ 完成禁用用户的操作。 + +## 忘记密码 + +前提:需要设置用户邮箱,有两种方式可以设置用户邮箱。 + +- 管理员在该用户详情页面,点击 __编辑__ ,在弹出框输入用户邮箱地址,点击 __确定__ 完成邮箱设置。 + + ![编辑](../../../images/enableuser.png) + +- 用户还可以进入 __个人中心__ ,在 __安全设置__ 页面设置邮箱地址。 + + ![个人中心](../../../images/mailbox.png) + +如果用户登录时忘记密码,请参考[重置密码](../password.md)。 + +## 删除用户 + +!!! warning + + 删除用户后,该用户将无法再通过任何方式访问平台资源,请谨慎删除。 + 在删除用户之前,请确保您的关键程序不再使用该用户创建的密钥。 + 如果您不确定,建议在删除前先禁用该用户。 + 如果您删除了一个用户,然后再创建一个同名的新用户,则新用户将被视为一个新的独立身份,它不会继承已删除用户的角色。 + +1. 管理员进入 __用户与访问控制__ ,选择 __用户__ ,进入用户列表,点击 __┇__ -> __删除__ 。 + + ![删除用户菜单](../../../images/deleteuser01.png) + +2. 点击 __移除__ 完成删除用户的操作。 + + ![删除用户确认](../../../images/deleteuser02.png) diff --git a/docs/zh/docs/admin/ghippo/access-control/webhook.md b/docs/zh/docs/admin/ghippo/access-control/webhook.md new file mode 100644 index 0000000..d0cdf8e --- /dev/null +++ b/docs/zh/docs/admin/ghippo/access-control/webhook.md @@ -0,0 +1,92 @@ +# Webhook 消息通知 + +算丰 AI 算力平台在接入客户的系统后,可以创建 Webhook,在用户创建/更新/删除/登录/登出之时发送消息通知。 + +Webhook 是一种用于实现实时事件通知的机制。它允许一个应用程序将数据或事件推送到另一个应用程序, +而无需轮询或持续查询。通过配置 Webhook,您可以指定在某个事件发生时,由目标应用程序接收并处理通知。 + +Webhook 的工作原理如下: + +1. 源应用程序(算丰 AI 算力平台)执行某个特定操作或事件。 +2. 源应用程序将相关数据和信息打包成 HTTP 请求,并将其发送到目标应用程序指定的 URL(例如企业微信群机器人)。 +3. 目标应用程序接收到请求后,根据其中的数据和信息进行相应的处理。 + +通过使用 Webhook,您可以实现以下功能: + +- 实时通知:当某个特定事件发生时,通过 Webhook 及时通知其他应用程序。 +- 自动化处理:目标应用程序可以根据收到的 Webhook 请求自动触发事先定义好的操作,无需手动干预。 +- 数据同步:通过 Webhook 将数据从一个应用程序传递到另一个应用程序,实现数据的同步更新。 + +常见的应用场景包括: + +- 版本控制系统(例如 GitHub、GitLab)中,当代码仓库发生变动时,自动触发构建和部署操作。 +- 电子商务平台中,当订单状态发生变化时,向物流系统发送更新通知。 +- 聊天机器人平台中,当接收到用户消息时,通过 Webhook 将消息推送到目标服务器进行处理。 + +## 配置步骤 + +算丰 AI 算力平台图形化配置 Webhook 的操作步骤如下: + +1. 在 __全局管理__ -> __用户与访问控制__ -> __接入管理__ ,创建一个客户端 ID。 + + ![oem in](../../../images/webh01.png) + +1. 点击某个客户端 ID,进入详情页,点击 __创建 Webhook__ 按钮。 + + ![button](../../../images/webh02.png) + +1. 在弹窗中填入字段信息后点击 __确定__ 。 + + - 对象:目前仅支持 __用户__ 对象 + - 行为:用户创建/更新/删除/登录/登录时发送 Webhook 消息 + - URL:接收消息的地址 + - Method:视情况选择适用的方法,例如企业微信推荐使用 POST 方法 + - 高级配置:可以用 Json 编写消息体。如果是企业微信群,请参阅[群机器人配置说明](https://developer.work.weixin.qq.com/document/path/91770) + + ![fill](../../../images/webh03.png) + +1. 屏幕提示 Webhook 创建成功。 + + ![success](../../../images/webh04.png) + +1. 现在去试着创建一个用户。 + + ![create](../../../images/webh05.png) + +1. 用户创建成功,可以看到企业微信群收到了一条消息。 + + ![message](../../../images/webh06.png) + +## 高级配置示例 + +**系统默认的消息体** + +算丰 AI 算力平台预先定义了一些变量,您可以根据自己情况在消息体中使用这些变量。 + +```json +{ + "id": "{{$$.ID$$}}", + "email": "{{$$.Email$$}}", + "username": "{{$$.Name$$}}", + "last_name": "{{$$.LastName$$}}", + "first_name": "{{$$.FirstName$$}}", + "created_at": "{{$$.CreatedAt$$}}", + "enabled": "{{$$.Enabled$$}}" +} +``` + +**企业微信群机器人的 Message Body** + +```json +{ + "msgtype": "text", + "text": { + "content": "{{$$.Name$$}} hello world" + } +} +``` + +## 参考文档 + +- [OEM OUT 文档](../../best-practice/oem/oem-out.md) +- [OEM IN 文档](../../best-practice/oem/oem-in.md) diff --git a/docs/zh/docs/admin/ghippo/audit/audit-log.md b/docs/zh/docs/admin/ghippo/audit/audit-log.md new file mode 100644 index 0000000..946d043 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/audit-log.md @@ -0,0 +1,65 @@ +# 审计日志 + +审计日志帮助您监控并记录每个用户的活动,提供了与安全相关的、按时间顺序排列的记录的收集、存储和查询功能。 +借助审计日志服务,您可以持续监控并保留用户在全局管理模块的使用行为,包括但不限于创建用户、用户登录/登出、用户授权以及与 Kubernetes 相关的用户操作行为。 + +## 功能特性 + +审计日志功能具有以下特点: + +- 开箱即用:在安装使用该平台时,审计日志功能将会被默认启用,自动记录与用户相关的各种行为, + 如创建用户、授权、登录/登出等。默认可以在平台内查看 365 天的用户行为。 +- 安全分析:审计日志会对用户操作进行详细的记录并提供导出功能,通过这些事件您可以判断账号是否存在风险。 +- 实时记录:迅速收集操作事件,用户操作后可在审计日志列表进行追溯,随时发现可疑行为。 +- 方便可靠:审计日志支持手动清理和自动清理两种方式,可根据您的存储大小配置清理策略。 + +## 查看审计日志 + +1. 使用具有 __admin__ 或 __Audit Owner__ 角色的用户登录 AI 算力平台。 + + ![登录 AI 算力平台](../../../images/lang00.png) + +2. 在左侧导航栏底部,点击 __全局管理__ -> __审计日志__ 。 + + ![审计日志](../../../images/audit01.png) + +## 用户操作 + +在 __用户操作__ 页签中,可以按时间范围,也可以通过模糊搜索、精确搜索来查找用户操作事件。 + +点击某个事件最右侧的 __┇__ ,可以查看事件详情。 + +![用户审计日志](../../../images/audit02.png) + +事件详情如下图所示。 + +![用户事件详情](../../../images/audit03.png) + +点击右上角的 __导出__ 按钮,可以按 CSV 和 Excel 格式导出当前所选时间范围内的用户操作日志。 + +![导出](../../../images/audit04.png) + +## 系统操作 + +在 __系统操作__ 页签中,可以按时间范围,也可以通过模糊搜索、精确搜索来查找系统操作事件。 + +同样点击某个事件最右侧的 __┇__ ,可以查看事件详情。 + +![系统事件详情](../../../images/audit05.png) + +点击右上角的 __导出__ 按钮,可以按 CSV 和 Excel 格式导出当前所选时间范围内的系统操作日志。 + +![导出](../../../images/audit06.png) + +## 设置 + +在 __设置__ 页签中,您可以清理用户操作和系统操作的审计日志。 + +![清理](../../../images/audit07.png) + +可以手动清理,建议清理前先导出并保存。也可以设置日志的最长保存时间实现自动清理。 + +!!! note + + 审计日志中与 Kubernetes 相关的日志记录由可观测性模块提供,为减轻审计日志的存储压力,全局管理默认不采集 Kubernetes 相关日志。 + 如需记录请参阅开启 [K8s 审计日志](./open-k8s-audit.md)。开启后的清理功能与全局管理的清理功能一致,但互不影响。 diff --git a/docs/zh/docs/admin/ghippo/audit/gproduct-audit/ghippo.md b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/ghippo.md new file mode 100644 index 0000000..6e934d9 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/ghippo.md @@ -0,0 +1,60 @@ +--- +hide: + - toc +--- + +# 全局管理审计项汇总 + +| 事件名称 | 资源类型 | 备注 | +| --- | --- | --- | +| 修改用户email:UpdateEmail-Account | Account | | +| 修改用户密码:UpdatePassword-Account | Account | | +| 创建sk:CreateAccessKeys-Account | Account | | +| 修改sk:UpdateAccessKeys-Account | Account | | +| 删除sk:DeleteAccessKeys-Account | Account | | +| 创建用户:Create-User | User | | +| 删除用户:Delete-User | User | | +| 更新用户信息:Update-User | User | | +| 更新用户角色: UpdateRoles-User | User | | +| 设置用户密码: UpdatePassword-User | User | | +| 创建用户密钥: CreateAccessKeys-User | User | | +| 更新用户密钥: UpdateAccessKeys-User | User | | +| 删除用户密钥:DeleteAccessKeys-User | User | | +| 创建用户组:Create-Group | Group | | +| 删除用户组:Delete-Group | Group | | +| 更新用户组:Update-Group | Group | | +| 添加用户至用户组:AddUserTo-Group | Group | | +| 从用户组删除用户: RemoveUserFrom-Group | Group | | +| 更新用户组角色: UpdateRoles-Group | Group | | +| 角色关联用户:UpdateRoles-User | User | | +| 创建Ldap :Create-LADP | LADP | | +| 更新Ldap:Update-LADP | LADP | | +| 删除Ldap : Delete-LADP | LADP | OIDC没有走APIserver审计不到 | +| 登录:Login-User | User | | +| 登出:Logout-User | User | | +| 设置密码策略:UpdatePassword-SecurityPolicy | SecurityPolicy | | +| 设置会话超时:UpdateSessionTimeout-SecurityPolicy | SecurityPolicy | | +| 设置账号锁定:UpdateAccountLockout-SecurityPolicy | SecurityPolicy | | +| 设置自动登出:UpdateLogout-SecurityPolicy | SecurityPolicy | | +| 邮件服务器设置 MailServer-SecurityPolicy | SecurityPolicy | | +| 外观定制 CustomAppearance-SecurityPolicy | SecurityPolicy | | +| 正版授权 OfficialAuthz-SecurityPolicy | SecurityPolicy | | +| 创建工作空间:Create-Workspace | Workspace | | +| 删除工作空间:Delete-Workspace | Workspace | | +| 绑定资源:BindResourceTo-Workspace | Workspace | | +| 解绑资源:UnBindResource-Workspace | Workspace | | +| 绑定共享资源:BindShared-Workspace | Workspace | | +| 设置资源配额:SetQuota-Workspace | Workspace | | +| 工作空间授权:Authorize-Workspace | Workspace | | +| 删除授权 DeAuthorize-Workspace | Workspace | | +| 编辑授权 UpdateDeAuthorize-Workspace | Workspace | | +| 更新工作空间 Update-Workspace | Workspace | | +| 创建文件夹:Create-Folder | Folder | | +| 删除文件夹:Delete-Folder | Folder | | +| 编辑文件夹授权:UpdateAuthorize-Folder | Folder | | +| 更新文件夹:Update-Folder | Folder | | +| 新增文件夹授权:Authorize-Folder | Folder | | +| 删除文件夹授权:DeAuthorize-Folder | Folder | | +| 设置审计日志自动清理:AutoCleanup-Audit | Audit | | +| 手动清理审计日志:ManualCleanup-Audit | Audit | | +| 导出审计日志:Export-Audit | Audit | | \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/audit/gproduct-audit/insight.md b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/insight.md new file mode 100644 index 0000000..3191ef4 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/insight.md @@ -0,0 +1,50 @@ +--- +hide: + - toc +--- + +# 可观测性审计项汇总 + +| 事件名称 | 资源类型 | 备注 | +| --- | --- | --- | +| 创建拨测任务:Create-ProbeJob | ProbeJob | | +| 编辑拨测任务:Update-ProbeJob | ProbeJob | | +| 删除拨测任务:Delete-ProbeJob | ProbeJob | | +| 创建告警策略:Create-AlertPolicy | AlertPolicy | | +| 编辑告警策略:Update-AlertPolicy | AlertPolicy | | +| 删除告警策略:Delete-AlertPolicy | AlertPolicy | | +| 导入告警策略:Import-AlertPolicy | AlertPolicy | | +| 在告警策略中添加规则:Create-AlertRule | AlertRule | | +| 在告警策略中编辑规则:Update-AlertRule | AlertRule | | +| 在告警策略中删除规则:Delete-AlertRule | AlertRule | | +| 创建告警模板:Create-RuleTemplate | RuleTemplate | | +| 编辑告警模板:Update-RuleTemplate | RuleTemplate | | +| 删除告警模板:Delete-RuleTemplate | RuleTemplate | | +| 创建邮箱组:Create-email | email | | +| 编辑邮箱组:Update-email | email | | +| 删除邮箱组:Delete-Receiver | Receiver | | +| 创建钉钉机器人:Create-dingtalk | dingtalk | | +| 编辑钉钉机器人:Update-dingtalk | dingtalk | | +| 删除钉钉机器人:Delete-Receiver | Receiver | | +| 创建企微机器人:Create-wecom | wecom | | +| 编辑企微机器人:Update-wecom | wecom | | +| 删除企微机器人:Delete-Receiver | Receiver | | +| 创建 Webhook:Create-webhook | webhook | | +| 编辑 Webhook:Update-webhook | webhook | | +| 删除 Webhook:Delete-Receiver | Receiver | | +| 创建 SMS:Create-sms | sms | | +| 编辑 SMS:Update-sms | sms | | +| 删除 SMS:Delete-Receiver | Receiver | | +| 创建 SMS 服务器:Create-aliyun(或者:tencent,custom) | aliyun, tencent, custom | | +| 编辑 SMS 服务器:Update-aliyun(或者:tencent,custom) | aliyun, tencent, custom | | +| 删除 SMS 服务器:Delete-SMSserver | SMSserver | | +| 创建消息模板:Create-MessageTemplate | MessageTemplate | | +| 编辑消息模板:Update-MessageTemplate | MessageTemplate | | +| 删除消息模板:Delete-MessageTemplate | MessageTemplate | | +| 创建告警静默:Create-AlertSilence | AlertSilence | | +| 编辑告警静默:Update-AlertSilence | AlertSilence | | +| 删除告警静默:Delete-AlertSilence | AlertSilence | | +| 创建告警抑制规则:Create-AlertInhibition | AlertInhibition | | +| 编辑告警抑制规则:Update-AlertInhibition | AlertInhibition | | +| 删除告警抑制规则:Delete-AlertInhibition | AlertInhibition | | +| 更新系统配置:Update-SystemSettings | SystemSettings | | diff --git a/docs/zh/docs/admin/ghippo/audit/gproduct-audit/kpanda.md b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/kpanda.md new file mode 100644 index 0000000..f529dbf --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/kpanda.md @@ -0,0 +1,48 @@ +--- +hide: + - toc +--- + +# 容器管理审计项汇总 + +| 事件名称 | 资源类型 | +| ------- | ------ | +| 创建集群:Create-Cluster | Cluster | +| 卸载集群:Delete-Cluster | Cluster | +| 接入集群:Integrate-Cluster | Cluster | +| 解除接入的集群:Remove-Cluster | Cluster | +| 集群升级:Upgrade-Cluster | Cluster | +| 集群接入节点:Integrate-Node | Node | +| 集群节点移除:Remove-Node | Node | +| 集群节点 GPU 模式切换:Update-NodeGPUMode | NodeGPUMode | +| helm仓库创建:Create-HelmRepo | HelmRepo | +| helm应用部署:Create-HelmApp | HelmApp | +| helm应用删除:Delete-HelmApp | HelmApp | +| 创建无状态负载:Create-Deployment | Deployment | +| 删除无状态负载:Delete-Deployment | Deployment | +| 创建守护进程:Create-DaemonSet | DaemonSet | +| 删除守护进程:Delete-DaemonSet | DaemonSet | +| 创建有状态负载:Create-StatefulSet | StatefulSet | +| 删除有状态负载:Delete-StatefulSet | StatefulSet | +| 创建任务:Create-Job | Job | +| 删除任务:Delete-Job | Job | +| 创建定时任务:Create-CronJob | CronJob | +| 删除定时任务:Delete-CronJob | CronJob | +| 删除容器组:Delete-Pod | Pod | +| 创建服务:Create-Service | Service | +| 删除服务:Delete-Service | Service | +| 创建路由:Create-Ingress | Ingress | +| 删除路由:Delete-Ingress | Ingress | +| 创建存储池:Create-StorageClass | StorageClass | +| 删除存储池:Delete-StorageClass | StorageClass | +| 创建数据卷:Create-PersistentVolume | PersistentVolume | +| 删除数据卷:Delete-PersistentVolume | PersistentVolume | +| 创建数据卷声明:Create-PersistentVolumeClaim | PersistentVolumeClaim | +| 删除数据卷声明:Delete-PersistentVolumeClaim | PersistentVolumeClaim | +| 删除副本集:Delete-ReplicaSet | ReplicaSet | +| ns绑定工作空间:BindResourceTo-Workspace | Workspace | +| ns解绑工作空间 :UnBindResource-Workspace | Workspace | +| 集群绑定工作空间:BindResourceTo-Workspace | Workspace | +| 集群解绑工作空间:UnBindResource-Workspace | Workspace | +| 打开控制台:Create-CloudShell | CloudShell | +| 关闭控制台:Delete-CloudShell | CloudShell | diff --git a/docs/zh/docs/admin/ghippo/audit/gproduct-audit/virtnest.md b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/virtnest.md new file mode 100644 index 0000000..5ad9117 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/gproduct-audit/virtnest.md @@ -0,0 +1,22 @@ +--- +hide: + - toc +--- + +# 云主机审计项汇总 + +| 事件名称 | 资源类型 | 备注 | +| --- | --- | --- | +| 重启云主机:Restart-VMs | VM | | +| 云主机转换为模板:ConvertToTemplate-VMs | VM | | +| 编辑云主机:Edit-VMs | VM | | +| 更新云主机:Update-VMs | VM | | +| 快照恢复:Restore-VMs | VM | | +| 开机云主机:Power on-VMs | VM | | +| 实时迁移:LiveMigrate-VMs | VM | | +| 删除云主机:Delete-VMs | VM | | +| 删除云主机模板:Delete-VM Template | VM Template | | +| 创建云主机:Create-VMs | VM | | +| 创建快照:CreateSnapshot-VMs | VM | | +| 关机云主机:Power off-VMs | VM | | +| 克隆云主机:Clone-VMs | VM | | diff --git a/docs/zh/docs/admin/ghippo/audit/open-audit.md b/docs/zh/docs/admin/ghippo/audit/open-audit.md new file mode 100644 index 0000000..a2ec68a --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/open-audit.md @@ -0,0 +1,126 @@ +# 采集 K8s 审计日志 + +- 生成 K8s 审计日志:K8s 本身生成的审计日志,开启该功能后,会在指定目录下生成 K8s 审计日志的日志文件 +- 采集 K8s 审计日志:通过 insight-agent 采集上述 ‘K8s 审计日志’的日志文件,’采集 K8s 审计日志‘ 的前提条件是: + - 集群生成了 ‘K8s 审计日志‘ + - 日志输出开关已打开 + - 日志采集开关已打开 + +## 算丰 AI 算力平台安装完成时状态 + +- 管理集群的 K8s 审计日志开关默认开启 +- 管理集群的采集 K8s 审计日志开关默认关闭 + - 默认设置不支持配置 + +## 管理集群采集 K8s 审计日志开关 + +### 确认是否开启了 K8s 审计日志 + +执行以下命令查看 __/var/log/kubernetes/audit__ 目录下是否有审计日志生成。 +若有,则表示 K8s 审计日志成功开启。 + +```shell +ls /var/log/kubernetes/audit +``` + +若未开启,请参考[生成 K8s 审计日志](open-k8s-audit.md)。 + +### 开启采集 K8s 审计日志流程 + +1. 添加 chartmuseum 到 helm repo 中 + + ```shell + helm repo add chartmuseum http://10.5.14.30:8081 + ``` + + 这条命令中的 IP 需要修改为火种节点的 IP 地址。 + + !!! note + + 使用自建 Harbor 仓库的情况下,请修改第一步中的 chart repo 地址为自建仓库的 insight-agent chart 地址。 + +2. 保存当前 insight-agent helm value + + ```shell + helm get values insight-agent -n insight-system -o yaml > insight-agent-values-bak.yaml + ``` + +3. 获取当前版本号 ${insight_version_code} + + ```shell + insight_version_code=`helm list -n insight-system |grep insight-agent | awk {'print $10'}` + ``` + +4. 更新 helm value 配置 + + ```shell + helm upgrade --install --create-namespace --version ${insight_version_code} --cleanup-on-fail insight-agent chartmuseum/insight-agent -n insight-system -f insight-agent-values-bak.yaml --set global.exporters.auditLog.kubeAudit.enabled=true + ``` + +5. 重启 insight-system 下的所有 fluentBit pod + + ```shell + fluent_pod=`kubectl get pod -n insight-system | grep insight-agent-fluent-bit | awk {'print $1'} | xargs` + kubectl delete pod ${fluent_pod} -n insight-system + ``` + +### 关闭采集 K8s 审计日志 + +其余步骤和开启采集 K8s 审计日志一致,仅需修改上一节中第 4 步:更新 helm value 配置。 + +```shell +helm upgrade --install --create-namespace --version ${insight_version_code} --cleanup-on-fail insight-agent chartmuseum/insight-agent -n insight-system -f insight-agent-values-bak.yaml --set global.exporters.auditLog.kubeAudit.enabled=false +``` + +## 工作集群开关 + +各工作集群开关独立,按需开启。 + +### 创建集群时打开采集审计日志步骤 + +采集 K8s 审计日志功能默认为关闭状态。若需要开启,可以按照如下步骤: + +![默认关闭](../../../images/worker01.png) + +![开启审计日志](../../../images/worker02.png) + +将该按钮设置为启用状态,开启采集 K8s 审计日志功能。 + +通过算丰 AI 算力平台创建工作集群时,确认该集群的 K8s 审计日志选择 ‘true',这样创建出来的工作集群 K8s 审计日志是开启的。 + +![审计日志开启](../../../images/worker03.png) + +等待集群创建成功后,该工作集群的 K8s 审计日志将被采集。 + +### 接入的集群和创建完成后开关步骤 + +#### 确认开启 K8s 审计日志 + +执行以下命令查看 __/var/log/kubernetes/audit__ 目录下是否有审计日志生成,若有,则表示 K8s 审计日志成功开启。 + +```shell +ls /var/log/kubernetes/audit +``` + +若未开启,请参考[文档的开启关闭 K8s 审计日志](open-k8s-audit.md) + +#### 开启采集 K8s 审计日志 + +采集 K8s 审计日志功能默认为关闭状态,若需要开启,可以按照如下步骤: + +1. 选中已接入并且需要开启采集 K8s 审计日志功能的集群 + + ![选中集群](../../../images/worker04.png) + +2. 进入 helm 应用管理页面,更新 insight-agent 配置 + (若未安装 insight-agent,可以[安装 insight-agent](../../../insight/quickstart/install/install-agent.md)) + + ![进入 Helm 应用页面](../../../images/worker05.png) + +3. 开启/关闭采集 K8s 审计日志按钮 + + ![开启/关闭按钮](../../../images/worker06.png) + +4. 接入集群的情况下开关后仍需要重启 fluent-bit pod 才能生效 + + ![重启](../../../images/worker07.png) diff --git a/docs/zh/docs/admin/ghippo/audit/open-k8s-audit.md b/docs/zh/docs/admin/ghippo/audit/open-k8s-audit.md new file mode 100644 index 0000000..ef53304 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/open-k8s-audit.md @@ -0,0 +1,193 @@ +# 生成 K8s 审计日志 + +默认 Kubernetes 集群不会生成审计日志信息。通过以下配置,可以开启 Kubernetes 的审计日志功能。 + +!!! note + + 公有云环境中可能无法控制 Kubernetes 审计日志输出及输出路径。 + +1. 准备审计日志的 Policy 文件 +2. 配置 API 服务器,开启审计日志 +3. 重启并验证 + +## 准备审计日志 Policy 文件 + +??? note "点击查看审计日志 Policy YAML 文件" + + ```yaml title="policy.yaml" + apiVersion: audit.k8s.io/v1 + kind: Policy + rules: + # The following requests were manually identified as high-volume and low-risk, + # so drop them. + - level: None + users: ["system:kube-proxy"] + verbs: ["watch"] + resources: + - group: "" # core + resources: ["endpoints", "services", "services/status"] + - level: None + # Ingress controller reads `configmaps/ingress-uid` through the unsecured port. + # TODO(#46983): Change this to the ingress controller service account. + users: ["system:unsecured"] + namespaces: ["kube-system"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["configmaps"] + - level: None + users: ["kubelet"] # legacy kubelet identity + verbs: ["get"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + userGroups: ["system:nodes"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + users: + - system:kube-controller-manager + - system:kube-scheduler + - system:serviceaccount:kube-system:endpoint-controller + verbs: ["get", "update"] + namespaces: ["kube-system"] + resources: + - group: "" # core + resources: ["endpoints"] + - level: None + users: ["system:apiserver"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["namespaces", "namespaces/status", "namespaces/finalize"] + # Don't log HPA fetching metrics. + - level: None + users: + - system:kube-controller-manager + verbs: ["get", "list"] + resources: + - group: "metrics.k8s.io" + # Don't log these read-only URLs. + - level: None + nonResourceURLs: + - /healthz* + - /version + - /swagger* + # Don't log events requests. + - level: None + resources: + - group: "" # core + resources: ["events"] + # Secrets, ConfigMaps, TokenRequest and TokenReviews can contain sensitive & binary data, + # so only log at the Metadata level. + - level: Metadata + resources: + - group: "" # core + resources: ["secrets", "configmaps", "serviceaccounts/token"] + - group: authentication.k8s.io + resources: ["tokenreviews"] + omitStages: + - "RequestReceived" + # Get responses can be large; skip them. + - level: Request + verbs: ["get", "list", "watch"] + resources: + - group: "" # core + - group: "admissionregistration.k8s.io" + - group: "apiextensions.k8s.io" + - group: "apiregistration.k8s.io" + - group: "apps" + - group: "authentication.k8s.io" + - group: "authorization.k8s.io" + - group: "autoscaling" + - group: "batch" + - group: "certificates.k8s.io" + - group: "extensions" + - group: "metrics.k8s.io" + - group: "networking.k8s.io" + - group: "policy" + - group: "rbac.authorization.k8s.io" + - group: "settings.k8s.io" + - group: "storage.k8s.io" + omitStages: + - "RequestReceived" + # Default level for known APIs + - level: RequestResponse + resources: + - group: "" # core + - group: "admissionregistration.k8s.io" + - group: "apiextensions.k8s.io" + - group: "apiregistration.k8s.io" + - group: "apps" + - group: "authentication.k8s.io" + - group: "authorization.k8s.io" + - group: "autoscaling" + - group: "batch" + - group: "certificates.k8s.io" + - group: "extensions" + - group: "metrics.k8s.io" + - group: "networking.k8s.io" + - group: "policy" + - group: "rbac.authorization.k8s.io" + - group: "settings.k8s.io" + - group: "storage.k8s.io" + omitStages: + - "RequestReceived" + # Default level for all other requests. + - level: Metadata + omitStages: + - "RequestReceived" + ``` + +将以上审计日志文件放到 __/etc/kubernetes/audit-policy/__ 文件夹下,并取名为 __apiserver-audit-policy.yaml__ 。 + +## 配置 API 服务器 + +打开 API 服务器的配置文件 kube-apiserver.yaml ,一般会在 __/etc/kubernetes/manifests/__ 文件夹下,并添加以下配置信息: + +这一步操作前请备份 kube-apiserver.yaml ,并且备份的文件不能放在 __/etc/kubernetes/manifests/__ 下,建议放在 __/etc/kubernetes/tmp__ 。 + +1. 在 __spec.containers.command__ 下添加命令: + + ```yaml + --audit-log-maxage=30 + --audit-log-maxbackup=10 + --audit-log-maxsize=100 + --audit-log-path=/var/log/audit/kube-apiserver-audit.log + --audit-policy-file=/etc/kubernetes/audit-policy/apiserver-audit-policy.yaml + ``` + +2. 在 __spec.containers.volumeMounts__ 下添加: + + ```yaml + - mountPath: /var/log/audit + name: audit-logs + - mountPath: /etc/kubernetes/audit-policy + name: audit-policy + ``` + +3. 在 __spec.volumes__ 下添加: + + ```yaml + - hostPath: + path: /var/log/kubernetes/audit + type: "" + name: audit-logs + - hostPath: + path: /etc/kubernetes/audit-policy + type: "" + name: audit-policy + ``` + +## 测试并验证 + +稍等一会,API 服务器会自动重启,执行以下命令查看 __/var/log/kubernetes/audit__ 目录下是否有审计日志生成,若有,则表示 K8s 审计日志成功开启。 + +```shell +ls /var/log/kubernetes/audit +``` + +如果想关闭,去掉 __spec.containers.command__ 中的相关命令即可。 diff --git a/docs/zh/docs/admin/ghippo/audit/source-ip.md b/docs/zh/docs/admin/ghippo/audit/source-ip.md new file mode 100644 index 0000000..e775520 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/audit/source-ip.md @@ -0,0 +1,47 @@ +# 审计日志获取源 IP + +审计日志源 IP 在系统和网络管理中扮演着关键角色,它有助于追踪活动、维护安全、解决问题并确保系统合规性。 +但是获取源 IP 会带来一定的性能损耗,所以在算丰 AI 算力平台中审计日志并不总是开启的, +在不同的安装模式下,审计日志源 IP 的默认开启情况不同,并且开启的方式不同。 +下面会根据安装模式分别介绍审计日志源 IP 的默认开启情况以及如何开启。 + +!!! note + + 开启审计日志会修改 istio-ingressgateway 的副本数,带来一定的性能损耗。 + 开启审计日志需要关闭 kube-proxy 的负载均衡以及拓扑感知路由,会对集群性能产生一定的影响。 + 开启审计日志后,访问IP所对应的节点上必须保证存在 istio-ingressgateway ,若因为节点健康或其他问题导致 istio-ingressgateway 发生漂移,需要手动调度回该节点,否则会影响算丰 AI 算力平台的正常使用。 + +## 判断安装模式的方法 + +```bash +kubectl get pod -n metallb-system +``` + +在集群中执行上面的命令,若返回结果如下,则表示该集群为非 MetalLB 安装模式 + +```console +No resources found in metallbs-system namespace. +``` + +## NodePort 安装模式 + +该模式安装下,审计日志源 IP 默认是关闭的,开启步骤如下: + +1. 设置 __istio-ingressgateway__ 的 HPA 的最小副本数为控制面节点数 + + ```bash + count=$(kubectl get nodes --selector=node-role.kubernetes.io/control-plane | wc -l) + count=$((count-1)) + + kubectl patch hpa istio-ingressgateway -n istio-system -p '{"spec":{"minReplicas":'$count'}}' + ``` + +2. 修改 __istio-ingressgateway__ 的 service 的 __externalTrafficPolicy__ 和 __internalTrafficPolicy__ 值为 "Local" + + ```bash + kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local","internalTrafficPolicy":"Local"}}' + ``` + +## MetalLB 安装模式 + +该模式下安装完成后,会默认获取审计日志源 IP。 diff --git a/docs/zh/docs/admin/ghippo/best-practice/authz-plan.md b/docs/zh/docs/admin/ghippo/best-practice/authz-plan.md new file mode 100644 index 0000000..0aeacab --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/authz-plan.md @@ -0,0 +1,41 @@ +--- +hide: + - toc +--- + +# 普通用户授权规划 + +普通用户是指能够使用 AI 算力中心大部分产品模块及功能(管理功能除外),对权限范围内的资源有一定的操作权限,能够独立使用资源部署应用。 + +对这类用户的授权及资源规划流程如下图所示。 + +```mermaid +graph TB + + start([开始]) --> user[1. 创建用户] + user --> ns[2. 准备 Kubernetes 命名空间] + ns --> ws[3. 准备工作空间] + ws --> ws-to-ns[4. 工作空间绑定命名空间] + ws-to-ns --> authu[5. 给用户授权 Workspace Editor] + authu --> complete([结束]) + +click user "https://docs.daocloud.io/ghippo/user-guide/access-control/user/" +click ns "https://docs.daocloud.io/kpanda/user-guide/namespaces/createns/" +click ws "https://docs.daocloud.io/ghippo/user-guide/workspace/workspace/" +click ws-to-ns "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-to-ns/" +click authu "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-permission/" + + classDef plain fill:#ddd,stroke:#fff,stroke-width:4px,color:#000; + classDef k8s fill:#326ce5,stroke:#fff,stroke-width:4px,color:#fff; + classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + class user,ns,ws,ws-to-ns,authu cluster; + class start,complete plain; +``` + +授权后普通用户在各模块的权限为: + +- [应用工作台](../permissions/amamba.md) +- [微服务引擎](../permissions/skoala.md) +- [服务网格](../permissions/mspider.md)(需要重复 2 - 4 准备网格/网格命名空间并绑定到工作空间) +- [可观测性](../../insight/intro/permission.md) +- [数据服务](../permissions/mcamel.md) diff --git a/docs/zh/docs/admin/ghippo/best-practice/cluster-for-multiws.md b/docs/zh/docs/admin/ghippo/best-practice/cluster-for-multiws.md new file mode 100644 index 0000000..d737cc6 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/cluster-for-multiws.md @@ -0,0 +1,82 @@ +# 将集群分配给多个工作空间(租户) + +集群资源通常由运维人员进行管理。在分配资源分配时,他们需要创建命名空间来隔离资源,并设置资源配额。 +这种方式有个弊端,如果企业的业务量很大,手动分配资源需要较大的工作量,而想要灵活调配资源额度也有不小难度。 + +AI 算力中心为此引入了工作空间的概念。工作空间通过共享资源可以提供更高维度的资源限额能力,实现工作空间(租户)在资源限额下自助式创建 Kubernetes 命名空间的能力。 + +举例而言,如果想要让几个部门共享不同的集群。 + +| | Cluster01(普通) | Cluster02(高可用) | +| ----------------- | ----------------- | ------------------- | +| 部门(工作空间)A | 50 quota | 10 quota | +| 部门(工作空间)B | 100 quota | 20 quota | + +可以参照以下流程将集群分享给多个部门/工作空间/租户: + +```mermaid +graph TB + +preparews[准备工作空间] --> preparecs[准备集群] +--> share[将集群共享到工作空间] +--> judge([判断工作空间剩余额度]) +judge -.大于剩余额度.->modifyns[修改命名空间额度] +judge -.小于剩余额度.->createns[创建命名空间] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class preparews,preparecs,share, cluster; +class judge plain +class modifyns,createns k8s + +click preparews "https://docs.daocloud.io/ghippo/user-guide/workspace/cluster-for-multiws/#_2" +click preparecs "https://docs.daocloud.io/ghippo/user-guide/workspace/cluster-for-multiws/#_3" +click share "https://docs.daocloud.io/ghippo/user-guide/workspace/cluster-for-multiws/#_4" +click createns "https://docs.daocloud.io/amamba/user-guide/namespace/namespace/#_3" +click modifyns "https://docs.daocloud.io/amamba/user-guide/namespace/namespace/#_4" +``` + +## 准备一个工作空间 + +工作空间是为了满足多租户的使用场景,基于集群、集群命名空间、网格、网格命名空间、多云、多云命名空间等多种资源形成相互隔离的资源环境, +工作空间可以映射为项目、租户、企业、供应商等多种概念。 + +1. 使用 admin/folder admin 角色的用户登录 AI 算力中心,点击左侧导航栏底部的 __全局管理__ -> __工作空间与层级__ 。 + + ![全局管理](../images/ws01.png) + +2. 点击右上角的 __创建工作空间__ 按钮。 + + ![创建工作空间](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/ws02.png) + +3. 填写工作空间名称、所属文件夹等信息后,点击 __确定__ ,完成创建工作空间。 + + ![确定](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/ws03.png) + +## 准备一个集群 + +工作空间是为了满足多租户的使用场景,基于集群、集群命名空间、网格、网格命名空间、多云、多云命名空间等多种资源形成相互隔离的资源环境,工作空间可以映射为项目、租户、企业、供应商等多种概念。 + +参照以下步骤准备一个集群。 + +1. 点击左侧导航栏底部的 __容器管理__ ,选择 __集群列表__ 。 + + ![容器管理](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/clusterlist01.png) + +1. 点击 __创建集群__ [创建一个集群](../../kpanda/clusters/create-cluster.md),或点击 __接入集群__ [接入一个集群](../../kpanda/clusters/integrate-cluster.md)。 + +## 在工作空间添加集群 + +返回 __全局管理__ ,为工作空间添加集群。 + +1. 依次点击 __全局管理__ -> __工作空间与层级__ -> __共享资源__ ,点击某个工作空间名称后,点击 __新增共享资源__ 按钮。 + + ![新增资源](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/addcluster01.png) + +1. 选择集群,填写资源限额后,点击 __确定__ 。 + + ![新增资源](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/addcluster02.png) + +下一步:将集群资源分配给多个工作空间后,用户可以前往 __应用工作台__ 在这些工作空间下[创建命名空间并部署应用](../../amamba/namespace/namespace.md)。 diff --git a/docs/zh/docs/admin/ghippo/best-practice/folder-practice.md b/docs/zh/docs/admin/ghippo/best-practice/folder-practice.md new file mode 100644 index 0000000..3451dc2 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/folder-practice.md @@ -0,0 +1,34 @@ +--- +hide: + - toc +--- + +# 文件夹最佳实践 + +文件夹代表一个组织机构(例如一个部门),是资源层次结构中的一个节点。 + +一个文件夹可以包含工作空间、子文件夹或两者的组合。 +它提供了身份管理、多层级和权限映射能力,能够将用户/用户组在文件夹中的角色映射到其下的子文件夹、工作空间和资源上。 +因此借助于文件夹,企业管理者能够集中管控所有资源。 + +1. 构建企业层级关系 + + 首先要按照现有的企业层级结构,构建与企业相同的文件夹层级。 + AI 算力中心支持 5 级文件夹,可以根据企业实际情况自由组合,将文件夹和工作空间映射为企业中的部门、项目、供应商等实体。 + + 文件夹不直接与资源挂钩,而是通过工作空间间接实现资源分组。 + + ![层级结构](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/fdpractice.png) + +2. 用户身份管理 + + 文件夹提供了 Folder Admin、Folder Editor、Folder Viewer 三种角色。 + [查看角色权限](../access-control/role.md),可通过[授权](../access-control/role.md)给同一文件夹中的用户/用户组授予不同的角色。 + +3. 角色权限映射 + + 企业管理者:在根文件夹授予 Folder Admin 角色。他将拥有所有部门、项目及其资源的管理权限。 + + 部门管理者:在各个子文件夹、工作空间单独授予管理权限。 + + 项目成员:在工作空间、资源层级单独授予管理权限。 diff --git a/docs/zh/docs/admin/ghippo/best-practice/gproduct/GProduct-manual.pdf b/docs/zh/docs/admin/ghippo/best-practice/gproduct/GProduct-manual.pdf new file mode 100644 index 0000000..83498cd Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/gproduct/GProduct-manual.pdf differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/gproduct/gproduct-demo-main.tar.gz b/docs/zh/docs/admin/ghippo/best-practice/gproduct/gproduct-demo-main.tar.gz new file mode 100644 index 0000000..9502b83 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/gproduct/gproduct-demo-main.tar.gz differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/gproduct/intro.md b/docs/zh/docs/admin/ghippo/best-practice/gproduct/intro.md new file mode 100644 index 0000000..4b7ea92 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/gproduct/intro.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# GProduct 如何对接全局管理 + +GProduct 是 AI 算力中心中除全局管理外的所有其他模块的统称,这些模块需要与全局管理对接后才能加入到 AI 算力中心中。 + +## 对接什么 + +- [对接导航栏](./nav.md) + + 入口统一放在左侧导航栏。 + +- [接入路由和 AuthN](route-auth.md) + + 统一 IP 或域名,将路由入口统一走全局管理的 Istio Gateway。 + +- 统一登录 / 统一 AuthN 认证 + + 登录统一使用全局管理 (Keycloak) 登录页,API authn token 验证使用 Istio Gateway。 + GProduct 对接全局管理后不需要关注如何实现登录和认证。 + +## 视频演示和 PDF + +将 AI 算力中心集成到客户系统(OEM OUT),参阅 [OEM OUT 文档](../oem/oem-out.md)。 + +
+ +
+ +将客户系统集成到 AI 算力中心(OEM IN),参阅 [OEM IN 文档](../oem/oem-in.md)。 + +
+ +
diff --git a/docs/zh/docs/admin/ghippo/best-practice/gproduct/nav.md b/docs/zh/docs/admin/ghippo/best-practice/gproduct/nav.md new file mode 100644 index 0000000..09bc398 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/gproduct/nav.md @@ -0,0 +1,95 @@ +--- +hide: + - toc +--- + +# 对接导航栏 + +以容器管理(开发代号 `kpanda` )为例,对接到导航栏。 + +对接后的预期效果如图: + +![对接效果](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/gproduct01.png) + +## 对接方法 + +参照以下步骤对接 GProduct: + +1. 通过 GProductNavigator CR 将容器管理的各功能项注册到导航栏菜单。 + + ```yaml + apiVersion: ghippo.io/v1alpha1 + kind: GProductNavigator + metadata: + name: kpanda + spec: + gproduct: kpanda + name: 容器管理 + localizedName: + zh-CN: 容器管理 + en-US: Container Management + url: /kpanda + category: 容器 # (1) + iconUrl: /kpanda/nav-icon.png + order: 10 # (2) + menus: + - name: 备份管理 + localizedName: + zh-CN: 备份管理 + en-US: Backup Management + iconUrl: /kpanda/bkup-icon.png + url: /kpanda/backup + ``` + + 1. 当前只支持概览、工作台、容器、微服务、数据服务、管理,六选一 + 2. 数字越大排在越上面 + + 全局管理的导航栏 __category__ 配置在 ConfigMap,暂时不能以注册方式增加,需要联系全局管理团队来添加。 + +2. `kpanda` 前端作为微前端接入到 AI 算力中心父应用 Anakin 中 + + 前端使用 [qiankun](https://qiankun.umijs.org/zh) 来接入子应用 UI, + 可以参考[快速上手](https://qiankun.umijs.org/zh/guide/getting-started)。 + + 在注册 GProductNavigator CR 后,接口会生成对应的注册信息,供前端父应用注册使用。 + 例如 `kpanda` 就会生成以下注册信息: + + ```go + { + "id": "kpanda", + "title": "容器管理", + "url": "/kpanda", + "uiAssetsUrl": "/ui/kpanda/", // 结尾的/是必须的 + "needImportLicense": false + }, + ``` + + 以上注册信息与 qiankun 子应用信息字段的对应关系是: + + ```yaml + { + name: id, + entry: uiAssetsUrl, + container: '#container', + activeRule: url, + loader, + props: globalProps, + } + ``` + + container 和 loader 由前端父应用提供,子应用无需关心。 + props 会提供一个包含用户基本信息、子产品注册信息等的 pinia store。 + + qiankun 启动时会使用如下参数: + + ```go + start({ + sandbox: { + experimentalStyleIsolation: true, + }, + // 去除子应用中的favicon防止在Firefox中覆盖父应用的favicon + getTemplate: (template) => template.replaceAll(//g, ''), + }); + ``` + +请参阅前端团队出具的 [GProduct 对接 demo tar 包](./gproduct-demo-main.tar.gz)。 diff --git a/docs/zh/docs/admin/ghippo/best-practice/gproduct/route-auth.md b/docs/zh/docs/admin/ghippo/best-practice/gproduct/route-auth.md new file mode 100644 index 0000000..3509139 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/gproduct/route-auth.md @@ -0,0 +1,77 @@ +--- +hide: + - toc +--- + +# 接入路由和登录认证 + +接入后统一登录和密码验证,效果如下图: + +![接入效果](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/gproduct02.png) + +各个 GProduct 模块的 API bear token 验证都走 Istio Gateway。 + +接入后的路由映射图如下: + +![接入效果](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/gproduct03.png) + +## 接入方法 + +以 `kpanda` 为例注册 GProductProxy CR。 + +```yaml +# GProductProxy CR 示例, 包含路由和登录认证 + +# spec.proxies: 后写的路由不能是先写的路由子集, 反之可以 +# spec.proxies.match.uri.prefix: 如果是后端 api, 建议在 prefix 末尾添加 "/" 表述这段 path 结束(特殊需求可以不用加) +# spec.proxies.match.uri: 支持 prefix 和 exact 模式; Prefix 和 Exact 只能 2 选 1; Prefix 优先级大于 Exact + +apiVersion: ghippo.io/v1alpha1 +kind: GProductProxy +metadata: + name: kpanda # (1) +spec: + gproduct: kpanda # (2) + proxies: + - labels: + kind: UIEntry + match: + uri: + prefix: /kpanda # (3) + rewrite: + uri: /index.html + destination: + host: ghippo-anakin.ghippo-system.svc.cluster.local + port: 80 + authnCheck: false # (4) + - labels: + kind: UIAssets + match: + uri: + prefix: /ui/kpanda/ # (5) + destination: + host: kpanda-ui.kpanda-system.svc.cluster.local + port: 80 + authnCheck: false + - match: + uri: + prefix: /apis/kpanda.io/v1/a + destination: + host: kpanda-service.kpanda-system.svc.cluster.local + port: 80 + authnCheck: false + - match: + uri: + prefix: /apis/kpanda.io/v1 # (6) + destination: + host: kpanda-service.kpanda-system.svc.cluster.local + port: 80 + authnCheck: true +``` + +1. cluster 级别 CRD +2. 需要用小写指定 GProduct 名字 +3. 还可支持 exact +4. 是否需要 istio-gateway 给该条路由 API 作 AuthN Token 认证, false 为跳过认证 +5. UIAssets 建议末尾添加 __/__ 表示结束(不然前端可能会出现问题) +6. 后写的路由不能是先写的路由的子集, 反之可以 diff --git a/docs/zh/docs/admin/ghippo/best-practice/menu/menu-display-or-hiding.md b/docs/zh/docs/admin/ghippo/best-practice/menu/menu-display-or-hiding.md new file mode 100644 index 0000000..433ee7f --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/menu/menu-display-or-hiding.md @@ -0,0 +1,348 @@ +# 导航栏菜单根据权限显示/隐藏 + +在现有的权限体系下, 全局管理可以根据用户的权限控制导航栏的菜单是否展示, +但是由于容器管理的授权信息未同步到全局管理,导致全局管理无法准确判断容器管理菜单是否需要展示。 + +本文通过配置实现了: +将容器管理及可观测性的菜单在 **全局管理无法判断的部分, 默认不显示** , +通过 **白名单** 授权的方式,实现菜单的隐藏与显示(通过容器管理页面授权的集群或命名空间权限,全局管理均无法感知和判断)。 + +例如:A 用户在容器管理是 cluster A 的 Cluster Admin 角色, +这种情况下全局管理无法判断是否有权限展示容器管理菜单。 +通过本文档配置后,用户 A 默认不可见容器管理菜单,需要 **显式地在全局管理授权** 才可以看到容器管理菜单。 + +## 前提条件 + +已开启基于权限显示/隐藏菜单的功能,开启方法如下: + +* 新安装的环境, 使用 `helm install` 时增加 `--set global.navigatorVisibleDependency=true` 参数 +* 已有环境,`helm get values ghippo -n ghippo-system -o yaml` 备份 values, 随后修改 bak.yaml 并添加 `global.navigatorVisibleDependency: true` + +![开启菜单隐藏](../../images/menu1.png) + +再使用以下命令升级全局管理: + +```shell +helm upgrade ghippo ghippo-release/ghippo \ + -n ghippo-system \ + -f ./bak.yaml \ + --version ${version} +``` + +## 配置导航栏 + +在 kpanda-global-cluster 中 apply 如下 YAML: + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: GProductNavigator +metadata: + name: kpanda-menus-custom +spec: + category: container + gproduct: kpanda + iconUrl: ./ui/kpanda/kpanda.svg + isCustom: true + localizedName: + en-US: Container Management + zh-CN: 容器管理 + menus: + - iconUrl: '' + isCustom: true + localizedName: + en-US: Clusters + zh-CN: 集群列表 + name: Clusters + order: 80 + url: ./kpanda/clusters + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Namespaces + zh-CN: 命名空间 + name: Namespaces + order: 70 + url: ./kpanda/namespaces + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Workloads + zh-CN: 工作负载 + name: Workloads + order: 60 + url: ./kpanda/workloads/deployments + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Permissions + zh-CN: 权限管理 + name: Permissions + order: 10 + url: ./kpanda/rbac/content/cluster + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + name: 容器管理 + order: 50 + url: ./kpanda/clusters + visible: true + +--- +apiVersion: ghippo.io/v1alpha1 +kind: GProductNavigator +metadata: + name: insight-menus-custom +spec: + category: microservice + gproduct: insight + iconUrl: ./ui/insight/logo.svg + isCustom: true + localizedName: + en-US: Insight + zh-CN: 可观测性 + menus: + - iconUrl: '' + isCustom: true + localizedName: + en-US: Overview + zh-CN: 概览 + name: Overview + order: 9 + url: ./insight/overview + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Dashboard + zh-CN: 仪表盘 + name: Dashboard + order: 8 + url: ./insight/dashboard + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Infrastructure + zh-CN: 基础设施 + name: Infrastructure + order: 7 + url: ./insight/clusters + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Metrics + zh-CN: 指标 + name: Metrics + order: 6 + url: ./insight/metric/basic + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Logs + zh-CN: 日志 + name: Logs + order: 5 + url: ./insight/logs + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Trace Tracking + zh-CN: 链路追踪 + name: Trace Tracking + order: 4 + url: ./insight/topology + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Alerts + zh-CN: 告警 + name: Alerts + order: 3 + url: ./insight/alerts/active/metrics + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: Collect Management + zh-CN: 采集管理 + name: Collect Management + order: 2 + url: ./insight/agents + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + - iconUrl: '' + isCustom: true + localizedName: + en-US: System Management + zh-CN: 系统管理 + name: System Management + order: 1 + url: ./insight/system-components + visible: true + visibleDependency: + permissions: + - kpanda.cluster.* + - kpanda.menu.get + name: 可观测性 + order: 30 + url: ./insight + visible: true + +--- +apiVersion: ghippo.io/v1alpha1 +kind: GProductResourcePermissions +metadata: + name: kpanda +spec: + actions: + - localizedName: + en-US: Create + zh-CN: 创建 + name: create + - localizedName: + en-US: Delete + zh-CN: 删除 + name: delete + - localizedName: + en-US: Update + zh-CN: 编辑 + name: update + - localizedName: + en-US: Get + zh-CN: 查看 + name: get + - localizedName: + en-US: Admin + zh-CN: 管理 + name: admin + authScopes: + - resourcePermissions: + - actions: + - name: get + - dependPermissions: + - action: get + name: create + - dependPermissions: + - action: get + name: update + - dependPermissions: + - action: get + name: delete + resourceType: cluster + - actions: + - name: get + resourceType: menu + scope: platform + - resourcePermissions: + - actions: + - name: admin + tips: + - en-US: >- + If the workspace is bound to a cluster, it will be assigned + the Cluster Admin role upon authorization. + zh-CN: 若工作空间绑定了集群,授权后还将被映射为对应集群的 Cluster Admin 角色 + resourceType: cluster + - actions: + - name: get + tips: + - en-US: >- + If the workspace is bound to a namespace, it will be + assigned the NS View role upon authorization. + zh-CN: 若工作空间绑定了命名空间,授权后还将被映射为对应命名空间的 NS View 角色 + - name: update + tips: + - en-US: >- + If the workspace is bound to a namespace, it will be + assigned the NS Edit role upon authorization. + zh-CN: 若工作空间绑定了命名空间,授权后还将被映射为对应命名空间的 NS Edit 角色 + - name: admin + tips: + - en-US: >- + If the workspace is bound to a namespace, it will be + assigned the NS Admin role upon authorization. + zh-CN: 若工作空间绑定了命名空间,授权后还将被映射为对应命名空间的 NS Admin 角色 + resourceType: namespace + scope: workspace + gproduct: kpanda + resourceTypes: + - localizedName: + en-US: Cluster Management + zh-CN: 集群管理 + name: cluster + - localizedName: + en-US: Menu + zh-CN: 菜单 + name: menu + - localizedName: + en-US: Namespace Management + zh-CN: 命名空间 + name: namespace +``` + +## 通过自定义角色实现上述效果 + +!!! note + + 仅容器管理模块的菜单需要单独配置菜单权限,其他模块会根据用户的权限自动显示/隐藏 + +创建一个自定义角色,包含的权限点为容器管理的菜单查看权限,后续授权给需要查看容器管理菜单的用户。 + +![授权](../../images/menu2.png) + +![查看权限点](../../images/menu3.png) + +效果如下,可以看到容器管理和可观测性的导航栏菜单: + +![验证结果](../../images/menu4.png) diff --git a/docs/zh/docs/admin/ghippo/best-practice/menu/navigator.md b/docs/zh/docs/admin/ghippo/best-practice/menu/navigator.md new file mode 100644 index 0000000..cc31ceb --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/menu/navigator.md @@ -0,0 +1,143 @@ +# 自定义导航栏 + +当前自定义导航栏需要通过手动创建导航栏的 YAML ,并 apply 到集群中。 + +## 导航栏分类 + +![导航栏分类](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/images/nav01.png) + +若需要新增或重新排序导航栏分类可以通过新增、修改 category YAML 实现。 + +category 的 YAML 示例如下: + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: NavigatorCategory +metadata: + name: management-custom # (1)! +spec: + name: Management # (2)! + isCustom: true # (3)! + localizedName: # (4)! + zh-CN: 管理 + en-US: Management + order: 100 # (5)! +``` + +1. 命名规则:由小写的"spec.name"与"-custom"而成 +2. 若是用于修改category +3. 该字段必须为true +4. 定义分类的中英文名称 +5. 排序,数字越大,越靠上 + +编写好 YAML 文件后,通过执行如下命令后,刷新页面即可看到新增、修改的导航栏分类。 + +```bash +kubectl apply -f xxx.yaml +``` + +## 导航栏菜单 + +![导航栏菜单](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/images/nav02.png) + +若需要新增或重新排序导航栏菜单可以通过新增 navigator YAML 实现。 + +!!! note + + 若需要编辑已存在的导航栏菜单(非用户自己新增的 custom 菜单),需要令新增 custom 菜单 gproduct 字段与需要覆盖的菜单的 gproduct 相同, + 新的导航栏菜单会将 menus 中 name 相同的部分执行覆盖,name 不同的地方做新增操作。 + +### 一级菜单 + +作为产品插入到某个导航栏分类下 + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: GProductNavigator +metadata: + name: gmagpie-custom # (1)! +spec: + name: Operations Management + iconUrl: ./ui/gmagpie/gmagpie.svg + localizedName: # (2)! + zh-CN: 运营管理 + en-US: Operations Management + url: ./gmagpie + category: management # (3)! + menus: # (4)! + - name: Access Control + iconUrl: ./ui/ghippo/menus/access-control.svg + localizedName: + zh-CN: 用户与访问控制 + en-US: Access Control + url: ./ghippo/users + order: 50 # (5)! + - name: Workspace + iconUrl: ./ui/ghippo/menus/workspace-folder.svg + localizedName: + zh-CN: 工作空间与层级 + en-US: Workspace and Folder + url: ./ghippo/workspaces + order: 40 + - name: Audit Log + iconUrl: ./ui/ghippo/menus/audit-logs.svg + localizedName: + zh-CN: 审计日志 + en-US: Audit Log + url: ./ghippo/audit + order: 30 + - name: Settings + iconUrl: ./ui/ghippo/menus/setting.svg + localizedName: + zh-CN: 平台设置 + en-US: Settings + url: ./ghippo/settings + order: 10 + gproduct: gmagpie # (6)! + visible: true # (7)! + isCustom: true # (8)! + order: 20 # (9)! + target: blank # (10)! +``` + +1. 命名规则:由小写的"spec.gproduct"与"-custom"而成 +2. 定义菜单的中英文名称 +3. 与parentGProduct二选一,用于区分一级菜单还是二级菜单,与NavigatorCategory的spec.name字段对应来完成匹配 +4. 二级菜单 +5. 排序,数字越小,越靠上 +6. 定义菜单的标志,用于和parentGProduct字段联动,实现父子关系。 +7. 设置该菜单是否可见,默认为true +8. 该字段必须为true +9. 排序,数字越大,越靠上 +10. 新开标签页 + +### 二级菜单 + +作为子产品插入到某个一级菜单的二级菜单中 + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: GProductNavigator +metadata: + name: gmagpie-custom # (1)! +spec: + name: Operations Management + iconUrl: ./ui/gmagpie/gmagpie.svg + localizedName: # (2)! + zh-CN: 运营管理 + en-US: Operations Management + url: ./gmagpie + parentGProduct: ghippo # (3)! + gproduct: gmagpie # (4)! + visible: true # (5)! + isCustom: true # (6)! + order: 20 # (7)! +``` + +1. 命名规则:由小写的"spec.gproduct"与"-custom"而成 +2. 定义菜单的中英文名称 +3. 与category二选一,用于区分一级菜单还是二级菜单, 若添加该字段,则会忽视掉menus字段,并将该菜单作为二级菜单插入到与gproduct为ghippo的一级菜单中 +4. 定义菜单的标志,用于和parentGProduct字段联动,实现父子关系 +5. 设置该菜单是否可见,默认为true +6. 该字段必须为true +7. 排序,数字越大,越靠上 diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/custom-idp.md b/docs/zh/docs/admin/ghippo/best-practice/oem/custom-idp.md new file mode 100644 index 0000000..26895b1 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/custom-idp.md @@ -0,0 +1,88 @@ +# 定制 AI 算力中心对接外部身份提供商 (IdP) + +身份提供商(IdP, Identity Provider):当 AI 算力中心需要使用客户系统作为用户源, +使用客户系统登录界面来进行登录认证时,该客户系统被称为 AI 算力中心的身份提供商 + +## 适用场景 + +如果客户对 Ghippo 登录 IdP 有高度定制需求,例如支持企业微信、微信等其他社会组织登录需求,请根据本文档实施。 + +## 支持版本 + +Ghippo 0.15.0及以上版本。 + +## 具体方法 + +### 自定义 ghippo keycloak plugin + +1. 定制 plugin + + 参考 [keycloak 官方文档](https://www.keycloak.org/guides#getting-started)和 + [keycloak 自定义 IdP](./keycloak-idp.md) 进行开发。 + +2. 构建镜像 + + ```sh + # FROM scratch + FROM scratch + + # plugin + COPY ./xxx-jar-with-dependencies.jar /plugins/ + ``` + +!!! note + + 如果需要两个定制化 IdP,需要复制两个 jar 包。 + +### 部署 Ghippo keycloak plugin 步骤 + +1. [把 Ghippo 升级到 0.15.0 或以上](../../install/offline-install.md)。 + 您也可以直接安装部署 Ghippo 0.15.0 版本,但需要把以下信息手动记录下来。 + + ```sh + helm -n ghippo-system get values ghippo -o yaml + ``` + + ```yaml + apiserver: + image: + repository: release.daocloud.io/ghippo-ci/ghippo-apiserver + tag: v0.4.2-test-3-gaba5ec2 + controllermanager: + image: + repository: release.daocloud.io/ghippo-ci/ghippo-apiserver + tag: v0.4.2-test-3-gaba5ec2 + global: + database: + builtIn: true + reverseProxy: http://192.168.31.10:32628 + ``` + +1. 升级成功后,手工跑一个安装命令, `--set` 里设的参数值从上述保存的内容里得到,并且外加几个参数值: + + - global.idpPlugin.enabled:是否启用定制 plugin,默认已关闭 + - global.idpPlugin.image.repository:初始化自定义 plugin 的 initContainer 用的 image 地址 + - global.idpPlugin.image.tag:初始化自定义 plugin 的 initContainer 用的 image tag + - global.idpPlugin.path:自定义 plugin 的目录文件在上述 image 里所在的位置 + + 具体示例如下: + + ```sh + helm upgrade \ + ghippo \ + ghippo-release/ghippo \ + --version v0.4.2-test-3-gaba5ec2 \ + -n ghippo-system \ + --set apiserver.image.repository=release.daocloud.io/ghippo-ci/ghippo-apiserver \ + --set apiserver.image.tag=v0.4.2-test-3-gaba5ec2 \ + --set controllermanager.image.repository=release.daocloud.io/ghippo-ci/ghippo-apiserver \ + --set controllermanager.image.tag=v0.4.2-test-3-gaba5ec2 \ + --set global.reverseProxy=http://192.168.31.10:32628 \ + --set global.database.builtIn=true \ + --set global.idpPlugin.enabled=true \ + --set global.idpPlugin.image.repository=chenyang-idp \ + --set global.idpPlugin.image.tag=v0.0.1 \ + --set global.idpPlugin.path=/plugins/. + ``` + +1. 在 keycloak 管理页面选择所要使用的插件。 diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/demo.md b/docs/zh/docs/admin/ghippo/best-practice/oem/demo.md new file mode 100644 index 0000000..4e4ff6f --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/demo.md @@ -0,0 +1,43 @@ +# gproduct-demo + +本页说明如何搭建 GProduct Demo 环境。 + +## 搭建环境 + +```sh +npm install +``` + +编译和热加载开发环境: + +```sh +npm run serve +``` + +编译和构建: + +```sh +npm run build +``` + +补全 Lint 检查文件: + +```sh +npm run lint +``` + +## 自定义配置 + +参见[配置参考](https://cli.vuejs.org/config/)。 + +构建镜像: + +```sh +docker build -t release.daocloud.io/henry/gproduct-demo . +``` + +在 K8s 上运行: + +```sh +kubectl apply -f demo.yaml +``` diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/App.vue b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/App.vue new file mode 100644 index 0000000..4712eb0 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/App.vue @@ -0,0 +1,62 @@ + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/default1.conf b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/default1.conf new file mode 100644 index 0000000..e91d586 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/default1.conf @@ -0,0 +1,34 @@ +# /etc/nginx/conf.d/default.conf 文件 +server { + listen 80; + server_name localhost; + + location /dx-arch/ { + proxy_pass https://10.6.165.2:30034/; # 客户系统地址 + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location / { + proxy_pass https://10.6.165.50:30443/; + proxy_http_version 1.1; + proxy_read_timeout 300s; # 容器管理 CloudTTY 功能需要这行 + proxy_send_timeout 300s; # 容器管理 CloudTTY 功能需要这行 + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header Upgrade $http_upgrade; # 容器管理 CloudTTY 功能需要这行 + proxy_set_header Connection $connection_upgrade; # 容器管理 CloudTTY 功能需要这行 + } +} + +# /etc/nginx/nginx.conf 里记得定义如下变量 +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/default2.conf b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/default2.conf new file mode 100644 index 0000000..3d6212b --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/default2.conf @@ -0,0 +1,26 @@ +server { + listen 80; + server_name localhost; + + location /dce5/ { + proxy_pass https://10.6.8.2:30343/; + proxy_http_version 1.1; + proxy_read_timeout 300s; # 如需要使用容器管理 CloudTTY 功能需要这行,否则可以去掉 + proxy_send_timeout 300s; # 如需要使用容器管理 CloudTTY 功能需要这行,否则可以去掉 + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header Upgrade $http_upgrade; # 如需要使用容器管理 CloudTTY 功能需要这行,否则可以去掉 + proxy_set_header Connection $connection_upgrade; # 如需要使用容器管理 CloudTTY 功能需要这行,否则可以去掉 + } + + location / { + proxy_pass https://10.6.165.50:30443/; # 假设这是客户系统地址(如意云) + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } } \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/demo.yaml b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/demo.yaml new file mode 100644 index 0000000..2a4dd2e --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/demo.yaml @@ -0,0 +1,84 @@ +kind: Namespace +apiVersion: v1 +metadata: + name: gproduct-demo +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gproduct-demo + namespace: gproduct-demo + labels: + app: gproduct-demo +spec: + selector: + matchLabels: + app: gproduct-demo + template: + metadata: + name: gproduct-demo + labels: + app: gproduct-demo + spec: + containers: + - name: gproduct-demo + image: release.daocloud.io/henry/gproduct-demo + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: gproduct-demo + namespace: gproduct-demo +spec: + type: NodePort + ports: + - port: 80 + protocol: TCP + targetPort: 80 + selector: + app: gproduct-demo +--- +apiVersion: ghippo.io/v1alpha1 +kind: GProductNavigator +metadata: + name: gproduct-demo +spec: + gproduct: gproduct-demo + name: gproduct-demo + localizedName: + zh-CN: gproduct 示例 + en-US: gproduct-demo + url: ./demo + category: 容器 # + iconUrl: ./ui/demo/logo.svg + order: 10 # +--- +apiVersion: ghippo.io/v1alpha1 +kind: GProductProxy +metadata: + name: gproduct-demo # +spec: + gproduct: gproduct-demo # + proxies: + - labels: + kind: UIEntry + match: + uri: + prefix: /demo # + rewrite: + uri: /index.html + destination: + host: ghippo-anakin.ghippo-system.svc.cluster.local + port: 80 + authnCheck: false # + - labels: + kind: UIAssets + match: + uri: + prefix: /ui/demo/ # + destination: + host: gproduct-demo.gproduct-demo.svc.cluster.local + port: 80 + authnCheck: false diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/gproduct-demo-main.tar.gz b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/gproduct-demo-main.tar.gz new file mode 100644 index 0000000..9502b83 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/gproduct-demo-main.tar.gz differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/nginx.conf b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/nginx.conf new file mode 100644 index 0000000..f8c304a --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/nginx.conf @@ -0,0 +1,69 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + # gzip + gzip on; + gzip_min_length 1000; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; + + server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html =404; + } + + location = /index.html { + root /usr/share/nginx/html; + add_header Cache-Control no-cache; + } + + location ~ /ui/demo/(.*)$ { + root /usr/share/nginx/html; + try_files /$1 /index.html; + } + + location ~* .(css|js)$ { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html =404; + expires 365d; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + location = /ping { + add_header Content-Type "text/plain;charset=utf-8"; + return 200 "pong"; + } + } +} diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/pom.xml b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/pom.xml new file mode 100644 index 0000000..f56df99 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/pom.xml @@ -0,0 +1,77 @@ + + + com.daocloud.keycloak + keycloak-ghippo + 1.0-SNAPSHOT + 4.0.0 + + + UTF-8 + 1.8 + 1.8 + 22.0.1 + + + + + org.keycloak + keycloak-core + ${keycloak.version} + provided + + + + org.keycloak + keycloak-server-spi + ${keycloak.version} + provided + + + + org.keycloak + keycloak-server-spi-private + ${keycloak.version} + provided + + + + org.keycloak + keycloak-services + ${keycloak.version} + provided + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-assembly-plugin + 2.5.5 + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/xxxProvider.java b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/xxxProvider.java new file mode 100644 index 0000000..d7feabb --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/xxxProvider.java @@ -0,0 +1,295 @@ +package org.keycloak.broker.oauth; + +import com.fasterxml.jackson.databind.JsonNode; +import org.jboss.logging.Logger; +import org.keycloak.broker.oidc.OIDCIdentityProvider; +import org.keycloak.broker.oidc.OIDCIdentityProviderConfig; +import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper; +import org.keycloak.broker.provider.BrokeredIdentityContext; +import org.keycloak.broker.provider.IdentityBrokerException; +import org.keycloak.broker.provider.util.SimpleHttp; +import org.keycloak.common.util.Time; +import org.keycloak.constants.AdapterConstants; +import org.keycloak.events.EventBuilder; +import org.keycloak.jose.jws.JWSInput; +import org.keycloak.jose.jws.JWSInputException; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserSessionModel; +import org.keycloak.protocol.oidc.OIDCLoginProtocol; +import org.keycloak.representations.AccessTokenResponse; +import org.keycloak.representations.IDToken; +import org.keycloak.representations.JsonWebToken; +import org.keycloak.services.resources.IdentityBrokerService; +import org.keycloak.services.resources.RealmsResource; +import org.keycloak.util.JsonSerialization; + +import javax.ws.rs.core.*; +import java.io.IOException; + +/* +这里继承了部分 oidc 的功能,能这样写, +keycloak 没有能继承的功能,请参考 OIDCIdentityProvider 的代码是怎么编写的 +public class OAuthIdentityProvider extends OIDCIdentityProvider { +} + */ +public class OAuthIdentityProvider extends OIDCIdentityProvider { + protected static final Logger logger = Logger.getLogger(OAuthIdentityProvider.class); + + public static final String SCOPE_OPENID = "openid"; + public static final String FEDERATED_ID_TOKEN = "FEDERATED_ID_TOKEN"; + public static final String USER_INFO = "UserInfo"; + public static final String FEDERATED_ACCESS_TOKEN_RESPONSE = "FEDERATED_ACCESS_TOKEN_RESPONSE"; + public static final String VALIDATED_ID_TOKEN = "VALIDATED_ID_TOKEN"; + public static final String ACCESS_TOKEN_EXPIRATION = "accessTokenExpiration"; + public static final String EXCHANGE_PROVIDER = "EXCHANGE_PROVIDER"; + private static final String BROKER_STATE_PARAM = "BROKER_STATE"; + + public OAuthIdentityProvider(KeycloakSession session, OIDCIdentityProviderConfig config) { + super(session, config); + } + + @Override + public Object callback(RealmModel realm, AuthenticationCallback callback, EventBuilder event) { + return new OAuthEndpoint(callback, realm, event); + } + + @Override + public Response keycloakInitiatedBrowserLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm) { + if (getConfig().getLogoutUrl() == null || getConfig().getLogoutUrl().trim().equals("")) return null; + String idToken = getIDTokenForLogout(session, userSession); + if (idToken != null && getConfig().isBackchannelSupported()) { + backchannelLogout(userSession, idToken); + return null; + } else { + String sessionId = userSession.getId(); + UriBuilder logoutUri = UriBuilder.fromUri(getConfig().getLogoutUrl()) + .queryParam("state", sessionId); + if (idToken != null) logoutUri.queryParam("id_token_hint", idToken); + String redirect = RealmsResource.brokerUrl(uriInfo) + .path(IdentityBrokerService.class, "getEndpoint") + .path(OIDCEndpoint.class, "logoutResponse") + .build(realm.getName(), getConfig().getAlias()).toString(); + logoutUri.queryParam("post_logout_redirect_uri", redirect); + Response response = Response.status(302).location(logoutUri.build()).build(); + return response; + } + } + + private String getIDTokenForLogout(KeycloakSession session, UserSessionModel userSession) { + String tokenExpirationString = userSession.getNote(FEDERATED_TOKEN_EXPIRATION); + long exp = tokenExpirationString == null ? 0 : Long.parseLong(tokenExpirationString); + int currentTime = Time.currentTime(); + if (exp > 0 && currentTime > exp) { + String response = refreshTokenForLogout(session, userSession); + AccessTokenResponse tokenResponse = null; + try { + tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + return tokenResponse.getIdToken(); + } else { + return userSession.getNote(FEDERATED_ID_TOKEN); + + } + } + + protected class OAuthEndpoint extends OIDCEndpoint { + public OAuthEndpoint(AuthenticationCallback callback, RealmModel realm, EventBuilder event) { + super(callback, realm, event); + } + + @Override + public SimpleHttp generateTokenRequest(String authorizationCode) { + session.setAttribute(OAUTH2_PARAMETER_CODE, authorizationCode); + return super.generateTokenRequest(authorizationCode) + .param(AdapterConstants.CLIENT_SESSION_STATE, "n/a"); + // hack to get backchannel logout to work + } + } + + /** + * 解析逻辑 + */ + @Override + public BrokeredIdentityContext getFederatedIdentity(String response) { + AccessTokenResponse tokenResponse = null; + try { + + tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class); + } catch (IOException e) { + throw new IdentityBrokerException("Could not decode access token response.", e); + } + String accessToken = verifyAccessToken(tokenResponse); + String encodedIdToken = tokenResponse.getIdToken(); + JsonWebToken idToken = (encodedIdToken != null) ? validateToken(encodedIdToken) : null; + + try { + BrokeredIdentityContext identity = extractIdentity(tokenResponse, accessToken, idToken); + + if ((idToken != null) && (!identity.getId().equals(idToken.getSubject()))) { + throw new IdentityBrokerException("Mismatch between the subject in the id_token and the subject from the user_info endpoint"); + } + + if (idToken != null) { + identity.getContextData().put(BROKER_STATE_PARAM, idToken.getOtherClaims().get(OIDCLoginProtocol.STATE_PARAM)); + } + + if (getConfig().isStoreToken()) { + if (tokenResponse.getExpiresIn() > 0) { + long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn(); + tokenResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration); + response = JsonSerialization.writeValueAsString(tokenResponse); + } + identity.setToken(response); + } + + return identity; + } catch (Exception e) { + throw new IdentityBrokerException("Could not fetch attributes from userinfo endpoint.", e); + } + } + + private static final MediaType APPLICATION_JWT_TYPE = MediaType.valueOf("application/jwt"); + + /** + * 具体的解析逻辑,有问题请修改这快代码,其他部分请勿改动,改动请咨询 ghippo 开发人员 + */ + protected BrokeredIdentityContext extractIdentity(AccessTokenResponse tokenResponse, String accessToken, JsonWebToken idToken) throws IOException { + String id = (idToken != null) ? idToken.getSubject() : null; + BrokeredIdentityContext identity = (id != null) ? new BrokeredIdentityContext(id) : null; + String name = (idToken != null) ? (String) idToken.getOtherClaims().get(IDToken.NAME) : null; + String givenName = (idToken != null) ? (String) idToken.getOtherClaims().get(IDToken.GIVEN_NAME) : null; + String familyName = (idToken != null) ? (String) idToken.getOtherClaims().get(IDToken.FAMILY_NAME) : null; + String preferredUsername = (idToken != null) ? (String) idToken.getOtherClaims().get(getusernameClaimNameForIdToken()) : null; + String email = (idToken != null) ? (String) idToken.getOtherClaims().get(IDToken.EMAIL) : null; + + if (!getConfig().isDisableUserInfoService()) { + String userInfoUrl = getUserInfoUrl(); + if (userInfoUrl != null && !userInfoUrl.isEmpty() && (id == null || name == null || preferredUsername == null || email == null)) { + if (accessToken != null) { + SimpleHttp.Response response = executeRequest(userInfoUrl, SimpleHttp.doGet(userInfoUrl, session) + .param("access_token", accessToken) + .param("code", (String) session.getAttribute("code")) + .header("Authorization", "Bearer " + accessToken)); + + logger.info(session.getAttribute("code")); + String contentType = response.getFirstHeader(HttpHeaders.CONTENT_TYPE); + MediaType contentMediaType; + try { + contentMediaType = MediaType.valueOf(contentType); + } catch (IllegalArgumentException ex) { + contentMediaType = null; + } + if (contentMediaType == null || contentMediaType.isWildcardSubtype() || contentMediaType.isWildcardType()) { + throw new RuntimeException("Unsupported content-type [" + contentType + "] in response from [" + userInfoUrl + "]."); + } + JsonNode userInfo; + + if (MediaType.APPLICATION_JSON_TYPE.isCompatible(contentMediaType)) { + userInfo = response.asJson(); + } else if (APPLICATION_JWT_TYPE.isCompatible(contentMediaType)) { + JWSInput jwsInput; + + try { + jwsInput = new JWSInput(response.asString()); + } catch (JWSInputException cause) { + throw new RuntimeException("Failed to parse JWT userinfo response", cause); + } + + if (verify(jwsInput)) { + userInfo = JsonSerialization.readValue(jwsInput.getContent(), JsonNode.class); + } else { + throw new RuntimeException("Failed to verify signature of userinfo response from [" + userInfoUrl + "]."); + } + } else { + throw new RuntimeException("Unsupported content-type [" + contentType + "] in response from [" + userInfoUrl + "]."); + } + + id = getJsonProperty(userInfo, "UserId"); // 微信没有 sub 只有 UserId + name = getJsonProperty(userInfo, "name"); + givenName = getJsonProperty(userInfo, IDToken.GIVEN_NAME); + familyName = getJsonProperty(userInfo, IDToken.FAMILY_NAME); + preferredUsername = getUsernameFromUserInfo(userInfo); + email = getJsonProperty(userInfo, "email"); + + identity = (id != null) ? new BrokeredIdentityContext(id) : null; + AbstractJsonUserAttributeMapper.storeUserProfileForMapper(identity, userInfo, getConfig().getAlias()); + } + } + } + if (idToken != null) { + identity.getContextData().put(VALIDATED_ID_TOKEN, idToken); + } + + identity.setId(id); + + if (givenName != null) { + identity.setFirstName(givenName); + } + + if (familyName != null) { + identity.setLastName(familyName); + } + + if (givenName == null && familyName == null) { + identity.setName(name); + } + + identity.setEmail(email); + + identity.setBrokerUserId(getConfig().getAlias() + "." + id); + + if (preferredUsername == null) { + preferredUsername = email; + } + + if (preferredUsername == null) { + preferredUsername = id; + } + + identity.setUsername(preferredUsername); + if (tokenResponse != null && tokenResponse.getSessionState() != null) { + identity.setBrokerSessionId(getConfig().getAlias() + "." + tokenResponse.getSessionState()); + } + if (tokenResponse != null) identity.getContextData().put(FEDERATED_ACCESS_TOKEN_RESPONSE, tokenResponse); + if (tokenResponse != null) processAccessTokenResponse(identity, tokenResponse); + + return identity; + } + + + private String verifyAccessToken(AccessTokenResponse tokenResponse) { + String accessToken = tokenResponse.getToken(); + + if (accessToken == null) { + throw new IdentityBrokerException("No access_token from server. error='" + tokenResponse.getError() + + "', error_description='" + tokenResponse.getErrorDescription() + + "', error_uri='" + tokenResponse.getErrorUri() + "'"); + } + return accessToken; + } + + private SimpleHttp.Response executeRequest(String url, SimpleHttp request) throws IOException { + SimpleHttp.Response response = request.asResponse(); + if (response.getStatus() != 200) { + String msg = "failed to invoke url [" + url + "]"; + try { + String tmp = response.asString(); + if (tmp != null) msg = tmp; + + } catch (IOException e) { + + } + throw new IdentityBrokerException("Failed to invoke url [" + url + "]: " + msg); + } + return response; + } + + + @Override + public void preprocessFederatedIdentity(KeycloakSession session, RealmModel realm, BrokeredIdentityContext context) { + + } +} \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/examples/xxxProviderFactory.java b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/xxxProviderFactory.java new file mode 100644 index 0000000..2911380 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/examples/xxxProviderFactory.java @@ -0,0 +1,52 @@ +package org.keycloak.broker.oauth; + +import org.keycloak.broker.oidc.OIDCIdentityProviderConfig; +import org.keycloak.broker.provider.AbstractIdentityProviderFactory; +import org.keycloak.models.IdentityProviderModel; +import org.keycloak.models.KeycloakSession; + +/* +一定要这样写 +public class xxxProviderFactory extends AbstractIdentityProviderFactory { + ... +} + +剩下的根据 services/src/main/java/org/keycloak/broker/oidc/KeycloakOIDCIdentityProviderFactory.java 缺什么补什么 +如果你用 ide,ide 会提示你缺啥 +*/ +public class OAuthIdentityProviderFactory extends AbstractIdentityProviderFactory { + + public static final String PROVIDER_ID = "oauth"; // 留意这个变量,后面定义 html 要用 + + /* + 定义了在页面上的名称 + */ + @Override + public String getName() { + return "OAuth"; + } + + /* + 就这样些,如果你自定义了 ProviderConfig,请把 OIDCIdentityProviderConfig 改一下 + */ + @Override + public OAuthIdentityProvider create(KeycloakSession session, IdentityProviderModel model) { + return new OAuthIdentityProvider(session, new OIDCIdentityProviderConfig(model)); + } + + /* + 定义了 id,建议唯一不要重复,也要在页面显示的 + */ + @Override + public String getId() { + return PROVIDER_ID; + } + + /* + 复用 oidc 的 config, 你也可以自己定义,参考 OIDCIdentityProviderConfig 文件 + */ + @Override + public OIDCIdentityProviderConfig createConfig() { + return new OIDCIdentityProviderConfig(); + } +} \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-01.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-01.png new file mode 100644 index 0000000..80e02f9 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-01.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-02.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-02.png new file mode 100644 index 0000000..d5cead5 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-02.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-03.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-03.png new file mode 100644 index 0000000..68ad4f4 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/dce5-03.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/first1.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/first1.png new file mode 100644 index 0000000..6246d2c Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/first1.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/first2.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/first2.png new file mode 100644 index 0000000..103476f Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/first2.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/idp06.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/idp06.png new file mode 100644 index 0000000..7799d22 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/idp06.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/label-studio-2.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/label-studio-2.png new file mode 100644 index 0000000..3f4dcad Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/label-studio-2.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/login.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/login.png new file mode 100644 index 0000000..91cd420 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/login.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-dce5.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-dce5.png new file mode 100644 index 0000000..c39d05e Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-dce5.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-in01.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-in01.png new file mode 100644 index 0000000..0d6940a Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-in01.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-in02.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-in02.png new file mode 100644 index 0000000..60f3f95 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-in02.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-label-studio.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-label-studio.png new file mode 100644 index 0000000..a084842 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oem-label-studio.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/oemin-image-2.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oemin-image-2.png new file mode 100644 index 0000000..51c329b Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oemin-image-2.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/oemin-jierudetali.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oemin-jierudetali.png new file mode 100644 index 0000000..55ebc78 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/oemin-jierudetali.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/second1.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/second1.png new file mode 100644 index 0000000..90eb259 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/second1.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/second2.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/second2.png new file mode 100644 index 0000000..489ebbc Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/second2.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/images/src-2.png b/docs/zh/docs/admin/ghippo/best-practice/oem/images/src-2.png new file mode 100644 index 0000000..b105ff2 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/best-practice/oem/images/src-2.png differ diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/keycloak-idp.md b/docs/zh/docs/admin/ghippo/best-practice/oem/keycloak-idp.md new file mode 100644 index 0000000..f2ee6fe --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/keycloak-idp.md @@ -0,0 +1,84 @@ +# Keycloak 自定义 IdP + +要求:keycloak >= v20 + +已知问题 keycloak >= v21,删除了旧版 theme 的支持,可能会在 v22 修复。 +参见 [Issue #15344 ](https://github.com/keycloak/keycloak/issues/15344)。 + +此次 demo 使用 Keycloak v20.0.5。 + +## 基于 source 开发 + +### 配置环境 + +参照 [keycloak/building.md](https://github.com/keycloak/keycloak/blob/main/docs/building.md) 配置环境。 + +参照 [keycloak/README.md](https://github.com/keycloak/keycloak/blob/main/quarkus/README.md) 运行以下命令: + +```sh +cd quarkus +mvn -f ../pom.xml clean install -DskipTestsuite -DskipExamples -DskipTests +``` + +### 从 IDE 运行 + +![从 IDE 运行](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp01.png) + +### __添加 service 代码__ + +#### 如果可从 keycloak 继承部分功能 + +在目录 __services/src/main/java/org/keycloak/broker__ 下添加文件: + +文件名需要是 __xxxProvider.java__ 和 __xxxProviderFactory.java__ + +![java](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp02.png) + +**[xxxProviderFactory.java](./examples/xxxProviderFactory.java) 示例:** + +留意 __PROVIDER_ID = "oauth";__ 这个变量,后面定义 html 会用到。 + +**[xxxProvider.java](./examples/xxxProvider.java) 示例** + +#### 如果不能从 keycloak 继承功能 + +参考下图中的三个文件编写你的代码: + +![none heritance](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp03.png) + +**添加 xxxProviderFactory 到 resource service** + +在 __services/src/main/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderFactory__ +添加 xxxProviderFactory,这样刚刚编写的能工作了: + +![running](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp04.png) + +**添加 html 文件** + +复制 __themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html__ +文件到(改名为 __realm-identity-provider-oauth.html__ ,还记得上文中需要留意的变量吗) + __themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oauth.html__ + +到此所有的文件都添加完成了,开始调试功能。 + +## 打包成 jar 作为插件运行 + +新建一个 java 项目,并将上面的代码复制到项目中,如下所示: + +![pom](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp04.png) + +参见 [pom.xml](./examples/pom.xml)。 + +运行 __mvn clean package__ ,打包完成得到 __xxx-jar-with-dependencies.jar__ 文件。 + +下载 [keycloak Release 20.0.5](https://github.com/keycloak/keycloak/releases/tag/20.0.5) zip 包并解压。 + +![release](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp05.png) + +将 __xxx-jar-with-dependencies.jar__ 复制到 __keycloak-20.0.5/providers__ 目录中。 + +运行以下命令查看功能是否完整: + +```sh +bin/kc.sh start-dev +``` diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/oem-in.md b/docs/zh/docs/admin/ghippo/best-practice/oem/oem-in.md new file mode 100644 index 0000000..9a1f1bd --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/oem-in.md @@ -0,0 +1,278 @@ +# 如何将客户系统集成到 AI 算力中心(OEM IN) + +OEM IN 是指合作伙伴的平台作为子模块嵌入 AI 算力中心,出现在 AI 算力中心一级导航栏。 +用户通过 AI 算力中心进行登录和统一管理。实现 OEM IN 共分为 5 步,分别是: + +1. [统一域名](#_2) +1. [打通用户体系](#_3) +1. [对接导航栏](#_4) +1. [定制外观](#_5) +1. [打通权限体系(可选)](#_6) + +!!! note + + 以下使用开源软件 Label Studio 来做嵌套演示。实际场景需要自己解决客户系统的问题: + + 例如客户系统需要自己添加一个 Subpath,用于区分哪些是 AI 算力中心的服务,哪些是客户系统的服务。 + +## 环境准备 + +1. 部署 AI 算力中心环境: + + `https://10.6.202.177:30443` 作为 AI 算力中心的环境。 + + ![AI 算力中心](./images/oem-dce5.png) + +1. 部署客户系统环境: + + `http://10.6.202.177:30123` 作为客户系统 + + 应用过程中对客户系统的操作请根据实际情况进行调整。 + +1. 规划客户系统的 Subpath 路径: `http://10.6.202.177:30123/label-studio` + (建议使用辨识度高的名称作为 Subpath,不能与主 AI 算力中心的 HTTP router 发生冲突)。 + 请确保用户通过 `http://10.6.202.177:30123/label-studio` 能够正常访问客户系统。 + + ![Label Studio](./images/oem-label-studio.png) + +## 统一域名和端口 + +1. SSH 登录到 AI 算力中心服务器。 + + ```bash + ssh root@10.6.202.177 + ``` + +1. 使用 `vim` 命令创建和修改 __label-studio.yaml__ 文件 + + ```bash + vim label-studio.yaml + ``` + + ```yaml title="label-studio.yaml" + apiVersion: networking.istio.io/v1beta1 + kind: ServiceEntry + metadata: + name: label-studio + namespace: ghippo-system + spec: + exportTo: + - "*" + hosts: + - label-studio.svc.external + ports: + # 添加虚拟端口 + - number: 80 + name: http + protocol: HTTP + location: MESH_EXTERNAL + resolution: STATIC + endpoints: + # 改为客户系统的域名(或IP) + - address: 10.6.202.177 + ports: + # 改为客户系统的端口号 + http: 30123 + --- + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + # 修改为客户系统的名字 + name: label-studio + namespace: ghippo-system + spec: + exportTo: + - "*" + hosts: + - "*" + gateways: + - ghippo-gateway + http: + - match: + - uri: + exact: /label-studio # 修改为客户系统在 AI 算力中心.0 Web UI 入口中的路由地址 + - uri: + prefix: /label-studio/ # 修改为客户系统在 AI 算力中心.0 Web UI 入口中的路由地址 + route: + - destination: + # 修改为上文 ServiceEntry 中的 spec.hosts 的值 + host: label-studio.svc.external + port: + # 修改为上文 ServiceEntry 中的 spec.ports 的值 + number: 80 + --- + apiVersion: security.istio.io/v1beta1 + kind: AuthorizationPolicy + metadata: + # 修改为客户系统的名字 + name: label-studio + namespace: istio-system + spec: + action: ALLOW + selector: + matchLabels: + app: istio-ingressgateway + rules: + - from: + - source: + requestPrincipals: + - '*' + - to: + - operation: + paths: + - /label-studio # 修改为 VirtualService 中的 spec.http.match.uri.prefix 的值 + - /label-studio/* # 修改为 VirtualService 中的 spec.http.match.uri.prefix 的值(注意,末尾需要添加 "*") + ``` + +1. 使用 `kubectl` 命令应用 __label-studio.yaml__ : + + ```bash + kubectl apply -f label-studio.yaml + ``` + +1. 验证 Label Studio UI 的 IP 和 端口是否一致: + + ![Label Studio](./images/label-studio-2.png) + +## 打通用户体系 + +将客户系统与 AI 算力中心平台通过 OIDC/OAUTH 等协议对接,使用户登录 AI 算力中心平台后进入客户系统时无需再次登录。 + +!!! note + + 这里使用两套 AI 算力中心相互对接来进行演示。涵盖将 AI 算力中心 作为用户源登录客户平台,和将客户平台作为用户源登录 AI 算力中心 平台两种场景。 + +1. **AI 算力中心作为用户源,登录客户平台:** + 首先将第一套 AI 算力中心作为用户源,实现对接后第一套 AI 算力中心中的用户可以通过 OIDC 直接登录第二套 AI 算力中心, + 而无需在第二套中再次创建用户。在第一套 AI 算力中心中通过 __全局管理__ -> __用户与访问控制__ -> __接入管理__ 创建 SSO 接入。 + + ![接入管理列表](../oem/images/first1.png) + + ![接入管理列表](../oem/images/first2.png) + +1. **客户平台作为用户源,登录 AI 算力中心:** + 将第一套 AI 算力中心 中生成的客户端 ID、客户端密钥、单点登录 URL 等填写到第二套 AI 算力中心 + __全局管理__ -> __用户与访问控制__ -> __身份提供商__ -> __OIDC__ 中,完成用户对接。 + 对接后,第一套 AI 算力中心中的用户可以通过 OIDC 直接登录第二套 AI 算力中心,而无需在第二套中再次创建用户。 + + ![oidc1](../oem/images/second2.png) + + ![oidc2](../oem/images/second1.png) + +1. 对接完成后,第二套 AI 算力中心 登录页面将出现 OIDC 选项,首次登录时选择通过 OIDC 登录(自定义名称,这里是名称是 loginname), + 后续将直接进入无需再次选择。 + + ![登录页](../oem/images/login.png) + +!!! note + + 使用两套 AI 算力中心,表明客户只要支持 OIDC 协议,无论是 AI 算力中心作为用户源,还是“客户平台”作为用户源,两种场景都支持。 + +## 对接导航栏 + +参考文档下方的 tar 包来实现一个空壳的前端子应用,把客户系统以 iframe 的形式放进该空壳应用里。 + +1. 下载 gproduct-demo-main.tar.gz 文件,打开 src/App-iframe.vue 文件,修改其中的 src 属性值(即进入客户系统的地址): + + - 绝对地址:`src="https://10.6.202.177:30443/label-studio" (AI 算力中心地址 + Subpath)` + - 相对地址:`src="./external-anyproduct/insight"` + + ```html title="App-iframe.vue" + + + + ``` + +1. 删除 src 文件夹下的 App.vue 和 main.ts 文件,同时将: + + - App-iframe.vue 重命名为 App.vue + - main-iframe.ts 重命名为 main.ts + +1. 按照 readme 步骤构建镜像(注意:执行最后一步前需要将 __demo.yaml__ 中的镜像地址替换成构建出的镜像地址) + + ```yaml title="demo.yaml" + kind: Namespace + apiVersion: v1 + metadata: + name: gproduct-demo + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: gproduct-demo + namespace: gproduct-demo + labels: + app: gproduct-demo + spec: + selector: + matchLabels: + app: gproduct-demo + template: + metadata: + name: gproduct-demo + labels: + app: gproduct-demo + spec: + containers: + - name: gproduct-demo + image: release.daocloud.io/gproduct-demo # 修改这个镜像地址 + ports: + - containerPort: 80 + --- + apiVersion: v1 + kind: Service + ... + ``` + +对接完成后,将在 AI 算力中心的一级导航栏出现 __客户系统__ ,点击可进入客户系统。 + +![客户系统](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/oemin-menu.png) + +## 定制外观 + +!!! note + + AI 算力中心支持通过写 CSS 的方式来实现外观定制。实际应用中客户系统如何实现外观定制需要根据实际情况处理。 + +登录客户系统,通过 __全局管理__ -> __平台设置__ -> __外观定制__ 可以自定义平台背景颜色、logo、名称等, +具体操作请参照[外观定制](../../platform-setting/appearance.md)。 + +## 打通权限体系(可选) + +**方案思路一:** + +定制化团队可实现一定制模块,AI 算力中心将每一次的用户登录事件通过 Webhook 的方式通知到定制模块, +定制模块可自行调用 AnyProduct 和 AI 算力中心的 [OpenAPI](https://docs.daocloud.io/openapi/index.html) 将该用户的权限信息同步。 + +**方案思路二:** + +通过 Webhook 方式,将每一次的授权变化都通知到 AnyProduct(如有需求,后续可实现)。 + +### AnyProduct 使用 AI 算力中心的其他能力(可选) + +操作方法为调用 AI 算力中心[OpenAPI](https://docs.daocloud.io/openapi/index.html)。 + +## 参考资料 + +- 参考 [OEM OUT 文档](./oem-out.md) +- 参阅 [gProduct-demo-main 对接 tar 包](./examples/gproduct-demo-main.tar.gz) diff --git a/docs/zh/docs/admin/ghippo/best-practice/oem/oem-out.md b/docs/zh/docs/admin/ghippo/best-practice/oem/oem-out.md new file mode 100644 index 0000000..f72e709 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/oem/oem-out.md @@ -0,0 +1,83 @@ +# 如何将AI 算力中心集成到客户系统(OEM OUT) + +OEM OUT 是指将 AI 算力中心作为子模块接入其他产品,出现在其他产品的菜单中。 +用户登录其他产品后可直接跳转至 AI 算力中心无需二次登录。实现 OEM OUT 共分为 5 步,分别是: + +* [统一域名](#_1) +* [打通用户体系](#_2) +* [对接导航栏](#_3) +* [定制外观](#_4) +* [打通权限体系(可选)](#_5) + +## 统一域名 + +1. 部署 AI 算力中心(假设部署完的访问地址为 `https://10.6.8.2:30343/`) + +1. 客户系统和 AI 算力中心前可以放一个 nginx 反代来实现同域访问, + __/__ 路由到客户系统, __/dce5 (subpath)__ 路由到 AI 算力中心系统, __vi /etc/nginx/conf.d/default.conf__ 示例如下: + + ```nginx + server { + listen 80; + server_name localhost; + + location /dce5/ { + proxy_pass https://10.6.8.2:30343/; + proxy_http_version 1.1; + proxy_read_timeout 300s; # 如需要使用 kpanda cloudtty功能需要这行,否则可以去掉 + proxy_send_timeout 300s; # 如需要使用 kpanda cloudtty功能需要这行,否则可以去掉 + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header Upgrade $http_upgrade; # 如需要使用 kpanda cloudtty功能需要这行,否则可以去掉 + proxy_set_header Connection $connection_upgrade; # 如需要使用 kpanda cloudtty功能需要这行,否则可以去掉 + } + + location / { + proxy_pass https://10.6.165.50:30443/; # 假设这是客户系统地址(如意云) + proxy_http_version 1.1; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } + ``` + +1. 假设 nginx 入口地址为 10.6.165.50,按[自定义 AI 算力中心反向代理服务器地址](../../install/reverse-proxy.md)把 + AI_PROXY 反代设为 `http://10.6.165.50/dce5`。确保能够通过 `http://10.6.165.50/dce5`访问 AI 算力中心。 + 客户系统也需要进行反代设置,需要根据不同平台的情况进行处理。 + + ![反向代理](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/agent.png) + +## 打通用户体系 + +将客户系统与 AI 算力中心平台通过 OIDC/OAUTH 等协议对接,使用户登录客户系统后进入 AI 算力中心时无需再次登录。 +在拿到客户系统的 OIDC 信息后填入 __全局管理__ -> __用户与访问控制__ -> __身份提供商__ 中。 + +![身份提供商](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/idp.png) + +对接完成后,AI 算力中心登录页面将出现 OIDC(自定义)选项,首次从客户系统进入 AI 算力中心时选择通过 OIDC 登录, +后续将直接进入 AI 算力中心无需再次选择。 + +![登录页](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/ghippo/best-practice/oem/images/login.png) + +## 对接导航栏 + +对接导航栏是指 AI 算力中心出现在客户系统的菜单中,用户点击相应的菜单名称能够直接进入 AI 算力中心。 +因此对接导航栏依赖于客户系统,不同平台需要按照具体情况进行处理。 + +## 定制外观 + +通过 __全局管理__ -> __平台设置__ -> __外观定制__ 可以自定义平台背景颜色、logo、名称等, +具体操作请参照[外观定制](../../platform-setting/appearance.md)。 + +## 打通权限体系(可选) + +打通权限较为复杂,如有需求请联系全局管理团队。 + +## 参考 + +- [OEM IN 文档](./oem-in.md) diff --git a/docs/zh/docs/admin/ghippo/best-practice/super-group.md b/docs/zh/docs/admin/ghippo/best-practice/super-group.md new file mode 100644 index 0000000..3ba4c51 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/super-group.md @@ -0,0 +1,78 @@ +--- +hide: + - toc +--- + +# 超大型企业的架构管理 + +伴随业务的持续扩张,公司规模不断壮大,子公司、分公司纷纷设立,有的子公司还进一步设立孙公司, +原先的大部门也逐渐细分成多个小部门,从而使得组织结构的层级日益增多。这种组织结构的变化,也对 IT 治理架构产生了影响。 + +![architecture](../images/1.png) + +具体操作步骤如下: + +1. 开启 Folder/WS 之间的隔离模式 + + 请参考[开启 Folder/WS 之间的隔离模式](../install/user-isolation.md)。 + +2. 按照实际情况规划企业架构 + + 在多层级组织架构下,建议将二级文件夹作为隔离单元,进行“子公司”之间的用户/用户组/资源之间的隔离。 + 隔离后“子公司”之间的用户/用户组/资源互不可见。 + + ![ws](../images/6.png) + +3. 创建用户/打通用户体系 + + 由主平台管理员 Admin 在平台统一[创建用户](../access-control/user.md)或通过 LDAP/OIDC/OAuth2.0 + 等[身份提供商](../access-control/ldap.md)能力将用户统一对接到 AI 算力中心。 + +4. 创建文件夹角色 + + 在 Folder/WS 的隔离模式下,需要平台管理员 Admin 通过 **授权** 首先将用户邀请到各个子公司,“子公司管理员(Folder Admin)”才能够对这些用户进行管理, + 如二次授权或者编辑权限。建议简化平台管理员 Admin 的管理工作,创建一个无实际权限的角色来辅助平台管理员 Admin 实现通过“授权”将用户邀请到子公司的操作。 + 而子公司用户的实际权限下放到各个子公司管理员(Folder Admin)自行管理。 + + !!! note + + 资源绑定权限点单独使用不生效,因此符合上述通过“授权”将用户邀请到子公司的操作,再由子公司管理员 Folder Admin 自行管理的要求。 + + 以下演示如何创建资源绑定 **无实际权限的角色** ,即 minirole。 + + ![role1](../images/7.png) + + ![role2](../images/8.png) + +5. 给用户授权 + + 平台管理员通过“授权”将用户按照实际情况邀请到各个子公司,并任命子公司管理员。 + + ![folerauth](../images/9.png) + + 将子公司普通用户授权为 “minirole” (1),将子公司管理员授权为 Floder Admin。 + { .annotate } + + 1. 即第 4 步(上一步)中创建的 **无实际权限的角色** + + ![folerauth1](../images/10.png) + + ![folerauth2](../images/11.png) + +6. 子公司管理员自行管理用户/用户组 + + 子公司管理员 Folder Admin 登录平台后只能看到自己所在的“子公司 2”, + 并能够通过创建文件夹、创建工作空间调整架构,通过添加授权/编辑权限为子公司 2 中的用户赋予其他权限。 + + ![folerauth3](../images/12.png) + + 在添加授权时,子公司管理员 Folder Admin 只能看到被平台管理员通过“授权”邀请进来的用户,而不能看到平台上的所有用户, + 从而实现 Folder/WS 之间的用户隔离,用户组同理(平台管理员视角能够看到并授权平台上所有的用户和用户组)。 + + ![folerauth4](../images/13.png) + +!!! note + + 超大型企业与大/中/小型企业的主要区别在于 Folder 和工作空间中用户/用户组之间是否可见。 + 超大型企业里子公司与子公司之间用户/用户组不可见 + 权限隔离; + 大/中/小型企业部门之间的用户相互可见 + 权限隔离。 diff --git a/docs/zh/docs/admin/ghippo/best-practice/system-message.md b/docs/zh/docs/admin/ghippo/best-practice/system-message.md new file mode 100644 index 0000000..ea9eeeb --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/system-message.md @@ -0,0 +1,37 @@ +# 系统消息 + +系统消息用于通知所有用户,类似于系统公告,会在特定时间显示在 AI 算力中心UI 的顶部栏。 + +## 配置系统消息 + +通过在[全局服务集群](../../kpanda/clusters/cluster-role.md#_2) apply 系统消息的 YAML 即可创建一条系统消息,消息的显示时间由 YAML 中的时间字段决定。 +系统消息仅在 start、end 字段配置的时间范围之内才会显示。 + +1. 在集群列表中,点击全局服务集群的名称,进入全局服务集群。 + + ![选择集群](../images/system-message1.png) + +2. 选择左侧导航栏的 __自定义资源__ ,搜索 `ghippoconfig`,点击搜索出来的 `ghippoconfigs.ghippo.io` + + ![选择自定义资源](../images/system-message2.png) + +3. 点击 __YAML 创建__ ,或修改已存在的 YAML + + ![选择自定义资源](../images/system-message3.png) + +4. 最终效果如下 + + ![最终效果](../images/system-message4.png) + +以下是一个 YAML 示例: + +```yaml +apiVersion: ghippo.io/v1alpha1 +kind: GhippoConfig +metadata: + name: system-message +spec: + message: "this is a message" + start: 2024-01-02T15:04:05+08:00 + end: 2024-07-24T17:26:05+08:00 +``` diff --git a/docs/zh/docs/admin/ghippo/best-practice/ws-best-practice.md b/docs/zh/docs/admin/ghippo/best-practice/ws-best-practice.md new file mode 100644 index 0000000..5e6e17c --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/ws-best-practice.md @@ -0,0 +1,75 @@ +# 工作空间最佳实践 + +工作空间是一种资源分组单元,大多数资源都可以在工作空间下创建或手动绑定到某一个工作空间中。 +而工作空间通过授权和资源绑定,能够实现用户与角色的绑定关系,并一次性应用到工作空间的所有资源上。 + +通过工作空间,可以轻松管理团队与资源,解决跨模块、跨集群的资源授权问题。 + +## 工作空间的功能 + +工作空间包含三个功能:授权、资源组和共享资源。主要解决资源统一授权、资源分组及资源配额问题。 + +![工作空间](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/quota01.png) + +1. 授权:为用户/用户组授予该工作空间的不同角色,并将角色应用到工作空间的资源上。 + + 最佳实践:普通用户想要使用应用工作台、微服务引擎、服务网格、中间件模块功能,或者需要拥有容器管理、服务网格中部分资源的使用权限时,需要管理员授予该工作空间的使用权限(Workspace Admin、Workspace Edit、Workspace View)。 + 这里的管理员可以是 Admin 角色、该工作空间的 Workspace Admin 角色或该工作空间上层的 Folder Admin 角色。 + 查看 [Folder 与 Workspace 的关系](../workspace/ws-folder.md)。 + +2. 资源组:资源组支持 Cluster、Cluster-Namespace (跨集群)、Mesh、Mesh-Namespace、Kairship、Kairship-Namespace 六种资源类型。 + 一个资源只能绑定一个资源组,资源被绑定到资源组后,工作空间的所有者将拥有该资源的所有管理权限,相当于该资源的所有者,因此不受资源配额的限制。 + + 最佳实践:工作空间通过“授权”功能可以给部门成员授予不同角色权限,而工作空间能够把人与角色的授权关系一次性应用到工作空间的所有资源上。因此运维人员只需将资源绑定到资源组,将部门中的不同角色加入不同的资源组,就能确保资源的权限被正确分配。 + + | 角色 | 集群 Cluster | 跨集群 Cluster-Namespace | + | --------------- | ------------ | ------------------------ | + | Workspace Admin | Cluster Admin | NS Admin | + | Workspace Edit | ✗ | NS Editor | + | Workspace View | ✗ | NS Viewer | + +3. 共享资源:共享资源功能主要针对集群资源。 + + 一个集群可以共享给多个工作空间(指工作空间中的共享资源功能);一个工作空间也可以同时使用多个集群的资源。 + 但是集群资源被共享后,不意味着被共享者(工作空间)可以无限制地使用,因此通常会限制被共享者(工作空间)能够使用的资源限额。 + + 同时,与资源组不同,工作空间成员只是共享资源的使用者,能够在资源限额下使用集群中的资源。比如前往应用工作台创建命名空间、部署应用等,但并不具备集群的管理权限,限制后在该工作空间下创建/绑定的命名空间的资源配额总和不能超过集群在该工作空间设置的资源使用上限。 + + 最佳实践:运维部门手中有一个高可用集群 01,想要分配给部门 A(工作空间 A)和部门 B(工作空间 B)使用,其中部门 A 分配 CPU 50 核,部门 B 分配 CPU 100 核。 + 那么可以借用共享资源的概念,将集群 01 分别共享给部门 A 和部门 B,并限制部门 A 的 CPU 使用额度为 50,部门 B 的 CPU 使用额度为 100。 + 那么部门 A 的管理员(工作空间 A Admin)能够在应用工作台创建并使用命名空间,其中命名空间额度总和不能超过 50 核,部门 B 的管理员(工作空间 B Admin)能够在应用工作台创建并使用命名空间,其中命名空间额度总和不能超过 100 核。 + 部门 A 的管理员和部门 B 管理员创建的命名空间会被自动绑定在该部门,部门中的其他成员将对应的拥有命名空间的 Namesapce Admin、Namesapce Edit、Namesapce View 角色(这里部门指的是工作空间,工作空间还可以映射为组织、供应商等其他概念)。整个过程如下表: + + | 部门 | 角色 | 共享集群 Cluster | 资源配额 | + | ------------ | ------------------------------------------------------- | ------------ | ---------- | + | 部门管理员 A | Workspace Admin | 集群 01 | CPU 50 核 | + | 部门管理员 B | Workspace Admin | 集群 01 | CPU 100 核 | + +## 工作空间对 AI 算力中心各模块的作用 + +1. 模块名称:[应用工作台](../../amamba/intro/index.md)、[微服务引擎](../../skoala/intro/index.md)、[中间件](../../middleware/index.md)、[镜像仓库](../../kangaroo/intro/index.md)、[云边协同](../../kant/intro/index.md) + + 进入上述几个模块的前提是拥有某个工作空间的权限,因此在使用模块功能前必须具有 Admin 角色或者拥有某个工作空间的一定角色权限。 + + - 工作空间的角色会自动应用到工作空间包含的资源上。比如当您拥有工作空间 A 的 Workspace Admin 角色,那么对于该工作空间中的所有资源您都是 Admin 角色; + - 如果您是 Workspace Edit,那么对于工作空间中的所有资源您都是 Edit 角色; + - 如果您是 Workspace View,那么对于工作空间中的所有资源您都是 View 角色。 + + 另外,您在这些模块创建的资源也将自动被绑定到对应的工作空间中,而不需要其他额外的操作。 + +2. 模块名称:[容器管理](../../kpanda/intro/index.md)、[服务网格](../../mspider/intro/index.md)、[多云编排](../../kairship/intro/index.md) + + 由于功能模块的特殊性,在容器管理模块创建的资源不会自动被绑定到某个工作空间。 + + 如果您需要通过工作空间对人和资源进行统一授权管理,可以手动将需要的资源绑定到某个工作空间中,从而将用户在该工作空间的角色应用到资源上(这里的资源是可以跨集群的)。 + + 另外,在资源的绑定入口上容器管理与服务网格稍有差异,工作空间提供了容器管理中的 Cluster 、 Cluster-Namesapce 和服务网格中的 Mesh、Mesh-Namespace 资源的绑定入口,但尚未开放对服务网格的 kairship 和 Kairship-Namespace 资源的绑定。 + + 对于 kairship 和 Kairship-Namespace 资源,可以在服务网格的资源列表进行手动绑定。 + +## 工作空间的使用场景 + +- 映射为不同的部门、项目、组织等概念,同时可以将工作空间中 Workspace Admin、Workspace Edit 和 Workspace View 角色对应到部门、项目、组织中的不同角色 +- 将不同用途的资源加入不同的工作空间中分开管理和使用 +- 为不同工作空间设置完全独立的管理员,实现工作空间范围内的用户与权限管理 +- 将资源共享给不同的工作空间使用,并限制工作空间能够使用的资源额度上限 diff --git a/docs/zh/docs/admin/ghippo/best-practice/ws-to-ns.md b/docs/zh/docs/admin/ghippo/best-practice/ws-to-ns.md new file mode 100644 index 0000000..8567156 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/best-practice/ws-to-ns.md @@ -0,0 +1,127 @@ +# 工作空间(租户)绑定跨集群的命名空间 + +工作空间(租户)下绑定来自不同集群的命名空间,能够使工作空间(租户)灵活纳管平台上任意集群下的 Kubernetes Namespace。 +同时平台提供了权限映射能力,能够将用户在工作空间的权限映射到绑定的命名空间身上。 + +当工作空间(租户)下绑定一个或多个跨集群的命名空间时,管理员无需再次给工作空间中的成员授权, +成员们在工作空间上的角色将根据以下映射关系自动映射完成授权,避免了多次授权的重复性操作: + +- Workspace Admin 对应 Namespace Admin +- Workspace Editor 对应 Namespace Editor +- Workspace Viewer 对应 Namespace Viewer + +以下是一个例子: + +| 用户 | 工作空间 | 角色 | +| ------ | ----------- | --------------- | +| 用户 A | Workspace01 | Workspace Admin | + +将一个命名空间绑定到工作空间后: + +| 用户 | 所属范畴 | 角色 | +| ------ | ----------- | --------------- | +| 用户 A | Workspace01 | Workspace Admin | +| | Namespace01 | Namespace Admin | + +## 实现方案 + +将来自不同集群的不同命名空间绑定到同一工作空间(租户),给工作空间(租户)下的成员使用流程如图。 + +```mermaid +graph TB + +preparews[准备工作空间] --> preparens[准备命名空间] +--> judge([命名空间是否与绑定到其他工作空间]) +judge -.未绑定.->nstows[将命名空间绑定到工作空间] --> wsperm[管理工作空间访问权限] +judge -.已绑定.->createns[创建新的命名空间] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class preparews,preparens,createns,nstows,wsperm cluster; +class judge plain + +click preparews "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-to-ns/#_3" +click preparens "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-to-ns/#_4" +click nstows "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-to-ns/#_5" +click wsperm "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-to-ns/#_6" +click createns "https://docs.daocloud.io/ghippo/user-guide/workspace/ws-to-ns/#_4" +``` + +!!! tip + + 一个命名空间只能被一个工作空间绑定。 + +## 准备工作空间 + +工作空间是为了满足多租户的使用场景,基于集群、集群命名空间、网格、网格命名空间、多云、多云命名空间等多种资源形成相互隔离的资源环境。 +工作空间可以映射为项目、租户、企业、供应商等多种概念。 + +1. 使用 admin/folder admin 角色的用户登录 AI 算力中心,点击左侧导航栏底部的 __全局管理__ 。 + + ![全局管理](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/ws01.png) + +1. 点击左侧导航栏的 __工作空间与层级__ ,点击右上角的 __创建工作空间__ 按钮。 + + ![创建工作空间](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/ws02.png) + +1. 填写工作空间名称、所属文件夹等信息后,点击 __确定__ ,完成创建工作空间。 + + ![确定](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/ws03.png) + +提示:若平台中已存在创建好的命名空间,点击某个工作空间,在 __资源组__ 页签下,点击 __绑定资源__ ,可以直接绑定命名空间。 + +![弹出菜单绑定](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/across02.png) + +## 准备命名空间 + +命名空间是更小的资源隔离单元,将其绑定到工作空间后,工作空间的成员就可以进行管理和使用。 + +参照以下步骤准备一个还未绑定到任何工作空间的命名空间。 + +1. 点击左侧导航栏底部的 __容器管理__ 。 + + ![容器管理](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/crd00.png) + +1. 点击目标集群的名称,进入 __集群详情__ 。 + + ![集群详情](https://docs.daocloud.io/daocloud-docs-images/docs/kpanda/images/crd01.png) + +1. 在左侧导航栏点击 __命名空间__ ,进入命名空间管理页面,点击页面右侧的 __创建__ 按钮。 + + ![创建命名空间](https://docs.daocloud.io/daocloud-docs-images/docs/kpanda/images/ns01.png) + +1. 填写命名空间的名称,配置工作空间和标签(可选设置),然后点击 __确定__ 。 + + !!! info + + 工作空间主要用于划分资源组并为用户(用户组)授予对该资源的不同访问权限。有关工作空间的详细说明,可参考[工作空间与层级](../workspace/workspace.md)。 + + ![填写](https://docs.daocloud.io/daocloud-docs-images/docs/kpanda/images/ns02.png) + +1. 点击 __确定__ ,完成命名空间的创建。在命名空间列表右侧,点击 __┇__ ,可以从弹出菜单中选择 __绑定工作空间__ 。 + + ![确定和绑定](https://docs.daocloud.io/daocloud-docs-images/docs/kpanda/images/ns03.png) + +## 将命名空间绑定到工作空间 + +除了在命名空间列表中绑定外,也可以返回 __全局管理__ ,按照以下步骤绑定工作空间。 + +1. 依次点击 __全局管理__ -> __工作空间与层级__ -> __资源组__ ,点击某个工作空间名称后,点击 __绑定资源__ 按钮。 + + ![绑定资源](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/bind01.png) + +1. 选中要绑定的工作空间(可多选),点击 __确定__ 完成绑定。 + + ![确定](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/bind02.png) + +## 为工作空间添加成员并授权 + +1. 在 __工作空间与层级__ -> __授权__ 中,点击某个工作空间名称后,点击 __添加授权__ 按钮。 + + ![添加授权](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/wsauth01.png) + +1. 选择要授权的 __用户/用户组__ 、 __角色__ 后,点击 __确定__ 完成授权。 + + ![确定](../../images/wsauth02.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/images/1.png b/docs/zh/docs/admin/ghippo/images/1.png new file mode 100644 index 0000000..39a59ce Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/1.png differ diff --git a/docs/zh/docs/admin/ghippo/images/10.png b/docs/zh/docs/admin/ghippo/images/10.png new file mode 100644 index 0000000..338b014 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/10.png differ diff --git a/docs/zh/docs/admin/ghippo/images/11.png b/docs/zh/docs/admin/ghippo/images/11.png new file mode 100644 index 0000000..974a513 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/11.png differ diff --git a/docs/zh/docs/admin/ghippo/images/12.png b/docs/zh/docs/admin/ghippo/images/12.png new file mode 100644 index 0000000..11dcdf5 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/12.png differ diff --git a/docs/zh/docs/admin/ghippo/images/13.png b/docs/zh/docs/admin/ghippo/images/13.png new file mode 100644 index 0000000..7224083 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/13.png differ diff --git a/docs/zh/docs/admin/ghippo/images/14.png b/docs/zh/docs/admin/ghippo/images/14.png new file mode 100644 index 0000000..ce16822 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/14.png differ diff --git a/docs/zh/docs/admin/ghippo/images/2.png b/docs/zh/docs/admin/ghippo/images/2.png new file mode 100644 index 0000000..947221b Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/2.png differ diff --git a/docs/zh/docs/admin/ghippo/images/3.png b/docs/zh/docs/admin/ghippo/images/3.png new file mode 100644 index 0000000..002d4a2 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/3.png differ diff --git a/docs/zh/docs/admin/ghippo/images/4.png b/docs/zh/docs/admin/ghippo/images/4.png new file mode 100644 index 0000000..d1d95f4 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/4.png differ diff --git a/docs/zh/docs/admin/ghippo/images/5.png b/docs/zh/docs/admin/ghippo/images/5.png new file mode 100644 index 0000000..b9e64dc Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/5.png differ diff --git a/docs/zh/docs/admin/ghippo/images/6.png b/docs/zh/docs/admin/ghippo/images/6.png new file mode 100644 index 0000000..29c39fa Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/6.png differ diff --git a/docs/zh/docs/admin/ghippo/images/7.png b/docs/zh/docs/admin/ghippo/images/7.png new file mode 100644 index 0000000..2935252 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/7.png differ diff --git a/docs/zh/docs/admin/ghippo/images/8.png b/docs/zh/docs/admin/ghippo/images/8.png new file mode 100644 index 0000000..82a3839 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/8.png differ diff --git a/docs/zh/docs/admin/ghippo/images/9.png b/docs/zh/docs/admin/ghippo/images/9.png new file mode 100644 index 0000000..b87c349 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/9.png differ diff --git a/docs/zh/docs/admin/ghippo/images/about05.png b/docs/zh/docs/admin/ghippo/images/about05.png new file mode 100644 index 0000000..abb5865 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/about05.png differ diff --git a/docs/zh/docs/admin/ghippo/images/access.png b/docs/zh/docs/admin/ghippo/images/access.png new file mode 100644 index 0000000..990f48f Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/access.png differ diff --git a/docs/zh/docs/admin/ghippo/images/beian.png b/docs/zh/docs/admin/ghippo/images/beian.png new file mode 100644 index 0000000..c0b882c Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/beian.png differ diff --git a/docs/zh/docs/admin/ghippo/images/gmagpiereport.png b/docs/zh/docs/admin/ghippo/images/gmagpiereport.png new file mode 100644 index 0000000..0d2e271 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/gmagpiereport.png differ diff --git a/docs/zh/docs/admin/ghippo/images/ldap00.png b/docs/zh/docs/admin/ghippo/images/ldap00.png new file mode 100644 index 0000000..c70395e Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/ldap00.png differ diff --git a/docs/zh/docs/admin/ghippo/images/ldap01.png b/docs/zh/docs/admin/ghippo/images/ldap01.png new file mode 100644 index 0000000..4a3d198 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/ldap01.png differ diff --git a/docs/zh/docs/admin/ghippo/images/logindesign.png b/docs/zh/docs/admin/ghippo/images/logindesign.png new file mode 100644 index 0000000..c5ee0f0 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/logindesign.png differ diff --git a/docs/zh/docs/admin/ghippo/images/menu1.png b/docs/zh/docs/admin/ghippo/images/menu1.png new file mode 100644 index 0000000..87fb42d Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/menu1.png differ diff --git a/docs/zh/docs/admin/ghippo/images/menu2.png b/docs/zh/docs/admin/ghippo/images/menu2.png new file mode 100644 index 0000000..6f8ebd4 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/menu2.png differ diff --git a/docs/zh/docs/admin/ghippo/images/menu3.png b/docs/zh/docs/admin/ghippo/images/menu3.png new file mode 100644 index 0000000..043fe92 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/menu3.png differ diff --git a/docs/zh/docs/admin/ghippo/images/menu4.png b/docs/zh/docs/admin/ghippo/images/menu4.png new file mode 100644 index 0000000..4e4a9a3 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/menu4.png differ diff --git a/docs/zh/docs/admin/ghippo/images/mybusiness.png b/docs/zh/docs/admin/ghippo/images/mybusiness.png new file mode 100644 index 0000000..ff2cfd3 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/mybusiness.png differ diff --git a/docs/zh/docs/admin/ghippo/images/note.svg b/docs/zh/docs/admin/ghippo/images/note.svg new file mode 100644 index 0000000..5e473ae --- /dev/null +++ b/docs/zh/docs/admin/ghippo/images/note.svg @@ -0,0 +1,18 @@ + + + + Icon/16/Prompt备份@0.5x + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/ghippo/images/oauth2.png b/docs/zh/docs/admin/ghippo/images/oauth2.png new file mode 100644 index 0000000..916499d Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/oauth2.png differ diff --git a/docs/zh/docs/admin/ghippo/images/oidc-button.png b/docs/zh/docs/admin/ghippo/images/oidc-button.png new file mode 100644 index 0000000..a45f90e Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/oidc-button.png differ diff --git a/docs/zh/docs/admin/ghippo/images/oidc02.png b/docs/zh/docs/admin/ghippo/images/oidc02.png new file mode 100644 index 0000000..8be9dff Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/oidc02.png differ diff --git a/docs/zh/docs/admin/ghippo/images/password01zh.png b/docs/zh/docs/admin/ghippo/images/password01zh.png new file mode 100644 index 0000000..696dd14 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/password01zh.png differ diff --git a/docs/zh/docs/admin/ghippo/images/password02zh.png b/docs/zh/docs/admin/ghippo/images/password02zh.png new file mode 100644 index 0000000..887ea43 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/password02zh.png differ diff --git a/docs/zh/docs/admin/ghippo/images/password03zh-en.png b/docs/zh/docs/admin/ghippo/images/password03zh-en.png new file mode 100644 index 0000000..96ebb54 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/password03zh-en.png differ diff --git a/docs/zh/docs/admin/ghippo/images/password04zh.png b/docs/zh/docs/admin/ghippo/images/password04zh.png new file mode 100644 index 0000000..5d3b380 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/password04zh.png differ diff --git a/docs/zh/docs/admin/ghippo/images/password05zh.png b/docs/zh/docs/admin/ghippo/images/password05zh.png new file mode 100644 index 0000000..a9acea4 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/password05zh.png differ diff --git a/docs/zh/docs/admin/ghippo/images/report01.png b/docs/zh/docs/admin/ghippo/images/report01.png new file mode 100644 index 0000000..b0a1cf1 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/report01.png differ diff --git a/docs/zh/docs/admin/ghippo/images/security-policy.png b/docs/zh/docs/admin/ghippo/images/security-policy.png new file mode 100644 index 0000000..375eb0e Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/security-policy.png differ diff --git a/docs/zh/docs/admin/ghippo/images/selfapplication.png b/docs/zh/docs/admin/ghippo/images/selfapplication.png new file mode 100644 index 0000000..62cb8ee Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/selfapplication.png differ diff --git a/docs/zh/docs/admin/ghippo/images/sso2.png b/docs/zh/docs/admin/ghippo/images/sso2.png new file mode 100644 index 0000000..ff81e45 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/sso2.png differ diff --git a/docs/zh/docs/admin/ghippo/images/system-message1.png b/docs/zh/docs/admin/ghippo/images/system-message1.png new file mode 100644 index 0000000..7e1b4b3 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/system-message1.png differ diff --git a/docs/zh/docs/admin/ghippo/images/system-message2.png b/docs/zh/docs/admin/ghippo/images/system-message2.png new file mode 100644 index 0000000..3a363e4 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/system-message2.png differ diff --git a/docs/zh/docs/admin/ghippo/images/system-message3.png b/docs/zh/docs/admin/ghippo/images/system-message3.png new file mode 100644 index 0000000..146c506 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/system-message3.png differ diff --git a/docs/zh/docs/admin/ghippo/images/system-message4.png b/docs/zh/docs/admin/ghippo/images/system-message4.png new file mode 100644 index 0000000..7a0126e Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/system-message4.png differ diff --git a/docs/zh/docs/admin/ghippo/images/ws01.png b/docs/zh/docs/admin/ghippo/images/ws01.png new file mode 100644 index 0000000..8691d56 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/ws01.png differ diff --git a/docs/zh/docs/admin/ghippo/images/wsbind1.png b/docs/zh/docs/admin/ghippo/images/wsbind1.png new file mode 100644 index 0000000..de5ddb5 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/wsbind1.png differ diff --git a/docs/zh/docs/admin/ghippo/images/wsbind2.png b/docs/zh/docs/admin/ghippo/images/wsbind2.png new file mode 100644 index 0000000..26fe126 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/wsbind2.png differ diff --git a/docs/zh/docs/admin/ghippo/images/wsbind3.png b/docs/zh/docs/admin/ghippo/images/wsbind3.png new file mode 100644 index 0000000..3f78166 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/wsbind3.png differ diff --git a/docs/zh/docs/admin/ghippo/images/wsbind4.png b/docs/zh/docs/admin/ghippo/images/wsbind4.png new file mode 100644 index 0000000..591d786 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/wsbind4.png differ diff --git a/docs/zh/docs/admin/ghippo/images/wsbind5.png b/docs/zh/docs/admin/ghippo/images/wsbind5.png new file mode 100644 index 0000000..6b0f556 Binary files /dev/null and b/docs/zh/docs/admin/ghippo/images/wsbind5.png differ diff --git a/docs/zh/docs/admin/ghippo/install/gm-gateway.md b/docs/zh/docs/admin/ghippo/install/gm-gateway.md new file mode 100644 index 0000000..0fe91e1 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/install/gm-gateway.md @@ -0,0 +1,170 @@ +# 使用国密网关代理 AI 算力中心 + +参照以下步骤为 AI 算力中心配置国密网关。 + +## 软件介绍 + +**[Tengine](https://github.com/alibaba/tengine):** Tengine 是由淘宝网发起的 Web 服务器项目。它在 Nginx 的基础上, +针对大访问量网站的需求,添加了很多高级功能和特性。比如支持 Tongsuo 插件,支持国密证书等。 + +**[Tongsuo](https://github.com/Tongsuo-Project/Tongsuo):** 铜锁/Tongsuo(原 BabaSSL)是一个提供现代密码学算法和安全通信协议的开源基础密码库, +为存储、网络、密钥管理、隐私计算等诸多业务场景提供底层的密码学基础能力,实现数据在传输、使用、存储等过程中的私密性、完整性和可认证性, +为数据生命周期中的隐私和安全提供保护能力。 + +## 准备工作 + +一台安装了 Docker 的 Linux 主机,并且确保它能访问互联网。 + +## 编译和安装国密网关 + +下面介绍如何使用 Tengine 和 Tongsuo 构建国密网关。 + +!!! note + + 此配置仅供参考。 + +```Dockerfile +FROM docker.m.daocloud.io/debian:11.3 + +# Version +ENV TENGINE_VERSION="2.3.4" \ + TONGSUO_VERSION="8.3.2" + +# Install required system packages and dependencies +RUN apt update && \ + apt -y install \ + wget \ + gcc \ + make \ + libpcre3 \ + libpcre3-dev \ + zlib1g-dev \ + perl \ + && apt clean + +# Build tengine +RUN mkdir -p /tmp/pkg/cache/ && cd /tmp/pkg/cache/ \ + && wget https://github.com/alibaba/tengine/archive/refs/tags/${TENGINE_VERSION}.tar.gz -O tengine-${TENGINE_VERSION}.tar.gz \ + && tar zxvf tengine-${TENGINE_VERSION}.tar.gz \ + && wget https://github.com/Tongsuo-Project/Tongsuo/archive/refs/tags/${TONGSUO_VERSION}.tar.gz -O Tongsuo-${TONGSUO_VERSION}.tar.gz \ + && tar zxvf Tongsuo-${TONGSUO_VERSION}.tar.gz \ + && cd tengine-${TENGINE_VERSION} \ + && ./configure \ + --add-module=modules/ngx_openssl_ntls \ + --with-openssl=/tmp/pkg/cache/Tongsuo-${TONGSUO_VERSION} \ + --with-openssl-opt="--strict-warnings enable-ntls" \ + --with-http_ssl_module --with-stream \ + --with-stream_ssl_module --with-stream_sni \ + && make \ + && make install \ + && ln -s /usr/local/nginx/sbin/nginx /usr/sbin/ \ + && rm -rf /tmp/pkg/cache + +EXPOSE 80 443 +STOPSIGNAL SIGTERM +CMD ["nginx", "-g", "daemon off;"] +``` + +```shell +docker build -t tengine:0.0.1 . +``` + +## 生成 SM2 和 RSA TLS 证书 + +下面介绍如何生成 SM2 和 RSA TLS 证书,并配置国密网关。 + +### SM2 TLS 证书 + +!!! note + + 此证书仅适用于测试环境。 + +您可以参考 [Tongsuo 官方文档](https://www.yuque.com/tsdoc/ts)使用 [OpenSSL 生成 SM2 证书](https://www.yuque.com/tsdoc/ts/pb5vqr), +或者访问[国密 SSL 实验室申请 SM2 证书](https://www.gmssl.cn/gmssl/index.jsp?go=CA)。 + +最终我们会得到以下文件: + +```shell +-rw-r--r-- 1 root root 749 Dec 8 02:59 sm2.*.enc.crt.pem +-rw-r--r-- 1 root root 258 Dec 8 02:59 sm2.*.enc.key.pem +-rw-r--r-- 1 root root 749 Dec 8 02:59 sm2.*.sig.crt.pem +-rw-r--r-- 1 root root 258 Dec 8 02:59 sm2.*.sig.key.pem +``` + +### RSA TLS 证书 + +```shell +-rw-r--r-- 1 root root 216 Dec 8 03:21 rsa.*.crt.pem +-rw-r--r-- 1 root root 4096 Dec 8 02:59 rsa.*.key.pem +``` + +## 给国密网关配置 SM2 和 RSA TLS 证书 + +本文中使用的国密网关,支持 SM2 和 RSA 等 TLS 证书。双证书的优点是:当浏览器不支持 SM2 TLS 证书时,自动切换到 RSA TLS 证书。 + +更多详细配置,请参考[Tongsuo 官方文档](https://www.yuque.com/tsdoc/ts)。 + +我们进入 Tengine 容器内部: + +```shell +# 进入 nginx 配置文件存放目录 +cd /usr/local/nginx/conf + +# 创建 cert 文件夹,用于存放 TLS 证书 +mkdir cert + +# 把 SM2、RSA TLS 证书拷贝到 `/usr/local/nginx/conf/cert` 目录下 +cp sm2.*.enc.crt.pem sm2.*.enc.key.pem sm2.*.sig.crt.pem sm2.*.sig.key.pem /usr/local/nginx/conf/cert +cp rsa.*.crt.pem rsa.*.key.pem /usr/local/nginx/conf/cert + +# 编辑 nginx.conf 配置 +vim nginx.conf +... +server { + listen 443 ssl; + proxy_http_version 1.1; + # 开启国密功能,使其支持 SM2 算法的 TLS 证书 + enable_ntls on; + + # RSA 证书 + # 如果您的浏览器不支持国密证书,那么您可以开启此选项,Tengine 会自动识别最终用户的浏览器,并使用 RSA 证书进行回退 + ssl_certificate /usr/local/nginx/conf/cert/rsa.*.crt.pem; + ssl_certificate_key /usr/local/nginx/conf/cert/rsa.*.key.pem; + + # 配置两对 SM2 证书,用于加密和签名 + # SM2 签名证书 + ssl_sign_certificate /usr/local/nginx/conf/cert/sm2.*.sig.crt.pem; + ssl_sign_certificate_key /usr/local/nginx/conf/cert/sm2.*.sig.key.pem; + # SM2 加密证书 + ssl_enc_certificate /usr/local/nginx/conf/cert/sm2.*.enc.crt.pem; + ssl_enc_certificate_key /usr/local/nginx/conf/cert/sm2.*.enc.key.pem; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # 您需要将这里的地址修改为 Istio 入口网关的地址 + # 例如 proxy_pass https://istio-ingressgateway.istio-system.svc.cluster.local + # 或者 proxy_pass https://demo-dev.daocloud.io + proxy_pass https://istio-ingressgateway.istio-system.svc.cluster.local; + } +} +``` + +## 重新加载国密网关的配置 + +```shell +nginx -s reload +``` + +## 下一步 + +国密网关部署成功之后,[自定义 AI 算力中心反向代理服务器地址](reverse-proxy.md)。 + +## 验证 + +您可以部署一个支持国密证书的 Web 浏览器。 +例如 [Samarium Browser](https://github.com/guanzhi/SamariumBrowser), +然后通过 Tengine 访问 AI 算力中心 UI 界面,验证国密证书是否生效。 diff --git a/docs/zh/docs/admin/ghippo/install/login.md b/docs/zh/docs/admin/ghippo/install/login.md new file mode 100644 index 0000000..3db692e --- /dev/null +++ b/docs/zh/docs/admin/ghippo/install/login.md @@ -0,0 +1,38 @@ +--- +hide: + - toc +--- + +# 登录 + +用户在使用一个新系统前,在这个系统中是没有任何数据的,系统也无法识别这个新用户。为了标识用户身份、绑定用户数据,用户需要一个能唯一标识用户身份的帐号。 + +AI 算力中心在 __用户与访问控制__ 中通过管理员创建新用户的方式为用户分配一个附有一定权限的账号。该用户产生的所有行为都将关联到自己的帐号。 + +用户通过账号/密码进行登录,系统验证身份是否合法,如果验证合法,则用户成功登录。 + +!!! note + + 如果用户登录后 24 小时内无任何操作,将自动退出登录状态。如果登录的用户始终活跃,将持续处于登录状态。 + +用户登录的简单流程如下图。 + +```mermaid +graph TB + +user[输入用户名] --> pass[输入密码] --> judge([点击登录并校验用户名和密码]) +judge -.正确.->success[登录成功] +judge -.错误.->fail[提示错误] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class user,pass cluster; +class judge plain +class success,fail k8s +``` + +用户登录界面如下图。具体登录画面,请与实际产品为准。 + +![登录界面](https://docs.daocloud.io/daocloud-docs-images/docs/ghippo/images/login02.png) diff --git a/docs/zh/docs/admin/ghippo/install/offline-install.md b/docs/zh/docs/admin/ghippo/install/offline-install.md new file mode 100644 index 0000000..f690a32 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/install/offline-install.md @@ -0,0 +1,295 @@ +# 离线升级全局管理模块 + +本页说明[下载全局管理模块](https://docs.daocloud.io/download/)后,应该如何安装或升级。 + +!!! info + + 下述命令或脚本内出现的 `ghippo` 字样是全局管理模块的内部开发代号。 + +## 从安装包中加载镜像 + +您可以根据下面两种方式之一加载镜像,当环境中存在镜像仓库时,建议选择 chart-syncer 同步镜像到镜像仓库,该方法更加高效便捷。 + +### chart-syncer 同步镜像到镜像仓库 + +1. 创建 load-image.yaml + + !!! note + + 该 YAML 文件中的各项参数均为必填项。您需要一个私有的镜像仓库,并修改相关配置。 + + === "已安装 chart repo" + + 若当前环境已安装 chart repo,chart-syncer 也支持将 Chart 导出为 tgz 文件。 + + ```yaml title="load-image.yaml" + source: + intermediateBundlesPath: ghippo-offline # (1)! + target: + containerRegistry: 10.16.10.111 # (2)! + containerRepository: release.daocloud.io/ghippo # (3)! + repo: + kind: HARBOR # (4)! + url: http://10.16.10.111/chartrepo/release.daocloud.io # (5)! + auth: + username: "admin" # (6)! + password: "Harbor12345" # (7)! + containers: + auth: + username: "admin" # (8)! + password: "Harbor12345" # (9)! + ``` + + 1. 到执行 charts-syncer 命令的相对路径,而不是此 YAML 文件和离线包之间的相对路径 + 2. 需更改为你的镜像仓库 url + 3. 需更改为你的镜像仓库 + 4. 也可以是任何其他支持的 Helm Chart 仓库类别 + 5. 需更改为 chart repo url + 6. 你的镜像仓库用户名 + 7. 你的镜像仓库密码 + 8. 你的镜像仓库用户名 + 9. 你的镜像仓库密码 + + === "未安装 chart repo" + + 若当前环境未安装 chart repo,chart-syncer 也支持将 Chart 导出为 tgz 文件,并存放在指定路径。 + + ```yaml title="load-image.yaml" + source: + intermediateBundlesPath: ghippo-offline # (1)! + target: + containerRegistry: 10.16.10.111 # (2)! + containerRepository: release.daocloud.io/ghippo # (3)! + repo: + kind: LOCAL + path: ./local-repo # (4)! + containers: + auth: + username: "admin" # (5)! + password: "Harbor12345" # (6)! + ``` + + 1. 到执行 charts-syncer 命令的相对路径,而不是此 YAML 文件和离线包之间的相对路径 + 2. 需更改为你的镜像仓库 URL + 3. 需更改为你的镜像仓库 + 4. Chart 本地路径 + 5. 你的镜像仓库用户名 + 6. 你的镜像仓库密码 + +1. 执行同步镜像命令。 + + ```shell + charts-syncer sync --config load-image.yaml + ``` + +### Docker 或 containerd 直接加载 + +解压并加载镜像文件。 + +1. 解压 tar 压缩包。 + + ```shell + tar xvf ghippo.bundle.tar + ``` + + 解压成功后会得到几个文件: + + - hints.yaml + - images.tar + - original-chart + +2. 从本地加载镜像到 Docker 或 containerd。 + + === "Docker" + + ```shell + docker load -i images.tar + ``` + + === "containerd" + + ```shell + ctr -n k8s.io image import images.tar + ``` + +!!! note + + 每个 node 都需要做 Docker 或 containerd 加载镜像操作, + 加载完成后需要 tag 镜像,保持 Registry、Repository 与安装时一致。 + +## 升级 + +升级注意事项: + +=== "从 v0.11.x 升级到 ≥v0.12.0" + + 当从 v0.11.x (或更低版本) 升级到 v0.12.0 (或更高版本) 时,需要将 __bak.yaml__ 中所有 keycloak key 修改为 __keycloakx__ 。 + + 修改前: + + ```yaml title="bak.yaml" + USER-SUPPLIED VALUES: + keycloak: + ... + ``` + + 修改后: + + ```yaml title="bak.yaml" + USER-SUPPLIED VALUES: + keycloakx: + ... + ``` + +=== "从 v0.15.x 升级到 ≥v0.16.0" + + 当从 v0.15.x (或更低版本) 升级到 v0.16.0 (或更高版本) 时,需要修改数据库连接参数。 + + 修改前: + + ```yaml title="bak.yaml" + USER-SUPPLIED VALUES: + global: + database: + host: 127.0.0.1 + port: 3306 + apiserver: + dbname: ghippo + password: passowrd + user: ghippo + keycloakx: + dbname: keycloak + password: passowrd + user: keycloak + auditDatabase: + auditserver: + dbname: audit + password: passowrd + user: audit + host: 127.0.0.1 + port: 3306 + ``` + + 修改后: + + ```yaml title="bak.yaml" + USER-SUPPLIED VALUES: + global: + storage: + ghippo: + - driver: mysql + accessType: readwrite + dsn: {global.database.apiserver.user}:{global.database.apiserver.password}@tcp({global.database.host}:{global.database.port})/{global.database.apiserver.dbname}?charset=utf8mb4&multiStatements=true&parseTime=true + audit: + - driver: mysql + accessType: readwrite + dsn: {global.auditDatabase.auditserver.user}:{global.auditDatabase.auditserver.password}@tcp({global.auditDatabase.host}:{global.auditDatabase.port})/{global.auditDatabase.auditserver.dbname}?charset=utf8mb4&multiStatements=true&parseTime=true + keycloak: + - driver: mysql + accessType: readwrite + dsn: {global.database.keycloakx.user}:{global.database.keycloakx.password}@tcp({global.database.host}:{global.database.port})/{global.database.keycloakx.dbname}?charset=utf8mb4 + ``` + +有两种升级方式。您可以根据前置操作,选择对应的升级方案: + +=== "通过 Helm 仓库升级" + + 1. 检查全局管理 Helm 仓库是否存在。 + + ```shell + helm repo list | grep ghippo + ``` + + 若返回结果为空或如下提示,则进行下一步;反之则跳过下一步。 + + ```none + Error: no repositories to show + ``` + + 1. 添加全局管理的 Helm 仓库。 + + ```shell + helm repo add ghippo http://{harbor url}/chartrepo/{project} + ``` + + 1. 更新全局管理的 Helm 仓库。 + + ```shell + helm repo update ghippo # (1)! + ``` + + 1. Helm 版本过低会导致失败,若失败,请尝试执行 `helm update repo` + + 1. 选择您想安装的全局管理版本(建议安装最新版本)。 + + ```shell + helm search repo ghippo/ghippo --versions + ``` + + ```none + NAME CHART VERSION APP VERSION DESCRIPTION + ghippo/ghippo 0.9.0 v0.9.0 A Helm chart for GHippo + ... + ``` + + 1. 备份 `--set` 参数。 + + 在升级全局管理版本之前,建议您执行如下命令,备份老版本的 `--set` 参数。 + + ```shell + helm get values ghippo -n ghippo-system -o yaml > bak.yaml + ``` + + 1. 更新 Ghippo CRD: + + ```shell + helm pull ghippo/ghippo --version 0.9.0 && tar -zxf ghippo-0.9.0.tgz + kubectl apply -f ghippo/crds + ``` + + 1. 执行 `helm upgrade` 。 + + 升级前建议您覆盖 bak.yaml 中的 `global.imageRegistry` 字段为当前使用的镜像仓库地址。 + + ```shell + export imageRegistry={你的镜像仓库} + ``` + + ```shell + helm upgrade ghippo ghippo/ghippo \ + -n ghippo-system \ + -f ./bak.yaml \ + --set global.imageRegistry=$imageRegistry \ + --version 0.9.0 + ``` + +=== "通过 Chart 包升级" + + 1. 备份 `--set` 参数。 + + 在升级全局管理版本之前,建议您执行如下命令,备份老版本的 `--set` 参数。 + + ```shell + helm get values ghippo -n ghippo-system -o yaml > bak.yaml + ``` + + 1. 更新 Ghippo CRD: + + ```shell + kubectl apply -f ./crds + ``` + + 1. 执行 `helm upgrade`。 + + 升级前建议您覆盖 bak.yaml 中的 `global.imageRegistry` 为当前使用的镜像仓库地址。 + + ```shell + export imageRegistry={你的镜像仓库} + ``` + + ```shell + helm upgrade ghippo . \ + -n ghippo-system \ + -f ./bak.yaml \ + --set global.imageRegistry=$imageRegistry + ``` diff --git a/docs/zh/docs/admin/ghippo/install/reverse-proxy.md b/docs/zh/docs/admin/ghippo/install/reverse-proxy.md new file mode 100644 index 0000000..2ee9cf6 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/install/reverse-proxy.md @@ -0,0 +1,79 @@ +# 自定义 AI 算力中心反向代理服务器地址 + +具体设置步骤如下: + +1. 检查全局管理 helm 仓库是否存在。 + + ```shell + helm repo list | grep ghippo + ``` + + 若返回结果为空或如下提示,则进行下一步;反之则跳过下一步。 + + ```none + Error: no repositories to show + ``` + +2. 添加并且更新全局管理的 helm 仓库。 + + ```shell + helm repo add ghippo http://{harbor url}/chartrepo/{project} + helm repo update ghippo + ``` + +3. 设置环境变量,方便在下文中使用。 + + ```shell + # 您的反向代理地址,例如 `export AI_PROXY="https://demo-alpha.daocloud.io"` + export AI_PROXY="https://domain:port" + + # helm --set 参数备份文件 + export GHIPPO_VALUES_BAK="ghippo-values-bak.yaml" + + # 获取当前 ghippo 的版本号 + export GHIPPO_HELM_VERSION=$(helm get notes ghippo -n ghippo-system | grep "Chart Version" | awk -F ': ' '{ print $2 }') + ``` + +4. 备份 --set 参数。 + + ```shell + helm get values ghippo -n ghippo-system -o yaml > ${GHIPPO_VALUES_BAK} + ``` + +5. 添加您的反向代理地址。 + + !!! note + + - 如果可以,您可以使用 __yq__ 命令: + + ```shell + yq -i ".global.reverseProxy = \"${AI_PROXY}\"" ${GHIPPO_VALUES_BAK} + ``` + + - 或者您可以使用 __vim__ 命令编辑并保存: + + ```shell + vim ${GHIPPO_VALUES_BAK} + + USER-SUPPLIED VALUES: + ... + global: + ... + reverseProxy: ${AI_PROXY} # 只需要修改这一行 + ``` + +6. 执行 `helm upgrade` 使配置生效。 + + ```shell + helm upgrade ghippo ghippo/ghippo \ + -n ghippo-system \ + -f ${GHIPPO_VALUES_BAK} \ + --version ${GHIPPO_HELM_VERSION} + ``` + +7. 使用 __kubectl__ 重启全局管理 Pod,使配置生效。 + + ```shell + kubectl rollout restart deploy/ghippo-apiserver -n ghippo-system + kubectl rollout restart statefulset/ghippo-keycloakx -n ghippo-system + ``` diff --git a/docs/zh/docs/admin/ghippo/install/user-isolation.md b/docs/zh/docs/admin/ghippo/install/user-isolation.md new file mode 100644 index 0000000..3e0ba1d --- /dev/null +++ b/docs/zh/docs/admin/ghippo/install/user-isolation.md @@ -0,0 +1,75 @@ +# 开启 Folder/WS 之间的隔离模式 + +具体设置步骤如下: + +1. 检查全局管理 helm 仓库是否存在。 + + ```shell + helm repo list | grep ghippo + ``` + + 若返回结果为空或如下提示,则进行下一步;反之则跳过下一步。 + + ```none + Error: no repositories to show + ``` + +2. 添加并且更新全局管理的 helm 仓库。 + + ```shell + helm repo add ghippo http://{harbor url}/chartrepo/{project} + helm repo update ghippo + ``` + +3. 设置环境变量,方便在下文中使用。 + + ```shell + # helm --set 参数备份文件 + export GHIPPO_VALUES_BAK="ghippo-values-bak.yaml" + + # 获取当前 ghippo 的版本号 + export GHIPPO_HELM_VERSION=$(helm get notes ghippo -n ghippo-system | grep "Chart Version" | awk -F ': ' '{ print $2 }') + ``` + +4. 备份 --set 参数。 + + ```shell + helm get values ghippo -n ghippo-system -o yaml > ${GHIPPO_VALUES_BAK} + ``` + +5. 打开 Folder/WS 之间的隔离模式开关。 + + !!! note + + - 如果可以,您可以使用 __yq__ 命令: + + ```shell + yq -i ".apiserver.userIsolationMode = \"Folder\"" ${GHIPPO_VALUES_BAK} + ``` + + - 或者您可以使用 __vim__ 命令编辑并保存: + + ```shell + vim ${GHIPPO_VALUES_BAK} + + USER-SUPPLIED VALUES: + ... + # 添加下面两行即可 + apiserver: + userIsolationMode: Folder + ``` + +6. 执行 `helm upgrade` 使配置生效。 + + ```shell + helm upgrade ghippo ghippo/ghippo \ + -n ghippo-system \ + -f ${GHIPPO_VALUES_BAK} \ + --version ${GHIPPO_HELM_VERSION} + ``` + +7. 使用 __kubectl__ 重启全局管理 Pod,使配置生效。 + + ```shell + kubectl rollout restart deploy/ghippo-apiserver -n ghippo-system + ``` diff --git a/docs/zh/docs/admin/ghippo/password.md b/docs/zh/docs/admin/ghippo/password.md new file mode 100644 index 0000000..a105bc9 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/password.md @@ -0,0 +1,58 @@ +# 密码重置 + +如果您忘记密码,可以按本页面说明重置密码。 + +## 重置密码步骤 + +管理员最初创建一个用户时,会为其设置用户名和密码。 +该用户登录后,在 __个人中心__ 填写邮箱并修改密码。 +若该用户未设置邮箱,则只能联系管理员进行密码重置。 + +1. 如果用户忘记了密码,可以在登录界面点击 __忘记密码__ 。 + + ![登录界面](images/password01zh.png) + +1. 输入登录邮箱,点击 __提交__ 。 + + ![输入登录邮箱](images/password02zh.png) + +1. 在邮箱中找到密码重置邮件,点击下方链接进行密码重置,链接时效 5 分钟。 + + ![点击重置链接](images/password03zh-en.png) + +1. 在手机等终端设备安装支持 2FA 动态口令生成的应用(如 Google Authenticator),按照页面提示配置动态口令以激活账户,点击 __提交__ 。 + + ![配置动态口令](images/password04zh.png) + +1. 设置新密码,点击 __提交__ 。设置新密码的要求与创建用户时的密码规则一致。 + + ![更新密码](images/password05zh.png) + +1. 修改密码成功,直接跳转首页。 + +## 重置密码流程 + +整个密码重置的流程示意图如下。 + +```mermaid +graph TB + +pass[忘记密码] --> usern[输入用户名] +--> button[点击发送验证邮件的按钮] --> judge1[判断用户名是否正确] + + judge1 -.正确.-> judge2[判断是否绑定邮箱] + judge1 -.错误.-> tip1[提示用户名不正确] + + judge2 -.已绑定邮箱.-> send[发送重置邮件] + judge2 -.未绑定邮箱.-> tip2[提示未绑定邮箱
联系管理员重置密码] + +send --> click[点击邮件中的链接] --> config[配置动态口令] --> reset[重置密码] +--> success[成功重置密码] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class pass,usern,button,tip1,send,tip2,send,click,config,reset,success plain; +class judge1,judge2 k8s +``` diff --git a/docs/zh/docs/admin/ghippo/permissions/baize.md b/docs/zh/docs/admin/ghippo/permissions/baize.md new file mode 100644 index 0000000..24da317 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/permissions/baize.md @@ -0,0 +1,65 @@ +--- +hide: + - toc +--- + +# AI Lab 权限说明 + +AI Lab 支持四种用户角色: + +- Admin / Baize Owner:拥有 `开发控制台` 和 `运维管理` 全部功能的增删改查的权限。 +- Workspace Admin:拥有授权工作空间的 `开发控制台` 全部功能的增删改查的权限。 +- Workspace Editor:拥有授权工作空间的 `开发控制台` 全部功能的更新、查询的权限。 +- Workspace Viewer:拥有授权工作空间的 `开发控制台` 全部功能的查询的权限。 + +每种角色具有不同的权限,具体说明如下。 + + + +| 菜单对象 |操作 |Admin / Baize Owner |Workspace Admin |Workspace Editor |Workspace Viewer | +|-----------|-----------|---------------|---------|-----|----| +| **开发控制台** | | | | | | +| 概览 | 查看概览 | ✓ | ✓ | ✓ | ✓ | +| Notebooks | 查看 Notebooks 列表 | ✓ | ✓ | ✓ | ✓ | +| | 查看 Notebooks 详情 | ✓ | ✓ | ✓ | ✗ | +| | 创建 Notebooks | ✓ | ✓ | ✗ | ✗ | +| | 更新 Notebooks | ✓ | ✓ | ✓ | ✗ | +| | 克隆 Notebooks | ✓ | ✓ | ✗ | ✗ | +| | 停止 Notebooks | ✓ | ✓ | ✓ | ✗ | +| | 启动 Notebooks | ✓ | ✓ | ✓ | ✗ | +| | 删除 Notebooks | ✓ | ✓ | ✗ | ✗ | +| 任务列表 | 查看任务列表 | ✓ | ✓ | ✓ | ✓ | +| | 查看任务详情 | ✓ | ✓ | ✓ | ✓ | +| | 创建任务 | ✓ | ✓ | ✗ | ✗ | +| | 克隆任务 | ✓ | ✓ | ✗ | ✗ | +| | 查看任务负载详情 | ✓ | ✓ | ✓ | ✗ | +| | 删除任务 | ✓ | ✓ | ✗ | ✗ | +| 任务分析 | 查看任务分析 | ✓ | ✓ | ✓ | ✓ | +| | 查看任务分析详情 | ✓ | ✓ | ✓ | ✓ | +| | 删除任务分析 | ✓ | ✓ | ✗ | ✗ | +| 数据集列表 | 查看数据集列表 | ✓ | ✓ | ✓ | ✗ | +| | 创建数据集 | ✓ | ✓ | ✗ | ✗ | +| | 重新同步数据集 | ✓ | ✓ | ✓ | ✗ | +| | 更新凭证 | ✓ | ✓ | ✓ | ✗ | +| | 删除数据集 | ✓ | ✓ | ✗ | ✗ | +| 环境管理 | 查看环境管理列表 | ✓ | ✓ | ✓ | ✓ | +| | 创建环境 | ✓ | ✓ | ✗ | ✗ | +| | 更新环境 | ✓ | ✓ | ✓ | ✗ | +| | 删除环境 | ✓ | ✓ | ✗ | ✗ | +| 推理服务 | 查看推理服务列表 | ✓ | ✓ | ✓ | ✓ | +| | 查看推理服务详情 | ✓ | ✓ | ✓ | ✓ | +| | 创建推理服务 | ✓ | ✓ | ✗ | ✗ | +| | 更新推理服务 | ✓ | ✓ | ✓ | ✗ | +| | 停止推理服务 | ✓ | ✓ | ✓ | ✗ | +| | 启动推理服务 | ✓ | ✓ | ✓ | ✗ | +| | 删除推理服务 | ✓ | ✓ | ✗ | ✗ | +| **运维管理** | | | | | | +| 概览 | 查看概览 | ✓ | ✗ | ✗ | ✗ | +| GPU 管理 | 查看 GPU 管理列表 | ✓ | ✗ | ✗ | ✗ | +| 队列管理 | 查看队列管理列表 | ✓ | ✗ | ✗ | ✗ | +| | 查看队列详情 | ✓ | ✗ | ✗ | ✗ | +| | 创建队列 | ✓ | ✗ | ✗ | ✗ | +| | 更新队列 | ✓ | ✗ | ✗ | ✗ | +| | 删除队列 | ✓ | ✗ | ✗ | ✗ | diff --git a/docs/zh/docs/admin/ghippo/permissions/kpanda.md b/docs/zh/docs/admin/ghippo/permissions/kpanda.md new file mode 100644 index 0000000..8775b6b --- /dev/null +++ b/docs/zh/docs/admin/ghippo/permissions/kpanda.md @@ -0,0 +1,366 @@ +--- +hide: + - toc +--- + +# 容器管理权限说明 + +容器管理模块使用以下角色: + +- Admin / Kpanda Owner +- [Cluster Admin](../../kpanda/permissions/permission-brief.md#cluster-admin) +- [NS Admin](../../kpanda/permissions/permission-brief.md#ns-admin) +- [NS Editor](../../kpanda/permissions/permission-brief.md#ns-editor) +- [NS Viewer](../../kpanda/permissions/permission-brief.md#ns-viewer) + +!!! note + + - 有关权限的更多信息,请参阅[容器管理权限体系说明](../../kpanda/permissions/permission-brief.md)。 + - 有关角色的创建、管理和删除,请参阅[角色和权限管理](../access-control/role.md)。 + - __Cluster Admin__ , __NS Admin__ , __NS Editor__ , __NS Viewer__ 的权限仅在当前的集群或命名空间内生效。 + +各角色所具备的权限如下: + + + +| 一级功能 | 二级功能 | 权限点 | Cluster Admin | Ns Admin | Ns Editor | NS Viewer | +| ------- | ------- | ---- | ------------- | -------- | ---------- | -------- | +| 集群 | 集群列表 | 查看集群列表 | ✓ | ✓ | ✓ | ✓ | +| | | 接入集群 | ✗ | ✗ | ✗ | ✗ | +| | | 创建集群 | ✗ | ✗ | ✗ | ✗ | +| | 集群操作 | 进入控制台 | ✓ | ✓(仅列表内可以进入) | ✓ | ✗ | +| | | 查看监控 | ✓ | ✗ | ✗ | ✗ | +| | | 编辑基础配置 | ✓ | ✗ | ✗ | ✗ | +| | | 下载 kubeconfig | ✓ | ✓(下载ns权限的kubeconfig) | ✓(下载 ns 权限的 kubeconfig) | ✓(下载 ns 权限的 kubeconfig) | +| | | 解除接入 | ✗ | ✗ | ✗ | ✗ | +| | | 查看日志 | ✓ | ✗ | ✗ | ✗ | +| | | 重试 | ✗ | ✗ | ✗ | ✗ | +| | | 卸载集群 | ✗ | ✗ | ✗ | ✗ | +| | 集群概览 | 查看集群概览 | ✓ | ✗ | ✗ | ✗ | +| | 节点管理 | 接入节点 | ✗ | ✗ | ✗ | ✗ | +| | | 查看节点列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看节点详情 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 暂停调度 | ✓ | ✗ | ✗ | ✗ | +| | | 修改标签 | ✓ | ✗ | ✗ | ✗ | +| | | 修改注解 | ✓ | ✗ | ✗ | ✗ | +| | | 修改污点 | ✓ | ✗ | ✗ | ✗ | +| | | 移除节点 | ✗ | ✗ | ✗ | ✗ | +| | 无状态负载 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 镜像创建 | ✓ | ✓ | ✓ | ✗ | +| | 选择 ns 绑定的 ws 内的实例 | 选择镜像 | ✓ | ✓ | ✓ | ✗ | +| | | IP 池查看 | ✓ | ✓ | ✓ | ✗ | +| | | 网卡编辑 | ✓ | ✓ | ✓ | ✗ | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 负载伸缩 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 状态 - 暂停升级 | ✓ | ✓ | ✓ | ✗ | +| | | 状态 - 停止 | ✓ | ✓ | ✓ | ✗ | +| | | 状态 - 重启 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 有状态负载 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 镜像创建 | ✓ | ✓ | ✓ | ✗ | +| | 选择ns绑定的ws内的实例 | 选择镜像 | ✓ | ✓ | ✓ | ✗ | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 负载伸缩 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-停止 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-重启 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 守护进程 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 镜像创建 | ✓ | ✓ | ✓ | ✗ | +| | 选择ns绑定的ws内的实例 | 选择镜像 | ✓ | ✓ | ✓ | ✗ | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-重启 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 任务 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 镜像创建 | ✓ | ✓ | ✓ | ✗ | +| | | 实例列表 | ✓ | ✓ | ✓ | ✓ | +| | 选择ns绑定的ws内的实例 | 选择镜像 | ✓ | ✓ | ✓ | ✗ | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✓ | +| | | 重启 | ✓ | ✓ | ✓ | ✗ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 定时任务 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 镜像创建 | ✓ | ✓ | ✓ | ✗ | +| | 选择ns绑定的ws内的实例 | 选择镜像 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 停止 | ✓ | ✓ | ✓ | ✗ | +| | | 查看任务列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 容器组 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✓ | +| | | 上传文件 | ✓ | ✓ | ✓ | ✗ | +| | | 下载文件 | ✓ | ✓ | ✓ | ✗ | +| | | 查看容器列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | ReplicaSet | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | Helm 应用 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | Helm 模板 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看详情 | ✓ | ✓ | ✓ | ✓ | +| | | 安装模板 | ✓ | ✓(ns级别的可以) | ✗ | ✗ | +| | | 下载模板 | ✓ | ✓ | ✓(和查看接口一致) | ✓ | +| | Helm 仓库 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 创建仓库 | ✓ | ✗ | ✗ | ✗ | +| | | 更新仓库 | ✓ | ✗ | ✗ | ✗ | +| | | 克隆仓库 | ✓ | ✗ | ✗ | ✗ | +| | | 刷新仓库 | ✓ | ✗ | ✗ | ✗ | +| | | 修改标签 | ✓ | ✗ | ✗ | ✗ | +| | | 修改注解 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 服务 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 路由 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 网络策略 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✗ | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 网络配置 | 配置网络 | ✓ | ✓ | ✓ | ✗ | +| | 自定义资源 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✗ | ✗ | ✗ | +| | | YAML 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 编辑 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | PVC | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 选择sc | ✓ | ✓ | ✓ | ✗ | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 克隆 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | PV | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✗ | ✗ | ✗ | +| | | YAML 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 编辑 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 更新 | ✓ | ✗ | ✗ | ✗ | +| | | 克隆 | ✓ | ✗ | ✗ | ✗ | +| | | 修改标签 | ✓ | ✗ | ✗ | ✗ | +| | | 修改注解 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | SC | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | YAML 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 更新 | ✓ | ✗ | ✗ | ✗ | +| | | 授权命名空间 | ✓ | ✗ | ✗ | ✗ | +| | | 解除授权 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 配置项 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 导出配置项 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 密钥 | 查看列表 | ✓ | ✓ | ✓ | ✗ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✗ | +| | | YAML 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 创建 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 导出密钥 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 命名空间 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | YAML 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 修改标签 | ✓ | ✓ | ✗ | ✗ | +| | | 解绑工作空间 | ✗ | ✗ | ✗ | ✗ | +| | | 绑定工作空间 | ✗ | ✗ | ✗ | ✗ | +| | | 配额管理 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 集群操作 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 查看日志 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | helm 操作 | 设置保留条数 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✓ | ✗ | ✗ | +| | | 查看日志 | ✓ | ✓ | ✗ | ✗ | +| | | 删除 | ✓ | ✓ | ✗ | ✗ | +| | 集群升级 | 查看详情 | ✓ | ✗ | ✗ | ✗ | +| | | 升级 | ✗ | ✗ | ✗ | ✗ | +| | 集群设置 | addon 插件配置 | ✓ | ✗ | ✗ | ✗ | +| | | 高级配置 | ✓ | ✗ | ✗ | ✗ | +| 命名空间 | | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 创建 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 修改标签 | ✓ | ✓ | ✗ | ✗ | +| | | 绑定工作空间 | ✓ | ✗ | ✗ | ✗ | +| | | 配额管理 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| 工作负载 | 无状态负载 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 负载伸缩 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-暂停升级 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-停止 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-重启 | ✓ | ✓ | ✓ | ✗ | +| | | 回退 | ✓ | ✓ | ✓ | ✗ | +| | | 修改标签注解 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 有状态负载 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 负载伸缩 | ✓ | ✓ | ✓ | ✗ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-停止 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-重启 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 守护进程 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 编辑 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 更新 | ✓ | ✓ | ✓ | ✗ | +| | | 状态-重启 | ✓ | ✓ | ✓ | ✗ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 任务 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✗ | +| | | 重启 | ✓ | ✓ | ✓ | ✗ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 定时任务 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| | 容器组 | 查看列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看/管理详情 | ✓ | ✓ | ✓ | ✓(仅查看) | +| | | 进入控制台 | ✓ | ✓ | ✓ | ✗ | +| | | 查看监控 | ✓ | ✓ | ✓ | ✓ | +| | | 查看日志 | ✓ | ✓ | ✓ | ✓ | +| | | 查看 YAML | ✓ | ✓ | ✓ | ✓ | +| | | 上传文件 | ✓ | ✓ | ✓ | ✗ | +| | | 下载文件 | ✓ | ✓ | ✓ | ✗ | +| | | 查看容器列表 | ✓ | ✓ | ✓ | ✓ | +| | | 查看事件 | ✓ | ✓ | ✓ | ✓ | +| | | 删除 | ✓ | ✓ | ✓ | ✗ | +| 备份恢复 | 应用备份 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✗ | ✗ | ✗ | +| | | 创建备份计划 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 更新计划 | ✓ | ✗ | ✗ | ✗ | +| | | 暂停 | ✓ | ✗ | ✗ | ✗ | +| | | 立即执行 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 恢复备份 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✗ | ✗ | ✗ | +| | | 恢复备份 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 备份点 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 对象存储 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | ETCD备份 | 查看备份策略列表 | ✓ | ✗ | ✗ | ✗ | +| | | 创建备份策略 | ✓ | ✗ | ✗ | ✗ | +| | | 查看日志 | ✓ | ✗ | ✗ | ✗ | +| | | 查看 YAML | ✓ | ✗ | ✗ | ✗ | +| | | 更新备份策略 | ✓ | ✗ | ✗ | ✗ | +| | | 停止/启动 | ✓ | ✗ | ✗ | ✗ | +| | | 立即执行 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✗ | ✗ | ✗ | +| | | 删除备份记录 | ✓ | ✗ | ✗ | ✗ | +| | | 查看备份点列表 | ✓ | ✗ | ✗ | ✗ | +| 集群巡检 | 集群巡检 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看/管理详情 | ✓ | ✗ | ✗ | ✗ | +| | | 集群巡检 | ✓ | ✗ | ✗ | ✗ | +| | | 设置 | ✓ | ✗ | ✗ | ✗ | +| 权限管理 | 集群权限 | 查看列表 | ✓ | ✗ | ✗ | ✗ | +| | | 授权用户为 cluster admin | ✓ | ✗ | ✗ | ✗ | +| | | 删除 | ✓ | ✗ | ✗ | ✗ | +| | 命名空间权限 | 查看列表 | ✓ | ✓ | ✗ | ✗ | +| | | 授权用户为 ns admin | ✓ | ✓ | ✗ | ✗ | +| | | 授权用户为 ns editor | ✓ | ✓ | ✗ | ✗ | +| | | 授权用户为 ns viewer | ✓ | ✓ | ✗ | ✗ | +| | | 编辑权限 | ✓ | ✓ | ✗ | ✗ | +| | | 删除 | ✓ | ✓ | ✗ | ✗ | +| 安全管理 | 合规性扫描 | 查看扫描报告列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描报告详情 | ✓ | ✗ | ✗ | ✗ | +| | | 下载扫描报告 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描报告 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描策略列表 | ✓ | ✗ | ✗ | ✗ | +| | | 创建扫描策略 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描策略 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描配置列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描配置详情 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描配置 | ✓ | ✗ | ✗ | ✗ | +| | 权限扫描 | 查看扫描报告列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描报告详情 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描报告 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描策略列表 | ✓ | ✗ | ✗ | ✗ | +| | | 创建扫描策略 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描策略 | ✓ | ✗ | ✗ | ✗ | +| | 漏洞扫描 | 查看扫描报告列表 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描报告详情 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描报告 | ✓ | ✗ | ✗ | ✗ | +| | | 查看扫描策略列表 | ✓ | ✗ | ✗ | ✗ | +| | | 创建扫描策略 | ✓ | ✗ | ✗ | ✗ | +| | | 删除扫描策略 | ✓ | ✗ | ✗ | ✗ | diff --git a/docs/zh/docs/admin/ghippo/personal-center/accesstoken.md b/docs/zh/docs/admin/ghippo/personal-center/accesstoken.md new file mode 100644 index 0000000..f14de70 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/personal-center/accesstoken.md @@ -0,0 +1,53 @@ +# 访问密钥 + +访问密钥(Access Key)可用于访问开放 API 和持续发布,用户可在个人中心参照以下步骤获取密钥并访问 API。 + +## 获取密钥 + +登录 AI 算力平台,在右上角的下拉菜单中找到 __个人中心__ ,可以在 __访问密钥__ 页面管理账号的访问密钥。 + +![ak list](../../../images/platform02.png) + +![created a key](../../../images/platform03.png) + +!!! info + + 访问密钥信息仅显示一次。如果您忘记了访问密钥信息,您需要重新创建新的访问密钥。 + +## 使用密钥访问 API + +在访问算丰 AI 算力平台openAPI 时,在请求中加上请求头 `Authorization:Bearer ${token}` 以标识访问者的身份, +其中 `${token}` 是上一步中获取到的密钥,具体接口信息参见 [OpenAPI 接口文档](../../../openapi/index.md)。 + +**请求示例** + +```bash +curl -X GET -H 'Authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRKVjlBTHRBLXZ4MmtQUC1TQnVGS0dCSWc1cnBfdkxiQVVqM2U3RVByWnMiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjE0MTU5NjksImlhdCI6MTY2MDgxMTE2OSwiaXNzIjoiZ2hpcHBvLmlvIiwic3ViIjoiZjdjOGIxZjUtMTc2MS00NjYwLTg2MWQtOWI3MmI0MzJmNGViIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJncm91cHMiOltdfQ.RsUcrAYkQQ7C6BxMOrdD3qbBRUt0VVxynIGeq4wyIgye6R8Ma4cjxG5CbU1WyiHKpvIKJDJbeFQHro2euQyVde3ygA672ozkwLTnx3Tu-_mB1BubvWCBsDdUjIhCQfT39rk6EQozMjb-1X1sbLwzkfzKMls-oxkjagI_RFrYlTVPwT3Oaw-qOyulRSw7Dxd7jb0vINPq84vmlQIsI3UuTZSNO5BCgHpubcWwBss-Aon_DmYA-Et_-QtmPBA3k8E2hzDSzc7eqK0I68P25r9rwQ3DeKwD1dbRyndqWORRnz8TLEXSiCFXdZT2oiMrcJtO188Ph4eLGut1-4PzKhwgrQ' https://demo-dev.daocloud.io/apis/ghippo.io/v1alpha1/users?page=1&pageSize=10 -k +``` + +**请求结果** + +```json +{ + "items": [ + { + "id": "a7cfd010-ebbe-4601-987f-d098d9ef766e", + "name": "a", + "email": "", + "description": "", + "firstname": "", + "lastname": "", + "source": "locale", + "enabled": true, + "createdAt": "1660632794800", + "updatedAt": "0", + "lastLoginAt": "" + } + ], + "pagination": { + "page": 1, + "pageSize": 10, + "total": 1 + } +} +``` diff --git a/docs/zh/docs/admin/ghippo/personal-center/language.md b/docs/zh/docs/admin/ghippo/personal-center/language.md new file mode 100644 index 0000000..7e7aca8 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/personal-center/language.md @@ -0,0 +1,31 @@ +--- +hide: + - toc +--- + +# 语言设置 + +本节说明如何设置界面语言。目前支持中文、English 两个语言。 + +语言设置是平台提供多语言服务的入口,平台默认显示为中文,用户可根据需要选择英语或自动检测浏览器语言首选项的方式来切换平台语言。 +每个用户的多语言服务是相互独立的,切换后不会影响其他用户。 + +平台提供三种切换语言方式:中文、英语-English、自动检测您的浏览器语言首选项。 + +操作步骤如下。 + +1. 使用您的用户名/密码登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ 。 + + ![全局管理](../../../images/ws01_6.png) + +2. 点击右上角的用户名位置,选择 __个人中心__ 。 + + ![个人中心](../../../images/lang01.png) + +3. 点击 __语言设置__ 页签。 + + ![语言设置](../../../images/lang02.png) + +4. 切换语言选项。 + + ![切换语言](../../../images/lang03.png) diff --git a/docs/zh/docs/admin/ghippo/personal-center/security-setting.md b/docs/zh/docs/admin/ghippo/personal-center/security-setting.md new file mode 100644 index 0000000..6381009 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/personal-center/security-setting.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 安全设置 + +功能说明:用于填写邮箱地址和修改登录密码。 + +- 邮箱:当管理员配置邮箱服务器地址之后,用户能够通过登录页的忘记密码按钮,填写该处的邮箱地址以找回密码。 +- 密码:用于登录平台的密码,建议定期修改密码。 + +具体操作步骤如下: + +1. 点击右上角的用户名位置,选择 __个人中心__ 。 + + ![个人中心](../../../images/lang01_1.png) + +2. 点击 __安全设置__ 页签。填写您的邮箱地址或修改登录密码。 + + ![安全设置](../../../images/security01.png) diff --git a/docs/zh/docs/admin/ghippo/personal-center/ssh-key.md b/docs/zh/docs/admin/ghippo/personal-center/ssh-key.md new file mode 100644 index 0000000..39b665a --- /dev/null +++ b/docs/zh/docs/admin/ghippo/personal-center/ssh-key.md @@ -0,0 +1,103 @@ +# 配置 SSH 公钥 + +本文说明如何配置 SSH 公钥。 + +## 步骤 1:查看已存在的 SSH 密钥 + +在生成新的 SSH 密钥前,请先确认是否需要使用本地已生成的 SSH 密钥,SSH 密钥对一般存放在本地用户的根目录下。 +Linux、Mac 请直接使用以下命令查看已存在的公钥,Windows 用户在 WSL(需要 Windows 10 或以上)或 Git Bash 下使用以下命令查看已生成的公钥。 + +- **ED25519 算法:** + + ```bash + cat ~/.ssh/id_ed25519.pub + ``` + +- **RSA 算法:** + + ```bash + cat ~/.ssh/id_rsa.pub + ``` + +如果返回一长串以 ssh-ed25519 或 ssh-rsa 开头的字符串,说明已存在本地公钥, +您可以跳过[步骤 2 生成 SSH 密钥](#2-ssh),直接操作[步骤 3](#3)。 + +## 步骤 2:生成 SSH 密钥 + +若[步骤 1](#1-ssh) 未返回指定的内容字符串,表示本地暂无可用 SSH 密钥,需要生成新的 SSH 密钥,请按如下步骤操作: + +1. 访问终端(Windows 请使用 [WSL](https://docs.microsoft.com/zh-cn/windows/wsl/install) 或 [Git Bash](https://gitforwindows.org/)), + 运行 `ssh-keygen -t`。 + +2. 输入密钥算法类型和可选的注释。 + + 注释会出现在 .pub 文件中,一般可使用邮箱作为注释内容。 + + - 基于 `ED25519` 算法,生成密钥对命令如下: + + ```bash + ssh-keygen -t ed25519 -C "<注释内容>" + ``` + + - 基于 `RSA` 算法,生成密钥对命令如下: + + ```bash + ssh-keygen -t rsa -C "<注释内容>" + ``` + +3. 点击回车,选择 SSH 密钥生成路径。 + + 以 ED25519 算法为例,默认路径如下: + + ```console + Generating public/private ed25519 key pair. + Enter file in which to save the key (/home/user/.ssh/id_ed25519): + ``` + + 密钥默认生成路径:`/home/user/.ssh/id_ed25519`,公钥与之对应为:`/home/user/.ssh/id_ed25519.pub`。 + +4. 设置一个密钥口令。 + + ```console + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + ``` + + 口令默认为空,您可以选择使用口令保护私钥文件。 + 如果您不想在每次使用 SSH 协议访问仓库时,都要输入用于保护私钥文件的口令,可以在创建密钥时,输入空口令。 + +5. 点击回车,完成密钥对创建。 + +## 步骤 3:拷贝公钥 + +除了在命令行打印出已生成的公钥信息手动复制外,可以使用命令拷贝公钥到粘贴板下,请参考操作系统使用以下命令进行拷贝。 + +- Windows(在 [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) 或 [Git Bash](https://gitforwindows.org/) 下): + + ```bash + cat ~/.ssh/id_ed25519.pub | clip + ``` + +- Mac: + + ```bash + tr -d '\n'< ~/.ssh/id_ed25519.pub | pbcopy + ``` + +- GNU/Linux (requires xclip): + + ```bash + xclip -sel clip < ~/.ssh/id_ed25519.pub + ``` + +## 步骤 4:在算丰 AI 算力平台上设置公钥 + +1. 登录算丰 AI 算力平台UI 页面,在页面右上角选择 **个人中心** -> **SSH 公钥** 。 + +2. 添加生成的 SSH 公钥信息。 + + 1. SSH 公钥内容。 + + 2. 公钥标题:支持自定义公钥名称,用于区分管理。 + + 3. 过期时间:设置公钥过期时间,到期后公钥将自动失效,不可使用;如果不设置,则永久有效。 diff --git a/docs/zh/docs/admin/ghippo/platform-setting/about.md b/docs/zh/docs/admin/ghippo/platform-setting/about.md new file mode 100644 index 0000000..50773f8 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/platform-setting/about.md @@ -0,0 +1,26 @@ +--- +hide: + - toc +--- + +# 关于平台 + + __关于平台__ 主要呈现平台各个子模块当前更新的版本,声明了平台使用的各个开源软件,并以动画视频的方式致谢了平台的技术团队。 + +查看步骤: + +1. 使用具有 __Admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ 。 + + ![全局管理](../../../images/ws01_3.png) + +2. 点击 __平台设置__ ,选择 __关于平台__ ,查看产品版本、开源软件声明和技术团队。 + + ![关于平台](../images/about05.png) + + **License 声明** + + ![license 声明](../../../images/about02.png) + + **技术团队** + + ![技术团队](../../../images/about03.png) diff --git a/docs/zh/docs/admin/ghippo/platform-setting/appearance.md b/docs/zh/docs/admin/ghippo/platform-setting/appearance.md new file mode 100644 index 0000000..ab86120 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/platform-setting/appearance.md @@ -0,0 +1,106 @@ +# 外观定制 + +在算丰 AI 算力平台中,可通过 __外观定制__ 更换登录界面、顶部导航栏以及底部版权和备案信息,帮助用户更好地辨识产品。 + +## 定制说明 + +1. 使用具有 __admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ -> __平台设置__ 。 + + ![全局管理](../../../images/ws01_5.png) + +2. 选择 __外观定制__ ,在 __登录页定制__ 页签中,修改登录页的图标和文字后,点击 __保存__ 。 + + ![外观定制](../images/logindesign.png) + +3. 退出登录,在登录页刷新后可看到配置后的效果 + + ![登录页](../../../images/visual02.png) + +4. 点击 __顶部导航栏定制__ 页签,修改导航栏的图标和文字后,点击 __保存__ 。 + + ![顶部导航栏](../../../images/visual06.png) + +5. 点击 __高级定制__ ,可以用 CSS 样式设置登录页、导航栏、底部版权及备案信息。 + + ![高级定制](../../../images/appear05.png) + +## 高级定制 + +高级定制能够通过 CSS 样式来修改整个容器平台的颜色、字体间隔、字号等。 +您需要熟悉 CSS 语法。删除黑色输入框的内容,可恢复到默认状态,当然也可以点击 __一键还原__ 按钮。 + +**登录页定制的 CSS 样例:** + +```css +.test { + width: 12px; +} + +#kc-login { + /* color: red!important; */ +} +``` + +**登录后页面定制的 CSS 样例:** + +```css +.dao-icon.dao-iconfont.icon-service-global.dao-nav__head-icon { + color: red!important; +} +.ghippo-header-logo { + background-color: green!important; +} +.ghippo-header { + background-color: rgb(128, 115, 0)!important; +} +.ghippo-header-nav-main { + background-color: rgb(0, 19, 128)!important; +} +.ghippo-header-sub-nav-main .dao-popper-inner { + background-color: rgb(231, 82, 13) !important; +} +``` + +**Footer(页面底部的版权、备案等信息)定制示例** + +```css + + + +``` + +!!! note + + 如果想要恢复默认设置,可以点击 __一键还原__ 。请注意,一键还原后将丢弃所有自定义设置。 diff --git a/docs/zh/docs/admin/ghippo/platform-setting/mail-server.md b/docs/zh/docs/admin/ghippo/platform-setting/mail-server.md new file mode 100644 index 0000000..81129b0 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/platform-setting/mail-server.md @@ -0,0 +1,46 @@ +--- +hide: + - toc +--- + +# 邮件服务器 + +算丰 AI 算力平台会在用户忘记密码时,向用户发送电子邮件以验证电子邮件地址,确保用户是本人操作。 +要使算丰 AI 算力平台能够发送电子邮件,需要先提供您的邮件服务器地址。 + +具体操作步骤如下: + +1. 使用具有 __admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ 。 + + ![全局管理](../../../images/ws01_4.png) + +1. 点击 __平台设置__ ,选择 __邮件服务器设置__ 。 + + ![邮件服务器](../../../images/mail01.png) + + 填写以下字段配置邮件服务器: + + | 字段 | 描述 | 举例值 | + | ----------------- | ------------------------------------------------------------ | ------------ | + | SMTP 服务器地址 | 能够提供邮件服务的 SMTP 服务器地址 | smtp.163.com | + | SMTP 服务器端口 | 发送邮件的端口 | 25 | + | 用户名 | SMTP 用户的名称 | test@163.com | + | 密码 | SMTP 账号的密码 | 123456 | + | 发件人邮箱 | 发件人的邮箱地址 | test@163.com | + | 使用 SSL 安全连接 | SSL 可以用于加密邮件,从而提高通过邮件传输的信息的安全性,通常需为邮件服务器配置证书 | 不开启 | + +1. 配置完成后点击 __保存__ ,点击 __测试邮件服务器__ 。 + + ![测试](../../../images/mail02.png) + +1. 屏幕右上角出现成功发送邮件的提示,则表示邮件服务器被成功设置。 + + ![成功](../../../images/mail03.png) + +## 常见问题 + +问:邮件服务器设置后用户仍无法找回密码是什么原因? + +答:用户可能未设置邮箱或者设置了错误的邮箱地址;此时可以让 admin 角色的用户在 __全局管理__ -> __用户与访问控制__ 中通过用户名找到该用户,并在用户详情中为该用户设置新的登录密码。 + +如果邮件服务器没有连通,请检查邮件服务器地址、用户名及密码是否正确。 diff --git a/docs/zh/docs/admin/ghippo/platform-setting/security.md b/docs/zh/docs/admin/ghippo/platform-setting/security.md new file mode 100644 index 0000000..932fee1 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/platform-setting/security.md @@ -0,0 +1,27 @@ +--- +hide: + - toc +--- + +# 安全策略 + +算丰 AI 算力平台在图形界面上提供了基于密码和访问控制的安全策略。 + +**密码策略** + +- 新密码不能与最近的历史密码相同。 +- 密码过期后,系统强制要求修改密码。 +- 密码不能与用户名相同。 +- 密码不能和用户的邮箱地址相同。 +- 自定义密码规则。 +- 自定义密码最小长度。 + +**访问控制策略** + +- 会话超时策略:用户在 x 小时内没有操作,退出当前账号。 +- 账号锁定策略:限制时间内多次登录失败,账号将被锁定。 +- 登录/退出策略:关闭浏览器的同时退出登录。 + +进入全局管理后,在左侧导航栏点击 __平台设置__ -> __安全策略__ ,即可设置密码策略和访问控制策略。 + +![安全策略](../images/security-policy.png) diff --git a/docs/zh/docs/admin/ghippo/report-billing/billing.md b/docs/zh/docs/admin/ghippo/report-billing/billing.md new file mode 100644 index 0000000..5874369 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/report-billing/billing.md @@ -0,0 +1,39 @@ +--- +hide: + - toc +--- + +# 计量计费 + +计量计费在报表的基础上,对资源的使用数据做了进一步的计费处理。支持用户手动设置 CPU、内存、存储、GPU 的单价以及货币单位等,设置后系统将自动统计出集群、节点、容器组、命名空间、工作空间在一段时间内的花费情况,时间段用户可自由调整,可按照周、月、季度、年筛选调整后导出 Excel 或 Csv 格式的计费报表。 + +## 计费规则及生效时间 + +- 计费规则:默认按照请求值和使用量的最大值计费。 +- 生效时间:次日生效,以次日凌晨时获取的单价和数量计算当天产生的费用。 + +## 功能特性 + +- 支持自定义设置 CPU 、内存、存储以及 GPU 的计费单位,以及货币单位。 +- 支持查询自定义时间范围的统计数据,根据所选时间段自动计算出该时间段内的计费情况。 +- 支持以 CSV 和 Excel 两种格式导出计费报表。 +- 支持开启/关闭单个计费报表,开启/关闭后,平台将在 20 分钟内开始/停止采集数据,往期已经采集到的数据还将正常显示。 +- 支持对 CPU、内存总量、存储、GPU、总计等计费数据的选择性展示。 + +## 报表维度 + +目前支持以下几种报表: + +- 集群计费报表:展示某段时间内全部集群的 CPU、内存总量、存储、GPU、总计等计费情况,以及该段时间内该集群下的节点数量,可通过点击节点数量快捷进入节点计费报表,并查看该段时间内该集群下的节点计费情况。 +- 节点计费报表:展示某段时间内全部节点的 CPU、内存总量、存储、GPU、总计等计费情况,以及节点的 IP、类型和所属集群。 +- 容器组报表:展示某段时间内全部容器组的 CPU、内存总量、存储、GPU、总计等计费情况,以及容器组的所属命名空间、所属集群和所属工作空间。 +- 工作空间计费报表:展示某段时间内全部工作空间的 CPU、内存总量、存储、GPU、总计等计费情况,以及命名空间数量和容器组数量,可通过点击命名空间数量快捷进入命名空间计费报表,并查看该段时间内该工作空间下命名空间的计费情况;同样的方式可查看该段时间内该工作空间下的容器组的计费情况。 +- 命名空间计费报表:某段时间内全部命名空间的 CPU、内存总量、存储、GPU、总计等计费情况,以及容器组数量、所属集群、所属工作空间,可通过点击容器组数量快捷进入容器组计费报表,并查看该段时间内该命名空间下的容器组的计费情况。 + +## 操作步骤 + +1. 使用具有 __admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ -> __运营管理__ 。 + + ![报表管理](../images/gmagpiereport.png) + +2. 进入 **运营管理** 后切换不同菜单可查看集群、节点、容器组等计费报表。 diff --git a/docs/zh/docs/admin/ghippo/report-billing/index.md b/docs/zh/docs/admin/ghippo/report-billing/index.md new file mode 100644 index 0000000..e8f27b9 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/report-billing/index.md @@ -0,0 +1,17 @@ +--- +hide: + - toc +--- + +# 运营管理 + +运营管理通过可视化的方式,为您展示平台上统计时间范围内集群、节点、命名空间、容器组、工作空间等维度的 CPU/内存/存储/GPU 的使用总量和使用率等信息。 +以及通过使用量、使用时间及单价等信息,自动计算出的平台消费信息。该模块默认开启所有报表统计,同时也支持平台管理员对单个报表进行手动开启或关闭, +开启/关闭后将在最长 20 分钟内,平台开始/停止采集报表数据,往期已采集到的数据还将正常展示。 +运营管理数据最多可在平台上保留 365 天,超过保留时间的统计数据将被自动删除。您也可以通过 CSV 或 Excel 方式下载报表后进行进一步的统计和分析。 + +[报表管理](./report.md)通过 CPU 利用率、内存利用率、存储利用率、GPU 算力利用率、GPU 显存利用率 5 个维度,对集群、节点、容器组、工作空间、命名空间 5 种资源进行数据统计。同时联动审计和告警模块,支持对审计数据和告警数据进行统计管理。共计支持 7 种类型报表。 + +[计量计费](./billing.md)针对平台上的集群、节点、容器组、命名空间和工作空间 5 种资源进行计费统计。 +根据不同资源中 CPU、内存、存储和 GPU 的使用量,以及用户手动配置的价格和货币单位自动计算出每种资源在统计时间的消费情况, +根据所选时间跨度不同,可快速计算出该跨度内的实际消费情况,如月度、季度、年度等。 diff --git a/docs/zh/docs/admin/ghippo/report-billing/report.md b/docs/zh/docs/admin/ghippo/report-billing/report.md new file mode 100644 index 0000000..c359e22 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/report-billing/report.md @@ -0,0 +1,41 @@ +--- +hide: + - toc +--- + +# 报表管理 + +报表管理以可视化的方式,展示了集群、节点、容器组(Pod)、工作空间、命名空间、审计及告警维度的统计数据,为平台的计费及使用情况的调优提供了可靠的基础数据。 + +## 功能特性 + +- 支持查询自定义时间范围的统计数据 +- 支持以 CSV 和 Excel 两种格式导出报表 +- 支持开启/关闭单个报表,开启/关闭后,平台将在 20 分钟内开始/停止采集数据,往期已经采集到的数据还将正常显示 +- 支持展示 CPU 使用率、内存使用率、存储使用率和 GPU 显存使用率的最大、最小和平均值 + +## 报表维度 + +目前支持以下几种报表: + +- 集群报表:展示某段时间内所有集群的 CPU 使用率、内存使用率、存储使用率和 GPU 显存使用率的最大、最小和平均值,以及该段时间内集群下的节点数量, + 可通过点击节点数量快捷进入节点报表,并查看该段时间内该集群下的节点使用情况。 +- 节点报表:展示某段时间内所有节点的 CPU 使用率、内存使用率、存储使用率和 GPU 显存使用率的最大、最小和平均值,以及节点的 IP、类型和所属集群。 +- 容器组报表:展示某段时间内所有容器组的 CPU 使用率、内存使用率、存储使用率和 GPU 显存使用率的最大、最小和平均值,以及容器组的所属命名空间、所属集群和所属工作空间。 +- 工作空间报表:展示某段时间内所有工作空间的 CPU 使用率、内存使用率、存储使用率和 GPU 显存使用率的最大、最小和平均值,以及命名空间数量和容器组数量, + 可通过点击命名空间数量快捷进入命名空间报表,并查看该段时间内该工作空间下命名空间的使用情况;同样的方式可查看该段时间下该工作空间下的容器组的使用情况。 +- 命名空间报表:展示某段时间内所有命名空间的 CPU 使用率、内存使用率、存储使用率和 GPU 显存使用率的最大、最小和平均值,以及容器组数量、所属集群、所属工作空间, + 可通过点击容器组数量快捷进入容器组报表,并查看该段时间内该命名空间下的容器组的使用情况。 +- 审计报表:分为用户操作和资源操作两个报表。用户操作报表主要统计单个用户在一段时间内的操作次数,以及成功和失败的次数; + 资源操作报表主要统计所有用户对某种类型资源的操作次数。 +- 告警报表:展示某段时间内所有节点的告警数量,以及致命、严重、告警分别产生的次数。 + +## 操作步骤 + +1. 使用具有 __Admin__ 角色的用户登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ -> __运营管理__ 。 + + ![报表管理](../../../images/gmagpiereport.png) + +2. 进入运营管理后切换不同菜单可查看集群、节点、容器组等报表。 + + ![报表](../images/report01.png) diff --git a/docs/zh/docs/admin/ghippo/troubleshooting/ghippo01.md b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo01.md new file mode 100644 index 0000000..147061c --- /dev/null +++ b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo01.md @@ -0,0 +1,45 @@ +--- +hide: + - toc +--- + +# 重启集群(云主机)istio-ingressgateway 无法启动? + +报错提示如下图: + +![](https://docs.daocloud.io/daocloud-docs-images/docs/reference/images/bug01.png) + +可能原因:RequestAuthentication CR 的 jwtsUri 地址无法访问, +导致 istiod 无法下发配置给 istio-ingressgateway(Istio 1.15 可以规避这个 bug: +[https://github.com/istio/istio/pull/39341/](https://github.com/istio/istio/pull/39341/files)) + +解决方法: + +1. 备份 RequestAuthentication ghippo CR。 + + ```shell + kubectl get RequestAuthentication ghippo -n istio-system -o yaml > ghippo-ra.yaml + ``` + +2. 删除 RequestAuthentication ghippo CR。 + + ```shell + kubectl delete RequestAuthentication ghippo -n istio-system + ``` + +3. 重启 Istio。 + + ```shell + kubectl rollout restart deploy/istiod -n istio-system + kubectl rollout restart deploy/istio-ingressgateway -n istio-system + ``` + +4. 重新 apply RequestAuthentication ghippo CR。 + + ```sh + kubectl apply -f ghippo-ra.yaml + ``` + + !!! note + + apply RequestAuthentication ghippo CR 之前,请确保 ghippo-apiserver 和 ghippo-keycloak 已经正常启动。 diff --git a/docs/zh/docs/admin/ghippo/troubleshooting/ghippo02.md b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo02.md new file mode 100644 index 0000000..850e492 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo02.md @@ -0,0 +1,27 @@ +--- +hide: + - toc +--- + +# 登录无限循环,报错 401 或 403 + +出现这个问题原因为:ghippo-keycloak 连接的 Mysql 数据库出现故障, 导致 __OIDC Public keys__ 被重置 + +在全局管理 0.11.1 及以上版本,您可以参照以下步骤,使用 __helm__ 更新全局管理配置文件即可恢复正常。 + +```shell +# 更新 helm 仓库 +helm repo update ghippo + +# 备份 ghippo 参数 +helm get values ghippo -n ghippo-system -o yaml > ghippo-values-bak.yaml + +# 获取当前部署的 ghippo 版本号 +version=$(helm get notes ghippo -n ghippo-system | grep "Chart Version" | awk -F ': ' '{ print $2 }') + +# 执行更新操作, 使配置文件生效 +helm upgrade ghippo ghippo/ghippo \ +-n ghippo-system \ +-f ./ghippo-values-bak.yaml \ +--version ${version} +``` diff --git a/docs/zh/docs/admin/ghippo/troubleshooting/ghippo03.md b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo03.md new file mode 100644 index 0000000..b01450c --- /dev/null +++ b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo03.md @@ -0,0 +1,67 @@ +# Keycloak 无法启动 + +*[Ghippo]: AI 算力中心全局管理的开发代号 + +## 常见故障 + +### 故障表现 + +MySQL 已就绪,无报错。在安装全局管理后 keycloak 无法启动(> 10 次)。 + +![img](https://docs.daocloud.io/daocloud-docs-images/docs/reference/images/restart01.png) + +### 检查项 + +- 如果数据库是 MySQL,检查 keycloak database 编码是否是 UTF8。 +- 检查从 keycloak 到数据库的网络,检查数据库资源是否充足,包括但不限于资源限制、存储空间、物理机资源。 + +### 解决步骤 + +![img](https://docs.daocloud.io/daocloud-docs-images/docs/reference/images/restart02.png) + +1. 检查 MySQL 资源占用是否到达 limit 限制 +1. 检查 MySQL 中 database keycloak table 的数量是不是 95 + (Keycloak 不同版本数据库数量可能会不一样,可以与同版本的开发或测试环境的 Keycloak 数据库数量进行比较), + 如数量少了,则说明数据库表初始化有问题(查询表数量命令提示为:show tables;) +1. 删除 keycloak database 并创建,提示 **CREATE DATABASE IF NOT EXISTS keycloak CHARACTER SET utf8** +1. 重启 Keycloak Pod 解决问题 + +## CPU does not support ×86-64-v2 + +### 故障表现 + +keycloak 无法正常启动,keycloak pod 运行状态为 `CrashLoopBackOff` 并且 keycloak 的 log 出现如下图所示的信息 + +![img.png](../images/14.png) + +### 检查项 +运行下面的检查脚本,查询当前节点 cpu 的 x86-64架构的特征级别 +```bash +cat <<"EOF" > detect-cpu.sh +#!/bin/sh -eu + +flags=$(cat /proc/cpuinfo | grep flags | head -n 1 | cut -d: -f2) + +supports_v2='awk "/cx16/&&/lahf/&&/popcnt/&&/sse4_1/&&/sse4_2/&&/ssse3/ {found=1} END {exit !found}"' +supports_v3='awk "/avx/&&/avx2/&&/bmi1/&&/bmi2/&&/f16c/&&/fma/&&/abm/&&/movbe/&&/xsave/ {found=1} END {exit !found}"' +supports_v4='awk "/avx512f/&&/avx512bw/&&/avx512cd/&&/avx512dq/&&/avx512vl/ {found=1} END {exit !found}"' + +echo "$flags" | eval $supports_v2 || exit 2 && echo "CPU supports x86-64-v2" +echo "$flags" | eval $supports_v3 || exit 3 && echo "CPU supports x86-64-v3" +echo "$flags" | eval $supports_v4 || exit 4 && echo "CPU supports x86-64-v4" +EOF + +chmod +x detect-cpu.sh +sh detect-cpu.sh +``` + +执行下面命令查看当前 cpu 的特性,如果输出中包含 sse4_2,则表示你的处理器支持SSE 4.2。 +```bash +lscpu | grep sse4_2 +``` + +### 解决方法 + +需要升级你的云主机或物理机 CPU 以支持 x86-64-v2 及以上,确保x86 CPU 指令集支持 sse4.2,如何升级需要你咨询云主机平台提供商或着物理机提供商。 + +详见:https://github.com/keycloak/keycloak/issues/17290 diff --git a/docs/zh/docs/admin/ghippo/troubleshooting/ghippo04.md b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo04.md new file mode 100644 index 0000000..4cf4e25 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/troubleshooting/ghippo04.md @@ -0,0 +1,13 @@ +--- +hide: + - toc +--- + +# 单独升级全局管理时升级失败 + +若升级失败时包含如下信息,可以参考[离线升级](../install/offline-install.md#__tabbed_3_2)中的更新 +ghippo crd 步骤完成 crd 安装 + +```console +ensure CRDs are installed first +``` diff --git a/docs/zh/docs/admin/ghippo/workspace/folder-permission.md b/docs/zh/docs/admin/ghippo/workspace/folder-permission.md new file mode 100644 index 0000000..90a40b0 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/folder-permission.md @@ -0,0 +1,39 @@ +# 文件夹权限说明 + +文件夹具有权限映射能力,能够将用户/用户组在本文件夹的权限映射到其下的子文件夹、工作空间以及资源上。 + +若用户/用户组在本文件夹是 Folder Admin 角色,映射到子文件夹仍为 Folder Admin 角色,映射到其下的工作空间则为 Workspace Admin; +若在 __工作空间与层级__ -> __资源组__ 中绑定了 Namespace,则映射后该用户/用户组同时还是 Namespace Admin。 + +!!! note + + 文件夹的权限映射能力不会作用到共享资源上,因为共享是将集群的使用权限共享给多个工作空间,而不是将管理权限受让给工作空间,因此不会实现权限继承和角色映射。 + +## 应用场景 + +文件夹具有层级能力,因此将文件夹对应于企业中的部门/供应商/项目等层级时, + +- 若用户/用户组在一级部门具有管理权限(Admin),其下的二级、三级、四级部门或项目同样具有管理权限; +- 若用户/用户组在一级部门具有使用权限(Editor),其下的二级、三级、四级部门或项目同样具有使用权限; +- 若用户/用户组在一级部门具有只读权限(Viewer),其下的二级、三级、四级部门或项目同样具有只读权限。 + +| 对象 | 操作 | Folder Admin | Folder Editor | Folder Viewer | +| --------------------------- | -------- | ------------ | ------------- | ------------- | +| 对文件夹本身 | 查看 | ✓ | ✓ | ✓ | +| | 授权 | ✓ | ✗ | ✗ | +| | 修改别名 | ✓ | ✗ | ✗ | +| 对子文件夹 | 创建 | ✓ | ✗ | ✗ | +| | 查看 | ✓ | ✓ | ✓ | +| | 授权 | ✓ | ✗ | ✗ | +| | 修改别名 | ✓ | ✗ | ✗ | +| 对其下的工作空间 | 创建 | ✓ | ✗ | ✗ | +| | 查看 | ✓ | ✓ | ✓ | +| | 授权 | ✓ | ✗ | ✗ | +| | 修改别名 | ✓ | ✗ | ✗ | +| 对其下的工作空间 - 资源组 | 查看 | ✓ | ✓ | ✓ | +| | 资源绑定 | ✓ | ✗ | ✗ | +| | 解除绑定 | ✓ | ✗ | ✗ | +| 对其下的工作空间 - 共享资源 | 查看 | ✓ | ✓ | ✓ | +| | 新增共享 | ✓ | ✗ | ✗ | +| | 解除共享 | ✓ | ✗ | ✗ | +| | 资源限额 | ✓ | ✗ | ✗ | diff --git a/docs/zh/docs/admin/ghippo/workspace/folders.md b/docs/zh/docs/admin/ghippo/workspace/folders.md new file mode 100644 index 0000000..78fe786 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/folders.md @@ -0,0 +1,36 @@ +--- +hide: + - toc +--- + +# 创建/删除文件夹 + +文件夹具有权限映射能力,能够将用户/用户组在本文件夹的权限映射到其下的子文件夹、工作空间以及资源上。 + +参照以下步骤创建一个文件夹。 + +1. 使用 admin/folder admin 角色的用户登录 AI 算力平台,点击左侧导航栏底部的 __全局管理__ -> __工作空间与层级__ 。 + + ![全局管理](../../../images/ws01_1.png) + +1. 点击右上角的 __创建文件夹__ 按钮。 + + ![创建文件夹](../../../images/fd02.png) + +1. 填写文件夹名称、上一级文件夹等信息后,点击 __确定__ ,完成创建文件夹。 + + ![确定](../../../images/fd03.png) + +!!! tip + + 创建成功后文件夹名称将显示在左侧的树状结构中,以不同的图标表示工作空间和文件夹。 + + ![工作空间和文件夹](../../../images/ws04_1.png) + +!!! note + + 选中某一个文件夹或文件夹,点击右侧的 __┇__ 可以进行编辑或删除。 + + - 当该文件夹下资源组、共享资源中存在资源时,该文件夹无法被删除,需要将所有资源解绑后再删除。 + + - 当微服务引擎模块在该文件夹下存在接入注册中心资源时,该文件夹无法被删除,需要将所有接入注册中心移除后再删除文件夹。 diff --git a/docs/zh/docs/admin/ghippo/workspace/quota.md b/docs/zh/docs/admin/ghippo/workspace/quota.md new file mode 100644 index 0000000..2bc8e0a --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/quota.md @@ -0,0 +1,93 @@ +# 资源配额(Quota) + +共享资源并非意味着被共享者可以无限制地使用被共享的资源。 +Admin、Kpanda Owner 和 Workspace Admin 可以通过共享资源中的 __资源配额__ 功能限制某个用户的最大使用额度。 +若不限制,则表示可以无限制使用。 + +- CPU 请求(Core) +- CPU 限制(Core) +- 内存请求(MB) +- 内存限制(MB) +- 存储请求总量(GB) +- 存储卷声明(个) +- GPU 类型、规格、数量(包括但不限于 Nvidia、Ascend、lluvatar等GPU卡类型) + +一个资源(集群)可以被多个工作空间共享,一个工作空间也可以同时使用多个共享集群中的资源。 + +## 资源组和共享资源 + +共享资源和资源组中的集群资源均来自容器管理,但是集群绑定和共享给同一个工作空间将会产生两种截然不同的效果。 + +1. 绑定资源 + + 使工作空间中的用户/用户组具有该集群的全部管理和使用权限,Workspace Admin 将被映射为 Cluster Admin。 + Workspace Admin 能够进入[容器管理模块](../../../kpanda/permissions/permission-brief.md)管理该集群。 + + ![资源组](../../../images/quota01.png) + + !!! note + + 当前容器管理模块暂无 Cluster Editor 和 Cluster Viewer 角色,因此 Workspace Editor、Workspace Viewer 还无法映射。 + +2. 新增共享资源 + + 使工作空间中的用户/用户组具有该集群资源的使用权限,这些资源可以在创建命名空间(Namespace)时使用。 + + ![共享资源](../../../images/quota02.png) + + 与资源组不同,将集群共享到工作空间时,用户在工作空间的角色不会映射到资源上,因此 Workspace Admin 不会被映射为 Cluster admin。 + +本节展示 3 个与资源配额有关的场景。 + +## 创建命名空间 + +创建命名空间时会涉及到资源配额。 + +1. 在工作空间 ws01 新增一个共享集群。 + + ![新增共享集群](../../../images/quota03.png) + +1. 在应用工作台选择工作空间 ws01 和共享集群,创建命名空间 ns01。 + + ![创建命名空间](../../../images/quota04.png) + + - 若在共享集群中未设置资源配额,则创建命名空间时可不设置资源配额。 + - 若在共享集群中已设置资源配额(例如 CPU 请求 = 100 core),则创建命名空间时 __CPU 请求 ≤ 100 core__ 。 + +## 命名空间绑定到工作空间 + +前提:工作空间 ws01 已新增共享集群,操作者为 Workspace Admin + Kpanda Owner 或 Admin 角色。 + +以下两种绑定方式的效果相同。 + +- 在容器管理中将创建的命名空间 ns01 绑定到 ws01 + + ![绑定到工作空间](../../../images/quota05.png) + + - 若在共享集群未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,均可成功绑定。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,则命名空间 ns01 必须满足 __CPU 请求 ≤ 100 core__ 才能绑定成功。 + +- 在全局管理中,将命名空间 ns01 绑定到 ws01 + + ![绑定到工作空间](../../../images/quota06.png) + + - 若在共享集群未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,均可成功绑定。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,则命名空间 ns01 必须满足 __CPU 请求 ≤ 100 core__ 才能绑定成功。 + +## 从工作空间解绑命名空间 + +以下两种解绑方式的效果相同。 + +- 在容器管理中将命名空间 ns01 从工作空间 ws01 解绑 + + ![绑定到工作空间](../../../images/quota07.png) + + - 若在共享集群中未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,解绑后均不会对资源配额产生影响。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,命名空间 ns01 也设置了资源配额,则解绑后将释放相应的资源额度。 + +- 在全局管理中将命名空间 ns01 从工作空间 ws01 解绑 + + ![绑定到工作空间](../../../images/quota08.png) + + - 若在共享集群未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,解绑后均不会对资源配额产生影响。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,命名空间 ns01 也设置了资源配额,则解绑后将释放相应的资源额度。 diff --git a/docs/zh/docs/admin/ghippo/workspace/res-gp-and-shared-res.md b/docs/zh/docs/admin/ghippo/workspace/res-gp-and-shared-res.md new file mode 100644 index 0000000..06e5546 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/res-gp-and-shared-res.md @@ -0,0 +1,30 @@ +# 资源组与共享资源的区别 + +资源组与共享资源均支持绑定集群,但使用上存在很大区别。 + +## 使用场景区别 + +- 资源组绑定集群:资源组绑定集群通常被用来批量授权。资源组绑定集群后, + 工作空间管理员将被映射为集群管理员,能够管理并使用集群资源。 +- 共享资源绑定集群:资源共享绑定集群通常被用来做资源限额。 + 典型的场景是平台管理员将集群分配给一级供应商后,再由一级供应商分配给二级供应商并对二级供应商进行资源限额。 + +![diff](../../../images/res-gp01.png) + +说明:在该场景中,需要平台管理员对二级供应商进行资源限制,暂时还不支持一级供应商限制二级供应商的集群额度。 + +## 集群额度的使用区别 + +- 资源组绑定集群:工作空间的管理员将被映射为该集群的管理员,相当于在容器管理-权限管理中被授予 Cluster Admin 角色, + 能够无限制支配该集群资源,管理节点等重要内容,且资源组不能够被资源限额。 +- 共享资源绑定资源:工作空间管理员仅能够使用集群中的额度在应用工作台创建命名空间,不具备集群的管理权限。 + 若对该工作空间限制额度,则工作空间管理仅能够在额度范围内创建并使用命名空间。 + +## 资源类型的区别 + +- 资源组:能够绑定集群、集群-命名空间、多云、多云-命名空间、网格、网格-命名空间 +- 共享资源:仅能够绑定集群 + +## 资源组与共享资源的相同点 + +在资源组/共享资源绑定集群后都可以前往应用工作台创建命名空间,创建后命名空间将自动绑定到工作空间。 diff --git a/docs/zh/docs/admin/ghippo/workspace/workspace.md b/docs/zh/docs/admin/ghippo/workspace/workspace.md new file mode 100644 index 0000000..7f7b991 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/workspace.md @@ -0,0 +1,38 @@ +--- +hide: + - toc +--- + +# 创建/删除工作空间 + +工作空间是一种资源范畴,代表一种资源层级关系。 +工作空间可以包含集群、命名空间、注册中心等资源。 +通常一个工作空间对应一个项目,可以为每个工作空间分配不同的资源,指派不同的用户和用户组。 + +参照以下步骤创建一个工作空间。 + +1. 使用 admin/folder admin 角色的用户登录 AI 算力平台,点击左侧导航栏底部的 __全局管理__ -> __工作空间与层级__ 。 + + ![全局管理](../../../images/ws01.png) + +3. 点击右上角的 __创建工作空间__ 按钮。 + + ![创建工作空间](../../../images/ws02.png) + +4. 填写工作空间名称、所属文件夹等信息后,点击 __确定__ ,完成创建工作空间。 + + ![确定](../../../images/ws03.png) + +!!! tip + + 创建成功后工作空间名称将显示在左侧的树状结构中,以不同的图标表示文件夹和工作空间。 + + ![文件夹与工作空间](../../../images/ws04.png) + +!!! note + + 选中某一个工作空间或文件夹,点击右侧的 __...__ 可以进行编辑或删除。 + + - 当该工作空间下资源组、共享资源中存在资源时,该工作空间无法被删除,需要将所有资源解绑后再删除。 + - 当微服务引擎模块在该工作空间下存在接入注册中心资源时,该工作空间无法被删除,需要将所有接入注册中心移除后再删除工作空间。 + - 当镜像仓库模块在该工作空间下存在镜像空间或集成仓库时,该工作空间无法被删除,需要将镜像空间解绑,将仓库集成删除后再删除工作空间。 diff --git a/docs/zh/docs/admin/ghippo/workspace/ws-folder.md b/docs/zh/docs/admin/ghippo/workspace/ws-folder.md new file mode 100644 index 0000000..696924f --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/ws-folder.md @@ -0,0 +1,66 @@ +--- +hide: + - toc +--- + +# 工作空间与层级 + + __工作空间与层级__ 是一个具有层级的资源隔离和资源分组特性,主要解决资源统一授权、资源分组以及资源限额问题。 + +![层级结构](../../../images/fdpractice.png) + + __工作空间与层级__ 有两个概念:工作空间和文件夹。 + +## 工作空间 + +工作空间可通过 __授权__ 、 __资源组__ 和 __共享资源__ 来管理资源,使用户(用户组)之间能够共享工作空间中的资源。 + +![工作空间](../../../images/wsfd01.png) + +- 资源 + + 资源处于资源管理模块层级结构的最低层级,资源包括 Cluster、Namespace、Pipeline、网关等。 + 所有这些资源的父级只能是工作空间,而工作空间作为资源容器是一种资源分组单位。 + +- 工作空间 + + 工作空间通常代指一个项目或环境,每个工作空间的资源相对于其他工作空间中的资源时逻辑隔离的。 + 您可以通过工作空间中的授权,授予用户(用户组)同一组资源的不同访问权限。 + + 从层次结构的底层算起,工作空间位于第一层,且包含资源。 + 除共享资源外,所有资源有且仅有一个父项。所有工作空间也有且仅有一个父级文件夹。 + + 资源通过工作空间进行分组,而工作空间中存在两种分组模式,分别是 __资源组__ 和 __共享资源__ 。 + +- 资源组 + + 一个资源只能加入一个资源组,资源组与工作空间一一对应。 + 资源被加入到资源组后,Workspace Admin 将获得资源的管理权限,相当于该资源的所有者。 + +- 共享资源 + + 而对于共享资源来说,多个工作空间可以共享同一个或者多个资源。 + 资源的所有者,可以选择将自己拥有的资源共享给工作空间使用,一般共享时资源所有者会限制被共享工作空间能够使用的资源额度。 + 资源被共享后,Workspace Admin 仅具有资源限额下的资源使用权限,无法管理资源或者调整工作空间能够使用的资源量。 + + 同时共享资源对于资源本身也具有一定的要求,只有 Cluster(集群)资源可以被共享。 + Cluster Admin 能够将 Cluster 资源分享给不同的工作空间使用,并且限制工作空间在此 Cluster 上的使用额度。 + + Workspace Admin 在资源限额内能够创建多个 Namespace,但是 Namespace 的资源额度总和不能超过 Cluster 在该工作空间的资源限额。 + 对于 Kubernetes 资源,当前能够分享的资源类型仅有 Cluster。 + +## 文件夹 + +文件夹可用于构建企业业务层级关系。 + +- 文件夹是在工作空间基础之上的进一步分组机制,具有层级结构。 + 一个文件夹可以包含工作空间、其他文件夹或两者的组合,能够形成树状的组织关系。 + +- 借助文件夹您可以映射企业业务层级关系,按照部门对工作空间进行分组。 + 文件夹不直接与资源挂钩,而是通过工作空间间接实现资源分组。 + +- 文件夹有且仅有一个父级文件夹,而根文件夹是层次结构的最高层级。 + 根文件夹没有父级,文件夹和工作空间均挂靠到根文件夹下。 + +另外,用户(用户组)在文件夹中能够通过层级结构继承来自父项的权限。 +用户在层次结构中的权限来自当前层级的权限以及继承其父项权限的组合结果,权限之间是加合关系不存在互斥。 diff --git a/docs/zh/docs/admin/ghippo/workspace/ws-permission.md b/docs/zh/docs/admin/ghippo/workspace/ws-permission.md new file mode 100644 index 0000000..b8d3c89 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/ws-permission.md @@ -0,0 +1,45 @@ +# 工作空间权限说明 + +工作空间具有权限映射和资源隔离能力,能够将用户/用户组在工作空间的权限映射到其下的资源上。 +若用户/用户组在工作空间是 Workspace Admin 角色,同时工作空间-资源组中绑定了资源 Namespace,则映射后该用户/用户组将成为 Namespace Admin。 + +!!! note + + 工作空间的权限映射能力不会作用到共享资源上,因为共享是将集群的使用权限共享给多个工作空间,而不是将管理权限受让给工作空间,因此不会实现权限继承和角色映射。 + +## 应用场景 + +通过将资源绑定到不同的工作空间能够实现资源隔离。 +因此借助权限映射、资源隔离和共享资源能力能够将资源灵活分配给各个工作空间(租户)。 + +通常适用于以下两个场景: + +- 集群一对一 + + | 普通集群 | 部门/租户(工作空间) | 用途 | + | -------- | ---------------- | -------- | + | 集群 01 | A | 管理和使用 | + | 集群 02 | B | 管理和使用 | + +- 集群一对多 + + | 集群 | 部门/租户(工作空间) | 资源限额 | + | ------- | ---------------- | ---------- | + | 集群 01 | A | 100 核 CPU | + | | B | 50 核 CPU | + +## 权限说明 + +| 操作对象 | 操作 | Workspace Admin | Workspace Editor | Workspace Viewer | +| :------- | :---------------- | :-------------- | :--------------- | :--------------- | +| 本身 | 查看 | ✓ | ✓ | ✓ | +| - | 授权 | ✓ | ✗ | ✗ | +| - | 修改别名 | ✓ | ✓ | ✗ | +| 资源组 | 查看 | ✓ | ✓ | ✓ | +| - | 资源绑定 | ✓ | ✗ | ✗ | +| - | 解除绑定 | ✓ | ✗ | ✗ | +| 共享资源 | 查看 | ✓ | ✓ | ✓ | +| - | 新增共享 | ✓ | ✗ | ✗ | +| - | 解除共享 | ✓ | ✗ | ✗ | +| - | 资源限额 | ✓ | ✗ | ✗ | +| - | 使用共享资源 [^1] | ✓ | ✗ | ✗ | diff --git a/docs/zh/docs/admin/ghippo/workspace/wsbind-permission.md b/docs/zh/docs/admin/ghippo/workspace/wsbind-permission.md new file mode 100644 index 0000000..264a556 --- /dev/null +++ b/docs/zh/docs/admin/ghippo/workspace/wsbind-permission.md @@ -0,0 +1,36 @@ +# 资源绑定权限说明 + +假如用户小明(“小明”代表任何有资源绑定需求的用户)已经具备了 +[Workspace Admin 角色](../access-control/role.md#_4)或已通过[自定义角色](../access-control/custom-role.md)授权, +同时自定义角色中包含[工作空间的“资源绑定”权限](./ws-permission.md#_3),希望将某个集群或者某个命名空间绑定到其所在的工作空间中。 + +要将集群/命名空间资源绑定到工作空间,不仅需要该[工作空间的“资源绑定”权限](./ws-permission.md#_3),还需要 +[Cluster Admin](../../../kpanda/permissions/permission-brief.md#cluster-admin) 的资源权限。 + +## 给小明授权 + +1. 使用[平台 Admin 角色](../access-control/role.md#_2), + 在 **工作空间** -> **授权** 页面给小明授予 Workspace Admin 角色。 + + ![资源绑定](../images/wsbind1.png) + +1. 然后在 **容器管理** -> **权限管理** 页面,通过 **添加授权** 将小明授权为 Cluster Admin。 + + ![集群授权1](../images/wsbind2.png) + + ![集群授权2](../images/wsbind3.png) + +## 绑定到工作空间 + +使用小明的账号登录 AI 算力平台,在 **容器管理** -> **集群列表** 页面,通过 **绑定工作空间** 功能, +小明可以将指定集群绑定到自己的工作空间中。 + +!!! note + + 小明能且只能在容器管理模块将集群或者该集群下的命名空间绑定到某个工作空间,无法在全局管理模块完成此操作。 + +![cluster绑定](../images/wsbind4.png) + +绑定命名空间到工作空间也至少需要 Workspace Admin + Cluster Admin 权限。 + +![ns绑定](../images/wsbind5.png) diff --git a/docs/zh/docs/admin/host/createhost.md b/docs/zh/docs/admin/host/createhost.md new file mode 100644 index 0000000..801c8dc --- /dev/null +++ b/docs/zh/docs/admin/host/createhost.md @@ -0,0 +1,41 @@ +# 创建和启动云主机 + +用户完成注册,为其分配了工作空间、命名空间和资源后,即可以创建并启动云主机。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](../register/index.md) +- [为用户绑定了工作空间](../register/bindws.md) +- [为工作空间分配了资源](../register/wsres.md) + +## 操作步骤 + +1. 用户登录 AI 算力平台 +1. 点击 **创建云主机** -> **通过模板创建** + + ![create](../images/host01.png) + +1. 定义的云主机各项配置后点击 **下一步** + + === "基本配置" + + ![basic](../images/host02.png) + + === "模板配置" + + ![template](../images/host03.png) + + === "存储与网络" + + ![storage](../images/host05.png) + +1. 配置 root 密码或 ssh 密钥后点击 **确定** + + ![pass](../images/host06.png) + +1. 返回主机列表,等待状态变为 **运行中** 之后,可以通过右侧的 **┇** 启动主机。 + + ![pass](../images/host07.png) + +下一步:[使用云主机](./usehost.md) diff --git a/docs/zh/docs/admin/host/usehost.md b/docs/zh/docs/admin/host/usehost.md new file mode 100644 index 0000000..ffba6eb --- /dev/null +++ b/docs/zh/docs/admin/host/usehost.md @@ -0,0 +1,31 @@ +# 使用云主机 + +创建并启动云主机之后,用户就可以开始使用云主机。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已创建并启动云主机](./createhost.md) + +## 操作步骤 + +1. 以管理员身份登录 AI 算力平台 +1. 导航到 **容器管理** -> **容器网络** -> **服务** ,点击服务的名称,进入服务详情页,在右上角点击 **更新** + + ![service](../images/usehost01.png) + +1. 更改端口范围为 30900-30999,但不能冲突。 + + ![port](../images/usehost02.png) + +1. 以终端用户登录 AI 算力平台,导航到对应的服务,查看访问端口。 + + ![port](../images/usehost03.png) + +1. 在外网使用 SSH 客户端登录云主机 + + ![ssh](../images/usehost04.png) + +1. 至此,你可以在云主机上执行各项操作。 + +下一步:[云资源共享:配额管理](../share/quota.md) diff --git a/docs/zh/docs/admin/images/add01.png b/docs/zh/docs/admin/images/add01.png new file mode 100644 index 0000000..9abedc0 Binary files /dev/null and b/docs/zh/docs/admin/images/add01.png differ diff --git a/docs/zh/docs/admin/images/add02.png b/docs/zh/docs/admin/images/add02.png new file mode 100644 index 0000000..ff6dca8 Binary files /dev/null and b/docs/zh/docs/admin/images/add02.png differ diff --git a/docs/zh/docs/admin/images/add03.png b/docs/zh/docs/admin/images/add03.png new file mode 100644 index 0000000..4e6172f Binary files /dev/null and b/docs/zh/docs/admin/images/add03.png differ diff --git a/docs/zh/docs/admin/images/add04.png b/docs/zh/docs/admin/images/add04.png new file mode 100644 index 0000000..03e968d Binary files /dev/null and b/docs/zh/docs/admin/images/add04.png differ diff --git a/docs/zh/docs/admin/images/add05.png b/docs/zh/docs/admin/images/add05.png new file mode 100644 index 0000000..b5018eb Binary files /dev/null and b/docs/zh/docs/admin/images/add05.png differ diff --git a/docs/zh/docs/admin/images/bindws01.png b/docs/zh/docs/admin/images/bindws01.png new file mode 100644 index 0000000..52c64ac Binary files /dev/null and b/docs/zh/docs/admin/images/bindws01.png differ diff --git a/docs/zh/docs/admin/images/bindws02.png b/docs/zh/docs/admin/images/bindws02.png new file mode 100644 index 0000000..cc53748 Binary files /dev/null and b/docs/zh/docs/admin/images/bindws02.png differ diff --git a/docs/zh/docs/admin/images/bindws03.png b/docs/zh/docs/admin/images/bindws03.png new file mode 100644 index 0000000..78d2bf4 Binary files /dev/null and b/docs/zh/docs/admin/images/bindws03.png differ diff --git a/docs/zh/docs/admin/images/bindws04.png b/docs/zh/docs/admin/images/bindws04.png new file mode 100644 index 0000000..91fc55f Binary files /dev/null and b/docs/zh/docs/admin/images/bindws04.png differ diff --git a/docs/zh/docs/admin/images/bindws05.png b/docs/zh/docs/admin/images/bindws05.png new file mode 100644 index 0000000..a1bbe21 Binary files /dev/null and b/docs/zh/docs/admin/images/bindws05.png differ diff --git a/docs/zh/docs/admin/images/bindws06.png b/docs/zh/docs/admin/images/bindws06.png new file mode 100644 index 0000000..c157644 Binary files /dev/null and b/docs/zh/docs/admin/images/bindws06.png differ diff --git a/docs/zh/docs/admin/images/bindws07.png b/docs/zh/docs/admin/images/bindws07.png new file mode 100644 index 0000000..0239d61 Binary files /dev/null and b/docs/zh/docs/admin/images/bindws07.png differ diff --git a/docs/zh/docs/admin/images/bindws08.png b/docs/zh/docs/admin/images/bindws08.png new file mode 100644 index 0000000..bc5881f Binary files /dev/null and b/docs/zh/docs/admin/images/bindws08.png differ diff --git a/docs/zh/docs/admin/images/bindws09.png b/docs/zh/docs/admin/images/bindws09.png new file mode 100644 index 0000000..ee587b0 Binary files /dev/null and b/docs/zh/docs/admin/images/bindws09.png differ diff --git a/docs/zh/docs/admin/images/bindws10.png b/docs/zh/docs/admin/images/bindws10.png new file mode 100644 index 0000000..1e99f7e Binary files /dev/null and b/docs/zh/docs/admin/images/bindws10.png differ diff --git a/docs/zh/docs/admin/images/bindws11.png b/docs/zh/docs/admin/images/bindws11.png new file mode 100644 index 0000000..53fa67d Binary files /dev/null and b/docs/zh/docs/admin/images/bindws11.png differ diff --git a/docs/zh/docs/admin/images/home.png b/docs/zh/docs/admin/images/home.png new file mode 100644 index 0000000..2477dbc Binary files /dev/null and b/docs/zh/docs/admin/images/home.png differ diff --git a/docs/zh/docs/admin/images/host01.png b/docs/zh/docs/admin/images/host01.png new file mode 100644 index 0000000..692e221 Binary files /dev/null and b/docs/zh/docs/admin/images/host01.png differ diff --git a/docs/zh/docs/admin/images/host02.png b/docs/zh/docs/admin/images/host02.png new file mode 100644 index 0000000..6091415 Binary files /dev/null and b/docs/zh/docs/admin/images/host02.png differ diff --git a/docs/zh/docs/admin/images/host03.png b/docs/zh/docs/admin/images/host03.png new file mode 100644 index 0000000..2eecbed Binary files /dev/null and b/docs/zh/docs/admin/images/host03.png differ diff --git a/docs/zh/docs/admin/images/host04.png b/docs/zh/docs/admin/images/host04.png new file mode 100644 index 0000000..b1d0c2e Binary files /dev/null and b/docs/zh/docs/admin/images/host04.png differ diff --git a/docs/zh/docs/admin/images/host05.png b/docs/zh/docs/admin/images/host05.png new file mode 100644 index 0000000..67806a5 Binary files /dev/null and b/docs/zh/docs/admin/images/host05.png differ diff --git a/docs/zh/docs/admin/images/host06.png b/docs/zh/docs/admin/images/host06.png new file mode 100644 index 0000000..dae145f Binary files /dev/null and b/docs/zh/docs/admin/images/host06.png differ diff --git a/docs/zh/docs/admin/images/host07.png b/docs/zh/docs/admin/images/host07.png new file mode 100644 index 0000000..e94e450 Binary files /dev/null and b/docs/zh/docs/admin/images/host07.png differ diff --git a/docs/zh/docs/admin/images/k8s01.png b/docs/zh/docs/admin/images/k8s01.png new file mode 100644 index 0000000..a06d26a Binary files /dev/null and b/docs/zh/docs/admin/images/k8s01.png differ diff --git a/docs/zh/docs/admin/images/k8s02.png b/docs/zh/docs/admin/images/k8s02.png new file mode 100644 index 0000000..4ae0a2d Binary files /dev/null and b/docs/zh/docs/admin/images/k8s02.png differ diff --git a/docs/zh/docs/admin/images/k8s03.png b/docs/zh/docs/admin/images/k8s03.png new file mode 100644 index 0000000..f6e2fc5 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s03.png differ diff --git a/docs/zh/docs/admin/images/k8s04.png b/docs/zh/docs/admin/images/k8s04.png new file mode 100644 index 0000000..579e978 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s04.png differ diff --git a/docs/zh/docs/admin/images/k8s05.png b/docs/zh/docs/admin/images/k8s05.png new file mode 100644 index 0000000..54e89ee Binary files /dev/null and b/docs/zh/docs/admin/images/k8s05.png differ diff --git a/docs/zh/docs/admin/images/k8s06.png b/docs/zh/docs/admin/images/k8s06.png new file mode 100644 index 0000000..87a9478 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s06.png differ diff --git a/docs/zh/docs/admin/images/k8s07.png b/docs/zh/docs/admin/images/k8s07.png new file mode 100644 index 0000000..512762b Binary files /dev/null and b/docs/zh/docs/admin/images/k8s07.png differ diff --git a/docs/zh/docs/admin/images/k8s08.png b/docs/zh/docs/admin/images/k8s08.png new file mode 100644 index 0000000..8407336 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s08.png differ diff --git a/docs/zh/docs/admin/images/k8s09.png b/docs/zh/docs/admin/images/k8s09.png new file mode 100644 index 0000000..a27d8fd Binary files /dev/null and b/docs/zh/docs/admin/images/k8s09.png differ diff --git a/docs/zh/docs/admin/images/k8s10.png b/docs/zh/docs/admin/images/k8s10.png new file mode 100644 index 0000000..d6e5c78 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s10.png differ diff --git a/docs/zh/docs/admin/images/k8s11.png b/docs/zh/docs/admin/images/k8s11.png new file mode 100644 index 0000000..0965c31 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s11.png differ diff --git a/docs/zh/docs/admin/images/k8s12.png b/docs/zh/docs/admin/images/k8s12.png new file mode 100644 index 0000000..63592d1 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s12.png differ diff --git a/docs/zh/docs/admin/images/k8s13.png b/docs/zh/docs/admin/images/k8s13.png new file mode 100644 index 0000000..da71956 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s13.png differ diff --git a/docs/zh/docs/admin/images/k8s14.png b/docs/zh/docs/admin/images/k8s14.png new file mode 100644 index 0000000..ef07530 Binary files /dev/null and b/docs/zh/docs/admin/images/k8s14.png differ diff --git a/docs/zh/docs/admin/images/notebook01.png b/docs/zh/docs/admin/images/notebook01.png new file mode 100644 index 0000000..4888a93 Binary files /dev/null and b/docs/zh/docs/admin/images/notebook01.png differ diff --git a/docs/zh/docs/admin/images/notebook02.png b/docs/zh/docs/admin/images/notebook02.png new file mode 100644 index 0000000..79699cb Binary files /dev/null and b/docs/zh/docs/admin/images/notebook02.png differ diff --git a/docs/zh/docs/admin/images/notebook03.png b/docs/zh/docs/admin/images/notebook03.png new file mode 100644 index 0000000..3098322 Binary files /dev/null and b/docs/zh/docs/admin/images/notebook03.png differ diff --git a/docs/zh/docs/admin/images/notebook04.png b/docs/zh/docs/admin/images/notebook04.png new file mode 100644 index 0000000..b34a57e Binary files /dev/null and b/docs/zh/docs/admin/images/notebook04.png differ diff --git a/docs/zh/docs/admin/images/notebook05.png b/docs/zh/docs/admin/images/notebook05.png new file mode 100644 index 0000000..07329e4 Binary files /dev/null and b/docs/zh/docs/admin/images/notebook05.png differ diff --git a/docs/zh/docs/admin/images/notebook06.png b/docs/zh/docs/admin/images/notebook06.png new file mode 100644 index 0000000..50d43ff Binary files /dev/null and b/docs/zh/docs/admin/images/notebook06.png differ diff --git a/docs/zh/docs/admin/images/notebook07.png b/docs/zh/docs/admin/images/notebook07.png new file mode 100644 index 0000000..18c9e6d Binary files /dev/null and b/docs/zh/docs/admin/images/notebook07.png differ diff --git a/docs/zh/docs/admin/images/notebook08.png b/docs/zh/docs/admin/images/notebook08.png new file mode 100644 index 0000000..015c025 Binary files /dev/null and b/docs/zh/docs/admin/images/notebook08.png differ diff --git a/docs/zh/docs/admin/images/notebook09.png b/docs/zh/docs/admin/images/notebook09.png new file mode 100644 index 0000000..bb7fcc5 Binary files /dev/null and b/docs/zh/docs/admin/images/notebook09.png differ diff --git a/docs/zh/docs/admin/images/quota01.png b/docs/zh/docs/admin/images/quota01.png new file mode 100644 index 0000000..389b47d Binary files /dev/null and b/docs/zh/docs/admin/images/quota01.png differ diff --git a/docs/zh/docs/admin/images/quota02.png b/docs/zh/docs/admin/images/quota02.png new file mode 100644 index 0000000..ac37f40 Binary files /dev/null and b/docs/zh/docs/admin/images/quota02.png differ diff --git a/docs/zh/docs/admin/images/quota03.png b/docs/zh/docs/admin/images/quota03.png new file mode 100644 index 0000000..2635d7c Binary files /dev/null and b/docs/zh/docs/admin/images/quota03.png differ diff --git a/docs/zh/docs/admin/images/remove01.png b/docs/zh/docs/admin/images/remove01.png new file mode 100644 index 0000000..f3491b2 Binary files /dev/null and b/docs/zh/docs/admin/images/remove01.png differ diff --git a/docs/zh/docs/admin/images/remove02.png b/docs/zh/docs/admin/images/remove02.png new file mode 100644 index 0000000..8160244 Binary files /dev/null and b/docs/zh/docs/admin/images/remove02.png differ diff --git a/docs/zh/docs/admin/images/remove03.png b/docs/zh/docs/admin/images/remove03.png new file mode 100644 index 0000000..1a80f89 Binary files /dev/null and b/docs/zh/docs/admin/images/remove03.png differ diff --git a/docs/zh/docs/admin/images/remove04.png b/docs/zh/docs/admin/images/remove04.png new file mode 100644 index 0000000..8cf2feb Binary files /dev/null and b/docs/zh/docs/admin/images/remove04.png differ diff --git a/docs/zh/docs/admin/images/remove05.png b/docs/zh/docs/admin/images/remove05.png new file mode 100644 index 0000000..a7b59fa Binary files /dev/null and b/docs/zh/docs/admin/images/remove05.png differ diff --git a/docs/zh/docs/admin/images/ssh01.png b/docs/zh/docs/admin/images/ssh01.png new file mode 100644 index 0000000..7384554 Binary files /dev/null and b/docs/zh/docs/admin/images/ssh01.png differ diff --git a/docs/zh/docs/admin/images/ssh02.png b/docs/zh/docs/admin/images/ssh02.png new file mode 100644 index 0000000..293ceff Binary files /dev/null and b/docs/zh/docs/admin/images/ssh02.png differ diff --git a/docs/zh/docs/admin/images/ssh03.png b/docs/zh/docs/admin/images/ssh03.png new file mode 100644 index 0000000..268c245 Binary files /dev/null and b/docs/zh/docs/admin/images/ssh03.png differ diff --git a/docs/zh/docs/admin/images/ssh04.png b/docs/zh/docs/admin/images/ssh04.png new file mode 100644 index 0000000..2f9ebd9 Binary files /dev/null and b/docs/zh/docs/admin/images/ssh04.png differ diff --git a/docs/zh/docs/admin/images/ssh05.png b/docs/zh/docs/admin/images/ssh05.png new file mode 100644 index 0000000..b34d72a Binary files /dev/null and b/docs/zh/docs/admin/images/ssh05.png differ diff --git a/docs/zh/docs/admin/images/usehost01.png b/docs/zh/docs/admin/images/usehost01.png new file mode 100644 index 0000000..c4a5a39 Binary files /dev/null and b/docs/zh/docs/admin/images/usehost01.png differ diff --git a/docs/zh/docs/admin/images/usehost02.png b/docs/zh/docs/admin/images/usehost02.png new file mode 100644 index 0000000..a8f46c6 Binary files /dev/null and b/docs/zh/docs/admin/images/usehost02.png differ diff --git a/docs/zh/docs/admin/images/usehost03.png b/docs/zh/docs/admin/images/usehost03.png new file mode 100644 index 0000000..cc36100 Binary files /dev/null and b/docs/zh/docs/admin/images/usehost03.png differ diff --git a/docs/zh/docs/admin/images/usehost04.png b/docs/zh/docs/admin/images/usehost04.png new file mode 100644 index 0000000..caa09c2 Binary files /dev/null and b/docs/zh/docs/admin/images/usehost04.png differ diff --git a/docs/zh/docs/admin/images/workload01.png b/docs/zh/docs/admin/images/workload01.png new file mode 100644 index 0000000..1db6174 Binary files /dev/null and b/docs/zh/docs/admin/images/workload01.png differ diff --git a/docs/zh/docs/admin/images/workload02.png b/docs/zh/docs/admin/images/workload02.png new file mode 100644 index 0000000..27ab3af Binary files /dev/null and b/docs/zh/docs/admin/images/workload02.png differ diff --git a/docs/zh/docs/admin/images/workload03.png b/docs/zh/docs/admin/images/workload03.png new file mode 100644 index 0000000..e517c14 Binary files /dev/null and b/docs/zh/docs/admin/images/workload03.png differ diff --git a/docs/zh/docs/admin/images/workload04.png b/docs/zh/docs/admin/images/workload04.png new file mode 100644 index 0000000..5abe7a4 Binary files /dev/null and b/docs/zh/docs/admin/images/workload04.png differ diff --git a/docs/zh/docs/admin/images/workload05.png b/docs/zh/docs/admin/images/workload05.png new file mode 100644 index 0000000..26efad6 Binary files /dev/null and b/docs/zh/docs/admin/images/workload05.png differ diff --git a/docs/zh/docs/admin/images/workload06.png b/docs/zh/docs/admin/images/workload06.png new file mode 100644 index 0000000..9c3bd86 Binary files /dev/null and b/docs/zh/docs/admin/images/workload06.png differ diff --git a/docs/zh/docs/admin/images/wsres01.png b/docs/zh/docs/admin/images/wsres01.png new file mode 100644 index 0000000..779e2e2 Binary files /dev/null and b/docs/zh/docs/admin/images/wsres01.png differ diff --git a/docs/zh/docs/admin/images/wsres02.png b/docs/zh/docs/admin/images/wsres02.png new file mode 100644 index 0000000..bc2094c Binary files /dev/null and b/docs/zh/docs/admin/images/wsres02.png differ diff --git a/docs/zh/docs/admin/images/wsres03.png b/docs/zh/docs/admin/images/wsres03.png new file mode 100644 index 0000000..563cd3a Binary files /dev/null and b/docs/zh/docs/admin/images/wsres03.png differ diff --git a/docs/zh/docs/admin/index.md b/docs/zh/docs/admin/index.md new file mode 100644 index 0000000..a51230d --- /dev/null +++ b/docs/zh/docs/admin/index.md @@ -0,0 +1,69 @@ +--- +hide: + - toc +--- + +# 算丰 AI 算力平台 - 管理员 + +这是算丰 AI 算力平台面向管理员的运维文档。 + +
+ +- :octicons-fiscal-host-16:{ .lg .middle } __云主机__ + + --- + + 云主机是部署在云端的虚拟机。 + + - [管理云主机](./virtnest/vm/create-secret.md) + - [云主机 vGPU](./virtnest/gpu/vm-vgpu.md) + - [云主机模板](./virtnest/template/index.md) + - [从 VMWare 导入云主机](./virtnest/best-practice/import-ubuntu.md) + +- :simple-kubernetes:{ .lg .middle } __容器管理__ + + --- + + 管理 K8s 集群、节点、应用、资源和权限。 + + - [创建集群](k8s/create-k8s.md) + - [添加工作节点](k8s/add-node.md) + - [管理 Helm 应用](./kpanda/helm/README.md) + - [HPA 水平扩缩容](./kpanda/scale/create-hpa.md) + +- :simple-smart:{ .lg .middle } __算法开发__ + + --- + + 管理 AI 资源和队列。 + + - [管理资源](./baize/oam/resource.md) + - [管理队列](./baize/oam/queue/create.md) + - [AI 训推最佳实践](./baize/best-practice/deploy-nfs-in-worker.md) + - [算法开发故障排查](./baize/troubleshoot/index.md) + +- :fontawesome-solid-diagram-project:{ .lg .middle } __可观测性__ + + --- + + 了解可观测性资源,配置和故障排查。 + + - [部署资源规划](./insight/quickstart/res-plan/prometheus-res.md) + - [安装与升级](./insight/quickstart/install/index.md) + - [兼容性测试](./insight/compati-test/k8s-compatibility.md) + - [常见问题](./insight/faq/traceclockskew.md) + +- :fontawesome-solid-user:{ .lg .middle } __全局管理__ + + --- + + 管控用户、用户组、工作空间、资源等访问权限。 + + - [绑定工作空间](register/bindws.md) + - [为工作空间分配资源](register/wsres.md) + - [审计日志](./ghippo/audit/open-audit.md) + - [平台设置](./ghippo/platform-setting/security.md) + +
+ +![home](images/home.png) diff --git a/docs/zh/docs/admin/insight/alert-center/alert-policy.md b/docs/zh/docs/admin/insight/alert-center/alert-policy.md new file mode 100644 index 0000000..2b5b861 --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/alert-policy.md @@ -0,0 +1,128 @@ +# 告警策略 + +告警策略是在可观测性系统中定义的一组规则和条件,用于检测和触发警报,以便在系统出现异常或达到预定的阈值时及时通知相关人员或系统。 + +每条告警策略是一组告警规则的集合,支持对集群、节点、工作负载等资源、日志、事件设置告警规则。当告警对象达到策略下任一规则设定的阈值,则会自动触发告警并发送通知。 + +## 查看告警策略 + +1. 点击一级导航栏进入 __可观测性__。 +2. 左侧导航栏中,选择 __告警中心__ -> __告警策略__。 + + - 集群:单击集群下拉框可切换集群; + - 命名空间:单击命名空间切换下拉框。 + + ![告警策略](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy00.png) + +3. 点击告警策略名称可查看策略的基本信息、规则以及通知配置。 + + 1. 在规则列表中可查看规则类型、规则的表达式、级别、状态等信息。 + 2. 进入策略详情,可以添加、编辑、删除其下的告警规则。 + + ![告警策略](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy06.png) + +## 创建告警策略 + +1. 填写基本信息,选择一个或多个集群、节点或工作负载为告警对象后点击 __下一步__。 + + ![基本信息](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy01.png) + + !!! note + + - 选择`全部集群、节点或工作负载`:创建的告警规则对所有已安装 insight-agent 的集群生效。 + - 选择单个或多个集群集群、节点或工作负载:创建的告警规则仅对所选的资源对象生效。 + - 同时,用户只能对已权限的集群、命名空间设置告警规则。 + +### 手动添加规则 + +1. 在创建告警策略的第二部中,点击列表右上角的`添加规则`。 + + ![添加规则](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/alert-policy04.png) + +2. 在弹窗中创建告警规则,填写各项参数后点击 __确定__。 + + ![创建规则](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy04.png) + + - 模板规则:预定义了基础指标,可以按 CPU、内存、磁盘、网络设定要监控的指标。 + - PromQL 规则:输入一个 PromQL 表达式,具体请[查询 Prometheus 表达式](https://prometheus.io/docs/prometheus/latest/querying/basics/)。 + - 持续时长:告警被触发且持续时间达到该设定值后,告警策略将变为触发中状态。 + - 告警级别:包含紧急、警告、信息三种级别。 + - 高级设置:可以自定义标签和注解。 + + !!! info + + 系统定义了内置标签,若自定义标签与内置标签的`键`值相同,则自定义标签不生效。 + 内置标签有:`severity`、`rule_id`,`source`、`cluster_name`、`group_id`、 `target_type` 和 `target`。 + +#### 创建日志规则 + +完成基本信息的填写后,点击 __添加规则__,规则类型选择 __日志规则__。 + +!!! note + + 仅当资源对象选择节点或工作负载时,支持创建日志规则。 + +![通知配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy10.png) + +**字段说明:** + +- __过滤条件__:查询日志内容的字段,支持与、或、正则匹配、模糊匹配四种过滤条件。 +- __判断条件__:根据 __过滤条件__,输入关键字或匹配条件。 +- __时间范围__:日志查询的时间范围。 +- __阈值条件__:在输入框中输入告警阈值。当达到设置的阈值时,则触发告警。支持的比较运算符有: >、≥、=、≤、<。 +- __告警级别__:选择告警级别,用于表示告警的严重程度。 + +#### 创建事件规则 + +完成基本信息的填写后,点击 __添加规则__,规则类型选择 __事件规则__。 + +!!! note + + 仅当资源对象选择工作负载时,支持创建事件规则。 + +![通知配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy04.png) + +**字段说明:** + +- __事件规则__:仅支持资源对象选择工作负载 +- __事件原因__:不同的工作负载类型的事件原因不同,事件原因之间是“和”的关系。 +- __时间范围__:检测该时间范围内产生数据,若达到设置的阈值条件,则触发告警事件。 +- __阈值条件__:当产生的事件达到设置的阈值时,则触发告警事件。 +- __趋势图__:默认查询 10 分钟内的事件变化趋势,每个点的数值统计的是当前时间点到之前的某段时间(时间范围)内发生的总次数。 + +### 导入规则模板 + +1. 可点击 __模板导入__,选择平台管理员已创建好的告警模板批量导入告警规则。 + + ![告警模板](../../images/import-template.png){ width=1000px} + +1. 点击 __下一步__ 后配置通知。 + + ![通知配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy05.png) + +2. 配置完成后,点击 __确定__ 按钮,返回告警策略列表。 + +!!! tip + + 新建的告警策略为 __未触发__ 状态。一旦满足规则中的阈值条件和持续时间后,将变为 __触发中__ 状态。 + + +!!! warning + + 删除后的告警策略将完全消失,请谨慎操作。 + +## 通过 YAML 导入告警策略 + +1. 进入告警策略列表,点击 __YAML 创建__。 + + - 集群、命名空间的选择是为了告警策略的管理权限。 + - YAML 编辑器中请填写 __spec__ 及其中的内容,仅支持导入一个 group。 + - __告警规则名称__ 需要符合规范:名称只能包含大小写字母、数字、下划线(_)和连字符(-),必须以字母开头,最长 63 个字符。 + - 必填 __severity__ 且符合规范:critical、warning、info。 + - 必填表达式 __expr__。 + + ![yaml 创建](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/create-from-yaml.png){ width=1000px} + +2. 导入 YAML 文件后,点击 __预览__,可以对导入的 YAML 格式进行验证,并快速确认导入的告警规则。 + + ![yaml 创建](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/create-from-yaml01.png){ width=1000px} diff --git a/docs/zh/docs/admin/insight/alert-center/alert-template.md b/docs/zh/docs/admin/insight/alert-center/alert-template.md new file mode 100644 index 0000000..eedefe7 --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/alert-template.md @@ -0,0 +1,37 @@ +# 告警模板 + +告警模板可支持平台管理员创建告警模板及规则,业务侧可以直接使用告警模板创建告警策略。 +这个功能可以减少业务人员对告警规则的管理,且可以根据环境实际情况自行修改告警阈值。 + +## 创建告警模板 + +1. 左侧导航栏中,选择 **告警中心** -> **告警策略**,单击顶部的 **告警模板** 。 + + ![告警模板](../images/template01.png){ width=1000px} + +2. 点击 **创建告警模板** ,设置告警模板的名称、描述等信息。 + + ![设置名称](../images/template02.png){ width=1000px} + + ![添加规则](../images/template03.png){ width=1000px} + + | 参数 | 说明 | + | ---- | ---- | + | 模板名称 | 名称只能包含小写字母、数字和连字符(-),必须以小写字母或数字开头和结尾,最长 63 个字符。 | + | 描述 | 描述可包含任意字符,最长 256 个字符。| + | 资源类型 | 用于指定告警模板的匹配类型。 | + | 告警规则 | 支持预定义多个告警规则,可添加模板规则、PromQL 规则。 | + +3. 点击 **确定** 完成创建后返回告警模板列表,点击模板名称后可查看模板详情。 + +## 编辑告警模板 + +点击目标规则后的 **┇** ,点击 **编辑**,进入抑制规则的编辑页。 + +![告警模板](../images/template04.png){ width=1000px} + +## 删除告警模板 + +点击目标模板后侧的 **┇** ,点击 **删除**,在输入框中输入告警模板的名称即可删除。 + +![告警模板](../images/template05.png){ width=1000px} \ No newline at end of file diff --git a/docs/zh/docs/admin/insight/alert-center/index.md b/docs/zh/docs/admin/insight/alert-center/index.md new file mode 100644 index 0000000..c21138c --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/index.md @@ -0,0 +1,28 @@ +# 告警中心 + +告警中心是 AI 算力平台 提供的一个重要功能,它让用户可以通过图形界面方便地按照集群和命名空间查看所有活动和历史告警, +并根据告警级别(紧急、警告、提示)来搜索告警。 + +![alert list](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/alert00.png) + +所有告警都是基于预设的告警规则设定的阈值条件触发的。在 AI 算力平台中,内置了一些全局告警策略,同时您也可以随时创建、删除告警策略,对以下指标进行设置: + +- CPU 使用量 +- 内存使用量 +- 磁盘使用量 +- 磁盘每秒读次数 +- 磁盘每秒写次数 +- 集群磁盘读取吞吐量 +- 集群磁盘写入吞吐量 +- 网络发送速率 +- 网络接收速率 + +还可以为告警规则添加标签和注解。告警规则分为活跃和过期规则,支持启用/禁用某些规则来实现告警静默。 + +当达到阈值条件后,可以配置告警通知方式,包括邮件、钉钉、企业微信、Webhook 和短信通知。 +所有通知的消息模板都可以自定义,同时还支持按设定的间隔时间发送通知。 + +此外,告警中心还支持通过阿里云、腾讯云等提供的短信服务将告警消息发送给指定用户,实现多种方式的告警通知。 + +AI 算力平台 告警中心是一个功能强大的告警管理平台,可帮助用户及时发现和解决集群中出现的问题, +提高业务稳定性和可用性,便于集群巡检和故障排查。 diff --git a/docs/zh/docs/admin/insight/alert-center/inhibition.md b/docs/zh/docs/admin/insight/alert-center/inhibition.md new file mode 100644 index 0000000..67484bc --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/inhibition.md @@ -0,0 +1,67 @@ +# 告警抑制 + +告警抑制主要是对于某些不需要立即关注的告警进行临时隐藏或者降低其优先级的一种机制。这个功能的目的是为了减少不必要的告警信息对运维人员的干扰,使他们能够集中精力处理更重要的问题。 + +告警抑制通过定义一组规则来识别和忽略某些告警,当它们在特定条件下发生时。主要有以下几种情况: + +- 父子关系抑制:当一个父告警(例如某个节点的崩溃)触发时,可以抑制所有由此引起的子告警(例如该节点上运行的容器崩溃)。 +- 相似告警抑制:当多个告警具有相同的特征(例如同一实例上的相同问题)时,可以抑制重复的告警通知。 + +## 创建抑制规则 + +1. 左侧导航栏中,选择 **告警中心** -> **告警降噪**,单击顶部的 **告警抑制** 。 + + ![告警抑制](../images/inhibition01.png){ width=1000px} + +2. 点击 **新建抑制规则** ,设置抑制规则的名称、规则等。 + + !!! note + + 通过[规则标签](#_3)和[告警标签](#_4)定义一组规则来识别和忽略某些告警,达到避免同一问题可能会触发多个相似或相关的告警的问题。 + + ![新建规则](../images/inhibition02.png){ width=1000px} + + | 参数时间 | 说明 | + | ---- | ---- | + | 抑制规则名称 | 抑制规则名称只能包含小写字母、数字和连字符(-),必须以小写字母或数字开头和结尾,最长 63 个字符。 | + | 描述 | 描述可包含任意字符,最长 256 个字符。 | + | 集群 | 该抑制规则作用的集群。 | + | 命名空间 | 该抑制规则作用的命名空间。 | + | 根源告警 | 通过填写的标签条件匹配告警,会将符合所有标签条件的告警与符合抑制条件的进行对比,不符合抑制条件的告警将照常发送消息给用户。

取值范围说明:
- **告警级别**:指标或事件告警的级别,可以设置为:紧急、重要、提示。
- **资源类型**:告警对象所对应的资源类型,可以设置为:集群、节点、无状态负载、有状容负载、守护进程、容器组。
- **标签**:告警标识属性,由标签名和标签值构成,支持用户自定义。 | + | 抑制告警 | 用于指定目标警报(将被抑制的警报)的匹配条件,符合所有标签条件的告警将不会再发送消息给用户。 | + | 匹配标签 | 用于指定应该比较的标签列表,以确定源警报和目标警报是否匹配。只有在 equal 中指定的标签在源和目标警报中的值完全相同的情况下,才会触发抑制。equal 字段是可选的。如果省略 equal 字段,则会将所有标签用于匹配 | + +3. 点击**确定**完成创建后返回告警抑制列表,点击告警抑制名称后可查看抑制规则详情。 + +### 查看规则标签 + +1. 点击右侧导航栏选择 **告警中心** -> **告警策略** ,点击规则所在的策略详情。 +2. 点击目标规则名称,查看规则详情,查看对应告警规则的标签。 + + ![查看规则标签](../images/inhibition.png) + + !!! note + + 在`添加规则`时可添加`自定义标签`。 + +### 查看告警标签 + +1. 点击右侧导航栏选择 **告警中心** -> **告警列表** ,点击告警所在行查看告警详情。 + + ![查看告警标签](../images/inhibition-1.png) + + !!! note + + 告警标签用于描述告警的详细信息和属性,可以用来创建抑制规则。 + +## 编辑抑制规则 + +1. 点击目标规则后侧的 **┇** ,点击 **编辑**,进入抑制规则的编辑页。 + + ![编辑抑制规则](../images/inhibition03.png){ width=1000px} + +## 删除抑制规则 + +点击目标规则后侧的 **┇** ,点击 **删除**,在输入框中输入抑制规则的名称即可删除。 + +![删除抑制规则](../images/inhibition04.png){ width=1000px} diff --git a/docs/zh/docs/admin/insight/alert-center/message.md b/docs/zh/docs/admin/insight/alert-center/message.md new file mode 100644 index 0000000..80127ae --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/message.md @@ -0,0 +1,106 @@ +# 通知配置 + +在 __通知配置__ 页面,可以配置通过邮件、企业微信、钉钉、Webhook 和短信等方式向用户发送消息。 + +## 邮件组 + +1. 进入 __可观测性__ 后,在左侧导航栏中点击 __告警中心__ -> __通知配置__,默认位于邮件通知对象。 + + ![邮件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/email00.png) + +2. 点击 __添加邮箱组__,添加一个或多个邮件地址。 + + ![添加邮箱组](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/email01.png) + +3. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,可以编辑或删除邮箱组。 + +## 企业微信 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __企业微信__。 + + ![企业微信](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/wechatbot00.png) + + 有关企业微信群机器人的 URL,请参阅[企业微信官方文档:如何使用群机器人](https://developer.work.weixin.qq.com/document/path/91770)。 + +2. 点击 __添加群机器人__,添加一个或多个群机器人。 + + ![企业微信](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/wechatbot01.png) + +3. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除群机器人。 + +## 钉钉 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __钉钉__,点击 __添加群机器人__,添加一个或多个群机器人。 + + ![钉钉](../images/dingding.png) + + 有关钉钉群机器人的 URL,请参阅[钉钉官方文档:自定义机器人接入](https://open.dingtalk.com/document/robots/custom-robot-access)。 + + !!! note + + 加签的方式是钉钉机器人与开发者双向进行安全认证,若在创建钉钉机器人时开启了加签,则需要在此处输入钉钉生成的密钥。 + 可参考[钉钉自定义机器人安全设置](https://open.dingtalk.com/document/robots/customize-robot-security-settings)。 + +1. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除群机器人。 + +## 飞书 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __飞书__,点击 __添加群机器人__,添加一个或多个群机器人。 + + ![飞书](../images/notify-01.png) + + !!! note + + 当飞书的群机器人开启签名校验时,添加飞书通知时需要填写对应的签名密钥。请查阅 [自定义机器人使用指南](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN?lang=zh-CN)。 + +2. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除群机器人。 + +## Webhook + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __Webhook__。 + + ![webhook](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/webhook00.png) + + 有关 Webhook URL 及更多配置方式,请参阅 [webhook 文档](https://github.com/webhooksite/webhook.site)。 + +2. 点击 __新建 Webhook__,添加一个或多个 Webhook。 + + ![alt text](../images/webhook.png) + + `HTTP Headers`:非必填,设置请求头。可以添加多个 Headers。 + + !!! note + + 有关 Webhook URL 及更多配置方式,请参阅 [webhook 文档](https://github.com/webhooksite/webhook.site)。 + +3. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除 Webhook。 + +## 站内信 + +!!! note + + 告警消息发送至用户个人的`站内信`,点击顶部的 🔔 符号可以查看通知消息。 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __站内信__,点击创建。 + + - 站内信通知允许添加多个用户。 + + ![message](../images/notify-02.png) + +2. 配置完成后自动返回 站内信通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__。 + +## 短信组 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __短信__,点击 __添加短信组__,添加一个或多个短信组。 + + ![messsage](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/notify06.png) + +2. 在弹窗中输入名称、接收短信的对象、手机号以及通知服务器。 + + ![mobile](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/notify07.png) + + 通知服务器需要预先在 __通知配置__ -> __通知服务器__ 中添加创建。目前支持阿里云、腾讯云两种云服务器,具体配置的参数请参阅自己的云服务器信息。 + + ![cloud-notify](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/notify08.png) + +3. 短信组添加成功后,自动返回通知列表,点击列表右侧的 __┇__,可以编辑或删除短信组。 diff --git a/docs/zh/docs/admin/insight/alert-center/msg-template.md b/docs/zh/docs/admin/insight/alert-center/msg-template.md new file mode 100644 index 0000000..3ae240c --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/msg-template.md @@ -0,0 +1,49 @@ +# 消息模板 + +可观测性提供自定义消息模板内容的能力,支持邮件、企业微信、钉钉、Webhook、飞书、站内信等不同的通知对象定义不同的消息通知内容。 + +## 创建消息模板 + +1. 在左侧导航栏中,选择 __告警中心__ -> __消息模板__。 + + Insight 默认内置中英文两个模板,以便用户使用。 + + ![点击按钮](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/template00.png) + +2. 点击 __新建消息模板__ 按钮,填写模板内容。 + + ![点击按钮](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/template01.png) + +!!! info + + 可观测性预置了消息模板。若需要定义模板的内容,请参考[配置通知模板](../../reference/notify-helper.md)。 + +## 消息模板详情 + +点击某一消息模板的名称,右侧滑块可查看消息模板的详情。 + +![消息模板](../images/msg-detail.png) + +| 参数 | 变量 | 描述 | +| -- | -- | -- | +| 规则名称 | {{ .Labels.alertname }} | 触发告警的规则名称 | +| 策略名称 | {{ .Labels.alertgroup }} | 触发告警规则所属的告警策略名称 | +| 告警级别 | {{ .Labels.severity }} | 触发告警的级别 | +| 集群 | {{ .Labels.cluster }} | 触发告警的资源所在的集群 | +| 命名空间 | {{ .Labels.namespace }} | 触发告警的资源所在的命名空间 | +| 节点 | {{ .Labels.node }} | 触发告警的资源所在的节点 | +| 资源类型 | {{ .Labels.target_type }} | 告警对象的资源类型 | +| 资源名称 | {{ .Labels.target }} | 触发告警的对象名称 | +| 触发值 | {{ .Annotations.value }} | 触发告警通知时的指标值 | +| 发生时间 | {{ .StartsAt }} | 告警开始发生的时间 | +| 结束时间 | {{ .EndsAT }} | 告警结束的时间 | +| 描述 | {{ .Annotations.description }} | 告警的详细描述 | +| 标签 | {{ for .labels}} {{end}} | 告警的所有标签,使用 for 函数遍历 labels 列表,获取告警的所有标签内容。 | + +## 编辑或删除消息模板 + +在列表右侧点击 __┇__,在弹出菜单中选择 __编辑__ 或 __删除__,可以修改或删除消息模板。 + +!!! warning + + 请注意,删除模板后无法恢复,请谨慎操作。 diff --git a/docs/zh/docs/admin/insight/alert-center/silent.md b/docs/zh/docs/admin/insight/alert-center/silent.md new file mode 100644 index 0000000..740d901 --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/silent.md @@ -0,0 +1,20 @@ +# 告警静默 + +告警静默是指在特定的时间范围内,根据定义好的规则对符合条件的告警不再发送告警通知。该功能可以帮助运维人员避免在某些操作或事件期间接收到过多的噪声告警,同时便于更加精确地处理真正需要解决的问题。 + +在告警静默页面上,用户可以看到两个页签:活跃规则和过期规则。 +其中,活跃规则表示目前正在生效的规则,而过期规则则是以前定义过但已经过期(或者用户主动删除)的规则。 + +## 操作步骤 + +1. 在左侧导航栏中,选择 __告警中心__ -> __告警静默__ ,点击 __新建静默规则__ 按钮。 + + ![点击按钮](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/silence00.png) + +2. 填写静默规则的各项参数,如集群、命名空间、标签、时间等,以定义这条规则的作用范围和生效时间。 + + ![静默规则](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/silence01.png) + +3. 返回规则列表,在列表右侧点击 __┇__ ,可以编辑或删除静默规则。 + +通过告警静默功能,您可以灵活地控制哪些告警需要被忽略,在什么时间段内生效,从而提高运维效率,减少误报的可能性。 diff --git a/docs/zh/docs/admin/insight/alert-center/sms-provider.md b/docs/zh/docs/admin/insight/alert-center/sms-provider.md new file mode 100644 index 0000000..68981f7 --- /dev/null +++ b/docs/zh/docs/admin/insight/alert-center/sms-provider.md @@ -0,0 +1,52 @@ +# 配置通知服务器 + +可观测性 Insight 支持短信通知,目前通过集成阿里云、腾讯云的短信服务发送告警消息。本文介绍了如何在 insight 中配置短信通知的服务器。短信签名中支持的变量为消息模板中的默认变量,同时由于短信字数有限,建议选择较为明确的变量。 + +> 如何配置短信接收人可参考文档:[配置短信通知组](./message.md)。 + +## 操作步骤 + +1. 进入 __告警中心__ -> __通知配置__ -> __通知服务器__ 。 + + ![通知服务器](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/smsserver00.png) + +2. 点击 __添加通知服务器__ 。 + + 1. 配置阿里云服务器。 + + > 申请阿里云短信服务,请参考[阿里云短信服务](https://help.aliyun.com/document_detail/108062.html?spm=a2c4g.57535.0.0.2cec637ffna8ye)。 + + **字段说明:** + + - __AccessKey ID__ :阿里云用于标识用户的参数。 + - __AccessKey Secret__ :阿里云用于验证用户的密钥。AccessKey Secret 必须保密。 + - __短信签名__ :短信服务支持根据用户需求创建符合要求的签名。发送短信时,短信平台会将已审核通过的短信签名添加到短信内容中,再发送给短信接收方。 + - __模板 CODE__ :短信模板是发送短信的具体内容。 + - __参数模板__ :短信正文模板可以包含变量,用户可通过变量实现自定义短信内容。 + + 请参考[阿里云变量规范](https://help.aliyun.com/document_detail/463270.html)。 + + ![通知服务器](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sms02.png) + + !!! note + + 举例:在阿里云定义的模板内容为:${severity}:${alertname} 在 ${startat} 被触发。参数模板中的配置参考上图。 + + 2. 配置腾讯云服务器。 + + > 申请腾讯云短信服务,请参考[腾讯云短信](https://cloud.tencent.com/document/product/382/37794)。 + + 字段说明: + + - __Secret ID__ :腾讯云用于标识 API 调用者身份参数。 + - __SecretKey__ :腾讯云用于验证 API 调用者的身份的参数。 + - __短信模板 ID__ :短信模板 ID,由腾讯云系统自动生成。 + - __签名内容__ :短信签名内容,即在腾讯云短信签名中定义的实际网站名的全称或简称。 + - __SdkAppId__ :短信 SdkAppId,在腾讯云短信控制台添加应用后生成的实际 SdkAppId。 + - __参数模板__ :短信正文模板可以包含变量,用户可通过变量实现自定义短信内容。请参考:[腾讯云变量规范](https://cloud.tencent.com/document/product/382/39023#.E5.8F.98.E9.87.8F.E8.A7.84.E8.8C.83.3Ca-id.3D.22variable.22.3E.3C.2Fa.3E)。 + + ![通知服务器](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sms03.png) + + !!! note + + 举例:在腾讯云定义的模板内容为:{1}:{2} 在 {3} 被触发。参数模板中的配置参考上图。 diff --git a/docs/zh/docs/admin/insight/best-practice/debug-log.md b/docs/zh/docs/admin/insight/best-practice/debug-log.md new file mode 100644 index 0000000..5277808 --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/debug-log.md @@ -0,0 +1,58 @@ +# 日志采集排障指南 + +在集群中[安装 insight-agent](../quickstart/install/install-agent.md) 后, __insight-agent__ 中的 __Fluent Bit__ 会默认采集集群中的日志,包括 Kubernetes 事件日志、节点日志、容器日志等。 + __Fluent Bit__ 已配置好各种日志采集插件、相关的过滤器插件及日志输出插件。 +这些插件的工作状态决定了日志采集是否正常。 +下面是一个针对 __Fluent Bit__ 的仪表盘,它用来监控各个集群中 __Fluent Bit__ 的工作情况和插件的采集、处理、导出日志的情况。 + +1. 使用 AI 算力中心平台,进入 __可观测性__ ,选择左侧导航栏的 __仪表盘__ 。 + + ![insight 入口](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight01.png) + +2. 点击仪表盘标题 __概览__ 。 + + ![概览](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight02.png) + +3. 切换到 __insight-system__ -> __Fluent Bit__ 仪表盘。 + + ![fluentbit](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight03.png) + +4. __Fluent Bit__ 仪表盘上方有几个选项框,可以选择日志采集插件、日志过滤插件、日志输出插件及所在集群名。 + + ![fluentbit](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight04.png) + +## 插件说明 + +此处说明 __Fluent Bit__ 的几个插件。 + +**日志采集插件** + +| input plugin | 插件介绍 | 采集目录 | +| ---------------------- | ------------------ | ------------------------------------------------------------------- | +| tail.kube | 采集容器日志 | /var/log/containers/*.log | +| tail.kubeevent | 采集 Kubernetes 事件日志 | /var/log/containers/*-kubernetes-event-exporter*.log | +| tail.syslog.dmesg | 采集主机 dmesg 日志 | /var/log/dmesg | +| tail.syslog.messages | 采集主机常用日志 | /var/log/secure, /var/log/messages, /var/log/syslog,/var/log/auth.log | +| syslog.syslog.RSyslog | 采集 RSyslog 日志 | | +| systemd.syslog.systemd | 采集 Journald daemon 日志 | | +| tail.audit_log.k8s | 采集 Kubernetes 审计日志 | /var/log/*/audit/*.log | +| tail.audit_log.ghippo | 采集全局管理审计日志 | /var/log/containers/*_ghippo-system_audit-log*.log | +| tail.skoala-gw | 采集微服务网关日志 | /var/log/containers/*_skoala-gw*.log | + +**日志过滤插件** + +| filter plugin | 插件介绍 | +| ------------------------ | ---------------------------------- | +| Lua.audit_log.k8s | 使用 lua 过滤符合条件的 Kubernetes 审计日志 | + +!!! note + + 过滤器插件不止 Lua.audit_log.k8s,这里只介绍会丢弃日志的过滤器。 + +**日志输出插件** + +| output plugin | 插件介绍 | +| ------------------------ | ---------------------------------- | +| es.kube.kubeevent.syslog | 把 Kubernetes 审计日志、事件日志,syslog 日志写入 [ElasticSearch 集群](../../middleware/elasticsearch/intro/index.md) | +| forward.audit_log | 把 Kubernetes 审计日志和[全局管理的审计日志](../../ghippo/audit/audit-log.md)发送到 __全局管理__ | +| es.skoala | 把微服务网关的[请求日志](../../skoala/gateway/logs/reqlog.md)和[实例日志](../../skoala/gateway/logs/inslog.md)写入到 ElasticSearch 集群 | diff --git a/docs/zh/docs/admin/insight/best-practice/debug-trace.md b/docs/zh/docs/admin/insight/best-practice/debug-trace.md new file mode 100644 index 0000000..dd51718 --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/debug-trace.md @@ -0,0 +1,68 @@ +# 链路采集排障指南 + +在尝试排查链路数据采集的问题前,需先理解链路数据的传输路径,下面是链路数据传输示意图: + +```mermaid +graph TB + +sdk[Language proble / SDK] --> workload[Workload cluster otel collector] +--> otel[Global cluster otel collector] +--> jaeger[Global cluster jaeger collector] +--> es[Elasticsearch cluster] + +classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; +classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; +classDef cluster fill:#fff,stroke:#bbb,stroke-width:1px,color:#326ce5; + +class sdk,workload,otel,jaeger,es cluster +``` + +如上图所示,在任一步骤传输失败都会导致无法查询出链路数据。如果您在完成应用链路增强后发现没有链路数据,请执行以下步骤: + +1. 使用 AI 算力中心平台,进入 __可观测性__ ,选择左侧导航栏的 __仪表盘__ 。 + + ![insight 入口](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight01.png) + +2. 点击仪表盘标题 __概览__ 。 + + ![概览](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight02.png) + +3. 切换到 __insight-system__ -> __insight tracing debug__ 仪表盘。 + + ![tracing debug](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insighttrace01.png) + +4. 可以看到该仪表盘由三个区块组成,分别负责监控不同集群、不同组件传输链路的数据情况。通过生成的时序图表,检查链路数据传输是否存在问题。 + + - workload opentelemetry collector + - global opentelemetry collector + - global jaeger collector + + ![tracing debug](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insighttrace02.png) + +## 区块介绍 + +1. **workload opentelemetry collector** + + 展示不同工作集群的 __opentelemetry collector__ 在接受 language probe/SDK 链路数据,发送聚合链路数据情况。可以通过左上角的 __Cluster__ 选择框选择所在的集群。 + + ![tracing debug](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insighttrace03.png) + + !!! note + + 根据这四张时序图,可以判断出该集群的 __opentelemetry collector__ 是否正常运行。 + +2. **global opentelemetry collector** + + 展示 __全局服务集群__ 的 __opentelemetry collector__ 在接收 __工作集群__ 中 __otel collector__ 链路数据以及发送聚合链路数据的情况。 + + ![tracing debug](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insighttrace04.png) + + !!! note + + __全局服务集群__ 的 __opentelemetry collector__ 还负责发送所有工作集群的[全局管理模块](../../ghippo/intro/index.md)的[审计日志](../../ghippo/audit/audit-log.md)以及 Kubernetes 审计日志(默认不采集)到全局管理模块的 __audit server__ 组件。 + +3. **global jaeger collector** + + 展示 __全局服务集群__ 的 __jaeger collector__ 在接收 __全局服务集群__ 中 __otel collector__ 的数据,并发送链路数据到 [ElasticSearch 集群](../../middleware/elasticsearch/intro/index.md)的情况。 + + ![tracing debug](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insighttrace05.png) diff --git a/docs/zh/docs/admin/insight/best-practice/find_root_cause.md b/docs/zh/docs/admin/insight/best-practice/find_root_cause.md new file mode 100644 index 0000000..a478e2c --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/find_root_cause.md @@ -0,0 +1,48 @@ +# 使用 Insight 定位应用异常 + +本文将以 AI 算力中心中举例,讲解如何通过 Insight 发现 AI 算力中心中异常的组件并分析出组件异常的根因。 + +本文假设你已经了解 Insight 的产品功能或愿景。 + +## 拓扑图 — 从宏观察觉异常 + +随着企业对微服务架构的实践,企业中的服务数量可能会面临着数量多、调用复杂的情况,开发或运维人员很难理清服务之间的关系, +因此,我们提供了拓扑图监控的功能,我们可以通过拓扑图对当前系统中运行的微服务状况进行初步诊断。 + +如下图所示,我们通过拓扑图发现其中 __Insight-Server__ 这个节点的颜色为 __红色__ ,并将鼠标移到该节点上, +发现该节点的错误率为 __2.11%__ 。因此,我们希望查看更多细节去找到造成该服务错误率不为 __0__ 的原因: + +![01](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/01.png) + +当然,我们也可以点击最顶部的服务名,进入到该服务的总览界面: + +![02](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/02.png) + +## 服务总览 — 具体分析的开始 + +当你需要根据服务的入口和出口流量分别分析的时候,你可以在右上角进行筛选切换,筛选数据之后,我们发现该服务有很多 __操作__ +对应的错误率都不为 0. 此时,我们可以通过点击 __查看链路__ 对该 __操作__ 在这段时间产生的并记录下来的链路进行分析: + +![03](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/03.png) + +![04](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/04.png) + +## 链路详情 — 找到错误根因,消灭它们 + +在链路列表中,我们可以通过界面直观地发现链路列表中存在着 __错误__ 的链路(上图中红框圈起来的),我们可以点击错误的链路查看链路详情,如下图所示: + +![05](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/05.png) + +在链路图中我们也可以一眼就发现链路的最后一条数据是处于 __错误__ 状态,将其右边 __Logs__ 展开,我们定位到了造成这次请求错误的原因: + +![06](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/06.png) + +根据上面的分析方法,我们也可以定位到其他 __操作__ 错误的链路: + +![07](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/07.png) + +![08](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/08.png) + +![09](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/find_root_cause/09.png) + +## 接下来 — 你来分析! diff --git a/docs/zh/docs/admin/insight/best-practice/grafana-use-db.md b/docs/zh/docs/admin/insight/best-practice/grafana-use-db.md new file mode 100644 index 0000000..142a51b --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/grafana-use-db.md @@ -0,0 +1,125 @@ +# Insight Grafana 持久化到数据库 + +Insight 使用云原生的 `GrafanaOperator` + `CRD` 的方式来使用 Grafana。我们推荐使用 GrafanaDashboard(CRD) +来描述仪表盘的 JSON 数据,即通过 `GrafanaDashboard` 来增加、删除、修改仪表盘。 + +因为 Grafana 默认使用 SQLite3 作为本地数据库来存储配置信息,例如用户、仪表盘、告警等。 +当用户以 管理员身份,通过 UI 创建或者导入仪表盘之后,数据将临时存储在 SQLite3 中。 +当 Grafana 重启之后,将重置所有的仪表盘的数据,将只展示通过 GrafanaDashboard CR 描述的仪表盘数据,而通过 UI 创建,删除,修改也都将被全部重置。 + +Grafana 支持使用外部的 MySQL、PostgreSQL 等数据库替代内置的 SQLite3 作为内部存储。本文描述了如果给 Insight 提供的 Grafana 配置外置的数据库。 + +## 使用外部数据库 + +结合 Grafana(当前镜像版本 9.3.14)的官方文档。根据如下步骤配置使用外部的数据库,示例以 MySQL 为例: + +1. 在外部数据库(MySQL /PostgreSQL)中创建一个数据库(DB)。 +2. 配置 Grafana 使用这个数据库(MySQL 的 MGR 模式需要额外处理)。 + +## 操作步骤 + +1. 初始化数据库 + + 在数据库中创建一个新的 database 给 Grafana 使用,建议名称为 grafana + +1. 配置 Grafana 使用 DB + + 在 `insight-system` 下,名为 insight-grafana-operator-grafana 的 Grafana 的 CR 里的配置: + + ```yaml + apiVersion: integreatly.org/v1alpha1 + kind: Grafana + metadata: + name: insight-grafana-operator-grafana + namespace: insight-system + spec: + baseImage: 10.64.40.50/docker.m.daocloud.io/grafana/grafana:9.3.14 + config: + // 在 config 的尾部追加 + + database: + + type: mysql # 支持 mysql, postgres + + host: "10.6.216.101:30782" # 数据库的 Endpoint + + name: "grafana" # 提前创建的 database + + user: "grafana" + + password: "grafana_password" + ``` + +1. 如下是配置完成后在 Grafana 的配置文件 grafana-config 里的配置信息。 + + ```toml + [database] + host = 10.6.216.101:30782 + name = grafana + password = grafana_password + type = mysql + user = grafana + ``` + + 1. 在 insight.yaml 添加如下配置: + + ```yaml + grafana-operator: + grafana: + config: + database: + type: mysql + host: "10.6.216.101:30782" + name: "grafana" + user: "grafana" + password: "grafana_password" + ``` + + 1. 升级 insight server,建议通过 Helm 升级。 + + ```shell + helm upgrade insight insight/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version ${version} + ``` + +1. 通过命令行进行升级。 + + 1. 获取 insight Helm 中原来的配置。 + + ```shell + helm get values insight -n insight-system -o yaml > insight.yaml + ``` + + 1. 指定原来配置文件并保存 grafana 数据库的连接信息。 + + ```shell + helm upgrade --install \ + --version ${version} \ + insight insight/insight -n insight-system \ + -f ./insight.yaml \ + --set grafana-operator.grafana.config.database.type=mysql \ + --set grafana-operator.grafana.config.database.host=10.6.216.101:30782 \ + --set grafana-operator.grafana.config.database.name=grafana \ + --set grafana-operator.grafana.config.database.user=grafana \ + --set grafana-operator.grafana.config.database.password=grafana_password + ``` + +## 注意事项 + +1. 用户是否会覆盖内置仪表盘,导致升级失败? + + 回复:会。当用户编辑了 Dashbaord A(v1.1),且 Insight 也升级了 Dashboard A(v2.0), + 升级之后(升级镜像);用户看到内容还是 v1.1,而 v2.0 是不会更新到环境里。 + +1. 当使用 MGR 模式 MySQL 时会存在问题,导致 grafana-deployment 无法正常启动。 + + 原因:表 alert_rule_tag_v1 和 annotation_tag_v2 中没有主键,而 mysql mgr 必须有主键 + + 解决方法:向 alert_rule_tag_v1 和 annotation_tag_v2 临时表添加主键: + + ```SQL + alter table alert_rule_tag_v1 + add constraint alert_rule_tag_v1_pk + primary key (tag_id, alert_id); + + alter table annotation_tag_v2 + add constraint annotation_tag_v2_pk + primary key (tag_id, annotation_id); + ``` + diff --git a/docs/zh/docs/admin/insight/best-practice/insight-kafka.md b/docs/zh/docs/admin/insight/best-practice/insight-kafka.md new file mode 100644 index 0000000..f66c8ee --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/insight-kafka.md @@ -0,0 +1,339 @@ +# Kafka + Elasticsearch 流式架构应对超大规模日志方案 + +随着业务发展,越来越多的应用产生的日志数据会越来越多,为了保证系统能够正常采集并分析庞杂的日志数据时, +一般做法是引入 Kafka 的流式架构来解决大量数据异步采集的方案。采集到的日志数据会经过 Kafka 流转, +由相应的数据消费组件将数据从 Kafka 消费存入到 Elasticsearch 中,并通过 Insight 进行可视化展示与分析。 + +本文将介绍以下两种方案: + +- Fluentbit + Kafka + Logstash + Elasticsearch +- Fluentbit + Kafka + Vector + Elasticsearch + +当我们在日志系统中引入 Kafka 之后,数据流图如下图所示: + +![logging-kafka](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/logging-kafka.png) + +上面两种方案中有共通的地方,不同之处在于消费 Kafka 数据的组件,同时,为了不影响 Insight 数据分析, +我们需要在消费 Kafka 数据并写入到 ES 的数据和原来 Fluentbit 直接写入 ES 的数据的格式一致。 + +首先我们来看看 Fluentbit 怎么将日志写入 Kafka: + +## 修改 Fluentbit Output 配置 + +当 Kafka 集群准备就绪之后,我们需要修改 __insight-system__ 命名空间下 __ConfigMap__ 的内容, +新增以下三个 Kafka Output 并注释原来三个 Elasticsearch Output: + +假设 Kafka Brokers 地址为: `insight-kafka.insight-system.svc.cluster.local:9092` + +```console + [OUTPUT] + Name kafka + Match_Regex (?:kube|syslog)\.(.*) + Brokers insight-kafka.insight-system.svc.cluster.local:9092 + Topics insight-logs + format json + timestamp_key @timestamp + rdkafka.batch.size 65536 + rdkafka.compression.level 6 + rdkafka.compression.type lz4 + rdkafka.linger.ms 0 + rdkafka.log.connection.close false + rdkafka.message.max.bytes 2.097152e+06 + rdkafka.request.required.acks 1 + [OUTPUT] + Name kafka + Match_Regex (?:skoala-gw)\.(.*) + Brokers insight-kafka.insight-system.svc.cluster.local:9092 + Topics insight-gw-skoala + format json + timestamp_key @timestamp + rdkafka.batch.size 65536 + rdkafka.compression.level 6 + rdkafka.compression.type lz4 + rdkafka.linger.ms 0 + rdkafka.log.connection.close false + rdkafka.message.max.bytes 2.097152e+06 + rdkafka.request.required.acks 1 + [OUTPUT] + Name kafka + Match_Regex (?:kubeevent)\.(.*) + Brokers insight-kafka.insight-system.svc.cluster.local:9092 + Topics insight-event + format json + timestamp_key @timestamp + rdkafka.batch.size 65536 + rdkafka.compression.level 6 + rdkafka.compression.type lz4 + rdkafka.linger.ms 0 + rdkafka.log.connection.close false + rdkafka.message.max.bytes 2.097152e+06 + rdkafka.request.required.acks 1 +``` + +接下来就是消费 Kafka 数据之后写到 ES 的细微差别。 正如本文开始的描述,本文将介绍 Logstash 与 Vector 作为消费 Kafka 的两种方式。 + +## 消费 Kafka 并写入 Elasticsearch + +假设 Elasticsearch 的地址为:`https://mcamel-common-es-cluster-es-http.mcamel-system:9200` + +### 通过 Logstash 消费 + +如果你对 Logstash 技术栈比较熟悉,你可以继续使用该方式。 + +当你通过 Helm 部署 [Logstash](https://github.com/elastic/helm-charts/tree/main/logstash) 的时候, +在 __logstashPipeline__ 中增加如下 Pipeline 即可: + +```yaml +replicas: 3 +resources: + requests: + cpu: 100m + memory: 1536Mi + limits: + cpu: 1000m + memory: 1536Mi +logstashConfig: + logstash.yml: | + http.host: 0.0.0.0 + xpack.monitoring.enabled: false +logstashPipeline: + insight-event.conf: | + input { + kafka { + add_field => {"kafka_topic" => "insight-event"} + topics => ["insight-event"] + bootstrap_servers => "172.30.120.189:32082" # kafka的ip 和端口 + enable_auto_commit => true + consumer_threads => 1 # 对应 partition 的数量 + decorate_events => true + codec => "plain" + } + } + + filter { + mutate { gsub => [ "message", "@timestamp", "_@timestamp"] } + json {source => "message"} + date { + match => [ "_@timestamp", "UNIX" ] + remove_field => "_@timestamp" + remove_tag => "_timestampparsefailure" + } + mutate { + remove_field => ["event", "message"] + } + } + + output { + if [kafka_topic] == "insight-event" { + elasticsearch { + hosts => ["https://172.30.120.201:32427"] # elasticsearch 地址 + user => 'elastic' # elasticsearch 用户名 + ssl => 'true' + password => '0OWj4D54GTH3xK06f9Gg01Zk' # elasticsearch 密码 + ssl_certificate_verification => 'false' + action => "create" + index => "insight-es-k8s-event-logs-alias" + data_stream => "false" + } + } + } + insight-gw-skoala.conf: | + input { + kafka { + add_field => {"kafka_topic" => "insight-gw-skoala"} + topics => ["insight-gw-skoala"] + bootstrap_servers => "172.30.120.189:32082" + enable_auto_commit => true + consumer_threads => 1 + decorate_events => true + codec => "plain" + } + } + + filter { + mutate { gsub => [ "message", "@timestamp", "_@timestamp"] } + json {source => "message"} + date { + match => [ "_@timestamp", "UNIX" ] + remove_field => "_@timestamp" + remove_tag => "_timestampparsefailure" + } + mutate { + remove_field => ["event", "message"] + } + } + + output { + if [kafka_topic] == "insight-gw-skoala" { + elasticsearch { + hosts => ["https://172.30.120.201:32427"] + user => 'elastic' + ssl => 'true' + password => '0OWj4D54GTH3xK06f9Gg01Zk' + ssl_certificate_verification => 'false' + action => "create" + index => "skoala-gw-alias" + data_stream => "false" + } + } + } + insight-logs.conf: | + input { + kafka { + add_field => {"kafka_topic" => "insight-logs"} + topics => ["insight-logs"] + bootstrap_servers => "172.30.120.189:32082" + enable_auto_commit => true + consumer_threads => 1 + decorate_events => true + codec => "plain" + } + } + + filter { + mutate { gsub => [ "message", "@timestamp", "_@timestamp"] } + json {source => "message"} + date { + match => [ "_@timestamp", "UNIX" ] + remove_field => "_@timestamp" + remove_tag => "_timestampparsefailure" + } + mutate { + remove_field => ["event", "message"] + } + } + + output { + if [kafka_topic] == "insight-logs" { + elasticsearch { + hosts => ["https://172.30.120.201:32427"] + user => 'elastic' + ssl => 'true' + password => '0OWj4D54GTH3xK06f9Gg01Zk' + ssl_certificate_verification => 'false' + action => "create" + index => "insight-es-k8s-logs-alias" + data_stream => "false" + } + } + } +``` + +### 通过 Vector 消费 + +如果你对 Vector 技术栈比较熟悉,你可以继续使用该方式。 + +当你通过 Helm 部署 Vector 的时候,引用如下规则的 Configmap 配置文件即可: + +```yaml +metadata: + name: vector +apiVersion: v1 +data: + aggregator.yaml: | + api: + enabled: true + address: '0.0.0.0:8686' + sources: + insight_logs_kafka: + type: kafka + bootstrap_servers: 'insight-kafka.insight-system.svc.cluster.local:9092' + group_id: consumer-group-insight + topics: + - insight-logs + insight_event_kafka: + type: kafka + bootstrap_servers: 'insight-kafka.insight-system.svc.cluster.local:9092' + group_id: consumer-group-insight + topics: + - insight-event + insight_gw_skoala_kafka: + type: kafka + bootstrap_servers: 'insight-kafka.insight-system.svc.cluster.local:9092' + group_id: consumer-group-insight + topics: + - insight-gw-skoala + transforms: + insight_logs_remap: + type: remap + inputs: + - insight_logs_kafka + source: |2 + . = parse_json!(string!(.message)) + .@timestamp = now() + insight_event_kafka_remap: + type: remap + inputs: + - insight_event_kafka + - insight_gw_skoala_kafka + source: |2 + . = parse_json!(string!(.message)) + .@timestamp = now() + insight_gw_skoala_kafka_remap: + type: remap + inputs: + - insight_gw_skoala_kafka + source: |2 + . = parse_json!(string!(.message)) + .@timestamp = now() + sinks: + insight_es_logs: + type: elasticsearch + inputs: + - insight_logs_remap + api_version: auto + auth: + strategy: basic + user: elastic + password: 8QZJ656ax3TXZqQh205l3Ee0 + bulk: + index: insight-es-k8s-logs-alias-1418 + endpoints: + - 'https://mcamel-common-es-cluster-es-http.mcamel-system:9200' + tls: + verify_certificate: false + verify_hostname: false + insight_es_event: + type: elasticsearch + inputs: + - insight_event_kafka_remap + api_version: auto + auth: + strategy: basic + user: elastic + password: 8QZJ656ax3TXZqQh205l3Ee0 + bulk: + index: insight-es-k8s-event-logs-alias-1418 + endpoints: + - 'https://mcamel-common-es-cluster-es-http.mcamel-system:9200' + tls: + verify_certificate: false + verify_hostname: false + insight_es_gw_skoala: + type: elasticsearch + inputs: + - insight_gw_skoala_kafka_remap + api_version: auto + auth: + strategy: basic + user: elastic + password: 8QZJ656ax3TXZqQh205l3Ee0 + bulk: + index: skoala-gw-alias-1418 + endpoints: + - 'https://mcamel-common-es-cluster-es-http.mcamel-system:9200' + tls: + verify_certificate: false + verify_hostname: false +``` + +## 检查是否正常工作 + +你可以通过查看 Insight 日志查询界面是否有最新的数据,或者查看原本 Elasticsearch 的索引的数量有没有增长,增长即代表配置成功。 + +## 参考 + +- [Logstash Helm Chart](https://github.com/elastic/helm-charts/tree/main/logstash) +- [Vector Helm Chart](https://vector.dev/docs/setup/installation/package-managers/helm/) +- [Vector 实践](https://wiki.eryajf.net/pages/0322lius/#_0-%E5%89%8D%E8%A8%80) +- [Vector Perfomance](https://github.com/vectordotdev/vector/blob/master/README.md) diff --git a/docs/zh/docs/admin/insight/best-practice/integration_deepflow.md b/docs/zh/docs/admin/insight/best-practice/integration_deepflow.md new file mode 100644 index 0000000..c19fcd4 --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/integration_deepflow.md @@ -0,0 +1,86 @@ +# 集成 DeepFlow + +DeepFlow 是一款基于 eBPF 的可观测性产品。它的社区版已经被集成进 Insight 中,以下是集成方式。 + +## 前提条件 + +- 全局服务集群已经安装 Insight +- Insight 最低版本要求为 v0.23.0 +- 了解并满足 [DeepFlow 运行权限及内核要求](https://deepflow.io/docs/zh/ce-install/overview/#%E8%BF%90%E8%A1%8C%E6%9D%83%E9%99%90%E5%8F%8A%E5%86%85%E6%A0%B8%E8%A6%81%E6%B1%82) +- 存储卷就绪 + +## 安装 DeepFlow 和配置 Insight + +安装 DeepFlow 组件需要用到两个 Chart: + +- `deepflow`:包含 `deepflow-app`、`deepflow-server`、`deepflow-clickhouse`、`deepflow-agent` 等组件。 + 一般 `deepflow` 会部署在全局服务集群中,所以它也一并安装了 `deepflow-agent` +- `deepflow-agent`:只包含了 `deepflow-agent` 组件,用于采集 eBPF 数据并发送给 `deepflow-server` + +### 安装 DeepFlow + +DeepFlow 需要安装在全局服务集群中。 + +1. 进入 kpanda-global-cluster 集群,在左侧导航栏内点击 + __Helm 应用__ -> __Helm 模板__ ,仓库选择 __community__ ,搜索框找到 `deepflow`: + + ![找到 deepflow](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_chart.png) + +1. 点击 deepflow 卡片进入详情页: + + ![卡片详情](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_chart_readme.png) + +1. 点击 **安装** ,进入安装界面: + + ![开始安装](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_chart_config.png) + +1. 大部分 values 都有默认值。其中 Clickhouse 和 Mysql 都需要申请存储卷,它们的默认大小都是 __10Gi__ , + 可以通过 __persistence__ 关键字搜索到相关配置并修改。 + +1. 配置好后就可以点击 __确定__ ,执行安装了。 + +### 修改 Insight 配置 + +在安装 DeepFlow 后,还需要在 Insight 中开启相关的功能开关。 + +1. 在左侧导航栏内点击 __配置与密钥__ -> __配置项__ , 通过搜索框找到 insight-server-config 并进行编辑: + + ![找到 insight-server-config](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_integ_insight_cm.png) + +1. 在 YAML 配置中找到 __eBPF Flow feature__ 这个功能开关并将它开启: + + ![打开开关](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_integ_insight_cm_edit.png) + +1. 保存更改,重启 insight-server 后,Insight 主界面就会出现 __网络观测__ : + + ![保存并重启](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_ui.png) + +## 安装 DeepFlow Agent + +DeepFlow Agent 通过 `deepflow-agent` Chart 来安装在子集群中,用于采集子集群的 eBPF 观测数据并上报到全局服务集群中。 +类似于安装 `deepflow`,通过 __Helm 应用__ -> __Helm 模板__ ,仓库选择 __community__ , +通过搜索框查询 `deepflow-agent`,按流程进入安装界面。 + +![参数配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_agent_chart_config.png) + +参数说明: + +- __DeployComponent__ 部署模式,默认为 `daemonset` +- __timezone__ 时区,默认为 `Asia/Shanghai` +- __DeepflowServerNodeIPS__ 对应 deepflow server 安装集群的节点地址 +- __deepflowK8sClusterID__ 集群 UUID +- __agentGroupID__ agent 组 ID +- __controllerPort__ deepflow server 的数据上报端口,可以不填,默认为 `30035` +- __clusterNAME__ 集群名称 + +配置好后点击 __确定__ ,完成安装。 + +## 使用 + +在正确安装 DeepFlow 后,点击 __网络观测__ 就可以进入 DeepFlow Grafana UI。 +它内置了大量的 Dashboard 可供查看与帮助分析问题, +点击 __DeepFlow Templates__ ,可以浏览所有可以查看的 Dashboard: + +![网络观测1](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_ui_templates.png) + +![网络观测2](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/best-practice/images/deepflow_ui_template_list.png) diff --git a/docs/zh/docs/admin/insight/best-practice/sw-to-otel.md b/docs/zh/docs/admin/insight/best-practice/sw-to-otel.md new file mode 100644 index 0000000..323e6b7 --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/sw-to-otel.md @@ -0,0 +1,131 @@ +# 使用 OpenTelemetry 零代码接收 SkyWalking 链路数据 + +可观测性 Insight 通过 OpenTelemetry 将应用数据进行上报。若您的应用已使用 Skywalking 来采集链路, +可参考本文进行零代码改造将链路数据接入 Insight。 + +## 代码解读 + +为了能兼容不同的分布式追踪实现,OpenTelemetry 提供了组件植入的方式,让不同的厂商能够经由 OpenTelemetry +标准化数据处理后输出到不同的后端。Jaeger 与 Zipkin 在社区中实现了 JaegerReceiver、ZipkinReceiver。 +我们也为社区贡献了 SkyWalkingReceiver,并进行了持续的打磨,现在已经具备了在生产环境中使用的条件, +而且无需修改任何一行业务代码。 + +OpenTelemetry 与 SkyWalking 有一些共同点:都是使用 Trace 来定义一次追踪,并使用 Span 来标记追踪里的最小粒度。 +但是在一些细节和实现上还是会有差别: + +| - | Skywalking | OpenTelemetry | +| --- | ------- | ------------ | +| 数据结构 | __span__ -> __Segment__ -> __Trace__ | __Span__ -> __Trace__ | +| 属性信息 | __Tags__ | __Attributes__ | +| 应用时间 | __Logs__ | __Events__ | +| 引用关系 | __References__ | __Links__ | + +明确了这些差异后,就可以开始实现将 [SkyWalking Trace](https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent/Tracing.proto) +转换为 [OpenTelemetry Trace](https://opentelemetry.io/docs/reference/specification/overview/)。主要工作包括: + +1. 如何构造 OpenTelemetry 的 TraceId 和 SpanId + +2. 如何构造 OpenTelemetry 的 ParentSpanId + +3. 如何在 OpenTelemetry Span 中保留 SkyWalking 的原始 TraceId、SegmentId、SpanId + +首先,我们来看如何构造 OpenTelemetry 的 TraceId 和 SpanId。SkyWalking 和 OpenTelemetry +都是通过 TraceId 串联起各个分布式服务调用,并通过 SpanId 来标记每一个 Span,但是实现规格有较大差异: + +!!! info + + 代码实现见 GitHub: + + 1. [Skywalking Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/skywalkingreceiver) + 2. [PR: Create skywalking component folder/structure](https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/8107) + 3. [PR: add Skywalking tracing receiver impl](https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/8549) + +具体来讲,SkyWalking TraceId 和 SegmentId 所有可能的格式如下: + +![sw2otel-01](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sw2otel-01.png) + +其中,在 OpenTelemetry 协议里,Span 在所有 Trace 中都是唯一的,而在 SkyWalking 中, +Span 仅在每个 Segment 里是唯一的,这说明要通过 SegmentId 与 SpanId 结合才能在 SkyWalking 中对 +Span 做唯一标识,并转换为 OpenTelemetry 的 SpanId。 + +!!! info + + 代码实现见 GitHub: + + 1. [Skywalking Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/skywalkingreceiver) + 2. [PR: Fix skywalking traceid and spanid convertion](https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/11562) + +接下来,我们来看如何构造 OpenTelemetry 的 ParentSpanId。在一个 Segment 内部, +SkyWalking 的 ParentSpanId 字段可直接用于构造 OpenTelemetry 的 ParentSpanId 字段。 +但当一个 Trace 跨多个 Segment 时,SkyWalking 是通过 Reference 中的 ParentTraceSegmentId +和 ParentSpanId 表示的关联信息,于是此时需要通过 Reference 中的信息构建 OpenTelemetry 的 ParentSpanId。 + +> 代码实现见 GitHub:[Skywalking Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/skywalkingreceiver) + +最后,我们来看如何在 OpenTelemetry Span 中保留 SkyWalking 的原始 TraceId、SegmentId、SpanId。 +我们携带这些原始信息是为了能将分布式追踪后端展现的 OpenTelemetry TraceId、SpanId 与应用程序日志中的 +SkyWalking TraceId、SegmentId、SpanId 进行关联,打通追踪和日志。我们选择将 SkyWalking 中原有的 +TraceId、SegmentId、ParentSegmentId 携带到 OpenTelemetry Attributes 中。 + +!!! info + + 代码实现见 GitHub: + + 1. 代码实现见 GitHub:[Skywalking Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/skywalkingreceiver) + 2. [Add extra link attributes from skywalking ref](https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/12651) + +经过上述一系列转换后,我们将 SkyWalking Segment Object 完整的转换为了 OpenTelmetry Trace,如下图: + +![sw2otel-02](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sw2otel-02.png) + +## 部署 Demo + +下面我们以一个 Demo 来展示使用 OpenTelemetry 收集、展示 SkyWalking 追踪数据的完整过程。 + +首先,在部署 OpenTelemetry Agent 之后,开启如下配置,即可在 OpenTelemetry 中拥有兼容 SkyWalking 协议的能力: + +```yaml +# otel-agent config +receivers: + # add the following config + skywalking: + protocols: + grpc: + endpoint: 0.0.0.0:11800 # 接收 SkyWalking Agent 上报的 Trace 数据 + http: + endpoint: 0.0.0.0:12800 # 接收从前端/ nginx 等 HTTP 协议上报的 Trace 数据 +service: + pipelines: + traces: + # add receiver __skywalking__ + receivers: [skywalking] + +# otel-agent service yaml +spec: + ports: + - name: sw-http + port: 12800 + protocol: TCP + targetPort: 12800 + - name: sw-grpc + port: 11800 + protocol: TCP + targetPort: 11800 +``` + +接下来需要将业务应用对接的 SkyWalking OAP Service(如 oap:11800)修改为 OpenTelemetry Agent Service(如 otel-agent:11800), +就可以开始使用 OpenTelemetry 接收 SkyWalking 探针的追踪数据了。 + +我们以 SkyWalking-showcase Demo 为例展示整个效果。它使用 SkyWalking Agent 做追踪,通过 OpenTelemetry 标准化处理后使用 Jaeger 来呈现最终效果: + +![sw2otel-03](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sw2otel-03.png) + +通过 SkyWalking Showcase 的架构图,可知 SkyWalking 的数据经过 OpenTelemetry 标准化后,依然完整。在这个 Trace 里, +请求从 app/homepage 发起,之后在 app 同时发起两个请求 /rcmd/与/songs/top,分发到 recommandation/songs 两个服务中, +并最终到达数据库进行查询,从而完成整个请求链路。 + +![sw2otel-04](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sw2otel-04.png) + +另外,我们也可从 Jaeger 页面中查看到原始 SkyWalking Id 信息,便于与应用日志关联: + +![sw2otel-05](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sw2otel-05.png) diff --git a/docs/zh/docs/admin/insight/best-practice/tail-based-sampling.md b/docs/zh/docs/admin/insight/best-practice/tail-based-sampling.md new file mode 100644 index 0000000..e422e74 --- /dev/null +++ b/docs/zh/docs/admin/insight/best-practice/tail-based-sampling.md @@ -0,0 +1,380 @@ +# 链路数据采样介绍与配置 + +使用分布式链路跟踪,可以在分布式系统中观察请求如何在各个系统中流转。不可否认,它非常实用,例如了解您的服务连接和诊断延迟问题,以及许多其他好处。 + +但是,如果您的大多数请求都成功了,并且没有出现不可接受的延迟或错误,那么您真的需要所有这些数据吗?所以,你并不总是需要大量或者全量的数据来找到正确的见解。您只需要通过恰当的数据采样即可。 + +采样背后的想法是控制发送到可观察性收集器的链路,从而降低采集成本。不同的组织有不同的原因,比如为什么要抽样,以及想要抽样什么杨的数据。所以,我们需要自定义采样策略: + +- 管理成本:如果需要存储大量的遥测数据,则需要付出更多的计算、存储成本。 +- 关注有趣的跟踪:不同组织关注的数据也不同。 +- 过滤掉噪音:例如,您可能希望过滤掉健康检查。 + +在讨论采样时使用一致的术语是很重要的。Trace 或 Span 被视为 **采样** 或 **未采样**: + +- 采样:Trace 或 Span 被处理并保存。为它被采样者选择为总体的代表,所以它被认为是 **采样的**。 +- 未采样:不被处理或保存的 Trace 或 Span。因为它不是由采样器选择的,所以被认为是 **未采样**。 + +## 采样的方式有哪些? + +### 头部采样(Head Sampling) + +头部抽样是一种用于尽早做出抽样决定的采样技术。采样或删除 Trace/Span 的决定不是通过检查整个 Trace 来做出的。 + +例如,最常见的头部采样形式是一致概率采样。它也可以称为确定性采样。在这种情况下,将根据 TraceID 和要采样的所需 Trace 百分比做出采样决策。这可确保以一致的速率(例如所有 Trace的 5%)对整个 Trace 进行采样并且不遗漏 Span。 + +头部采样的好处是: +- 易于理解 +- 易于配置 +- 高效 +- 可以在跟踪收集管道中的任何位置完成 + +头部采样的主要缺点是无法根据整个 Trace 中的数据做出采样决策。这意味着头部抽样作为一种钝器是有效的,但对于必须考虑整个系统信息的抽样策略来说,这是完全不够的。例如,无法使用头部采样来确保对所有具有误差的迹线进行采样。为此,您需要尾部采样。 + +### 尾部采样(Tail Sampling)—— 推荐方案 + +尾部采样是通过考虑 Trace 内的全部或大部分 Span 来决定对 Trace 进行采样。尾部采样允许您根据从 Trace 的不同部分使用的特定条件对 Trace 进行采样,而头部采样则不具有此选项。 + +如何使用尾部采样的一些示例包括: + +- 始终对包含错误的 Trace 进行采样 +- 基于总体延迟的采样 +- 根据 Trace 中一个或多个 Span 上特定属性的存在或值对 Trace 进行采样; 例如,对源自新部署的服务的更多 Trace 进行采样 +- 根据特定条件对 Trace 应用不同的采样率 + +正如你所看到的,尾部采样有着更高程度的复杂度。对于必须对遥测数据进行采样的大型系统,几乎总是需要使用尾部采样来平衡数据量和数据的有用性。 + +如今,尾部采样有三个主要缺点: + +- 尾部采样可能难以操作。实现尾部采样的组件必须是可以接受和存储大量数据的有状态系统。根据流量模式,这可能需要数十个甚至数百个节点,这些节点都以不同的方式利用资源。此外,如果尾部采样器无法跟上接收的数据量,则可能需要“回退”到计算密集度较低的采样技术。由于这些因素,监控尾部采样组件以确保它们拥有做出正确采样决策所需的资源至关重要。 +- 尾部采样可能难以实现。根据您可用的采样技术类型,它并不总是“一劳永逸”的事情。随着系统的变化,您的采样策略也会发生变化。对于大型而复杂的分布式系统,实现采样策略的规则也可以是庞大而复杂的。 +- 如今,尾部采样器通常最终属于供应商特定技术领域。如果您使用付费供应商来实现可观测性,则可用的最有效的尾部采样选项可能仅限于供应商提供的内容。 + +最后,对于某些系统,尾部采样可以与头部采样结合使用。例如,一组生成大量 Trace 数据的服务可能首先使用头部采样仅对一小部分跟踪进行采样,然后在遥测管道中稍后使用尾部采样在导出到后端之前做出更复杂的采样决策。这样做通常是为了保护遥测管道免于过载。 + +**AI 算力中心 Insight 目前推荐使用尾部采样并优先支持尾部采样。** + +尾部采样处理器根据一组定义的策略对链路进行采样。但是,链路的所有跨度(Span)必须由同一收集器实例接收,以做出有效的采样决策。 + +因此,需要对 Insight 的 Global Opentelemetry Collector 架构进行调整以实现尾部采样策略。 + +## Insight 具体改动 + +在全局服务集群中的 `insight-opentelemetry-collector` 前面引入具有负载均衡能力的 Opentelemetry Collector Gateway 组件,使得同一组 Trace 能够根据 TraceID 路由到同一个 Opentelemetry Collector 实例。 + +1. 部署具有负载均衡能力的 OTEL COL Gateway 组件 + + 如果您使用了 Insight 0.25.x 版本,可以通过如下 Helm Upgrade 参数 `--set opentelemetry-collector-gateway.enabled=true` 快速开启,以此跳过如下部署过程。 + + 参照以下 YAML 配置来部署。 + + ??? note "点击查看部署配置" + + ```yaml + kind: ClusterRole + apiVersion: rbac.authorization.k8s.io/v1 + metadata: + name: insight-otel-collector-gateway + rules: + - apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "watch", "list"] + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: insight-otel-collector-gateway + namespace: insight-system + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: insight-otel-collector-gateway + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: insight-otel-collector-gateway + subjects: + - kind: ServiceAccount + name: insight-otel-collector-gateway + namespace: insight-system + --- + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: insight-otel-collector-gateway + app.kubernetes.io/name: insight-otel-collector-gateway + name: insight-otel-collector-gateway-collector + namespace: insight-system + apiVersion: v1 + data: + collector.yaml: | + receivers: + otlp: + protocols: + grpc: + http: + jaeger: + protocols: + grpc: + processors: + + extensions: + health_check: + pprof: + endpoint: :1888 + zpages: + endpoint: :55679 + exporters: + logging: + loadbalancing: + routing_key: "traceID" + protocol: + otlp: + # all options from the OTLP exporter are supported + # except the endpoint + timeout: 1s + tls: + insecure: true + resolver: + k8s: + service: insight-opentelemetry-collector + ports: + - 4317 + service: + extensions: [pprof, zpages, health_check] + pipelines: + traces: + receivers: [otlp, jaeger] + exporters: [loadbalancing] + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: insight-otel-collector-gateway + app.kubernetes.io/name: insight-otel-collector-gateway + name: insight-otel-collector-gateway + namespace: insight-system + spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: insight-otel-collector-gateway + app.kubernetes.io/name: insight-otel-collector-gateway + template: + metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: insight-otel-collector-gateway + app.kubernetes.io/name: insight-otel-collector-gateway + spec: + containers: + - args: + - --config=/conf/collector.yaml + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + image: ghcr.m.daocloud.io/openinsight-proj/opentelemetry-collector-contrib:5baef686672cfe5551e03b5c19d3072c432b6f33 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: / + port: 13133 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: otc-container + resources: + limits: + cpu: '1' + memory: 2Gi + requests: + cpu: 100m + memory: 400Mi + ports: + - containerPort: 14250 + name: jaeger-grpc + protocol: TCP + - containerPort: 8888 + name: metrics + protocol: TCP + - containerPort: 4317 + name: otlp-grpc + protocol: TCP + - containerPort: 4318 + name: otlp-http + protocol: TCP + - containerPort: 55679 + name: zpages + protocol: TCP + + volumeMounts: + - mountPath: /conf + name: otc-internal + + serviceAccount: insight-otel-collector-gateway + serviceAccountName: insight-otel-collector-gateway + volumes: + - configMap: + defaultMode: 420 + items: + - key: collector.yaml + path: collector.yaml + name: insight-otel-collector-gateway-collector + name: otc-internal + --- + kind: Service + apiVersion: v1 + metadata: + name: insight-opentelemetry-collector-gateway + namespace: insight-system + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: insight-otel-collector-gateway + app.kubernetes.io/name: insight-otel-collector-gateway + spec: + ports: + - name: fluentforward + protocol: TCP + port: 8006 + targetPort: 8006 + - name: jaeger-compact + protocol: UDP + port: 6831 + targetPort: 6831 + - name: jaeger-grpc + protocol: TCP + port: 14250 + targetPort: 14250 + - name: jaeger-thrift + protocol: TCP + port: 14268 + targetPort: 14268 + - name: metrics + protocol: TCP + port: 8888 + targetPort: 8888 + - name: otlp + protocol: TCP + appProtocol: grpc + port: 4317 + targetPort: 4317 + - name: otlp-http + protocol: TCP + port: 4318 + targetPort: 4318 + - name: zipkin + protocol: TCP + port: 9411 + targetPort: 9411 + - name: zpages + protocol: TCP + port: 55679 + targetPort: 55679 + selector: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: insight-otel-collector-gateway + app.kubernetes.io/name: insight-otel-collector-gateway + ``` + +1. 配置尾部采样规则 + + !!! note + + 需要在原本 insight-otel-collector-config configmap 配置组中增加尾部采样(tail_sampling processors)的规则。 + +1. 在 `processor` 中增加如下内容,具体规则可调整;参考 [OTel 官方示例](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/README.md#a-practical-example)。 + + ```yaml + ........ + tail_sampling: + decision_wait: 10s # 等待 10 秒,超过 10 秒后的 traceid 将不再处理 + num_traces: 1500000 # 内存中保存的 trace 数,假设每秒 1000 条 trace,最小不低于 1000 * decision_wait * 2; + # 设置过大会占用过多的内存资源,过小会导致部分 trace 被 drop 掉 + expected_new_traces_per_sec: 10 + policies: # 上报策略 + [ + { + name: latency-policy, + type: latency, # 耗时超过 500ms 上报 + latency: {threshold_ms: 500} + }, + { + name: status_code-policy, + type: status_code, # 状态码为 ERROR 的上报 + status_code: {status_codes: [ ERROR ]} + } + ] + ...... + tail_sampling: # 组合采样 + decision_wait: 10s # 等待 10 秒,超过 10 秒后的 traceid 将不再处理 + num_traces: 1500000 # 内存中保存的 trace 数,假设每秒 1000 条 trace,最小不低于 1000 * decision_wait * 2; + # 设置过大会占用过多的内存资源,过小会导致部分 trace 被 drop 掉 + expected_new_traces_per_sec: 10 + policies: [ + { + name: debug-worker-cluster-sample-policy, + type: and, + and: + { + and_sub_policy: + [ + { + name: service-name-policy, + type: string_attribute, + string_attribute: + { key: k8s.cluster.id, values: [xxxxxxx] }, + }, + { + name: trace-status-policy, + type: status_code, + status_code: { status_codes: [ERROR] }, + }, + { + name: probabilistic-policy, + type: probabilistic, + probabilistic: { sampling_percentage: 1 }, + } + ] + } + } + ] + ``` + +1. 在 `insight-otel-collector-config` **configmap** 中的 otel col pipeline 中激活该 `processor`: + + ```yaml + traces: + exporters: + - servicegraph + - otlp/jaeger + processors: + - memory_limiter + - tail_sampling # 👈 + - batch + receivers: + - otlp + ``` + +1. 重启 `insight-opentelemetry-collector` 组件。 + +1. 部署或更新 Insight-agent,将链路数据的上报地址修改为 `opentelemetry-collector-gateway` LB 的 `4317` 端口地址。 + + ```yaml + .... + exporters: + otlp/global: + endpoint: insight-opentelemetry-collector-gateway.insight-system.svc.cluster.local:4317 # 👈 修改为 gateway/lb 地址 + ``` + +## 参考 +- [sampling](https://opentelemetry.io/docs/concepts/sampling/) diff --git a/docs/zh/docs/admin/insight/collection-manag/agent-status.md b/docs/zh/docs/admin/insight/collection-manag/agent-status.md new file mode 100644 index 0000000..9f74d17 --- /dev/null +++ b/docs/zh/docs/admin/insight/collection-manag/agent-status.md @@ -0,0 +1,36 @@ +# insight-agent 组件状态说明 + +在 AI 算力平台中可观测性 Insight 作为多集群观测产品,为了实现多集群观测数据的统一采集,需要用户安装 Helm 应用 __insight-agent__ +(默认安装在 insight-system 命名空间)。参阅[如何安装 __insight-agent__ ](../quickstart/install/install-agent.md)。 + +## 状态说明 + +在 __可观测性__ -> __采集管理__ 部分可查看各集群安装 __insight-agent__ 的情况。 + +- __未安装__ :该集群中未在 insight-system 命名空间下安装 __insight-agent__ +- __运行中__ :该集群中成功安装 __insight-agent__ ,且部署的所有组件均处于运行中状态 +- __异常__ :若 insight-agent 处于此状态,说明 helm 部署失败或存在部署的组件处于非运行中状态 + +可通过以下方式排查: + +1. 执行以下命令,若状态为 __deployed__ ,则执行下一步。若为 __failed__ ,由于会影响应用的升级,建议在 __容器管理 -> helm 应用__ 卸载后重新安装 : + + ```bash + helm list -n insight-system + ``` + +2. 执行以下命令或在 __可观测性 -> 采集管理__ 中查看该集群部署的组件的状态,若存在非 __运行中__ 状态的容器组,请重启异常的容器组。 + + ```bash + kubectl get pods -n insight-system + ``` + +## 补充说明 + +1. __insight-agent__ 中指标采集组件 Prometheus 的资源消耗与集群中运行的容器组数量存在正比关系, + 请根据集群规模调整 Prometheus 的资源,请参考:[Prometheus 资源规划](../quickstart/res-plan/prometheus-res.md) + +2. 由于全局服务集群中指标存储组件 vmstorage 的存储容量与各个集群容器组数量总和存在正比关系。 + + - 请联系平台管理员根据集群规模调整 vmstorage 的磁盘容量,参阅 [vmstorage 磁盘容量规划](../quickstart/res-plan/vms-res-plan.md) + - 根据多集群规模调整 vmstorage 磁盘,参阅 [vmstorge 磁盘扩容](../quickstart/res-plan/modify-vms-disk.md) diff --git a/docs/zh/docs/admin/insight/collection-manag/collection-manag.md b/docs/zh/docs/admin/insight/collection-manag/collection-manag.md new file mode 100644 index 0000000..f2994db --- /dev/null +++ b/docs/zh/docs/admin/insight/collection-manag/collection-manag.md @@ -0,0 +1,26 @@ +--- +hide: + - toc +--- + +# 采集管理 + + __采集管理__ 主要是集中管理、展示集群安装采集插件 __insight-agent__ 的入口,帮助用户快速的查看集群采集插件的健康状态,并提供了快捷入口配置采集规则。 + +具体操作步骤如下: + +1. 点击左上角的,选择 __可观测性__ 。 + + ![一级导航](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/collectmanage01.png){ width="1000"} + +2. 选择左侧导航栏的 __采集管理__ ,查看全部集群采集插件的状态。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/collect00.png){ width="1000"} + +3. 集群接入 __insight-agent__ 且处于运行中状态时,点击某个集群名称进入详情。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/collect01.png){ width="1000"} + +4. 在 __服务监控__ 页签中,点击快捷链接跳转到 __容器管理__ -> __自定义资源__ 添加服务发现规则。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/collect02.png){ width="1000"} diff --git a/docs/zh/docs/admin/insight/collection-manag/metric-collect.md b/docs/zh/docs/admin/insight/collection-manag/metric-collect.md new file mode 100644 index 0000000..0fd8003 --- /dev/null +++ b/docs/zh/docs/admin/insight/collection-manag/metric-collect.md @@ -0,0 +1,341 @@ +# 指标抓取方式 + +Prometheus 主要通过 Pull 的方式来抓取目标服务暴露出来的监控接口,因此需要配置对应的抓取任务来请求监控数据并写入到 Prometheus 提供的存储中,目前 Prometheus 服务提供了如下几个任务的配置: + +- 原生 Job 配置:提供 Prometheus 原生抓取 Job 的配置。 +- Pod Monitor:在 K8S 生态下,基于 Prometheus Operator 来抓取 Pod 上对应的监控数据。 +- Service Monitor:在 K8S 生态下,基于 Prometheus Operator 来抓取 Service 对应 Endpoints 上的监控数据。 + +!!! note + + `[ ]` 中的配置项为可选。 + +## 原生 Job 配置 + +相应配置项说明如下: + +```yaml +# 抓取任务名称,同时会在对应抓取的指标中加了一个 label(job=job_name) +job_name: + +# 抓取任务时间间隔 +[ scrape_interval: | default = ] + +# 抓取请求超时时间 +[ scrape_timeout: | default = ] + +# 抓取任务请求 URI 路径 +[ metrics_path: | default = /metrics ] + +# 解决当抓取的 label 与后端 Prometheus 添加 label 冲突时的处理。 +# true: 保留抓取到的 label,忽略与后端 Prometheus 冲突的 label; +# false: 对冲突的 label,把抓取的 label 前加上 exported_,添加后端 Prometheus 增加的 label; +[ honor_labels: | default = false ] + +# 是否使用抓取到 target 上产生的时间。 +# true: 如果 target 中有时间,使用 target 上的时间; +# false: 直接忽略 target 上的时间; +[ honor_timestamps: | default = true ] + +# 抓取协议: http 或者 https +[ scheme: | default = http ] + +# 抓取请求对应 URL 参数 +params: + [ : [, ...] ] + +# 通过 basic auth 设置抓取请求头中 `Authorization` 的值,password/password_file 互斥,优先取 password_file 里面的值。 +basic_auth: + [ username: ] + [ password: ] + [ password_file: ] + +# 通过 bearer token 设置抓取请求头中 `Authorization` bearer_token/bearer_token_file 互斥,优先取 bearer_token 里面的值。 +[ bearer_token: ] + +# 通过 bearer token 设置抓取请求头中 `Authorization` bearer_token/bearer_token_file 互斥,优先取 bearer_token 里面的值。 +[ bearer_token_file: ] + +# 抓取连接是否通过 TLS 安全通道,配置对应的 TLS 参数 +tls_config: + [ ] + +# 通过代理服务来抓取 target 上的指标,填写对应的代理服务地址。 +[ proxy_url: ] + +# 通过静态配置来指定 target,详见下面的说明。 +static_configs: + [ - ... ] + +# CVM 服务发现配置,详见下面的说明。 +cvm_sd_configs: + [ - ... ] + +# 在抓取数据之后,把 target 上对应的 label 通过 relabel 的机制进行改写,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明。 +relabel_configs: + [ - ... ] + +# 数据抓取完成写入之前,通过 relabel 机制进行改写 label 对应的值,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明。 +metric_relabel_configs: + [ - ... ] + +# 一次抓取数据点限制,0:不作限制,默认为 0 +[ sample_limit: | default = 0 ] + +# 一次抓取 Target 限制,0:不作限制,默认为 0 +[ target_limit: | default = 0 ] +``` + +## Pod Monitor + +相应配置项说明如下: + +```yaml +# Prometheus Operator CRD 版本 +apiVersion: monitoring.coreos.com/v1 +# 对应 K8S 的资源类型,这里面 Pod Monitor +kind: PodMonitor +# 对应 K8S 的 Metadata,这里只用关心 name,如果没有指定 jobLabel,对应抓取指标 label 中 job 的值为 / +metadata: + name: redis-exporter # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不需要修改 +# 描述抓取目标 Pod 的选取及抓取任务的配置 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识 +spec: + # 填写对应 Pod 的 label,pod monitor 会取对应的值作为 job label 的值。 + # 如果查看的是 Pod Yaml,取 pod.metadata.labels 中的值。 + # 如果查看的是 Deployment/Daemonset/Statefulset,取 spec.template.metadata.labels。 + [ jobLabel: string ] + # 把对应 Pod 上的 Label 添加到 Target 的 Label 中 + [ podTargetLabels: []string ] + # 一次抓取数据点限制,0:不作限制,默认为 0 + [ sampleLimit: uint64 ] + # 一次抓取 Target 限制,0:不作限制,默认为 0 + [ targetLimit: uint64 ] + # 配置需要抓取暴露的 Prometheus HTTP 接口,可以配置多个 Endpoint + podMetricsEndpoints: + [ - ... ] # 详见下面 endpoint 说明 + # 选择要监控 Pod 所在的 namespace,不填为选取所有 namespace + [ namespaceSelector: ] + # 是否选取所有 namespace + [ any: bool ] + # 需要选取 namespace 列表 + [ matchNames: []string ] + # 填写要监控 Pod 的 Label 值,以定位目标 Pod [K8S metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#labelselector-v1-meta) + selector: + [ matchExpressions: array ] + [ example: - {key: tier, operator: In, values: [cache]} ] + [ matchLabels: object ] + [ example: k8s-app: redis-exporter ] +``` + +### 举例 1 + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: redis-exporter # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不要修改 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识,必填。 +spec: + podMetricsEndpoints: + - interval: 30s + port: metric-port # 填写 pod yaml 中 Prometheus Exporter 对应的 Port 的 Name + path: /metrics # 填写 Prometheus Exporter 对应的 Path 的值,不填默认 /metrics + relabelings: + - action: replace + sourceLabels: + - instance + regex: (.*) + targetLabel: instance + replacement: "crs-xxxxxx" # 调整成对应的 Redis 实例 ID + - action: replace + sourceLabels: + - instance + regex: (.*) + targetLabel: ip + replacement: "1.x.x.x" # 调整成对应的 Redis 实例 IP + namespaceSelector: # 选择要监控 Pod 所在的 namespace + matchNames: + - redis-test + selector: # 填写要监控 Pod 的 Label 值,以定位目标 pod + matchLabels: + k8s-app: redis-exporter +``` + +### 举例 2 + +```yaml +job_name: prometheus +scrape_interval: 30s +static_configs: +- targets: + - 127.0.0.1:9090 +``` + +## Service Monitor + +相应配置项说明如下: + +```yaml +# Prometheus Operator CRD 版本 +apiVersion: monitoring.coreos.com/v1 +# 对应 K8S 的资源类型,这里面 Service Monitor +kind: ServiceMonitor +# 对应 K8S 的 Metadata,这里只用关心 name,如果没有指定 jobLabel,对应抓取指标 label 中 job 的值为 Service 的名称。 +metadata: + name: redis-exporter # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不需要修改 +# 描述抓取目标 Pod 的选取及抓取任务的配置 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识,必填。 +spec: + # 填写对应 Pod 的 label(metadata/labels),service monitor 会取对应的值作为 job label 的值 + [ jobLabel: string ] + # 把对应 service 上的 Label 添加到 Target 的 Label 中 + [ targetLabels: []string ] + # 把对应 Pod 上的 Label 添加到 Target 的 Label 中 + [ podTargetLabels: []string ] + # 一次抓取数据点限制,0:不作限制,默认为 0 + [ sampleLimit: uint64 ] + # 一次抓取 Target 限制,0:不作限制,默认为 0 + [ targetLimit: uint64 ] + # 配置需要抓取暴露的 Prometheus HTTP 接口,可以配置多个 Endpoint + endpoints: + [ - ... ] # 详见下面 endpoint 说明 + # 选择要监控 Pod 所在的 namespace,不填为选取所有 namespace + [ namespaceSelector: ] + # 是否选取所有 namespace + [ any: bool ] + # 需要选取 namespace 列表 + [ matchNames: []string ] + # 填写要监控 Pod 的 Label 值,以定位目标 Pod [K8S metav1.LabelSelector](https://v1-17.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) + selector: + [ matchExpressions: array ] + [ example: - {key: tier, operator: In, values: [cache]} ] + [ matchLabels: object ] + [ example: k8s-app: redis-exporter ] +``` + +### 举例 + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: go-demo # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不要修改 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识,必填。 +spec: + endpoints: + - interval: 30s + # 填写 service yaml 中 Prometheus Exporter 对应的 Port 的 Name + port: 8080-8080-tcp + # 填写 Prometheus Exporter 对应的 Path 的值,不填默认 /metrics + path: /metrics + relabelings: + # ** 必须要有一个 label 为 application,这里假设 k8s 有一个 label 为 app, + # 我们通过 relabel 的 replace 动作把它替换成了 application + - action: replace + sourceLabels: [__meta_kubernetes_pod_label_app] + targetLabel: application + # 选择要监控 service 所在的 namespace + namespaceSelector: + matchNames: + - golang-demo + # 填写要监控 service 的 Label 值,以定位目标 service + selector: + matchLabels: + app: golang-app-demo +``` + +### endpoint_config + +相应配置项说明如下: + +```yaml +# 对应 port 的名称,这里需要注意不是对应的端口,默认:80,对应的取值如下: +# ServiceMonitor: 对应 Service>spec/ports/name; +# PodMonitor: 说明如下: +# 如果查看的是 Pod Yaml,取 pod.spec.containers.ports.name 中的值。 +# 如果查看的是 Deployment/Daemonset/Statefulset,取值 spec.template.spec.containers.ports.name +[ port: string | default = 80] +# 抓取任务请求 URI 路径 +[ path: string | default = /metrics ] +# 抓取协议: http 或者 https +[ scheme: string | default = http] +# 抓取请求对应 URL 参数 +[ params: map[string][]string] +# 抓取任务间隔的时间 +[ interval: string | default = 30s ] +# 抓取任务超时 +[ scrapeTimeout: string | default = 30s] +# 抓取连接是否通过 TLS 安全通道,配置对应的 TLS 参数 +[ tlsConfig: TLSConfig ] +# 通过对应的文件读取 bearer token 对应的值,放到抓取任务的 header 中 +[ bearerTokenFile: string ] +# 通过对应的 K8S secret key 读取对应的 bearer token,注意 secret namespace 需要和 PodMonitor/ServiceMonitor 相同 +[ bearerTokenSecret: string ] +# 解决当抓取的 label 与后端 Prometheus 添加 label 冲突时的处理。 +# true: 保留抓取到的 label,忽略与后端 Prometheus 冲突的 label; +# false: 对冲突的 label,把抓取的 label 前加上 exported_,添加后端 Prometheus 增加的 label; +[ honorLabels: bool | default = false ] +# 是否使用抓取到 target 上产生的时间。 +# true: 如果 target 中有时间,使用 target 上的时间; +# false: 直接忽略 target 上的时间; +[ honorTimestamps: bool | default = true ] +# basic auth 的认证信息,username/password 填写对应 K8S secret key 的值,注意 secret namespace 需要和 PodMonitor/ServiceMonitor 相同。 +[ basicAuth: BasicAuth ] +# 通过代理服务来抓取 target 上的指标,填写对应的代理服务地址 +[ proxyUrl: string ] +# 在抓取数据之后,把 target 上对应的 label 通过 relabel 的机制进行改写,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明 +relabelings: +[ - ...] +# 数据抓取完成写入之前,通过 relabel 机制进行改写 label 对应的值,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明 +metricRelabelings: +[ - ...] +``` + +### relabel_config + +相应配置项说明如下: + +```yaml +# 从原始 labels 中取哪些 label 的值进行 relabel,取出来的值通过 separator 中的定义进行字符拼接。 +# 如果是 PodMonitor/ServiceMonitor 对应的配置项为 sourceLabels +[ source_labels: '[' [, ...] ']' ] +# 定义需要 relabel 的 label 值拼接的字符,默认为 ';' +[ separator: | default = ; ] + +# action 为 replace/hashmod 时,通过 target_label 来指定对应 label name。 +# 如果是 PodMonitor/ServiceMonitor 对应的配置项为 targetLabel +[ target_label: ] + +# 需要对 source labels 对应值进行正则匹配的表达式 +[ regex: | default = (.*) ] + +# action 为 hashmod 时用到,根据 source label 对应值 md5 取模值 +[ modulus: ] + +# action 为 replace 的时候,通过 replacement 来定义当 regex 匹配之后需要替换的表达式,可以结合 regex 正规则表达式替换 +[ replacement: | default = $1 ] + +# 基于 regex 匹配到的值进行相关的操作,对应的 action 如下,默认为 replace: +# replace: 如果 regex 匹配到,通过 replacement 中定义的值替换相应的值,并通过 target_label 设值并添加相应的 label +# keep: 如果 regex 没有匹配到,丢弃 +# drop: 如果 regex 匹配到,丢弃 +# hashmod: 通过 moduels 指定的值把 source label 对应的 md5 值取模 +# 并添加一个新的 label,label name 通过 target_label 指定 +# labelmap: 如果 regex 匹配到,使用 replacement 替换对就的 label name +# labeldrop: 如果 regex 匹配到,删除对应的 label +# labelkeep: 如果 regex 没有匹配到,删除对应的 label +[ action: | default = replace ] +``` diff --git a/docs/zh/docs/admin/insight/collection-manag/probe-module.md b/docs/zh/docs/admin/insight/collection-manag/probe-module.md new file mode 100644 index 0000000..ce98720 --- /dev/null +++ b/docs/zh/docs/admin/insight/collection-manag/probe-module.md @@ -0,0 +1,309 @@ +# 自定义探测方式 + +Insight 使用 Prometheus 官方提供的 Blackbox Exporter 作为黑盒监控解决方案,可以通过 HTTP、HTTPS、DNS、ICMP、TCP 和 gRPC 方式对目标实例进行检测。可用于以下使用场景: + +- HTTP/HTTPS:URL/API可用性检测 +- ICMP:主机存活检测 +- TCP:端口存活检测 +- DNS:域名解析 + +在本文中,我们将介绍如何在已有的 Blackbox ConfigMap 中配置自定义的探测方式。 + +Insight 默认未开启 ICMP 探测方式,因为 ICMP 需要更高权限,因此,我们将以 ICMP 和 HTTP 探测方式作为示例,展示如何修改 ConfigMap 以实现自定义的 ICMP 和 HTTP 探测。 + +## 操作步骤 + +1. 进入 __容器管理__ 的 __集群列表__ ,点击进入目标集群的详情; +2. 点击左侧导航,选择 __配置与密钥__ -> __配置项__ ; +3. 找到名为 __insight-agent-prometheus-blackbox-exporter__ 的配置项,点击 __编辑 YAML__; + + 在 __modules__ 下添加自定义探测方式: + +=== "HTTP 探测" + + ```yaml + module: + http_2xx: + prober: http + timeout: 5s + http: + valid_http_versions: [HTTP/1.1, HTTP/2] + valid_status_codes: [] # Defaults to 2xx + method: GET + ``` + +=== "ICMP 探测" + + ```yaml + module: + ICMP: # ICMP 探测配置的示例 + prober: icmp + timeout: 5s + icmp: + preferred_ip_protocol: ip4 + icmp_example: # ICMP 探测配置的示例 2 + prober: icmp + timeout: 5s + icmp: + preferred_ip_protocol: "ip4" + source_ip_address: "127.0.0.1" + ``` + 由于 ICMP 需要更高权限,因此,我们还需要提升 Pod 权限,否则会出现 `operation not permitted` 的错误。有以下两种方式提升权限: + + - 方式一: 直接编辑 `BlackBox Exporter` 部署文件开启 + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: insight-agent-prometheus-blackbox-exporter + namespace: insight-system + spec: + template: + spec: + containers: + - name: blackbox-exporter + image: # ... (image, args, ports 等保持不变) + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_RAW + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + ``` + + - 方式二: 通过 Helm Upgrade 方式提权 + + ```diff + prometheus-blackbox-exporter: + enabled: true + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + runAsNonRoot: false + allowPrivilegeEscalation: false + capabilities: + add: ["NET_RAW"] + ``` + +!!! info + + 更多探测方式可参考 [blackbox_exporter Configuration](https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md)。 + +## 其他参考 + +以下 YAML 文件中包含了 HTTP、TCP、SMTP、ICMP、DNS 等多种探测方式,可根据需求自行修改 `insight-agent-prometheus-blackbox-exporter` 的配置文件。 + +??? note "点击查看完整的 YAML 文件" + + ```yaml + kind: ConfigMap + apiVersion: v1 + metadata: + name: insight-agent-prometheus-blackbox-exporter + namespace: insight-system + labels: + app.kubernetes.io/instance: insight-agent + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-blackbox-exporter + app.kubernetes.io/version: v0.24.0 + helm.sh/chart: prometheus-blackbox-exporter-8.8.0 + annotations: + meta.helm.sh/release-name: insight-agent + meta.helm.sh/release-namespace: insight-system + data: + blackbox.yaml: | + modules: + HTTP_GET: + prober: http + timeout: 5s + http: + method: GET + valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] + follow_redirects: true + preferred_ip_protocol: "ip4" + HTTP_POST: + prober: http + timeout: 5s + http: + method: POST + body_size_limit: 1MB + TCP: + prober: tcp + timeout: 5s + # 默认未开启: + # ICMP: + # prober: icmp + # timeout: 5s + # icmp: + # preferred_ip_protocol: ip4 + SSH: + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "^SSH-2.0-" + POP3S: + prober: tcp + tcp: + query_response: + - expect: "^+OK" + tls: true + tls_config: + insecure_skip_verify: false + http_2xx_example: # http 探测示例 + prober: http + timeout: 5s # 探测的超时时间 + http: + valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] # 返回信息中的 Version,一般默认即可 + valid_status_codes: [] # Defaults to 2xx # 有效的返回码范围,如果请求的返回码在该范围内,视为探测成功 + method: GET # 请求方法 + headers: # 请求的头部 + Host: vhost.example.com + Accept-Language: en-US + Origin: example.com + no_follow_redirects: false # 是否允许重定向 + fail_if_ssl: false + fail_if_not_ssl: false + fail_if_body_matches_regexp: + - "Could not connect to database" + fail_if_body_not_matches_regexp: + - "Download the latest version here" + fail_if_header_matches: # Verifies that no cookies are set + - header: Set-Cookie + allow_missing: true + regexp: '.*' + fail_if_header_not_matches: + - header: Access-Control-Allow-Origin + regexp: '(\*|example\.com)' + tls_config: # 针对 https 请求的 tls 的配置 + insecure_skip_verify: false + preferred_ip_protocol: "ip4" # defaults to "ip6" # 首选的 IP 协议版本 + ip_protocol_fallback: false # no fallback to "ip6" + http_post_2xx: # 带 Body 的 http 探测的示例 + prober: http + timeout: 5s + http: + method: POST # 探测的请求方法 + headers: + Content-Type: application/json + body: '{"username":"admin","password":"123456"}' # 探测时携带的 body + http_basic_auth_example: # 带用户名密码的探测的示例 + prober: http + timeout: 5s + http: + method: POST + headers: + Host: "login.example.com" + basic_auth: # 探测时要加的用户名密码 + username: "username" + password: "mysecret" + http_custom_ca_example: + prober: http + http: + method: GET + tls_config: # 指定探测时使用的根证书 + ca_file: "/certs/my_cert.crt" + http_gzip: + prober: http + http: + method: GET + compression: gzip # 探测时使用的压缩方法 + http_gzip_with_accept_encoding: + prober: http + http: + method: GET + compression: gzip + headers: + Accept-Encoding: gzip + tls_connect: # TCP 探测的示例 + prober: tcp + timeout: 5s + tcp: + tls: true # 是否使用 TLS + tcp_connect_example: + prober: tcp + timeout: 5s + imap_starttls: # 探测 IMAP 邮箱服务器的配置示例 + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "OK.*STARTTLS" + - send: ". STARTTLS" + - expect: "OK" + - starttls: true + - send: ". capability" + - expect: "CAPABILITY IMAP4rev1" + smtp_starttls: # 探测 SMTP 邮箱服务器的配置示例 + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "^220 ([^ ]+) ESMTP (.+)$" + - send: "EHLO prober\r" + - expect: "^250-STARTTLS" + - send: "STARTTLS\r" + - expect: "^220" + - starttls: true + - send: "EHLO prober\r" + - expect: "^250-AUTH" + - send: "QUIT\r" + irc_banner_example: + prober: tcp + timeout: 5s + tcp: + query_response: + - send: "NICK prober" + - send: "USER prober prober prober :prober" + - expect: "PING :([^ ]+)" + send: "PONG ${1}" + - expect: "^:[^ ]+ 001" + # icmp_example: # ICMP 探测配置的示例 + # prober: icmp + # timeout: 5s + # icmp: + # preferred_ip_protocol: "ip4" + # source_ip_address: "127.0.0.1" + dns_udp_example: # 使用 UDP 进行 DNS 查询的示例 + prober: dns + timeout: 5s + dns: + query_name: "www.prometheus.io" # 要解析的域名 + query_type: "A" # 该域名对应的类型 + valid_rcodes: + - NOERROR + validate_answer_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + fail_if_all_match_regexp: + - ".*127.0.0.1" + fail_if_not_matches_regexp: + - "www.prometheus.io.\t300\tIN\tA\t127.0.0.1" + fail_if_none_matches_regexp: + - "127.0.0.1" + validate_authority_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + validate_additional_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + dns_soa: + prober: dns + dns: + query_name: "prometheus.io" + query_type: "SOA" + dns_tcp_example: # 使用 TCP 进行 DNS 查询的示例 + prober: dns + dns: + transport_protocol: "tcp" # defaults to "udp" + preferred_ip_protocol: "ip4" # defaults to "ip6" + query_name: "www.prometheus.io" + ``` diff --git a/docs/zh/docs/admin/insight/collection-manag/service-monitor.md b/docs/zh/docs/admin/insight/collection-manag/service-monitor.md new file mode 100644 index 0000000..05128c3 --- /dev/null +++ b/docs/zh/docs/admin/insight/collection-manag/service-monitor.md @@ -0,0 +1,67 @@ +# 配置服务发现规则 + +可观测 Insight 支持通过 __容器管理__ 创建 CRD ServiceMonitor 的方式来满足您自定义服务发现的采集需求。 +用户可以通过使用 ServiceMonitor 自行定义 Pod 发现的 Namespace 范围以及通过 __matchLabel__ 来选择监听的 Service。 + +## 前提条件 + +集群已安装 Helm 应用 __insight-agent__ 且处于 __运行中__ 状态。 + +## 操作步骤 + +1. 选择左侧导航栏的 __采集管理__ ,查看全部集群采集插件的状态。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/collectmanage02.png) + +2. 点击列表中的某个集群名称进入采集配置详情。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/service-discover.png) + +3. 点击链接跳转到 __容器管理__ 中创建 Service Monitor。 + + ```yaml + apiVersion: monitoring.coreos.com/v1 + kind: ServiceMonitor + metadata: + name: micrometer-demo # (1) + namespace: insight-system # (2) + labels: + operator.insight.io/managed-by: insight + spec: + endpoints: # (3) + - honorLabels: true + interval: 15s + path: /actuator/prometheus + port: http + namespaceSelector: # (4) + matchNames: + - insight-system # (5) + selector: # (6) + matchLabels: + micrometer-prometheus-discovery: "true" + ``` + + 1. 指定 ServiceMonitor 的名称 + 2. 指定 ServiceMonitor 的命名空间 + 3. 这是服务端点,代表 Prometheus 所需的采集 Metrics 的地址。 __endpoints__ 为一个数组, + 同时可以创建多个 __endpoints__ 。每个 __endpoints__ 包含三个字段,每个字段的含义如下: + + - __interval__ :指定 Prometheus 对当前 __endpoints__ 采集的周期。单位为秒,在本次示例中设定为 __15s__ 。 + - __path__ :指定 Prometheus 的采集路径。在本次示例中,指定为 __/actuator/prometheus__ 。 + - __port__ :指定采集数据需要通过的端口,设置的端口为采集的 Service 端口所设置的 __name__ 。 + + 4. 这是需要发现的 Service 的范围。 __namespaceSelector__ 包含两个互斥字段,字段的含义如下: + + - __any__ :有且仅有一个值 __true__ ,当该字段被设置时,将监听所有符合 Selector 过滤条件的 Service 的变动。 + - __matchNames__ :数组值,指定需要监听的 __namespace__ 的范围。例如,只想监听 default 和 insight-system + 两个命名空间中的 Service,那么 __matchNames__ 设置如下: + + ```yaml + namespaceSelector: + matchNames: + - default + - insight-system + ``` + + 5. 此处匹配的命名空间为需要暴露指标的应用所在的命名空间 + 6. 用于选择 Service diff --git a/docs/zh/docs/admin/insight/compati-test/k8s-compatibility.md b/docs/zh/docs/admin/insight/compati-test/k8s-compatibility.md new file mode 100644 index 0000000..8975010 --- /dev/null +++ b/docs/zh/docs/admin/insight/compati-test/k8s-compatibility.md @@ -0,0 +1,39 @@ +--- +hide: + - toc +--- + +# Kubernetes 集群兼容性测试 + +✅:测试通过; ❌:测试未通过;空:未进行测试; + +## Insight Server 的 Kubernetes 兼容性测试 + +| 场景 | 测试方式 | K8s 1.31 | K8s 1.30 | K8s 1.29 | K8s 1.28 | K8s 1.27 | K8s 1.26 | k8s 1.25.0 | k8s 1.24 | k8s 1.23 | k8s 1.22 | +| ----- | ------- | -------- | -------- | -------- | -------- | -------- | -------- | --------- | --------- | --------- |--------- | +| 基线场景 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| 指标查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| 日志查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| 链路查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| 告警中心 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| 拓扑查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +## Insight Agent 的 Kubernetes 兼容性测试 + +| 场景 | 测试方式 | K8s 1.31 | K8s 1.30 | K8s 1.29 | K8s 1.28 | K8s 1.27 | K8s 1.26 | k8s 1.25 | k8s 1.24 | k8s 1.23 | k8s 1.22 | k8s 1.21 | k8s 1.20 | k8s 1.19 | k8s 1.18 | k8s 1.17 | k8s 1.16 | +| ----- | ------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |--------- |--------- |--------- |--------- |--------- |--------- | +| 基线场景 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +| 指标查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +| 日志查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +| 链路查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +| 告警中心 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +| 拓扑查询 | E2E | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | + +!!! note + + **Insight Agent 版本兼容历史:** + + 1. Insight Agent 从 v0.16.x 开始不兼容 k8s v1.16.15 + 2. Insight Agent v0.20.0 兼容 k8s v1.18.20 + 3. Insight Agent v0.19.2/v0.18.2/v0.17.x 不兼容 k8s v1.18.20 + 4. Insight Agent v0.30.1 不兼容 k8s v1.18.x 及 以下版本 diff --git a/docs/zh/docs/admin/insight/compati-test/ocp-compatibility.md b/docs/zh/docs/admin/insight/compati-test/ocp-compatibility.md new file mode 100644 index 0000000..cd6b505 --- /dev/null +++ b/docs/zh/docs/admin/insight/compati-test/ocp-compatibility.md @@ -0,0 +1,38 @@ +# Openshift 4.x 集群兼容性测试 + +✅:测试通过; ❌:测试未通过。 + +!!! note + + 表格中的测试功能非全量。 + +| case | 测试方式 | ocp4.10(k8s 1.23.0) |备注 | +| ------------ | ---------------- |--------- |--------- | +| 采集并查询 web 应用的指标 | 手工 | ✅| | +| 添加自定义指标采集 | 手工 | ✅| | +| 查询实时指标 | 手工 | ✅| | +| 瞬时指标查询 | 手工 | ✅| | +| 瞬时指标api字段功能验证 | 手工 | ✅| | +| 查询一段时间内指标 | 手工 | ✅| | +| 查询一段时间内指标 api 字段功能验证 | 手工 | ✅| | +| 批量查询集群CPU、内存使用率、集群 CPU 总量、集群内存使用量,集群节点总数 | 手工 | ✅| | +| 批量查询节点CPU、内存使用率、节点 CPU 总量、节点内存使用量 | 手工 | ✅| | +| 批量查询一段时间内的集群CPU、内存使用率、集群 CPU 总量、集群内存使用量,集群节点总数 | 手工 | ✅| | +| 批量查询查询一段时间内指标 api 字段功能验证 | 手工 | ✅ || +| 查询 Pod 日志 | 手工 | ✅| | +| 查询 SVC 日志 | 手工 | ✅| | +| 查询 statefulset 日志 | 手工 | ✅| | +| 查询 Deployment 日志 | 手工 | ✅| | +| 查询 NPD 日志 | 手工 | ✅| | +| 日志筛选 | 手工 | ✅| | +| 日志模糊查询-workloadSearch | 手工 | ✅| | +| 日志模糊查询-podSearch | 手工 | ✅| | +| 日志模糊查询-containerSearch | 手工 | ✅| | +| 日志精确查询-cluster | 手工 | ✅| | +| 日志精确查询-namespace | 手工 | ✅| | +| 日志查询 api 字段功能验证 | 手工 | ✅| | +| 告警规则-增删改查 | 手工 | ✅ || +| 告警模板-增删改查 | 手工 | ✅ || +| 通知方式-增删改查 | 手工 | ✅ || +| 链路查询 | 手工 | ✅ || +| 拓扑查询 | 手工 | ✅ || \ No newline at end of file diff --git a/docs/zh/docs/admin/insight/compati-test/rancher-compatibility.md b/docs/zh/docs/admin/insight/compati-test/rancher-compatibility.md new file mode 100644 index 0000000..5f421be --- /dev/null +++ b/docs/zh/docs/admin/insight/compati-test/rancher-compatibility.md @@ -0,0 +1,38 @@ +# Rancher 集群兼容性测试 + +✅:测试通过; ❌:测试未通过。 + +!!! note + + 表格中的测试功能非全量。 + +| case | | 测试方式 | Rancher rke2c1(k8s 1.24.11) |备注 | +| ------------ | ------------------------ | ---------------- |--------- |--------- | +| 采集并查询 web 应用的指标 | | 手工 | ✅| | +| 添加自定义指标采集 | | 手工 | ✅| | +| 查询实时指标 | | 手工 | ✅| | +| 查询瞬时指标 | | 手工 | ✅| | +| 验证查询瞬时指标 API 接口 | | 手工 | ✅| | +| 查询一段时间内指标 | | 手工 | ✅| | +| 验证查询一段时间内指标 API 接口 | | 手工 | ✅| | +| 批量查询集群 CPU、内存使用率、集群 CPU 总量、集群内存使用量,集群节点总数 | | 手工 | ✅| | +| 批量查询节点 CPU、内存使用率、节点 CPU 总量、节点内存使用量 | | 手工 | ✅| | +| 批量查询一段时间内的集群 CPU、内存使用率、集群 CPU 总量、集群内存使用量,集群节点总数 | | 手工 | ✅| | +| 验证批量查询一段时间内指标 API 接口 | | 手工 | ✅ || +| 查询 Pod 日志 | | 手工 | ✅| | +| 查询 SVC 日志 | | 手工 | ✅| | +| 查询 statefulset 日志 | | 手工 | ✅| | +| 查询 Deployment 日志 | | 手工 | ✅| | +| 查询 NPD 日志 | | 手工 | ✅| | +| 筛选日志 | | 手工 | ✅| | +| 模糊查询日志-workloadSearch | | 手工 | ✅| | +| 模糊查询日志-podSearch | | 手工 | ✅| | +| 模糊查询日志-containerSearch | | 手工 | ✅| | +| 精确查询日志-cluster | | 手工 | ✅| | +| 精确查询日志-namespace | | 手工 | ✅| | +| 验证查询日志 API 接口 | | 手工 | ✅| | +| 告警规则 - 增删改查 | | 手工 | ✅ || +| 告警模板 - 增删改查 | | 手工 | ✅ || +| 通知方式 - 增删改查 | | 手工 | ✅ || +| 链路查询 | | 手工 | ✅ || +| 拓扑查询 | | 手工 | ✅ || diff --git a/docs/zh/docs/admin/insight/dashboard/dashboard.md b/docs/zh/docs/admin/insight/dashboard/dashboard.md new file mode 100644 index 0000000..bf73f0d --- /dev/null +++ b/docs/zh/docs/admin/insight/dashboard/dashboard.md @@ -0,0 +1,32 @@ +--- +hide: + - toc +--- + +# 仪表盘 + +Grafana 是一种开源的数据可视化和监控平台,它提供了丰富的图表和面板,用于实时监控、分析和可视化各种数据源的指标和日志。可观测性 Insight 使用开源 Grafana 提供监控服务,支持从集群、节点、命名空间等多维度查看资源消耗情况, + +关于开源 Grafana 的详细信息,请参见 [Grafana 官方文档](https://grafana.com/docs/grafana/latest/getting-started/?spm=a2c4g.11186623.0.0.1f34de53ksAH9a)。 + +## 操作步骤 + +1. 在左侧导航栏选择 __仪表盘__ 。 + + - 在 __Insight /概览__ 仪表盘中,可查看多选集群的资源使用情况,并以命名空间、容器组等多个维度分析了资源使用、网络、存储等情况。 + + - 点击仪表盘左上侧的下拉框可切换集群。 + + - 点击仪表盘右下侧可切换查询的时间范围。 + + ![dashboard](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/dashboard00.png){ width="1000"} + +2. Insight 精选多个社区推荐仪表盘,可从节点、命名空间、工作负载等多个维度进行监控。点击 __insight-system / Insight /概览__ 区域切换仪表盘。 + + ![dashboard](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/dashboard01.png){ width="1000"} + +!!! note + + 1. 访问 Grafana UI 请参考[以管理员身份登录 Grafana](./login-grafana.md)。 + + 2. 导入自定义仪表盘请参考[导入自定义仪表盘](./import-dashboard.md)。 diff --git a/docs/zh/docs/admin/insight/dashboard/import-dashboard.md b/docs/zh/docs/admin/insight/dashboard/import-dashboard.md new file mode 100644 index 0000000..299468f --- /dev/null +++ b/docs/zh/docs/admin/insight/dashboard/import-dashboard.md @@ -0,0 +1,65 @@ +# 导入自定义仪表盘 + +通过使用 Grafana CRD,可以将仪表板的管理和部署纳入到 Kubernetes 的生命周期管理中,实现仪表板的版本控制、自动化部署和集群级的管理。本页介绍如何通过 CRD 和 UI 界面导入自定义的仪表盘。 + +## 操作步骤 + +1. 登录 AI 算力平台 平台,进入 __容器管理__ ,在集群列表中选择 __kpanda-global-cluster__ 。 + +2. 选择左侧导航栏的 __自定义资源__ ,在列表中查找 __grafanadashboards.integreatly.org__ 文件,进入详情。 + + ![导入仪表盘](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/importboard00.png){ width="1000"} + +3. 点击 __Yaml 创建__ ,使用以下模板,在 __Json__ 字段中替换仪表盘 JSON。 + + - __namespace__ :填写目标命名空间; + - __name__ :填写仪表盘的名称。 + - __label__ :必填, __operator.insight.io/managed-by: insight__ 。 + + ```yaml + apiVersion: integreatly.org/v1alpha1 + kind: GrafanaDashboard + metadata: + labels: + app: insight-grafana-operator + operator.insight.io/managed-by: insight + name: sample-dashboard + namespace: insight-system + spec: + json: > + { + "id": null, + "title": "Simple Dashboard", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "graphTooltip": 1, + "panels": [], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "time_options": [], + "refresh_intervals": [] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": "5s", + "schemaVersion": 17, + "version": 0, + "links": [] + } + ``` + +4. 点击 __确认__ 后,稍等片刻即可在 __仪表盘__ 中查看刚刚导入的仪表盘。 + +!!! info + + 自定义设计仪表盘,请参考[添加仪表盘面板](https://grafana.com/docs/grafana/latest/dashboards/add-organize-panels/)。 diff --git a/docs/zh/docs/admin/insight/dashboard/login-grafana.md b/docs/zh/docs/admin/insight/dashboard/login-grafana.md new file mode 100644 index 0000000..5bf6696 --- /dev/null +++ b/docs/zh/docs/admin/insight/dashboard/login-grafana.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 访问原生 Grafana + +Insight 借助 Grafana 提供了丰富的可视化能力,同时保留了访问原生 Grafana 的入口。 + +## 操作步骤 + +1. 登录浏览器,在浏览器中输入 Grafana 地址。 + + 访问地址: `http://ip:访问端口/ui/insight-grafana/login` + + 例如: `http://10.6.10.233:30209/ui/insight-grafana/login` + +2. 点击右下角的登录,使用默认用户名、密码(admin/admin)进行登录。 + + ![登录 grafana](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/grafana02.png){ width=1000px} + +3. 点击 __Log in__ 完成登录。 + + ![成功登录 grafana](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/grafana03.png){ width=1000px} diff --git a/docs/zh/docs/admin/insight/dashboard/overview.md b/docs/zh/docs/admin/insight/dashboard/overview.md new file mode 100644 index 0000000..bfdfb03 --- /dev/null +++ b/docs/zh/docs/admin/insight/dashboard/overview.md @@ -0,0 +1,20 @@ +--- +hide: + - toc +--- + +# 概览 + + __概率__ 仅统计已安装 __insight-agent__ 且其运行状态为正常的集群数据。可在概览中多集群的资源概况: + +- 告警统计:可查看所有集群的正在告警的统计数据。 +- 资源消耗:可按 CPU 使用率、内存使用率和磁盘使用率分别查看近一小时 TOP5 集群、节点的资源变化趋势。 +- 默认按照根据 CPU 使用率排序。您可切换指标切换集群、节点的排序方式。 +- 资源变化趋势:可查看近 15 天的节点个数趋势以及一小时 Pod 的运行趋势。 +- 服务请求排行:可查看多集群中请求延时、错误率排行 TOP5 的服务及所在集群和命名空间。 + +## 操作步骤 + +在左边导航栏选择 __概览__ 。 + +![概览](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/overview.png){ width="1000"} diff --git a/docs/zh/docs/admin/insight/data-query/log.md b/docs/zh/docs/admin/insight/data-query/log.md new file mode 100644 index 0000000..44ed51f --- /dev/null +++ b/docs/zh/docs/admin/insight/data-query/log.md @@ -0,0 +1,56 @@ +# 日志查询 + +Insight 默认采集节点日志、容器日志以及 kubernetes 审计日志。在日志查询页面中,可查询登录账号权限内的标准输出 (stdout) 日志,包括节点日志、产品日志、Kubenetes 审计日志等,快速在大量日志中查询到所需的日志,同时结合日志的来源信息和上下文原始数据辅助定位问题。 + +## 操作步骤 + +1. 点击一级导航栏进入 __可观测性__ 。 +2. 左侧导航栏中,选择 __日志__ 。 + + - 默认查询最近 24 小时; + - 第一次进入时,默认根据登录账号权限查询有权限的集群或命名空间的容器日志; + + ![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/log00.png) + +3. 顶部 Tab 默认进入 __普通查询__ 。 + + 1. 点击 __筛选__ 展开过滤面板,可切换日志搜索条件和类型。 + 2. 日志类型: + + - __容器日志__ :记录集群中容器内部的活动和事件,包括应用程序的输出、错误消息、警告和调试信息等。支持通过集群、命名空间、容器组、容器过滤日志。 + - __节点日志__ :记录集群中每个节点的系统级别日志。这些日志包含节点的操作系统、内核、服务和组件的相关信息。支持通过集群、节点、文件路径过滤日志。 + + 3. 支持对单个关键字进行模糊搜索。 + + ![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/log03.png) + +4. 顶部切换 Tab 选择 __Lucene 语法查询__ 。 + + 第一次进入时,默认选择登录账号权限查询有权限的集群或命名空间的容器日志。 + + ![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/log01.png) + + **Lucene 语法说明:** + + 1. 使用 逻辑操作符(AND、OR、NOT、"" )符查询多个关键字,例如:keyword1 AND (keyword2 OR keyword3) NOT keyword4。 + 2. 使用波浪号 (~) 实现模糊查询,在 "~" 后可指定可选的参数,用于控制模糊查询的相似度,不指定则默认使用 0.5。例如:error~。 + 3. 使用通配符 (*、?) 用作单字符通配符,表示匹配任意一个字符。 + 4. 使用方括号 [ ] 或花括号 { } 来查询范围,方括号 [ ] 表示闭区间,包含边界值。花括号 { } 表示开区间,排除边界值。范围查询只适用于能够进行排序的字段类型,如数字、日期等。例如:timestamp:[2022-01-01 TO 2022-01-31]。 + 5. 更多用法请查看:[Lucene 语法说明](../../reference/lucene.md)。 + +### 其他操作 + +#### 查看日志上下文 + +点击日志后的按钮,在右侧划出面板中可查看该条日志的默认 100 条上下文。可切换 __显示行数__ 查看更多上下文内容。 + +![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/logcontext.png) + +#### 导出日志数据 + +点击列表右上侧的下载按钮。 + +- 支持配置导出的日志字段,根据日志类型可配置的字段不同,其中 __日志内容__ 字段为必选。 +- 支持将日志查询结果导出为 **.txt** 或 **.csv** 格式。 + +![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/logexport.png){ width="500"} diff --git a/docs/zh/docs/admin/insight/data-query/metric.md b/docs/zh/docs/admin/insight/data-query/metric.md new file mode 100644 index 0000000..a485aa5 --- /dev/null +++ b/docs/zh/docs/admin/insight/data-query/metric.md @@ -0,0 +1,27 @@ +# 指标查询 + +指标查询支持查询容器各资源的指标数据,可查看监控指标的趋势变化。同时,高级查询支持原生 PromQL 语句进行指标查询。 + +## 前提条件 + +- 集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 点击一级导航栏进入 __可观测性__ 。 + +2. 左侧导航栏中,选择 __指标__ 。 + +3. 选择集群、类型、节点、指标名称查询条件后,点击 __搜索__ ,屏幕右侧将显示对应指标图表及数据详情。 + + - 支持自定义时间范围。可手动点击 __刷新__ 图标或选择默认时间间隔进行刷新。 + + ![查询结果](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/metrics00.png) + +4. 点击 __高级查询__ 页签通过原生的 PromQL 查询。 + + ![高级查询](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/metics01.png) + +!!! NOTE + + 参阅 [PromQL 语法](https://prometheus.io/docs/prometheus/latest/querying/basics/)。 diff --git a/docs/zh/docs/admin/insight/faq/expand-once-es-full.md b/docs/zh/docs/admin/insight/faq/expand-once-es-full.md new file mode 100644 index 0000000..4367661 --- /dev/null +++ b/docs/zh/docs/admin/insight/faq/expand-once-es-full.md @@ -0,0 +1,69 @@ +# ElasticSearch 数据塞满如何操作? + +当 ElasticSearch 内存占满时,可以选择[扩容](#_1)或者[删除数据](#_2)来解决: + +你可以运行如下命令查看 ES 节点的资源占比。 + +```bash +kubectl get pod -n mcamel-system | grep common-es-cluster-masters-es | awk '{print $1}' | xargs -I {} kubectl exec {} -n mcamel-system -c elasticsearch -- df -h | grep /usr/share/elasticsearch/data +``` + +## 扩容 + +在主机节点还有资源的情况下, **扩容** 是一种常见的方案,也就是提高 PVC 的容量。 + +1. 先运行以下命令获取 es-data-0 节点的 PVC 配置,请以实际的环境的 PVC 为准。 + + ```bash + kubectl edit -n mcamel-system pvc elasticsearch-data-mcamel-common-es-cluster-masters-es-data-0 + ``` + +2. 然后修改以下 `storage` 字段(需要使用的存储类 SC 可以扩容) + + ```yaml + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 35Gi # (1)! + ``` + + 1. 这个数值需调整 + +## 删除数据 + +当 ElasticSearch 内存占满时,你还可以删除 index 数据释放资源。 + +你可以参考以下步骤进入 Kibana 页面,手动执行删除操作。 + +1. 首先明确 Kibana Pod 是否存在并且正常运行: + + ```bash + kubectl get po -n mcamel-system |grep mcamel-common-es-cluster-masters-kb + ``` + +2. 若不存在,则手动设置 replica 为 1,并且等待服务正常运行;若存在,则跳过该步骤 + + ```bash + kubectl scale -n mcamel-system deployment mcamel-common-es-cluster-masters-kb --replicas 1 + ``` + +3. 修改 Kibana 的 Service 为 NodePort 暴露访问方式 + + ```bash + kubectl patch svc -n mcamel-system mcamel-common-es-cluster-masters-kb-http -p '{"spec":{"type":"NodePort"}}' + + # 修改完成后查看 NodePort。此例的端口为 30128,则访问方式为 https://{集群中的节点IP}:30128 + [root@insight-master1 ~]# kubectl get svc -n mcamel-system |grep mcamel-common-es-cluster-masters-kb-http + mcamel-common-es-cluster-masters-kb-http NodePort 10.233.51.174 5601:30128/TCP 108m + ``` + +4. 获取 ElasticSearch 的 Secret,用于登录 Kibana(用户名为 elastic) + + ```bash + kubectl get secrets -n mcamel-system mcamel-common-es-cluster-masters-es-elastic-user -o jsonpath="{.data.elastic}" |base64 -d + ``` + +5. 进入 **Kibana** -> **Stack Management** -> **Index Management** ,打开 **Include hidden indices** 选项,即可见所有的 index。 + 根据 index 的序号大小,保留序号大的 index,删除序号小的 index。 diff --git a/docs/zh/docs/admin/insight/faq/ignore-pod-log-collect.md b/docs/zh/docs/admin/insight/faq/ignore-pod-log-collect.md new file mode 100644 index 0000000..8c68670 --- /dev/null +++ b/docs/zh/docs/admin/insight/faq/ignore-pod-log-collect.md @@ -0,0 +1,29 @@ +# 容器日志黑名单 + +## 配置方式 + +1. 对于任意一个不需要采集容器日志的 Pod, 在 Pod 的 annotation 中添加 `insight.opentelemetry.io/log-ignore: "true"` 来指定不需要采集的容器日志,例如: + + ```yaml + apiVersion: apps/v1 + kind: Pod + metadata: + name: log-generator + spec: + selector: + matchLabels: + app.kubernetes.io/name: log-generator + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: log-generator + annotations: + insight.opentelemetry.io/log-ignore: "true" + spec: + containers: + - name: nginx + image: banzaicloud/log-generator:0.3.2 + ``` + +2. 重启 Pod,等待 Pod 恢复运行状态之后,Fluenbit 将不再采集这个 Pod 内的容器的日志。 diff --git a/docs/zh/docs/admin/insight/faq/traceclockskew.md b/docs/zh/docs/admin/insight/faq/traceclockskew.md new file mode 100644 index 0000000..0ad8e3d --- /dev/null +++ b/docs/zh/docs/admin/insight/faq/traceclockskew.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# 链路数据中的时钟偏移 + +在一个分布式系统中,由于 [Clock Skew(时钟偏斜调整)](https://zh.wikipedia.org/wiki/%E6%97%B6%E9%92%9F%E5%81%8F%E7%A7%BB)影响, +不同主机间存在时间漂移现象。通俗来说,不同主机在同一时刻的系统时间是有微小的偏差的。 + +链路追踪系统是一个典型的分布式系统,它在涉及时间数据采集上也受这种现象影响,比如在一条链路中服务端 span 的开始时间早于客户端 span, +这种现象逻辑上是不存在的,但是由于时钟偏移影响,链路数据在各个服务中被采集到的那一刻主机间的系统时存在偏差,最终造成如下图所示的现象: + +![时钟偏移](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/traceclockskew01.png) + +上图中出现的现象理论上无法消除。但该现象较少,即使出现也不会影响服务间的调用关系。 + +目前 Insight 使用 Jaeger UI 来展示链路数据,UI 在遇到这种链路时会提醒: + +![时钟偏移](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/traceclockskew02.png) + +目前 Jaeger 的社区正在[尝试通过 UI 层面来优化这个问题](https://github.com/jaegertracing/jaeger-ui/issues/197)。 + +更多的相关资料,请参考: + +- [Clock Skew Adjuster considered harmful](https://github.com/jaegertracing/jaeger/issues/1459#issuecomment-582519000) +- [Add ability to display unadjusted trace in the UI](https://github.com/jaegertracing/jaeger-ui/issues/197) +- [Clock Skew Adjustment](https://www.jaegertracing.io/docs/1.40/deployment/#clock-skew-adjustment) diff --git a/docs/zh/docs/admin/insight/images/big-log01.png b/docs/zh/docs/admin/insight/images/big-log01.png new file mode 100644 index 0000000..b178b19 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/big-log01.png differ diff --git a/docs/zh/docs/admin/insight/images/big-log02.png b/docs/zh/docs/admin/insight/images/big-log02.png new file mode 100644 index 0000000..a28c76a Binary files /dev/null and b/docs/zh/docs/admin/insight/images/big-log02.png differ diff --git a/docs/zh/docs/admin/insight/images/big-log03.png b/docs/zh/docs/admin/insight/images/big-log03.png new file mode 100644 index 0000000..f6616d8 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/big-log03.png differ diff --git a/docs/zh/docs/admin/insight/images/big-log04.png b/docs/zh/docs/admin/insight/images/big-log04.png new file mode 100644 index 0000000..bac3d72 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/big-log04.png differ diff --git a/docs/zh/docs/admin/insight/images/big-log05.png b/docs/zh/docs/admin/insight/images/big-log05.png new file mode 100644 index 0000000..db60fa0 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/big-log05.png differ diff --git a/docs/zh/docs/admin/insight/images/big-log06.png b/docs/zh/docs/admin/insight/images/big-log06.png new file mode 100644 index 0000000..6e9b8be Binary files /dev/null and b/docs/zh/docs/admin/insight/images/big-log06.png differ diff --git a/docs/zh/docs/admin/insight/images/cluster-1.png b/docs/zh/docs/admin/insight/images/cluster-1.png new file mode 100644 index 0000000..7d864a3 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/cluster-1.png differ diff --git a/docs/zh/docs/admin/insight/images/cluster.png b/docs/zh/docs/admin/insight/images/cluster.png new file mode 100644 index 0000000..9f1b922 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/cluster.png differ diff --git a/docs/zh/docs/admin/insight/images/container01.png b/docs/zh/docs/admin/insight/images/container01.png new file mode 100644 index 0000000..546b73c Binary files /dev/null and b/docs/zh/docs/admin/insight/images/container01.png differ diff --git a/docs/zh/docs/admin/insight/images/dingding.png b/docs/zh/docs/admin/insight/images/dingding.png new file mode 100644 index 0000000..0e5f35d Binary files /dev/null and b/docs/zh/docs/admin/insight/images/dingding.png differ diff --git a/docs/zh/docs/admin/insight/images/find_root_cause/10.png b/docs/zh/docs/admin/insight/images/find_root_cause/10.png new file mode 100644 index 0000000..7d83883 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/find_root_cause/10.png differ diff --git a/docs/zh/docs/admin/insight/images/import-template.png b/docs/zh/docs/admin/insight/images/import-template.png new file mode 100644 index 0000000..a56214b Binary files /dev/null and b/docs/zh/docs/admin/insight/images/import-template.png differ diff --git a/docs/zh/docs/admin/insight/images/inhibition-1.png b/docs/zh/docs/admin/insight/images/inhibition-1.png new file mode 100644 index 0000000..afcac8e Binary files /dev/null and b/docs/zh/docs/admin/insight/images/inhibition-1.png differ diff --git a/docs/zh/docs/admin/insight/images/inhibition.png b/docs/zh/docs/admin/insight/images/inhibition.png new file mode 100644 index 0000000..2fc334d Binary files /dev/null and b/docs/zh/docs/admin/insight/images/inhibition.png differ diff --git a/docs/zh/docs/admin/insight/images/inhibition01.png b/docs/zh/docs/admin/insight/images/inhibition01.png new file mode 100644 index 0000000..5653387 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/inhibition01.png differ diff --git a/docs/zh/docs/admin/insight/images/inhibition02.png b/docs/zh/docs/admin/insight/images/inhibition02.png new file mode 100644 index 0000000..2ce4352 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/inhibition02.png differ diff --git a/docs/zh/docs/admin/insight/images/inhibition03.png b/docs/zh/docs/admin/insight/images/inhibition03.png new file mode 100644 index 0000000..e9c86a0 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/inhibition03.png differ diff --git a/docs/zh/docs/admin/insight/images/inhibition04.png b/docs/zh/docs/admin/insight/images/inhibition04.png new file mode 100644 index 0000000..2d63479 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/inhibition04.png differ diff --git a/docs/zh/docs/admin/insight/images/insight-agent.svg b/docs/zh/docs/admin/insight/images/insight-agent.svg new file mode 100644 index 0000000..97cbf4a --- /dev/null +++ b/docs/zh/docs/admin/insight/images/insight-agent.svg @@ -0,0 +1,11 @@ + + + Icon / Logo 20*20 / Insight Agent@green + + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/insight/images/insight-ns-toleration.png b/docs/zh/docs/admin/insight/images/insight-ns-toleration.png new file mode 100644 index 0000000..b2eaa81 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/insight-ns-toleration.png differ diff --git a/docs/zh/docs/admin/insight/images/insight.svg b/docs/zh/docs/admin/insight/images/insight.svg new file mode 100644 index 0000000..1727286 --- /dev/null +++ b/docs/zh/docs/admin/insight/images/insight.svg @@ -0,0 +1,9 @@ + + + insight + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/insight/images/installagent01.png b/docs/zh/docs/admin/insight/images/installagent01.png new file mode 100644 index 0000000..edb3c27 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/installagent01.png differ diff --git a/docs/zh/docs/admin/insight/images/installagent02.png b/docs/zh/docs/admin/insight/images/installagent02.png new file mode 100644 index 0000000..b9f8e1f Binary files /dev/null and b/docs/zh/docs/admin/insight/images/installagent02.png differ diff --git a/docs/zh/docs/admin/insight/images/installagent03.png b/docs/zh/docs/admin/insight/images/installagent03.png new file mode 100644 index 0000000..cf298d0 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/installagent03.png differ diff --git a/docs/zh/docs/admin/insight/images/ipavo.svg b/docs/zh/docs/admin/insight/images/ipavo.svg new file mode 100644 index 0000000..d9476d1 --- /dev/null +++ b/docs/zh/docs/admin/insight/images/ipavo.svg @@ -0,0 +1,10 @@ + + + Icon / 00_Action / bar-chart + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/insight/images/kpandaservice.png b/docs/zh/docs/admin/insight/images/kpandaservice.png new file mode 100644 index 0000000..9f789fa Binary files /dev/null and b/docs/zh/docs/admin/insight/images/kpandaservice.png differ diff --git a/docs/zh/docs/admin/insight/images/log04.png b/docs/zh/docs/admin/insight/images/log04.png new file mode 100644 index 0000000..e72fd36 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/log04.png differ diff --git a/docs/zh/docs/admin/insight/images/logfilter00.png b/docs/zh/docs/admin/insight/images/logfilter00.png new file mode 100644 index 0000000..ade153c Binary files /dev/null and b/docs/zh/docs/admin/insight/images/logfilter00.png differ diff --git a/docs/zh/docs/admin/insight/images/map-setting.png b/docs/zh/docs/admin/insight/images/map-setting.png new file mode 100644 index 0000000..9c9539c Binary files /dev/null and b/docs/zh/docs/admin/insight/images/map-setting.png differ diff --git a/docs/zh/docs/admin/insight/images/msg-detail.png b/docs/zh/docs/admin/insight/images/msg-detail.png new file mode 100644 index 0000000..4fd4dab Binary files /dev/null and b/docs/zh/docs/admin/insight/images/msg-detail.png differ diff --git a/docs/zh/docs/admin/insight/images/node.png b/docs/zh/docs/admin/insight/images/node.png new file mode 100644 index 0000000..c8d1efe Binary files /dev/null and b/docs/zh/docs/admin/insight/images/node.png differ diff --git a/docs/zh/docs/admin/insight/images/notify-01.png b/docs/zh/docs/admin/insight/images/notify-01.png new file mode 100644 index 0000000..5b80920 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/notify-01.png differ diff --git a/docs/zh/docs/admin/insight/images/notify-02.png b/docs/zh/docs/admin/insight/images/notify-02.png new file mode 100644 index 0000000..70049ed Binary files /dev/null and b/docs/zh/docs/admin/insight/images/notify-02.png differ diff --git a/docs/zh/docs/admin/insight/images/policy-builtin.png b/docs/zh/docs/admin/insight/images/policy-builtin.png new file mode 100644 index 0000000..ab2d8a4 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/policy-builtin.png differ diff --git a/docs/zh/docs/admin/insight/images/policy02.png b/docs/zh/docs/admin/insight/images/policy02.png new file mode 100644 index 0000000..2a4e13e Binary files /dev/null and b/docs/zh/docs/admin/insight/images/policy02.png differ diff --git a/docs/zh/docs/admin/insight/images/policy03.png b/docs/zh/docs/admin/insight/images/policy03.png new file mode 100644 index 0000000..a8aa01b Binary files /dev/null and b/docs/zh/docs/admin/insight/images/policy03.png differ diff --git a/docs/zh/docs/admin/insight/images/policy07.png b/docs/zh/docs/admin/insight/images/policy07.png new file mode 100644 index 0000000..1302794 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/policy07.png differ diff --git a/docs/zh/docs/admin/insight/images/policy08.png b/docs/zh/docs/admin/insight/images/policy08.png new file mode 100644 index 0000000..9758b47 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/policy08.png differ diff --git a/docs/zh/docs/admin/insight/images/probe03.png b/docs/zh/docs/admin/insight/images/probe03.png new file mode 100644 index 0000000..d3c5a11 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/probe03.png differ diff --git a/docs/zh/docs/admin/insight/images/service-1.png b/docs/zh/docs/admin/insight/images/service-1.png new file mode 100644 index 0000000..c815654 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/service-1.png differ diff --git a/docs/zh/docs/admin/insight/images/service-map.png b/docs/zh/docs/admin/insight/images/service-map.png new file mode 100644 index 0000000..091169b Binary files /dev/null and b/docs/zh/docs/admin/insight/images/service-map.png differ diff --git a/docs/zh/docs/admin/insight/images/service.png b/docs/zh/docs/admin/insight/images/service.png new file mode 100644 index 0000000..c9e01fc Binary files /dev/null and b/docs/zh/docs/admin/insight/images/service.png differ diff --git a/docs/zh/docs/admin/insight/images/service01.png b/docs/zh/docs/admin/insight/images/service01.png new file mode 100644 index 0000000..4a4f557 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/service01.png differ diff --git a/docs/zh/docs/admin/insight/images/servicemap.png b/docs/zh/docs/admin/insight/images/servicemap.png new file mode 100644 index 0000000..8c6d448 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/servicemap.png differ diff --git a/docs/zh/docs/admin/insight/images/servicemap01.png b/docs/zh/docs/admin/insight/images/servicemap01.png new file mode 100644 index 0000000..5abde06 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/servicemap01.png differ diff --git a/docs/zh/docs/admin/insight/images/servicemap02.png b/docs/zh/docs/admin/insight/images/servicemap02.png new file mode 100644 index 0000000..857fa5f Binary files /dev/null and b/docs/zh/docs/admin/insight/images/servicemap02.png differ diff --git a/docs/zh/docs/admin/insight/images/silence03.png b/docs/zh/docs/admin/insight/images/silence03.png new file mode 100644 index 0000000..c7b2220 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/silence03.png differ diff --git a/docs/zh/docs/admin/insight/images/sms00.png b/docs/zh/docs/admin/insight/images/sms00.png new file mode 100644 index 0000000..4e58ac4 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/sms00.png differ diff --git a/docs/zh/docs/admin/insight/images/sms01.png b/docs/zh/docs/admin/insight/images/sms01.png new file mode 100644 index 0000000..e4e18b8 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/sms01.png differ diff --git a/docs/zh/docs/admin/insight/images/sms02.png b/docs/zh/docs/admin/insight/images/sms02.png new file mode 100644 index 0000000..3da97b3 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/sms02.png differ diff --git a/docs/zh/docs/admin/insight/images/smsserver01.png b/docs/zh/docs/admin/insight/images/smsserver01.png new file mode 100644 index 0000000..22c5fce Binary files /dev/null and b/docs/zh/docs/admin/insight/images/smsserver01.png differ diff --git a/docs/zh/docs/admin/insight/images/smsserver02.png b/docs/zh/docs/admin/insight/images/smsserver02.png new file mode 100644 index 0000000..3660ead Binary files /dev/null and b/docs/zh/docs/admin/insight/images/smsserver02.png differ diff --git a/docs/zh/docs/admin/insight/images/template01.png b/docs/zh/docs/admin/insight/images/template01.png new file mode 100644 index 0000000..d7f6144 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/template01.png differ diff --git a/docs/zh/docs/admin/insight/images/template02.png b/docs/zh/docs/admin/insight/images/template02.png new file mode 100644 index 0000000..5e908b3 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/template02.png differ diff --git a/docs/zh/docs/admin/insight/images/template03.png b/docs/zh/docs/admin/insight/images/template03.png new file mode 100644 index 0000000..c516692 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/template03.png differ diff --git a/docs/zh/docs/admin/insight/images/template04.png b/docs/zh/docs/admin/insight/images/template04.png new file mode 100644 index 0000000..86b1477 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/template04.png differ diff --git a/docs/zh/docs/admin/insight/images/template05.png b/docs/zh/docs/admin/insight/images/template05.png new file mode 100644 index 0000000..1c2d870 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/template05.png differ diff --git a/docs/zh/docs/admin/insight/images/trace02.png b/docs/zh/docs/admin/insight/images/trace02.png new file mode 100644 index 0000000..bde1b94 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/trace02.png differ diff --git a/docs/zh/docs/admin/insight/images/tracelog.png b/docs/zh/docs/admin/insight/images/tracelog.png new file mode 100644 index 0000000..3810728 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/tracelog.png differ diff --git a/docs/zh/docs/admin/insight/images/vmdisk14.png b/docs/zh/docs/admin/insight/images/vmdisk14.png new file mode 100644 index 0000000..ca100a8 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/vmdisk14.png differ diff --git a/docs/zh/docs/admin/insight/images/webhook.png b/docs/zh/docs/admin/insight/images/webhook.png new file mode 100644 index 0000000..69ef57a Binary files /dev/null and b/docs/zh/docs/admin/insight/images/webhook.png differ diff --git a/docs/zh/docs/admin/insight/images/workload-1.png b/docs/zh/docs/admin/insight/images/workload-1.png new file mode 100644 index 0000000..63f5a62 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/workload-1.png differ diff --git a/docs/zh/docs/admin/insight/images/workload-2.png b/docs/zh/docs/admin/insight/images/workload-2.png new file mode 100644 index 0000000..525dd78 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/workload-2.png differ diff --git a/docs/zh/docs/admin/insight/images/workload.png b/docs/zh/docs/admin/insight/images/workload.png new file mode 100644 index 0000000..90e5453 Binary files /dev/null and b/docs/zh/docs/admin/insight/images/workload.png differ diff --git a/docs/zh/docs/admin/insight/infra/cluster.md b/docs/zh/docs/admin/insight/infra/cluster.md new file mode 100644 index 0000000..6eac1cd --- /dev/null +++ b/docs/zh/docs/admin/insight/infra/cluster.md @@ -0,0 +1,33 @@ +# 集群监控 + +通过集群监控,你可以查看集群的基本信息、该集群中的资源消耗以及一段时间的资源消耗变化趋势等。 + +## 前提条件 + +集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ -> __集群__ 。在该页面可查看以下信息: + + - **资源概览** :多选集群中的节点、工作负载的正常和全部的数量统计; + - **故障** :统计当前集群产生的告警数量; + - **资源消耗** :所选集群的 CPU、内存、磁盘的实际使用量和总量; + - **指标说明** :所选集群的 CPU、内存、磁盘读写、网络接收发送的变化趋势。 + + ![集群监控](../images/cluster.png){ width="1000"} + +3. 切换到 __资源水位线监控__ 页签,可查看当前集群的更多监控数据。 + + ![集群监控](../images/cluster-1.png){ width="1000"} + +## 参考指标说明 + +| 指标名 | 说明 | +| -- | -- | +| CPU 使用率 | 该指标是指集群中所有 Pod 资源的实际 CPU 用量与所有节点的 CPU 总量的比率。| +| CPU 分配率 | 该指标是指集群中所有 Pod 的 CPU 请求量的总和与所有节点的 CPU 总量的比率。| +| 内存使用率 | 该指标是指集群中所有 Pod 资源的实际内存用量与所有节点的内存总量的比率。| +| 内存分配率 | 该指标是指集群中所有 Pod 的内存请求量的总和与所有节点的内存总量的比率。| diff --git a/docs/zh/docs/admin/insight/infra/container.md b/docs/zh/docs/admin/insight/infra/container.md new file mode 100644 index 0000000..a9c18c0 --- /dev/null +++ b/docs/zh/docs/admin/insight/infra/container.md @@ -0,0 +1,56 @@ +# 容器监控 + +容器监控是对集群管理中工作负载的监控,在列表中可查看工作负载的基本信息和状态。在工作负载详情页,可查看正在告警的数量以及 CPU、内存等资源消耗的变化趋势。 + +## 前提条件 + +集群已安装 insight-agent,且所有的容器组处于 __运行中__ 状态。 + +- 安装 insight-agent,请参考[在线安装 insight-agent](../quickstart/install/install-agent.md) + 或[离线升级 insight-agent](../quickstart/install/offline-install.md)。 + +## 操作步骤 + +请按照以下步骤查看服务监控指标: + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ -> __工作负载__ 。 + +3. 切换顶部 Tab,查看不同类型工作负载的数据。 + + ![容器监控](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/workload00.png){ width="1000"} + +4. 点击目标工作负载名称查看详情。 + + 1. 故障:在故障卡片中统计该工作负载当前正在告警的总数。 + 2. 资源消耗:在该卡片可查看工作负载的 CPU、内存、网络的使用情况。 + 3. 监控指标:可查看工作负载默认 1 小时的 CPU、内存、网络和磁盘的变化趋势。 + + ![容器监控](../images/workload.png){ width="1000"} + +5. 切换 Tab 到 __容器组列表__ ,可查看工作负载的各个容器组状态、所在节点、重启次数等信息。 + + ![容器监控](../images/workload-1.png){ width="1000"} + +6. 切换 Tab 到 __JVM 监控__ ,可查看各个容器组的 JVM 指标。 + + ![JVM 监控](../images/workload-2.png) + + !!! note + + 1. JVM 监控功能仅支持 Java 语言。 + 2. 开启 JVM 监控功能,请参考[开始监控 Java 应用](../quickstart/otel/java/index.md)。 + +## 指标参考说明 + +| **指标名称** | **说明** | +| -- | -- | +| CPU 使用量 |工作负载下所有容器组的 CPU 使用量之和。| +| CPU 请求量 | 工作负载下所有容器组的 CPU 请求量之和。| +| CPU 限制量 | 工作负载下所有容器组的 CPU 限制量之和。| +| 内存使用量 | 工作负载下所有容器组的内存使用量之和。| +| 内存请求量 | 工作负载下所有容器组的内存使用量之和。| +| 内存限制量 | 工作负载下所有容器组的内存限制量之和。| +| 磁盘读写速率 | 指定时间范围内磁盘每秒连续读取和写入的总和,表示磁盘每秒读取和写入操作数的性能度量。| +| 网络发送接收速率 | 指定时间范围内,按工作负载统计的网络流量的流入、流出速率。| diff --git a/docs/zh/docs/admin/insight/infra/event.md b/docs/zh/docs/admin/insight/infra/event.md new file mode 100644 index 0000000..eac30c1 --- /dev/null +++ b/docs/zh/docs/admin/insight/infra/event.md @@ -0,0 +1,49 @@ +# 事件查询 + +AI 算力平台 Insight 支持按集群、命名空间查询事件,并提供了事件状态分布图,对重要事件进行统计。 + +## 操作步骤 + +1. 点击一级导航栏进入 __可观测性__ 。 +2. 左侧导航栏中,选择 __基础设置 > 事件__ 。 + + ![事件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/event00.png) + +### 事件状态分布 + +默认显示最近 12 小时内发生的事件,您可以在右上角选择不同的时间范围来查看较长或较短的时间段。 +您还可以自定义采样间隔为 1 分钟至 5 小时。 + +通过事件状态分布图,您可以直观地了解事件的密集程度和分散情况。 +这有助于对后续的集群运维进行评估,并做好准备和安排工作。 +如果事件密集发生在特定时段,您可能需要调配更多的资源或采取相应措施来确保集群稳定性和高可用性。 +而如果事件较为分散,在此期间您可以合理安排其他运维工作,例如系统优化、升级或处理其他任务。 + +通过综合考虑事件状态分布图和时间范围,您能更好地规划和管理集群的运维工作,确保系统稳定性和可靠性。 + +### 事件总数和统计 + +通过重要事件统计,您可以方便地了解镜像拉取失败次数、健康检查失败次数、容器组(Pod)运行失败次数、 +Pod 调度失败次数、容器 OOM 内存耗尽次数、存储卷挂载失败次数以及所有事件的总数。这些事件通常分为「Warning」和「Normal」两类。 + +### 事件列表 + +事件列表以时间为轴,以流水的形式展示发生的事件。您可以根据「最近发生时间」和「级别」进行排序。 + +点击右侧的 ⚙️ 图标,您可以根据自己的喜好和需求来自定义显示的列。 + +在需要的时候,您还可以点击刷新图标来更新当前的事件列表。 + +## 其他操作 + +1. 在事件列表中操作列的图标,可查看某一事件的元数据信息。 + + ![history](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/event01.png){ width="1000"} + +2. 点击顶部页签的 __上下文__ 可查看该事件对应资源的历史事件记录。 + + ![history](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/event02.png){ width="1000"} + +## 参考 + +有关系统自带的 Event 事件的详细含义,请参阅 [Kubenetest API 事件列表](https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/cluster-resources/event-v1/)。 diff --git a/docs/zh/docs/admin/insight/infra/namespace.md b/docs/zh/docs/admin/insight/infra/namespace.md new file mode 100644 index 0000000..7cdc392 --- /dev/null +++ b/docs/zh/docs/admin/insight/infra/namespace.md @@ -0,0 +1,35 @@ +--- +hide: + - toc +--- + +# 命名空间监控 + +以命名空间为维度,快速查询命名空间内的资源消耗和变化趋势。 + +## 前提条件 + +集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ > __命名空间__ 。在该页面可查看以下信息: + + 1. **切换命名空间**:在顶部切换集群或命名空间; + 2. **资源概览**:统计所选命名空间下的正常和全部工作负载的数量; + 3. **故障**:统计所选命名空间下产生的告警数量; + 4. **事件**:统计所选命名空间下 24 小时内 Warning 级别的事件数量; + 5. **资源消耗**:统计所选命名空间下容器组的 CPU、内存使用量之和 及 CPU、内存配额情况。 + + ![命名空间](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/namespace00.png){ width="1000"} + +### 指标说明 + +| 指标名 | 说明 | +| -- | -- | +| CPU 使用量 | 所选命名空间中容器组的 CPU 使用量之和 | +| 内存使用量 | 所选命名空间中容器组的内存使用量之和 | +| 容器组 CPU 使用量 | 命名空间中各容器组的 CPU 使用量 | +| 容器组内存使用量 | 命名空间中各容器组的内存使用量 | diff --git a/docs/zh/docs/admin/insight/infra/node.md b/docs/zh/docs/admin/insight/infra/node.md new file mode 100644 index 0000000..9ca8e4f --- /dev/null +++ b/docs/zh/docs/admin/insight/infra/node.md @@ -0,0 +1,26 @@ +# 节点监控 + +通过节点监控,你可以概览所选集群下节点的当前健康状态、对应容器组的异常数量; +在当前节点详情页,你可以查看正在告警的数量以及 CPU、内存、磁盘等资源消耗的变化趋势图。 + +## 前提条件 + +集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ -> __节点__ 。在该页面可查看以下信息: + + - **集群切换** :切换顶部的下拉框可切换集群; + - **节点列表** :所选集群中的节点列表,单击切换节点。 + - **故障** :统计当前集群产生的告警数量; + - **资源消耗** :所选节点的 CPU、内存、磁盘的实际使用量和总量; + - **指标说明** :所选节点的 CPU、内存、磁盘读写、网络接收发送的变化趋势。 + + ![节点监控](../images/node.png){ width="1000"} + +3. 切换到 __资源水位线监控__ 页签,可查看当前节点的更多监控数据。 + + ![节点监控](../images/cluster-1.png){ width="1000"} diff --git a/docs/zh/docs/admin/insight/infra/probe.md b/docs/zh/docs/admin/insight/infra/probe.md new file mode 100644 index 0000000..50aad73 --- /dev/null +++ b/docs/zh/docs/admin/insight/infra/probe.md @@ -0,0 +1,86 @@ +# 拨测 + +拨测(Probe)指的是基于黑盒监控,定期通过 HTTP、TCP 等方式对目标进行连通性测试,快速发现正在发生的故障。 + +Insight 基于 [Prometheus Blackbox Exporter](https://github.com/prometheus/blackbox_exporter) +工具通过 HTTP、HTTPS、DNS、TCP 和 ICMP 等协议,对网络进行探测并返回探测结果以便了解网络状态。 + +## 前提条件 + +目标集群中[已成功部署 insight-agent](../quickstart/install/install-agent.md),且处于 __运行中__ 状态。 + +## 查看拨测任务 + +1. 进入 __可观测性__ 产品模块; +2. 在左边导航栏选择 __基础设施__ -> __拨测__。 + + - 点击表格中的集群或命名空间下拉框,可切换集群和命名空间 + - 你可以点击右侧的 ⚙️ 修改显示的列,默认为拨测名称、探测方式、探测目标、连通状态、创建时间 + - 连通状态有 3 种: + - 正常:Probe 成功连接到了目标,目标返回了预期的响应 + - 异常:Probe 无法连接到目标,或目标没有返回预期的响应 + - Pending:Probe 正在尝试连接目标 + - 你可以在 🔍 搜索框中键入名称,模糊搜索某些拨测任务 + + ![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe00.png){ width=1000px} + +## 创建拨测任务 + +1. 点击 __创建拨测任务__。 +2. 填写基本信息后点击 __下一步__ + + - 集群:选择需要拨测的集群 + - 命名空间:拨测所在的命名空间 + + ![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe01.png){ width=1000px} + +3. 配置探测参数。 + + - Blackbox 实例:选择负责探测的 blackbox 实例 + - 探测方式: + - HTTP:通过发送 HTTP 或 HTTPS 请求到目标 URL,检测其连通性和响应时间,这可以用于监测网站或 Web 应用的可用性和性能 + - TCP:通过建立到目标主机和端口的 TCP 连接,检测其连通性和响应时间。这可以用于监测基于 TCP 的服务,如 Web 服务器、数据库服务器等 + - 其他:支持通过配置 ConfigMap 自定义探测方式,可参考[自定义拨测方式](../collection-manag/probe-module.md) + - 探测目标:探测的目标地址,支持域名或 IP 地址等 + - 标签:自定义标签,该标签会自动添加到 Prometheus 的 Label 中 + - 探测间隔:探测间隔时间 + - 探测超时:探测目标时的最长等待时间 + + ![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe02.png){ width=1000px} + +4. 配置完成后,点击 __确定__ 即可完成创建。 + +!!! warning + + 拨测任务创建完成后,需要大概 3 分钟的时间来同步配置。在此期间,不会进行探测,无法查看探测结果。 + +## 编辑拨测任务 + +点击列表右侧的 __┇__ -> __编辑__,完成编辑后点击 __确定__。 + +![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe04.png){ width=1000px} + +## 查看监控面板 + +点击`拨测名称` 查看拨测任务中每个目标的监控状态,以图表方式显示针对网络状况的探测结果。 + +![probe](../images/probe03.png){ width=1000px} + +| 指标名称 | 描述 | +| -- | -- | +| Current Status Response | 表示 HTTP 探测请求的响应状态码。| +| Ping Status | 表示探测请求是否成功。1 表示探测请求成功,0 表示探测请求失败。 | +| IP Protocol | 表示探测请求使用的 IP 协议版本。 | +| SSL Expiry | 表示 SSL/TLS 证书的最早到期时间。 | +| DNS Response (Latency) | 表示整个探测过程的持续时间,单位是秒。 | +| HTTP Duration | 表示从发送请求到接收到完整响应的整个过程的时间。| + +## 删除拨测任务 + +点击列表右侧的 __┇__ -> __删除__,确认无误后点击 __确定__。 + +![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe05.png){ width=1000px} + +!!! caution + + 删除操作不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/admin/insight/quickstart/install/big-log-and-trace.md b/docs/zh/docs/admin/insight/quickstart/install/big-log-and-trace.md new file mode 100644 index 0000000..4822cae --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/big-log-and-trace.md @@ -0,0 +1,281 @@ +# 开启大日志和大链路模式 + +可观测性模块为了提高大规模环境下的数据写入能力,支持将日志切换为 +**大日志** 模式、将链路切换为 **大链路** 模式。本文将介绍以下几种开启方式: + +- 通过[安装器开启或升级](#_8)至大日志和大链路模式(通过 manifest.yaml 中同一个参数值控制) +- 通过 [Helm 命令手动开启](#helm)大日志和大链路模式 + +## 日志 + +本节说明普通日志模式和大日志模式的区别。 + +### 日志模式 + +组件:Fluentbit + Elasticsearch + +该模式简称为 ES 模式,数据流图如下所示: + +![日志模式](../../images/big-log01.png) + +### 大日志模式 + +组件:Fluentbit + **Kafka** + **Vector** + Elasticsearch + +该模式简称为 Kafka 模式,数据流图如下所示: + +![大日志模式](../../images/big-log02.png) + +## 链路 + +本节说明普通链路模式和大链路模式的区别。 + +### 链路模式 + +组件:Agent opentelemetry-collector + Global opentelemetry-collector + Jaeger-collector + Elasticsearch + +该模式简称为 OTlp 模式,数据流图如下所示: + +![链路模式](../../images/big-log03.png) + +### 大链路模式 + +组件:Agent opentelemetry-collector + Kafka + Global opentelemetry-collector + Jaeger-collector + Elasticsearch + +该模式简称为 Kafka 模式,数据流图如下所示: + +![大链路模式](../../images/big-log04.png) + +## 通过安装器开启 + +通过安装器部署/升级 AI 算力中心 时使用的 manifest.yaml 中存在 infrastructures.kafka 字段, +如果想开启可观测的大日志和大链路模式,则需要启用 kafka: + +```yaml title="manifest.yaml" +apiVersion: manifest.daocloud.io/v1alpha1 +kind: DCEManifest +... +infrastructures: + ... + kafka: + enable: true # 默认为 false + cpuLimit: 1 + memLimit: 2Gi + pvcSize: 15Gi +``` + +### 开启 + +安装时使用启用 `kafka` 的 manifest.yaml,则会默认安装 kafka 中间件, +并在安装 Insight 时默认开启大日志和大链路模式。安装命令为: + +```bash +./dce5-installer cluster-create -c clusterConfig.yaml -m manifest.yaml +``` + +### 升级 + +升级同样是修改 `kafka` 字段。但需要注意的是,因为老环境安装时使用的是 `kafka: false`, +所以环境中无 kafka。此时升级需要指定升级 `middleware`,才会同时安装 kafka 中间件。升级命令为: + +```bash +./dce5-installer cluster-create -c clusterConfig.yaml -m manifest.yaml -u gproduct,middleware +``` + +!!! note + + 在升级完成后,需要手动重启以下组件: + + - insight-agent-fluent-bit + - insight-agent-opentelemetry-collector + - insight-opentelemetry-collector + +## 通过 Helm 命令开启 + +前提条件:需要保证存在 **可用的 kafka** 且地址可正常访问。 + +根据以下命令获取老版本 insight 和 insight-agent 的 values(建议做好备份): + +```bash +helm get values insight -n insight-system -o yaml > insight.yaml +helm get values insight-agent -n insight-system -o yaml > insight-agent.yaml +``` + +### 开启大日志 + +有以下几种方式开启或升级至大日志模式: + +=== "在 `helm upgrade` 命令中使用 --set" + + 先运行以下 insight 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --set global.kafka.brokers="10.6.216.111:30592" \ + --set global.kafka.enabled=true \ + --set vector.enabled=true \ + --version 0.30.1 + ``` + + 然后运行以下 insight-agent 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --set global.exporters.logging.kafka.brokers="10.6.216.111:30592" \ + --set global.exporters.logging.output=kafka \ + --version 0.30.1 + ``` + +=== "修改 YAML 后运行 helm upgrade" + + 参照以下步骤修改 YAMl 后运行 `helm upgrade` 命令: + + 1. 修改 insight.yaml + + ```yaml title="insight.yaml" + global: + ... + kafka: + brokers: 10.6.216.111:30592 + enabled: true + ... + vector: + enabled: true + ``` + + 1. 升级 insight 组件: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version 0.30.1 + ``` + + 1. 修改 insight-agent.yaml + + ```yaml title="insight-agent.yaml" + global: + ... + exporters: + ... + logging: + ... + kafka: + brokers: 10.6.216.111:30592 + output: kafka + ``` + + 1. 升级 insight-agent: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version 0.30.1 + ``` + +=== "容器管理 UI 升级" + + 在容器管理模块中,找到对应的集群,从左侧导航栏选择 **Helm 应用** ,找到并更新 insight-agent。 + + 在 **Logging Settings** 中,为 **output** 选择 **kafka**,并填写正确的 **brokers** 地址。 + + ![kpanda](../../images/big-log05.png) + + 需要注意的是,在升级完成后,需手动重启 **insight-agent-fluent-bit** 组件。 + +### 开启大链路 + +有以下几种方式开启或升级至大链路模式: + +=== "在 `helm upgrade` 命令中使用 --set" + + 先运行以下 insight 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --set global.kafka.brokers="10.6.216.111:30592" \ + --set global.kafka.enabled=true \ + --set global.tracing.kafkaReceiver.enabled=true \ + --version 0.30.1 + ``` + + 然后运行以下 insight-agent 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --set global.exporters.trace.kafka.brokers="10.6.216.111:30592" \ + --set global.exporters.trace.output=kafka \ + --version 0.30.1 + ``` + +=== "修改 YAML 后运行 helm upgrade" + + 参照以下步骤修改 YAMl 后运行 `helm upgrade` 命令: + + 1. 修改 insight.yaml + + ```yaml title="insight.yaml" + global: + ... + kafka: + brokers: 10.6.216.111:30592 + enabled: true + ... + tracing: + ... + kafkaReceiver: + enabled: true + ``` + + 1. 升级 insight 组件: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version 0.30.1 + ``` + + 1. 修改 insight-agent.yaml + + ```yaml title="insight-agent.yaml" + global: + ... + exporters: + ... + trace: + ... + kafka: + brokers: 10.6.216.111:30592 + output: kafka + ``` + + 1. 升级 insight-agent: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version 0.30.1 + ``` + +=== "容器管理 UI 升级" + + 在容器管理模块中,找到对应的集群,从左侧导航栏选择 **Helm 应用** ,找到并更新 insight-agent。 + + 在 **Trace Settings** 中,为 **output** 选择 **kafka**,并填写正确的 **brokers** 地址。 + + ![UI 上升级](../../images/big-log06.png) + + 需要注意的是,在升级完成后,需手动 + **重启 insight-agent-opentelemetry-collector** 和 **insight-opentelemetry-collector** 组件。 diff --git a/docs/zh/docs/admin/insight/quickstart/install/component-scheduling.md b/docs/zh/docs/admin/insight/quickstart/install/component-scheduling.md new file mode 100644 index 0000000..3490c2e --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/component-scheduling.md @@ -0,0 +1,318 @@ +# 自定义 Insight 组件调度策略 + +当部署可观测平台 Insight 到 Kubernetes 环境时,正确的资源管理和优化至关重要。 +Insight 包含多个核心组件,如 Prometheus、OpenTelemetry、FluentBit、Vector、Elasticsearch 等, +这些组件在运行过程中可能因为资源占用问题对集群内其他 Pod 的性能产生负面影响。 +为了有效地管理资源并优化集群的运行,节点亲和性成为一项重要的配置选项。 + +本文将重点探讨如何通过[污点](#insight)和[节点亲和性](#label)的配置策略,使得每个组件能够在适当的节点上运行, +并避免资源竞争或争用,从而确保整个 Kubernetes 集群的稳定性和高效性。 + +## 通过污点为 Insight 配置专有节点 + +由于 Insight Agent 包含了 DaemonSet 组件,所以本节所述的配置方式是让除了 Insight DameonSet 之外的其余组件均运行在专有节点上。 + +该方式是通过为专有节点添加污点(taint),并配合污点容忍度(tolerations)来实现的。 +更多细节可以参考 [Kubernetes 官方文档](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)。 + +可以参考如下命令为节点添加及移除污点: + +```bash +# 添加污点 +kubectl taint nodes worker1 node.daocloud.io=insight-only:NoSchedule + +# 移除污点 +kubectl taint nodes worker1 node.daocloud.io:NoSchedule- +``` + +有以下两种途径让 Insight 组件调度至专有节点: + +### 1. 为每个组件添加污点容忍度 + +针对 `insight-server` 和 `insight-agent` 两个 Chart 分别进行配置: + +=== "insight-server Chart 配置" + + ```yaml + server: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + ui: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + runbook: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + # mysql: + victoria-metrics-k8s-stack: + victoria-metrics-operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmcluster: + spec: + vmstorage: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmselect: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vminsert: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmalert: + spec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + alertmanager: + spec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + jaeger: + collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + query: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + opentelemetry-collector-aggregator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + opentelemetry-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + grafana-operator: + operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + grafana: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + kibana: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + elastic-alert: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + vector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + ``` + +=== "insight-agent Chart 配置" + + ```yaml + kube-prometheus-stack: + prometheus: + prometheusSpec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + prometheus-node-exporter: + tolerations: + - effect: NoSchedule + operator: Exists + prometheusOperator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + kube-state-metrics: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + tailing-sidecar-operator: + operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-kubernetes-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + prometheus-blackbox-exporter: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + etcd-exporter: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + ``` + +### 2. 通过命名空间级别配置 + +让 `insight-system` 命名空间的 Pod 都容忍 `node.daocloud.io=insight-only` 污点。 + +1. 调整 `apiserver` 的配置文件 `/etc/kubernetes/manifests/kube-apiserver.yaml`,放开 `PodTolerationRestriction,PodNodeSelector`, 参考下图: + + ![insight-ns-toleration](../../images/insight-ns-toleration.png) + +2. 给 `insight-system` 命名空间增加注解: + + ```yaml + apiVersion: v1 + kind: Namespace + metadata: + name: insight-system + annotations: + scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Equal", "effect": "NoSchedule", "key": "node.daocloud.io", "value": "insight-only"}]' + ``` + +重启 insight-system 命名空间下面的组件即可正常容忍 insight-system 下的 Pod 调度。 + +## 为节点添加 Label 和节点亲和性来管理组件调度 + +!!! info + + 节点亲和性概念上类似于 `nodeSelector`,它使你可以根据节点上的 **标签(label)** 来约束 Pod 可以调度到哪些节点上。 + 节点亲和性有两种: + + 1. requiredDuringSchedulingIgnoredDuringExecution:调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。 + 2. preferredDuringSchedulingIgnoredDuringExecution:调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。 + + 更过细节请参考 [kubernetes 官方文档](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)。 + +为了实现不同用户对 Insight 组件调度的灵活需求,Insight 分别提供了较为细粒度的 Label 来实现不同组件的调度策略,以下是标签与组件的关系说明: + +| 标签 Key | 标签 Value | 说明 | +| --- | ------- | ------------ | +| `node.daocloud.io/insight-any` | 任意值,推荐用 `true` | 代表 Insight 所有组件优先考虑带了该标签的节点 | +| `node.daocloud.io/insight-prometheus` | 任意值,推荐用 `true` | 特指 Prometheus 组件 | +| `node.daocloud.io/insight-vmstorage` | 任意值,推荐用 `true` | 特指 VictoriaMetrics vmstorage 组件 | +| `node.daocloud.io/insight-vector` | 任意值,推荐用 `true` | 特指 Vector 组件 | +| `node.daocloud.io/insight-otel-col` | 任意值,推荐用 `true` | 特指 OpenTelemetry 组件 | + +可以参考如下命令为节点添加及移除标签: + +```bash +# 为 node8 添加标签,先将 insight-prometheus 调度到 node8 +kubectl label nodes node8 node.daocloud.io/insight-prometheus=true + +# 移除 node8 的 node.daocloud.io/insight-prometheus 标签 +kubectl label nodes node8 node.daocloud.io/insight-prometheus- +``` + +以下是 insight-prometheus 组件在部署时默认的亲和性偏好: + +```yaml +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: DoesNotExist + weight: 1 + - preference: + matchExpressions: + - key: node.daocloud.io/insight-prometheus # (1)! + operator: Exists + weight: 2 + - preference: + matchExpressions: + - key: node.daocloud.io/insight-any + operator: Exists + weight: 3 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - insight-agent-kube-prometh-prometheus +``` + +1. 先将 insight-prometheus 调度到带有 node.daocloud.io/insight-prometheus 标签的节点 diff --git a/docs/zh/docs/admin/insight/quickstart/install/gethosturl.md b/docs/zh/docs/admin/insight/quickstart/install/gethosturl.md new file mode 100644 index 0000000..0697ee8 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/gethosturl.md @@ -0,0 +1,176 @@ +# 获取全局服务集群的数据存储地址 + +可观测性是多集群统一观测的产品,为实现对多集群观测数据的统一存储、查询, +子集群需要将采集的观测数据上报给[全局服务集群](../../../kpanda/clusters/cluster-role.md#_2)进行统一存储。 +本文提供了在安装采集组件 insight-agent 时必填的存储组件的地址。 + +## 在全局服务集群安装 insight-agent + +如果在全局服务集群安装 insight-agent,推荐通过域名来访问集群: + +```shell +export vminsert_host="vminsert-insight-victoria-metrics-k8s-stack.insight-system.svc.cluster.local" # (1)! +export es_host="insight-es-master.insight-system.svc.cluster.local" # (2)! +export otel_col_host="insight-opentelemetry-collector.insight-system.svc.cluster.local" # (3)! +``` + +## 在其他集群安装 insight-agent + +### 通过 Insight Server 提供的接口获取地址 + +1. [管理集群](../../../kpanda/clusters/cluster-role.md#_3)使用默认的 LoadBalancer 方式暴露 + + 登录全局服务集群的控制台,执行以下命令: + + ```bash + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' + ``` + + !!! note + + 请替换命令中的 `${INSIGHT_SERVER_IP}` 参数。 + + 获得如下返回值: + + ```json + { + "values": { + "global": { + "exporters": { + "logging": { + "host": "10.6.182.32" + }, + "metric": { + "host": "10.6.182.32" + }, + "auditLog": { + "host": "10.6.182.32" + }, + "trace": { + "host": "10.6.182.32" + } + } + }, + "opentelemetry-operator": { + "enabled": true + }, + "opentelemetry-collector": { + "enabled": true + } + } + } + ``` + + - `global.exporters.logging.host` 是日志服务地址,不需要再设置对应服务的端口,都会使用相应默认值 + - `global.exporters.metric.host` 是指标服务地址 + - `global.exporters.trace.host` 是链路服务地址 + - `global.exporters.auditLog.host` 是审计日志服务地址(和链路使用的同一个服务不同端口) + +1. 管理集群禁用 LoadBalancer + + 调用接口时需要额外传递集群中任意外部可访问的节点 IP,会使用该 IP 拼接出对应服务的完整访问地址。 + + ```bash + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' --data '{"extra": {"EXPORTER_EXTERNAL_IP": "10.5.14.51"}}' + ``` + + 将获得如下的返回值: + + ```json + { + "values": { + "global": { + "exporters": { + "logging": { + "scheme": "https", + "host": "10.5.14.51", + "port": 32007, + "user": "elastic", + "password": "j8V1oVoM1184HvQ1F3C8Pom2" + }, + "metric": { + "host": "10.5.14.51", + "port": 30683 + }, + "auditLog": { + "host": "10.5.14.51", + "port": 30884 + }, + "trace": { + "host": "10.5.14.51", + "port": 30274 + } + } + }, + "opentelemetry-operator": { + "enabled": true + }, + "opentelemetry-collector": { + "enabled": true + } + } + } + ``` + + - `global.exporters.logging.host` 是日志服务地址 + - `global.exporters.logging.port` 是日志服务暴露的 NodePort + - `global.exporters.metric.host` 是指标服务地址 + - `global.exporters.metric.port` 是指标服务暴露的 NodePort + - `global.exporters.trace.host` 是链路服务地址 + - `global.exporters.trace.port` 是链路服务暴露的 NodePort + - `global.exporters.auditLog.host` 是审计日志服务地址(和链路使用的同一个服务不同端口) + - `global.exporters.auditLog.host` 是审计日志服务暴露的 NodePort + +### 通过 LoadBalancer 连接 + +1. 若集群中开启 `LoadBalancer` 且为 Insight 设置了 `VIP` 时,您也可以手动执行以下命令获取 `vminsert` 以及 `opentelemetry-collector` 的地址信息: + + ```shell + $ kubectl get service -n insight-system | grep lb + lb-insight-opentelemetry-collector LoadBalancer 10.233.23.12 4317:31286/TCP,8006:31351/TCP 24d + lb-vminsert-insight-victoria-metrics-k8s-stack LoadBalancer 10.233.63.67 8480:31629/TCP 24d + ``` + + - `lb-vminsert-insight-victoria-metrics-k8s-stack` 是指标服务的地址 + - `lb-insight-opentelemetry-collector` 是链路服务的地址 + +1. 执行以下命令获取 ` elasticsearch` 地址信息: + + ```shell + $ kubectl get service -n mcamel-system | grep es + mcamel-common-es-cluster-masters-es-http NodePort 10.233.16.120 9200:30465/TCP 47d + ``` + + `mcamel-common-es-cluster-masters-es-http` 是日志服务的地址 + +### 通过 NodePort 连接 + +全局服务集群禁用 LB 特性 + +在该情况下,默认不会创建上述的 LoadBalancer 资源,对应服务名为: + +- vminsert-insight-victoria-metrics-k8s-stack(指标服务) +- common-es(日志服务) +- insight-opentelemetry-collector(链路服务) + +上面两种情况获取到对应服务的对应端口信息后,进行如下设置: + +```shell +--set global.exporters.logging.host= # (1)! +--set global.exporters.logging.port= # (2)! +--set global.exporters.metric.host= # (3)! +--set global.exporters.metric.port= # (4)! +--set global.exporters.trace.host= # (5)! +--set global.exporters.trace.port= # (6)! +--set global.exporters.auditLog.host= # (7)! +``` + +1. 外部可访问的管理集群 NodeIP +2. 日志服务 9200 端口对应的 NodePort +3. 外部可访问的管理集群 NodeIP +4. 指标服务 8480 端口对应的 NodePort +5. 外部可访问的管理集群 NodeIP +6. 链路服务 4317 端口对应的 NodePort +7. 外部可访问的管理集群 NodeIP diff --git a/docs/zh/docs/admin/insight/quickstart/install/helm-installagent.md b/docs/zh/docs/admin/insight/quickstart/install/helm-installagent.md new file mode 100644 index 0000000..7b1d92c --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/helm-installagent.md @@ -0,0 +1,142 @@ +# 通过 Helm 部署 Insight Agent + +本文描述了在命令行中通过 Helm 命令安装 Insight Agent 社区版的操作步骤。 + +## 安装 Insight Agent + +1. 使用以下命令添加镜像仓库的地址 + + ```shell + helm repo add insight https://release.daocloud.io/chartrepo/insight + helm repo upgrade + helm search repo insight/insight-agent --versions + ``` + +2. 安装 __Insight Agent__ 需要确保全局服务集群中的 __Insight Server__ 正常运行,执行以下安装命令安装 __Insight Agent__ 社区版,该配置不启用 Tracing 功能: + + ```shell + helm upgrade --install --create-namespace --cleanup-on-fail \ + --version ${version} \ # 请指定部署版本 + insight-agent insight/insight-agent \ + --set global.exporters.logging.elasticsearch.host=10.10.10.x \ # 请替换“10.10.10.x" 为全局服务集群或外置的 Elasticsearch 的地址 + --set global.exporters.logging.elasticsearch.port=32517 \ # 请替换“32517" 为全局服务集群或外置的 Elasticsearch 暴露的端口 + --set global.exporters.logging.elasticsearch.user=elastic \ # 请替换“elastic" 为全局服务集群或外置的 Elasticsearch 的用户名 + --set global.exporters.logging.elasticsearch.password=dangerous \ # 请替换“dangerous" 为全局服务集群或外置的 Elasticsearch 的密码 + --set global.exporters.metric.host=${vminsert_address} \ # 请替换“10.10.10.x" 为全局服务集群中 vminsert 的地址 + --set global.exporters.metric.port=${vminsert_port} \ # 请替换“32517" 为全局服务集群中 vminsert 的地址 + --set global.exporters.auditLog.host=${opentelemetry-collector address} \ # 请替换“32517" 为全局服务集群中 opentelemetry-collector 的端口 + --set global.exporters.auditLog.port=${otel_col_auditlog_port}\ # 请替换“32517" 为全局服务集群中 opentelemetry-collector 容器端口为 8006 的 service 对外访问的地址 + -n insight-system + ``` + + !!! info + + 可参考 __如何获取连接地址__ 获取地址信息。 + +3. 执行以下命令确认安装状态: + + ```shell + helm list -A + kubectl get pods -n insight-system + ``` + +### 如何获取连接地址 + +#### 在全局服务集群安装 Insight Agent + +如果 Agent 是安装在管理集群,推荐通过域名来访问集群: + +```shell +export vminsert_host="vminsert-insight-victoria-metrics-k8s-stack.insight-system.svc.cluster.local" # 指标 +export es_host="insight-es-master.insight-system.svc.cluster.local" # 日志 +export otel_col_host="insight-opentelemetry-collector.insight-system.svc.cluster.local" # 链路 +``` + +#### 在工作集群安装 Insight Agent + +=== "全局服务集群使用默认的 LoadBalancer" + + 全局服务集群使用默认的 LoadBalancer 方式暴露服务时,登录全局服务集群的控制台,执行以下命令: + + ```shell + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' + ``` + + 将获得如下的返回值: + + ```shell + {"global":{"exporters":{"logging":{"output":"elasticsearch","elasticsearch":{"host":"10.6.182.32"},"kafka":{},"host":"10.6.182.32"},"metric":{"host":"10.6.182.32"},"auditLog": {"host":"10.6.182.32"}}},"opentelemetry-operator":{"enabled":true},"opentelemetry-collector":{"enabled":true}} + ``` + + 其中: + + - __global.exporters.logging.elasticsearch.host__ 是日志服务地址【不需要再设置对应服务的端口,都会使用相应默认值】; + - __global.exporters.metric.host__ 是指标服务地址; + - __global.exporters.trace.host__ 是链路服务地址; + - __global.exporters.auditLog.host__ 是审计日志服务地址 (和链路使用的同一个服务不同端口); + +=== "登录全局服务集群的控制台操作" + + 登录全局服务集群的控制台,执行以下命令: + + ```shell + kubectl get service -n insight-system | grep lb + kubectl get service -n mcamel-system | grep es + ``` + + 其中: + + - __lb-vminsert-insight-victoria-metrics-k8s-stack__ 是指标服务的地址; + - __lb-insight-opentelemetry-collector__ 是链路服务的地址; + - __mcamel-common-es-cluster-masters-es-http__ 是日志服务的地址; + +=== "全局服务集群使用 Nodeport" + + 全局服务集群使用 Nodeport 方式暴露服务时,登录全局服务集群的控制台,执行以下命令: + + ```shell + kubectl get service -n insight-system + kubectl get service -n mcamel-system + ``` + + 其中: + + - __vminsert-insight-victoria-metrics-k8s-stack__ 是指标服务的地址; + - __insight-opentelemetry-collector__ 是链路服务的地址; + - __mcamel-common-es-cluster-masters-es-http__ 是日志服务的地址; + +## 升级 Insight Agent + +1. 登录目标集群的控制台,执行以下命令备份 `--set` 参数。 + + ```shell + helm get values insight-agent -n insight-system -o yaml > insight-agent.yaml + ``` + +2. 执行以下命令更新仓库。 + + ```shell + helm repo upgrade + ``` + +3. 执行以下命令进行升级。 + + ```shell + helm upgrade insight-agent insight/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version ${version} # 指定升级版本 + ``` + +4. 执行以下命令确认安装状态: + + ```shell + kubectl get pods -n insight-system + ``` + +## 卸载 Insight Agent + +```shell +helm uninstall insight-agent -n insight-system --timeout 10m +``` diff --git a/docs/zh/docs/admin/insight/quickstart/install/index.md b/docs/zh/docs/admin/insight/quickstart/install/index.md new file mode 100644 index 0000000..88fab9a --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/index.md @@ -0,0 +1,21 @@ +# 开始观测 + +AI 算力中心 平台实现了对多云多集群的纳管,并支持创建集群。在此基础上,可观测性 Insight 作为多集群统一观测方案,通过部署 insight-agent 插件实现对多集群观测数据的采集,并支持通过 AI 算力中心 可观测性产品实现对指标、日志、链路数据的查询。 + + __insight-agent__ 是可观测性实现对多集群数据采集的工具,安装后无需任何修改,即可实现对指标、日志以及链路数据的自动化采集。 + +通过 __容器管理__ 创建的集群默认会安装 insight-agent,故在此仅针对接入的集群如何开启观测能力提供指导。 + +- [在线安装 insight-agent](install-agent.md) + +可观测性 Insight 作为多集群的统一观测平台,其部分组件的资源消耗与创建集群的数据、接入集群的数量息息相关,在安装 insight-agent 时,需要根据集群规模对相应组件的资源进行调整。 + +1. 根据创建集群的规模或接入集群的规模,调整 insight-agent 中采集组件 __Prometheus__ 的 CPU 和内存,请参考: [Prometheus 资源规划](../res-plan/prometheus-res.md) + +2. 由于多集群的指标数据会统一存储,则需要 AI 算力中心 平台管理员根据创建集群的规模、接入集群的规模对应调整 vmstorage 的磁盘,请参考:[vmstorage 磁盘容量规划](../res-plan/vms-res-plan.md)。 + +- 如何调整 vmstorage 的磁盘,请参考:[vmstorge 磁盘扩容](../res-plan/modify-vms-disk.md)。 + +由于 AI 算力中心 支持对多云多集群的纳管,insight-agent 目前也完成了部分验证,由于监控组件冲突问题导致在 Openshift 4.x 集群中安装 insight-agent 会出现问题,若您遇到同样问题,请参考以下文档: + +- [在 Openshift 4.x 安装 insight-agent](../other/install-agent-on-ocp.md) diff --git a/docs/zh/docs/admin/insight/quickstart/install/install-agent.md b/docs/zh/docs/admin/insight/quickstart/install/install-agent.md new file mode 100644 index 0000000..ee72ab3 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/install-agent.md @@ -0,0 +1,43 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# 在线安装 insight-agent + + __insight-agent__ 是集群观测数据采集的插件,支持对指标、链路、日志数据的统一观测。本文描述了如何在在线环境中为接入集群安装 insight-agent。 + +## 前提条件 + +- 集群已成功接入 __容器管理__ 模块。如何接入集群,请参考:[接入集群](../../../kpanda/clusters/integrate-cluster.md) + +## 操作步骤 + +1. 进入 __容器管理__ 模块,在 __集群列表__ 中找到要安装 insight-agent 的集群名称。 + + ![确定集群](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent01.png) + +2. 选择 __立即安装__ 跳转,或点击集群,在左侧导航栏内点击 __Helm 应用__ -> __Helm 模板__ ,搜索框查询 __insight-agent__ ,点击该卡片进入详情。 + + ![查询 insight-agent](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent02.png) + +3. 查看 insight-agent 的安装页面,点击 __安装__ 进入下一步。 + + ![安装](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent03.png) + +4. 选择安装的版本并在下方表单分别填写全局服务集群中对应数据存储组件的地址,确认填写的信息无误后,点击 __确定__ 。 + + - insight-agent 默认部署在集群的 insight-system 命名空间下。 + - 建议安装最新版本的 insight-agent。 + - 系统默认已填写数据上报的组件的地址,仍请您检查无误后再点击 __确定__  进行安装。 如需修改数据上报地址,请参考:[获取数据上报地址](../install/gethosturl.md)。 + + ![填写表单](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent04.png) + +5. 系统将自动返回  __Helm 应用__ 列表,当应用 insight-agent 的状态从  __未就绪__ 变为 __已部署__ ,且所有的组件状态为 __运行中__ 时,则安装成功。等待一段时间后,可在 __可观测性__ 模块查看该集群的数据。 + + ![结束界面](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent05.png) + +!!! note + + - 点击最右侧的 __┇__ ,您可以在弹出菜单中执行更多操作,如 __更新__ 、 __查看 YAML__ 和 __删除__ 。 diff --git a/docs/zh/docs/admin/insight/quickstart/install/knownissues.md b/docs/zh/docs/admin/insight/quickstart/install/knownissues.md new file mode 100644 index 0000000..bad326a --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/knownissues.md @@ -0,0 +1,73 @@ +# 已知问题 + +本页列出一些 Insight Agent 安装和卸载有关的问题及其解决办法。 + +## v0.23.0 + +### Insight Agent + +#### Insight Agent 卸载失败 + +当你运行以下命令卸载 Insight Agent 时。 + +```sh +helm uninstall insight-agent -n insight-system +``` + +`otel-oprator` 所使用的 `tls secret` 未被卸载掉。 + +`otel-operator` 定义的“重复利用 tls secret”的逻辑中,会去判断 `otel-oprator` 的 `MutationConfiguration` +是否存在并重复利用 MutationConfiguration 中绑定的 CA cert。但是由于 `helm uninstall` 已卸载 `MutationConfiguration`,导致出现空值。 + +综上请手动删除对应的 `secret`,以下两种方式任选一种即可: + +- **通过命令行删除**:登录目标集群的控制台,执行以下命令: + + ```sh + kubectl -n insight-system delete secret insight-agent-opentelemetry-operator-controller-manager-service-cert + ``` + +- **通过 UI 删除**:登录 AI 算力中心 容器管理,选择目标集群,从左侧导航进入`密钥`,输入 + `insight-agent-opentelemetry-operator-controller-manager-service-cert`,选择`删除`。 + +## v0.22.0 + +### Insight Agent + +#### 升级 Insight Agent 时更新日志收集端,未生效 + +更新 insight-agent 日志配置从 elasticsearch 改为 kafka 或者从 kafka 改为 elasticsearch,实际上都未生效,还是使用更新前配置。 + +**解决方案** : + +手动重启集群中的 fluentbit。 + +## v0.21.0 + +### Insight Agent + +#### PodMonitor 采集多份 JVM 指标数据 + +1. 这个版本的 **PodMonitor/insight-kubernetes-pod** 存在缺陷:会错误地创建 Job 去采集标记了 + `insight.opentelemetry.io/metric-scrape=true` 的 Pod 的所有 container;而实际上只需采集 + `insight.opentelemetry.io/metric-port` 所对应 container 的端口。 + +2. 因为 PodMonitor 声明之后,**PromethuesOperator** 会预设置一些服务发现配置。 + 再考虑到 CRD 的兼容性的问题。因此,放弃通过 PodMonitor 来配置通过 **annotation** 创建采集任务的机制。 + +3. 通过 Prometheus 自带的 additional scrape config 机制,将服务发现规则配置在 secret 中,在引入 Prometheus 里。 + +综上: + +1. 删除这个 **PodMonitor** 的当前 **insight-kubernetes-pod** +2. 使用新的规则 + +新的规则里通过 **action: keepequal** 来比较 **source_labels** 和 **target_label** 的一致性, +来判断是否要给某个 container 的 port 创建采集任务。需要注意,这个是 Prometheus 2.41.0(2022-12-20)和更高版本才具备的功能。 + +```diff ++ - source_labels: [__meta_kubernetes_pod_annotation_insight_opentelemetry_io_metric_port] ++ separator: ; ++ target_label: __meta_kubernetes_pod_container_port_number ++ action: keepequal +``` diff --git a/docs/zh/docs/admin/insight/quickstart/install/upgrade-note.md b/docs/zh/docs/admin/insight/quickstart/install/upgrade-note.md new file mode 100644 index 0000000..0c5b4b9 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/install/upgrade-note.md @@ -0,0 +1,149 @@ +# 升级注意事项 + +本页介绍一些升级 insight-server 和 insight-agent 的注意事项。 + +## insight-agent + +### 从 v0.28.x(或更低版本)升级到 v0.29.x + +由于 v0.29.0 升级了 Opentelemetry 社区的 operator chart 版本,values 中的 featureGates 的支持的值有所变化,因此,在 upgrade 之前,需要将 `featureGates` 的值设置为空, 即: + +```diff +- --set opentelemetry-operator.manager.featureGates="+operator.autoinstrumentation.go,+operator.autoinstrumentation.multi-instrumentation,+operator.autoinstrumentation.nginx" \ ++ --set opentelemetry-operator.manager.featureGates="" +``` + +## insight-server + +### 从 v0.26.x(或更低版本)升级到 v0.27.x 或更高版本 + +在 v0.27.x 版本中将 vector 组件的开关单独抽出。故原有环境开启了 vector,那在升级 insight-server 时,需要指定 `--set vector.enabled=true` 。 + +### 从 v0.19.x(或更低版本)升级到 0.20.x + +在升级 __Insight__ 之前,您需要执行以下命令手动删除 __jaeger-collector__ 和 __jaeger-query__ 部署: + +```bash +kubectl -n insight-system delete deployment insight-jaeger-collector +kubectl -n insight-system delete deployment insight-jaeger-query +``` + +### 从 v0.17.x(或更低版本)升级到 v0.18.x + +由于 0.18.x 中更新了 Jaeger 相关部署文件,因此需要在升级 insight-server 前手动执行如下命令: + +```bash +kubectl -n insight-system delete deployment insight-jaeger-collector +kubectl -n insight-system delete deployment insight-jaeger-query +``` + +由于 0.18.x 中指标名产生了变动,因此,需要在升级 insight-server 之后,insight-agent 也应该做升级。 + +此外,调整了开启链路模块的参数,以及 ElasticSearch 连接调整。具体参考以下参数: + +```diff ++ --set global.tracing.enable=true \ +- --set jaeger.collector.enabled=true \ +- --set jaeger.query.enabled=true \ ++ --set global.elasticsearch.scheme=${your-external-elasticsearch-scheme} \ ++ --set global.elasticsearch.host=${your-external-elasticsearch-host} \ ++ --set global.elasticsearch.port=${your-external-elasticsearch-port} \ ++ --set global.elasticsearch.user=${your-external-elasticsearch-username} \ ++ --set global.elasticsearch.password=${your-external-elasticsearch-password} \ +- --set jaeger.storage.elasticsearch.scheme=${your-external-elasticsearch-scheme} \ +- --set jaeger.storage.elasticsearch.host=${your-external-elasticsearch-host} \ +- --set jaeger.storage.elasticsearch.port=${your-external-elasticsearch-port} \ +- --set jaeger.storage.elasticsearch.user=${your-external-elasticsearch-username} \ +- --set jaeger.storage.elasticsearch.password=${your-external-elasticsearch-password} \ +``` + +### 从 v0.15.x(或更低版本)升级到 v0.16.x + +由于 0.16.x 中使用了 vmalertmanagers CRD 的新特性参数 disableRouteContinueEnforce, +因此需要在升级 insight-server 前手动执行如下命令。 + +```shell +kubectl apply --server-side -f https://raw.githubusercontent.com/VictoriaMetrics/operator/v0.33.0/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml --force-conflicts +``` + +!!! note + + 如您是离线安装,可以在解压 Insight 离线包后,请执行以下命令更新 CRD。 + + ```shell + kubectl apply --server-side -f insight/dependency-crds --force-conflicts + ``` + +## insight-agent + +### 从 v0.23.x(或更低版本)升级到 v0.24.x + +由于 0.24.x 版本中 `OTEL operator chart` 中新增了 CRD,但由于 Helm Upgrade 时并不会更新 CRD,因此,需要手动执行以下命令: + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-helm-charts/main/charts/opentelemetry-operator/crds/crd-opentelemetry.io_opampbridges.yaml +``` + +如您是离线安装,可以在解压 insight-agent 离线包后可找到上述 CRD 的 yaml,解压 Insight-Agent Chart 之后手动执行以下命令: + +```shell +kubectl apply -f charts/agent/crds/crd-opentelemetry.io_opampbridges.yaml +``` + +### 从 v0.19.x(或更低版本)升级到 v0.20.x + +由于 0.20.x 中增加了 Kafka 日志导出配置,日志导出配置做了一些调整。升级 __insight-agent__ 之前需要注意参数变化, +即原来 logging 的配置已经移到了配置中 logging.elasticsearch: + +```diff +- --set global.exporters.logging.host \ +- --set global.exporters.logging.port \ ++ --set global.exporters.logging.elasticsearch.host \ ++ --set global.exporters.logging.elasticsearch.port \ +``` + +### 从 v0.17.x(或更低版本)升级到 v0.18.x + +由于 0.18.x 中更新了 Jaeger 相关部署文件,因此需要在升级 insight-agent 前需要注意参数的改动。 + +```diff ++ --set global.exporters.trace.enable=true \ +- --set opentelemetry-collector.enabled=true \ +- --set opentelemetry-operator.enabled=true \ +``` + +### 从 v0.16.x(或更低版本)升级到 v0.17.x + +在 v0.17.x 版本中将 kube-prometheus-stack chart 版本从 41.9.1 升级至 45.28.1, 其中使用的 CRD 也存在一些字段的升级,如 servicemonitor 的 __attachMetadata__ 字段,因此需要在升级 insight-agent 前执行如下命令: + +```bash +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --force-conflicts +``` + +如您是离线安装,可以在解压 insight-agent 离线包后,在 insight-agent/dependency-crds 中找到上述 CRD 的 yaml。 + +### 从 v0.11.x(或更低版本)升级到 v0.12.x + +在 v0.12.x 将 kube-prometheus-stack chart 从 39.6.0 升级到 41.9.1,其中包括 prometheus-operator 升级到 v0.60.1, prometheus-node-exporter chart 升级到 4.3.0 等。 +prometheus-node-exporter 升级后使用了 [Kubernetes 推荐 label](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/),因此需要在升级前删除 __node-exporter__ 的 DaemonSet。 +prometheus-operator 更新了 CRD,因此需要在升级 insight-agent 前执行如下命令: + +```shell linenums="1" +kubectl delete daemonset insight-agent-prometheus-node-exporter -n insight-system +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml --force-conflicts +``` + +!!! note + + 如您是离线安装,可以在解压 insight-agent 离线包后,执行以下命令更新 CRD。 + + ```shell + kubectl apply --server-side -f insight-agent/dependency-crds --force-conflicts + ``` diff --git a/docs/zh/docs/admin/insight/quickstart/otel/golang/golang.md b/docs/zh/docs/admin/insight/quickstart/otel/golang/golang.md new file mode 100644 index 0000000..8eb650d --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/golang/golang.md @@ -0,0 +1,361 @@ +# 使用 OTel SDK 增强 Go 应用程序 + +Golang 无侵入式接入链路请参考 [通过 Operator 实现应用程序无侵入增强](../operator.md) 文档,通过注解实现自动接入链路。 + +OpenTelemetry 也简称为 OTel,是一个开源的可观测性框架,可以帮助在 Go 应用程序中生成和收集遥测数据:链路、指标和日志。 + +本文主要讲解如何在 Go 应用程序中通过 OpenTelemetry Go SDK 增强并接入链路监控。 + +## 使用 OTel SDK 增强 Go 应用 + +### 安装相关依赖 + +必须先安装与 OpenTelemetry exporter 和 SDK 相关的依赖项。如果您正在使用其他请求路由器,请参考[请求路由](#_3)。 +切换/进入到应用程序源文件夹后运行以下命令: + +```golang +go get go.opentelemetry.io/otel@v1.19.0 \ + go.opentelemetry.io/otel/trace@v1.19.0 \ + go.opentelemetry.io/otel/sdk@v1.19.0 \ + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin@v0.46.1 \ + go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.19.0 \ + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.19.0 +``` + +### 使用 OTel SDK 创建初始化函数 + +为了让应用程序能够发送数据,需要一个函数来初始化 OpenTelemetry。在 __main.go__ 文件中添加以下代码片段: + +```golang +import ( + "context" + "os" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "go.uber.org/zap" + "google.golang.org/grpc" +) + +var tracerExp *otlptrace.Exporter + +func retryInitTracer() func() { + var shutdown func() + go func() { + for { + // otel will reconnected and re-send spans when otel col recover. so, we don't need to re-init tracer exporter. + if tracerExp == nil { + shutdown = initTracer() + } else { + break + } + time.Sleep(time.Minute * 5) + } + }() + return shutdown +} + +func initTracer() func() { + // temporarily set timeout to 10s + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + serviceName, ok := os.LookupEnv("OTEL_SERVICE_NAME") + if !ok { + serviceName = "server_name" + os.Setenv("OTEL_SERVICE_NAME", serviceName) + } + otelAgentAddr, ok := os.LookupEnv("OTEL_EXPORTER_OTLP_ENDPOINT") + if !ok { + otelAgentAddr = "http://localhost:4317" + os.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", otelAgentAddr) + } + zap.S().Infof("OTLP Trace connect to: %s with service name: %s", otelAgentAddr, serviceName) + + traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithDialOption(grpc.WithBlock())) + if err != nil { + handleErr(err, "OTLP Trace gRPC Creation") + return nil + } + + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(traceExporter), + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(resource.NewWithAttributes(semconv.SchemaURL))) + + otel.SetTracerProvider(tracerProvider) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + + tracerExp = traceExporter + return func() { + // Shutdown will flush any remaining spans and shut down the exporter. + handleErr(tracerProvider.Shutdown(ctx), "failed to shutdown TracerProvider") + } +} + +func handleErr(err error, message string) { + if err != nil { + zap.S().Errorf("%s: %v", message, err) + } +} +``` + +### 在 main.go 中初始化跟踪器 + +修改 main 函数以在 main.go 中初始化跟踪器。另外当您的服务关闭时,应该调用 __TracerProvider.Shutdown()__ 确保导出所有 Span。该服务将该调用作为主函数中的延迟函数: + +```golang +func main() { + // start otel tracing + if shutdown := retryInitTracer(); shutdown != nil { + defer shutdown() + } + ...... +} +``` + +### 为应用添加 OTel Gin 中间件 + +通过在 __main.go__ 中添加以下行来配置 Gin 以使用中间件: + +```golang +import ( + .... + "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" +) + +func main() { + ...... + r := gin.Default() + r.Use(otelgin.Middleware("my-app")) + ...... +} +``` + +### 运行应用程序 + +- 本地调试运行 + + > 注意: 此步骤仅用于本地开发调试,生产环境中 Operator 会自动完成以下环境变量的注入。 + + 以上步骤已经完成了初始化 SDK 的工作,现在如果需要在本地开发进行调试,需要提前获取到 insight-system 命名空间下 insight-agent-opentelemerty-collector 的地址,假设为: __insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317__ 。 + + 因此,可以在你本地启动应用程序的时候添加如下环境变量: + + ```bash + OTEL_SERVICE_NAME=my-golang-app OTEL_EXPORTER_OTLP_ENDPOINT=http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317 go run main.go... + ``` + +- 生产环境运行 + + 请参考[通过 Operator 实现应用程序无侵入增强](../operator.md) 中 __只注入环境变量注解__ 相关介绍,为 deployment yaml 添加注解: + + ```console + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + + 如果无法使用注解的方式,您可以手动在 deployment yaml 添加如下环境变量: + +```yaml +······ +env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: 'http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317' + - name: OTEL_SERVICE_NAME + value: "your depolyment name" # (1)! + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES + value: 'k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)' +······ +``` + +1. 修改此值 + +## 请求路由 + +### OpenTelemetry gin/gonic 增强 + +```golang +# Add one line to your import() stanza depending upon your request router: +middleware "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" +``` + +然后注入 OpenTelemetry 中间件: + +```golang +router.Use(middleware.Middleware("my-app")) +``` + +### OpenTelemetry gorillamux 增强 + +```golang +# Add one line to your import() stanza depending upon your request router: +middleware "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" +``` + +然后注入 OpenTelemetry 中间件: + +```golang +router.Use(middleware.Middleware("my-app")) +``` + +### gRPC 增强 + +同样,OpenTelemetry 也可以帮助您自动检测 gRPC 请求。要检测您拥有的任何 gRPC 服务器,请将拦截器添加到服务器的实例化中。 + +```golang +import ( + grpcotel "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +) +func main() { + [...] + + s := grpc.NewServer( + grpc.UnaryInterceptor(grpcotel.UnaryServerInterceptor()), + grpc.StreamInterceptor(grpcotel.StreamServerInterceptor()), + ) +} +``` + +需要注意的是,如果你的程序里面使用到了 Grpc Client 调用第三方服务,你还需要对 Grpc Client 添加拦截器: + +```golang + [...] + + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()), + ) +``` + +### 如果不使用请求路由 + +```golang +import ( + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +) +``` + +在将 http.Handler 传递给 ServeMux 的每个地方,您都将包装处理程序函数。例如,将进行以下替换: + +```golang +- mux.Handle("/path", h) ++ mux.Handle("/path", otelhttp.NewHandler(h, "description of path")) +--- +- mux.Handle("/path", http.HandlerFunc(f)) ++ mux.Handle("/path", otelhttp.NewHandler(http.HandlerFunc(f), "description of path")) +``` + +通过这种方式,您可以确保使用 othttp 包装的每个函数都会自动收集其元数据并启动相应的跟踪。 + +## 数据库访问增强 + +### Golang Gorm + +OpenTelemetry 社区也开发了数据库访问库的中间件,比如 Gorm: +```golang +import ( + "github.com/uptrace/opentelemetry-go-extra/otelgorm" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{}) +if err != nil { + panic(err) +} + +otelPlugin := otelgorm.NewPlugin(otelgorm.WithDBName("mydb"), # 缺失会导致数据库相关拓扑展示不完整 + otelgorm.WithAttributes(semconv.ServerAddress("memory"))) # 缺失会导致数据库相关拓扑展示不完整 +if err := db.Use(otelPlugin); err != nil { + panic(err) +} +``` + +### 自定义 Span + +很多时候,OpenTelemetry 提供的中间件不能帮助我们记录更多内部调用的函数,需要我们自定义 Span 来记录 + +```golang + ······ + _, span := otel.Tracer("GetServiceDetail").Start(ctx, + "spanMetricDao.GetServiceDetail", + trace.WithSpanKind(trace.SpanKindInternal)) + defer span.End() + ······ +``` + +### 向 span 添加自定义属性和事件 + +也可以将自定义属性或标签设置为 Span。要添加自定义属性和事件,请按照以下步骤操作: + +### 导入跟踪和属性库 + +```golang +import ( + ... + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) +``` + +### 从上下文中获取当前 Span + +```golang +span := trace.SpanFromContext(c.Request.Context()) +``` + +### 在当前 Span 中设置属性 + +```golang +span.SetAttributes(attribute.String("controller", "books")) +``` + +### 为当前 Span 添加 Event + +添加 span 事件是使用 span 对象上的 __AddEvent__ 完成的。 + +```golang +span.AddEvent(msg) +``` + +## 记录错误和异常 + +```golang +import "go.opentelemetry.io/otel/codes" + +// 获取当前 span +span := trace.SpanFromContext(ctx) + +// RecordError 会自动将一个错误转换成 span even +span.RecordError(err) + +// 标记这个 span 错误 +span.SetStatus(codes.Error, "internal error") +``` + +## 参考 + +有关 Demo 演示请参考: +- [opentelemetry-demo/productcatalogservice](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice) +- [opentelemetry-collector-contrib/demo](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/examples/demo) diff --git a/docs/zh/docs/admin/insight/quickstart/otel/golang/meter.md b/docs/zh/docs/admin/insight/quickstart/otel/golang/meter.md new file mode 100644 index 0000000..633f516 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/golang/meter.md @@ -0,0 +1,255 @@ +# 使用 OTel SDK 为应用程序暴露指标 + +> 本文仅供希望评估或探索正在开发的 OTLP 指标的用户参考。 + +OpenTelemetry 项目要求以必须在 OpenTelemetry 协议 (OTLP) 中发出数据的语言提供 API 和 SDK。 + +## 针对 Golang 应用程序 + +Golang 可以通过 sdk 暴露 runtime 指标,具体来说,在应用中添加以下方法开启 metrics 暴露器: + +### 安装相关依赖 + +切换/进入到应用程序源文件夹后运行以下命令: + +```golang +go get go.opentelemetry.io/otel \ + go.opentelemetry.io/otel/attribute \ + go.opentelemetry.io/otel/exporters/prometheus \ + go.opentelemetry.io/otel/metric/global \ + go.opentelemetry.io/otel/metric/instrument \ + go.opentelemetry.io/otel/sdk/metric +``` + +### 使用 OTel SDK 创建初始化函数 + +```golang +import ( + ..... + + "go.opentelemetry.io/otel/attribute" + otelPrometheus "go.opentelemetry.io/otel/exporters/prometheus" + "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" + "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" + selector "go.opentelemetry.io/otel/sdk/metric/selector/simple" +) +func (s *insightServer) initMeter() *otelPrometheus.Exporter { + s.meter = global.Meter("xxx") + + config := otelPrometheus.Config{ + DefaultHistogramBoundaries: []float64{1, 2, 5, 10, 20, 50}, + Gatherer: prometheus.DefaultGatherer, + Registry: prometheus.NewRegistry(), + Registerer: prometheus.DefaultRegisterer, + } + + c := controller.New( + processor.NewFactory( + selector.NewWithHistogramDistribution( + histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries), + ), + aggregation.CumulativeTemporalitySelector(), + processor.WithMemory(true), + ), + ) + + exporter, err := otelPrometheus.New(config, c) + if err != nil { + zap.S().Panicf("failed to initialize prometheus exporter %v", err) + } + + global.SetMeterProvider(exporter.MeterProvider()) + + http.HandleFunc("/metrics", exporter.ServeHTTP) + + go func() { + _ = http.ListenAndServe(fmt.Sprintf(":%d", 8888), nil) + }() + + zap.S().Info("Prometheus server running on ", fmt.Sprintf(":%d", port)) + return exporter +} +``` + +以上方法会为您的应用暴露一个指标接口: http://localhost:8888/metrics + +随后,在 main.go 中对其进行初始化: + +```golang +func main() { +······ + tp := initMeter() +······ +} +``` + +此外,如果想添加自定义指标,可以参考: + +```golang +// exposeClusterMetric expose metric like "insight_logging_count{} 1" +func (s *insightServer) exposeLoggingMetric(lserver *log.LogService) { + s.meter = global.Meter("insight.io/basic") + + var lock sync.Mutex + logCounter, err := s.meter.AsyncFloat64().Counter("insight_log_total") + if err != nil { + zap.S().Panicf("failed to initialize instrument: %v", err) + } + + _ = s.meter.RegisterCallback([]instrument.Asynchronous{logCounter}, func(ctx context.Context) { + lock.Lock() + defer lock.Unlock() + count, err := lserver.Count(ctx) + if err == nil || count != -1 { + logCounter.Observe(ctx, float64(count)) + } + }) +} +``` + +随后,在 main.go 调用该方法: + +```golang +······ +s.exposeLoggingMetric(lservice) +······ +``` + +您可以通过访问 http://localhost:8888/metrics 来检查您的指标是否正常工作。 + +## 针对 Java 应用程序 + +Java 在使用 otel agent 在完成链路的自动接入的基础上,通过添加环境变量: + +```bash +OTEL_METRICS_EXPORTER=prometheus +``` + +就可以直接暴露 JVM 相关指标,您可以通过访问 http://localhost:8888/metrics 来检查您的指标是否正常工作。 + +随后,再配合 prometheus serviceMonitor 即可完成指标的接入。 +如果想暴露自定义指标请参阅 [opentelemetry-java-docs/prometheus](https://github.com/open-telemetry/opentelemetry-java-docs/blob/main/prometheus/README.md)。 + +主要分以下两步: + +- 创建 meter provider,并指定 prometheus 作为 exporter。 + + ```java + /* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + + package io.opentelemetry.example.prometheus; + + import io.opentelemetry.api.metrics.MeterProvider; + import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; + import io.opentelemetry.sdk.metrics.SdkMeterProvider; + import io.opentelemetry.sdk.metrics.export.MetricReader; + + public final class ExampleConfiguration { + + /** + * Initializes the Meter SDK and configures the prometheus collector with all default settings. + * + * @param prometheusPort the port to open up for scraping. + * @return A MeterProvider for use in instrumentation. + */ + static MeterProvider initializeOpenTelemetry(int prometheusPort) { + MetricReader prometheusReader = PrometheusHttpServer.builder().setPort(prometheusPort).build(); + + return SdkMeterProvider.builder().registerMetricReader(prometheusReader).build(); + } + } + + ``` + +- 自定义 meter 并开启 http server + + ```java + package io.opentelemetry.example.prometheus; + + import io.opentelemetry.api.common.Attributes; + import io.opentelemetry.api.metrics.Meter; + import io.opentelemetry.api.metrics.MeterProvider; + import java.util.concurrent.ThreadLocalRandom; + + /** + * Example of using the PrometheusHttpServer to convert OTel metrics to Prometheus format and expose + * these to a Prometheus instance via a HttpServer exporter. + * + *

A Gauge is used to periodically measure how many incoming messages are awaiting processing. + * The Gauge callback gets executed every collection interval. + */ + public final class PrometheusExample { + private long incomingMessageCount; + + public PrometheusExample(MeterProvider meterProvider) { + Meter meter = meterProvider.get("PrometheusExample"); + meter + .gaugeBuilder("incoming.messages") + .setDescription("No of incoming messages awaiting processing") + .setUnit("message") + .buildWithCallback(result -> result.record(incomingMessageCount, Attributes.empty())); + } + + void simulate() { + for (int i = 500; i > 0; i--) { + try { + System.out.println( + i + " Iterations to go, current incomingMessageCount is: " + incomingMessageCount); + incomingMessageCount = ThreadLocalRandom.current().nextLong(100); + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignored here + } + } + } + + public static void main(String[] args) { + int prometheusPort = 8888; + + // it is important to initialize the OpenTelemetry SDK as early as possible in your process. + MeterProvider meterProvider = ExampleConfiguration.initializeOpenTelemetry(prometheusPort); + + PrometheusExample prometheusExample = new PrometheusExample(meterProvider); + + prometheusExample.simulate(); + + System.out.println("Exiting"); + } + } + ``` + +随后,待 java 应用程序运行之后,您可以通过访问 http://localhost:8888/metrics 来检查您的指标是否正常工作。 + +## Insight 采集指标 + +最后重要的是,您已经在应用程序中暴露出了指标,现在需要 Insight 来采集指标。 + +推荐的指标暴露方式是通过 [servicemonitor](https://github.com/prometheus-operator/prometheus-operator/blob/501d079e3d3769b94dca6684cf155034e468829a/Documentation/design.md#servicemonitor) 或者 podmonitor。 + +### 创建 servicemonitor/podmonitor + +添加的 servicemonitor/podmonitor 需要打上 __label:"operator.insight.io/managed-by": "insight"__ 才会被 Operator 识别: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-app + labels: + operator.insight.io/managed-by: insight +spec: + selector: + matchLabels: + app: example-app + endpoints: + - port: web + namespaceSelector: + any: true +``` diff --git a/docs/zh/docs/admin/insight/quickstart/otel/java/index.md b/docs/zh/docs/admin/insight/quickstart/otel/java/index.md new file mode 100644 index 0000000..1d93a8d --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/java/index.md @@ -0,0 +1,16 @@ +# 开始监控 Java 应用 + +1. Java 应用链路接入与监控请参考 [通过 Operator 实现应用程序无侵入增强](../operator.md) 文档,通过注解实现自动接入链路。 + +2. Java 应用的 JVM 进行监控:已经暴露 JVM 指标和仍未暴露 JVM 指标的 Java 应用如何与可观测性 Insight 对接。 + +- 如果您的 Java 应用未开始暴露 JVM 指标,您可以参考如下文档: + + - [使用 JMX Exporter 暴露 JVM 监控指标](./jvm-monitor/jmx-exporter.md) + - [使用 OpenTelemetry Java Agent 暴露 JVM 监控指标](./jvm-monitor/otel-java-agent.md) + +- 如果您的 Java 应用已经暴露 JVM 指标,您可以参考如下文档: + + - [已有 JVM 指标的 Java 应用对接可观测性](./jvm-monitor/legacy-jvm.md) + +3. [将 TraceId 和 SpanId 写入 Java 应用日志](./mdc.md), 实现链路数据与日志数据关联 diff --git a/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md b/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md new file mode 100644 index 0000000..24c5ec3 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md @@ -0,0 +1,136 @@ +# 使用 JMX Exporter 暴露 JVM 监控指标 + +JMX-Exporter 提供了两种用法: + +1. 启动独立进程。JVM 启动时指定参数,暴露 JMX 的 RMI 接口,JMX Exporter 调用 RMI 获取 JVM 运行时状态数据, + 转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。 +2. JVM 进程内启动(in-process)。JVM 启动时指定参数,通过 javaagent 的形式运行 JMX-Exporter 的 jar 包, + 进程内读取 JVM 运行时状态数据,转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。 + +!!! note + + 官方不推荐使用第一种方式,一方面配置复杂,另一方面因为它需要一个单独的进程,而这个进程本身的监控又成了新的问题, + 所以本文重点围绕第二种用法讲如何在 Kubernetes 环境下使用 JMX Exporter 暴露 JVM 监控指标。 + +这里使用第二种用法,启动 JVM 时需要指定 JMX Exporter 的 jar 包文件和配置文件。 +jar 包是二进制文件,不好通过 configmap 挂载,配置文件我们几乎不需要修改, +所以建议是直接将 JMX Exporter 的 jar 包和配置文件都打包到业务容器镜像中。 + +其中,第二种方式我们可以选择将 JMX Exporter 的 jar 文件放在业务应用镜像中, +也可以选择在部署的时候挂载进去。这里分别对两种方式做一个介绍: + +## 方式一:将 JMX Exporter JAR 文件构建至业务镜像中 + +prometheus-jmx-config.yaml 内容如下: + +```yaml title="prometheus-jmx-config.yaml" +... +ssl: false +lowercaseOutputName: false +lowercaseOutputLabelNames: false +rules: +- pattern: ".*" +``` + +!!! note + + 更多配置项请参考底部介绍或[Prometheus 官方文档](https://github.com/prometheus/jmx_exporter#configuration)。 + +然后准备 jar 包文件,可以在 [jmx_exporter](https://github.com/prometheus/jmx_exporter) 的 Github 页面找到最新的 jar 包下载地址并参考如下 Dockerfile: + +```shell +FROM openjdk:11.0.15-jre +WORKDIR /app/ +COPY target/my-app.jar ./ +COPY prometheus-jmx-config.yaml ./ +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +ENV JAVA_TOOL_OPTIONS=-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml +EXPOSE 8081 8999 8080 8888 +ENTRYPOINT java $JAVA_OPTS -jar my-app.jar +``` + +注意: + +- 启动参数格式:-javaagent:=: +- 这里使用了 8088 端口暴露 JVM 的监控指标,如果和 Java 应用冲突,可自行更改 + +## 方式二:通过 init container 容器挂载 + +我们需要先将 JMX exporter 做成 Docker 镜像, 以下 Dockerfile 仅供参考: + +```shell +FROM alpine/curl:3.14 +WORKDIR /app/ +# 将前面创建的 config 文件拷贝至镜像 +COPY prometheus-jmx-config.yaml ./ +# 在线下载 jmx prometheus javaagent jar +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +``` + +根据上面 Dockerfile 构建镜像: __docker build -t my-jmx-exporter .__ + +在 Java 应用部署 Yaml 中加入如下 init container: + +??? note "点击展开 YAML 文件" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-demo-app + labels: + app: my-demo-app + spec: + selector: + matchLabels: + app: my-demo-app + template: + metadata: + labels: + app: my-demo-app + spec: + imagePullSecrets: + - name: registry-pull + initContainers: + - name: jmx-sidecar + image: my-jmx-exporter + command: ["cp", "-r", "/app/jmx_prometheus_javaagent-0.17.2.jar", "/target/jmx_prometheus_javaagent-0.17.2.jar"] ➊ + volumeMounts: + - name: sidecar + mountPath: /target + containers: + - image: my-demo-app-image + name: my-demo-app + resources: + requests: + memory: "1000Mi" + cpu: "500m" + limits: + memory: "1000Mi" + cpu: "500m" + ports: + - containerPort: 18083 + env: + - name: JAVA_TOOL_OPTIONS + value: "-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml" ➋ + volumeMounts: + - name: host-time + mountPath: /etc/localtime + readOnly: true + - name: sidecar + mountPath: /sidecar + volumes: + - name: host-time + hostPath: + path: /etc/localtime + - name: sidecar #共享 agent 文件夹 + emptyDir: {} + restartPolicy: Always + ``` + +经过如上的改造之后,示例应用 my-demo-app 具备了暴露 JVM 指标的能力。 +运行服务之后,我们可以通过 `http://lcoalhost:8088` 访问服务暴露出来的 prometheus 格式的指标。 + +接着,您可以参考 [已有 JVM 指标的 Java 应用对接可观测性](./legacy-jvm.md)。 diff --git a/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md b/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md new file mode 100644 index 0000000..0112bf9 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md @@ -0,0 +1,88 @@ +# 已有 JVM 指标的 Java 应用对接可观测性 + +如果您的 Java 应用通过其他方式(比如 Spring Boot Actuator)暴露了 JVM 的监控指标, +我们需要让监控数据被采集到。您可以通过在工作负载中添加注解(Kubernetes Annotations)的方式让 Insight 来采集已有的 JVM 指标: + +```yaml +annatation: + insight.opentelemetry.io/metric-scrape: "true" # 是否采集 + insight.opentelemetry.io/metric-path: "/" # 采集指标的路径 + insight.opentelemetry.io/metric-port: "9464" # 采集指标的端口 +``` + +例如为 __my-deployment-app__ 添加注解: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-app +spec: + selector: + matchLabels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + replicas: 1 + template: + metadata: + labels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + annotations: + insight.opentelemetry.io/metric-scrape: "true" # 是否采集 + insight.opentelemetry.io/metric-path: "/" # 采集指标的路径 + insight.opentelemetry.io/metric-port: "9464" # 采集指标的端口 +``` + +以下是完整示例: + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + type: NodePort + selector: + #app: my-deployment-with-aotu-instrumentation-app + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + port: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + selector: + matchLabels: + #app: my-deployment-with-aotu-instrumentation-app + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + annotations: + insight.opentelemetry.io/metric-scrape: "true" # 是否采集 + insight.opentelemetry.io/metric-path: "/actuator/prometheus" # 采集指标的路径 + insight.opentelemetry.io/metric-port: "8080" # 采集指标的端口 + spec: + containers: + - name: myapp + image: docker.m.daocloud.io/wutang/spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + containerPort: 8080 + resources: + limits: + cpu: 500m + memory: 800Mi + requests: + cpu: 200m + memory: 400Mi +``` + +以上示例中,Insight 会通过 __:8080//actuator/prometheus__ 抓取通过 **Spring Boot Actuator** 暴露出来的 Prometheus 指标。 diff --git a/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md b/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md new file mode 100644 index 0000000..49f44dd --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md @@ -0,0 +1,23 @@ +# 使用 OpenTelemetry Java Agent 暴露 JVM 监控指标 + +在 Opentelemetry Agent v1.20.0 及以上版本中,Opentelemetry Agent 新增了 JMX Metric Insight 模块,如果你的应用已经集成了 Opentelemetry Agent 去采集应用链路,那么你不再需要另外引入其他 Agent 去为我们的应用暴露 JMX 指标。Opentelemetry Agent 也是通过检测应用程序中本地可用的 MBean 公开的指标,对其进行收集并暴露指标。 + +Opentelemetry Agent 也针对常见的 Java Server 或框架内置了一些监控的样例,请参考[预定义的指标](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/semantic-conventions.md)。 + +使用 OpenTelemetry Java Agent 同样需要考虑如何将 JAR 挂载进容器,除了可以参考上面 JMX Exporter 挂载 JAR 文件的方式外,我们还可以借助 Opentelemetry 提供的 Operator 的能力来实现自动为我们的应用开启 JVM 指标暴露: + +如果你的应用已经集成了 Opentelemetry Agent 去采集应用链路,那么你不再需要另外引入其他 Agent 去为我们的应用暴露 JMX 指标。Opentelemetry Agent 通过检测应用程序中本地可用的 MBean 公开的指标,现在可以本地收集并暴露指标接口。 + +但是,截至目前版本,你仍然需要手动为应用加上相应注解之后,JVM 数据才会被 Insight 采集到,具体注解内容请参考 [已有 JVM 指标的 Java 应用对接可观测性](./legacy-jvm.md)。 + +## 为 Java 中间件暴露指标 + +Opentelemetry Agent 也内置了一些中间件监控的样例,请参考 [预定义指标](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/jmx-metrics/javaagent/README.md#predefined-metrics)。 + +默认没有指定任何类型,需要通过 __-Dotel.jmx.target.system__ JVM Options 指定,比如 __-Dotel.jmx.target.system=jetty,kafka-broker__ 。 + +## 参考 + +- [Gaining JMX Metric Insights with the OpenTelemetry Java Agent](https://opentelemetry.io/blog/2023/jmx-metric-insight/) + +- [Otel jmx metrics](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/jmx-metrics) diff --git a/docs/zh/docs/admin/insight/quickstart/otel/java/mdc.md b/docs/zh/docs/admin/insight/quickstart/otel/java/mdc.md new file mode 100644 index 0000000..d5d0c3f --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/java/mdc.md @@ -0,0 +1,111 @@ +# 将 TraceId 和 SpanId 写入 Java 应用日志 + +本文介绍如何使用 OpenTelemetry 将 TraceId 和 SpanId 自动写入 Java 应用日志。 +TraceId 与 SpanId 写入日志后,您可以将分布式链路数据与日志数据关联起来,实现更高效的故障诊断和性能分析。 + +## 支持的日志库 + +更多信息,请参见 [Logger MDC auto-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/logger-mdc-instrumentation.md)。 + +| 日志框架 | 支持自动埋点的版本 | 手动埋点需要引入的依赖 | +| ------- | --------------- | ------------------ | +| Log4j 1 | 1.2+ | 无| +| Log4j 2 | 2.7+ | [opentelemetry-log4j-context-data-2.17-autoconfigure](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure) | +| Logback | 1.0+ | [opentelemetry-logback-mdc-1.0](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/logback/logback-mdc-1.0/library) | + +## 使用 Logback(SpringBoot 项目) + +Spring Boot 项目内置了日志框架,并且默认使用 Logback 作为其日志实现。如果您的 Java 项目为 SpringBoot 项目,只需少量配置即可将 TraceId 写入日志。 + +在 `application.properties` 中设置 `logging.pattern.level`,添加 `%mdc{trace_id}` 与 `%mdc{span_id}` 到日志中。 + +```bash +logging.pattern.level=trace_id=%mdc{trace_id} span_id=%mdc{span_id} %5p ....省略... +``` + +以下为日志示例: + +```console +2024-06-26 10:56:31.200 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2024-06-26 10:56:31.201 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2024-06-26 10:56:31.209 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms +2024-06-26 10:56:31.296 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=5743699405074f4e INFO 53724 --- [nio-8081-exec-1] com.example.httpserver.ot.OTServer : hello world +``` + +## 使用 Log4j2 + +1. 在 `pom.xml` 中添加 `OpenTelemetry Log4j2` 依赖: + + !!! tip + + 请将 `OPENTELEMETRY_VERSION` 替换为[最新版本](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions) + + ```xml + + + io.opentelemetry.instrumentation + opentelemetry-log4j-context-data-2.17-autoconfigure + OPENTELEMETRY_VERSION + runtime + + + ``` + +1. 修改 `log4j2.xml` 配置,在 `pattern` 中添加 `%X{trace_id}` 与 `%X{span_id}`,可以将 `TraceId` 与 `SpanId` 自动写入日志: + + ```xml + + + + + + + + + + + + + + ``` + +1. 使用 Logback 在 `pom.xml` 中添加 `OpenTelemetry Logback` 依赖。 + + !!! tip + + 请将 `OPENTELEMETRY_VERSION` 替换为[最新版本](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions) + + ```xml + + + io.opentelemetry.instrumentation + opentelemetry-logback-mdc-1.0 + OPENTELEMETRY_VERSION + + + ``` + +1. 修改 `log4j2.xml` 配置,在 `pattern` 中添加 `%X{trace_id}` 与 `%X{span_id}`,可以将 `TraceId` 与 `SpanId` 自动写入日志: + + ```xml + + + + + %d{HH:mm:ss.SSS} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %msg%n + + + + + + + + + + + + + + + ``` diff --git a/docs/zh/docs/admin/insight/quickstart/otel/operator.md b/docs/zh/docs/admin/insight/quickstart/otel/operator.md new file mode 100644 index 0000000..8f4e071 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/operator.md @@ -0,0 +1,555 @@ +# 通过 Operator 实现应用程序无侵入增强 + +> 目前只有 Java、NodeJs、Python、.Net、Golang 支持 Operator 的方式无侵入接入。 + +## 前提条件 + +请确保 insight-agent 已经就绪。如若没有,请参考[安装 insight-agent 采集数据](../install/install-agent.md)并确保以下三项就绪: + +- 为 insight-agent 开启 trace 功能 +- trace 数据的地址以及端口是否填写正确 +- deployment/insight-agent-opentelemetry-operator 和 + deployment/insight-agent-opentelemetry-collector 对应的 Pod 已经准备就绪 + +## 安装 Instrumentation CR + +!!! tip + + 从 Insight v0.22.0 开始,不再需要手动安装 Instrumentation CR。 + +在 `insight-system` 命名空间下安装,不同版本之间有一些细小的差别。 + +=== "Insight v0.21.x" + + ```bash + K8S_CLUSTER_UID=$(kubectl get namespace kube-system -o jsonpath='{.metadata.uid}') + kubectl apply -f - < language specific env vars -> common env vars -> instrument spec configs' vars + ``` + + 但是需要避免手动覆盖 OTEL_RESOURCE_ATTRIBUTES_NODE_NAME,它在 Operator 内部作为一个 + Pod 是否已经注入探针的标识,如果手动添加了,探针可能无法注入。 + +## 自动注入示例 Demo + +注意这个 `annotations` 是加在 spec.annotations 下的。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-app + labels: + app: my-app +spec: + selector: + matchLabels: + app: my-app + replicas: 1 + template: + metadata: + labels: + app: my-app + annotations: + instrumentation.opentelemetry.io/inject-java: "insight-system/insight-opentelemetry-autoinstrumentation" + spec: + containers: + - name: myapp + image: jaegertracing/vertx-create-span:operator-e2e-tests + ports: + - containerPort: 8080 + protocol: TCP +``` + +最终生成的 YAML 内容如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-deployment-with-sidecar-565bd877dd-nqkk6 + generateName: my-deployment-with-sidecar-565bd877dd- + namespace: default + uid: aa89ca0d-620c-4d20-8bc1-37d67bad4ea4 + resourceVersion: '2668986' + creationTimestamp: '2022-04-08T05:58:48Z' + labels: + app: my-pod-with-sidecar + pod-template-hash: 565bd877dd + annotations: + cni.projectcalico.org/containerID: 234eae5e55ea53db2a4bc2c0384b9a1021ed3908f82a675e4a92a49a7e80dd61 + cni.projectcalico.org/podIP: 192.168.134.133/32 + cni.projectcalico.org/podIPs: 192.168.134.133/32 + instrumentation.opentelemetry.io/inject-java: "insight-system/insight-opentelemetry-autoinstrumentation" +spec: + volumes: + - name: kube-api-access-sp2mz + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + defaultMode: 420 + - name: opentelemetry-auto-instrumentation + emptyDir: {} + initContainers: + - name: opentelemetry-auto-instrumentation + image: >- + ghcr.m.daocloud.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java + command: + - cp + - /javaagent.jar + - /otel-auto-instrumentation/javaagent.jar + resources: {} + volumeMounts: + - name: opentelemetry-auto-instrumentation + mountPath: /otel-auto-instrumentation + - name: kube-api-access-sp2mz + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + containers: + - name: myapp + image: ghcr.io/pavolloffay/spring-petclinic:latest + env: + - name: OTEL_JAVAAGENT_DEBUG + value: 'true' + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: 'true' + - name: SPLUNK_PROFILER_ENABLED + value: 'false' + - name: JAVA_TOOL_OPTIONS + value: ' -javaagent:/otel-auto-instrumentation/javaagent.jar' + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://insight-agent-opentelemetry-collector.svc.cluster.local:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: '20' + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: '0.85' + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: 'true' + - name: OTEL_SERVICE_NAME + value: my-deployment-with-sidecar + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES_POD_UID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.uid + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES + value: >- + k8s.container.name=myapp,k8s.deployment.name=my-deployment-with-sidecar,k8s.deployment.uid=8de6929d-dda0-436c-bca1-604e9ca7ea4e,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.pod.uid=$(OTEL_RESOURCE_ATTRIBUTES_POD_UID),k8s.replicaset.name=my-deployment-with-sidecar-565bd877dd,k8s.replicaset.uid=190d5f6e-ba7f-4794-b2e6-390b5879a6c4 + - name: OTEL_PROPAGATORS + value: jaeger,b3 + resources: {} + volumeMounts: + - name: kube-api-access-sp2mz + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + - name: opentelemetry-auto-instrumentation + mountPath: /otel-auto-instrumentation + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + nodeName: k8s-master3 + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + schedulerName: default-scheduler + tolerations: + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + priority: 0 + enableServiceLinks: true + preemptionPolicy: PreemptLowerPriority +``` + +## 链路查询 + +如何查询已经接入的服务,参考[链路查询](../../trace/trace.md)。 diff --git a/docs/zh/docs/admin/insight/quickstart/otel/otel.md b/docs/zh/docs/admin/insight/quickstart/otel/otel.md new file mode 100644 index 0000000..5e18a38 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/otel.md @@ -0,0 +1,30 @@ +# 使用 OTel 赋予应用可观测性 + +> 增强是使应用程序代码能够生成遥测数据的过程。即一些可以帮助您监视或测量应用程序的性能和状态的东西。 + +OpenTelemetry 是领先的开源项目,为主要编程语言和流行框架提供检测库。它是云原生计算基金会下的一个项目,得到了社区庞大资源的支持。 +它为采集的数据提供标准化的数据格式,无需集成特定的供应商。 + +Insight 支持用于检测应用程序的 OpenTelemetry 来增强您的应用程序。 + +本指南介绍了使用 OpenTelemetry 进行遥测增强的基本概念。 +OpenTelemetry 还有一个由库、插件、集成和其他有用工具组成的生态系统来扩展它。 +您可以在 [Otel Registry](https://opentelemetry.io/registry/) 中找到这些资源。 + +您可以使用任何开放标准库进行遥测增强,并使用 Insight 作为可观察性后端来摄取、分析和可视化数据。 + +为了增强您的代码,您可以使用 OpenTelemetry 为特定语言提供的增强操作: + +Insight 目前提供了使用 OpenTelemetry 增强 .Net NodeJS、Java、Python 和 Golang 应用程序的简单方法。请遵循以下指南。 + +## 链路增强 + +- 链路接入的最佳实践:[通过 Operator 实现应用程序无侵入增强](./operator.md) +- 以 Go 语言为例的手动埋点接入:[使用 OpenTelemetry SDK 增强 Go 应用程序](./golang/golang.md) +- [利用 ebpf 实现 Go 语言无侵入探针](https://github.com/keyval-dev/opentelemetry-go-instrumentation/blob/master/docs/getting-started/README.md)(实验性功能) + + diff --git a/docs/zh/docs/admin/insight/quickstart/otel/send_tracing_to_insight.md b/docs/zh/docs/admin/insight/quickstart/otel/send_tracing_to_insight.md new file mode 100644 index 0000000..a8351c9 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/otel/send_tracing_to_insight.md @@ -0,0 +1,99 @@ +# 向 Insight 发送链路数据 + +此文档主要描述客户应用如何自行将链路数据上报给 Insight。主要包含如下两种场景: + +1. 客户应用通过 OTEL Agent/SDK 上报链路给 Insight +2. 通过 Opentelemtry Collector(简称 OTEL COL) 将链路转发给 Insight + +在每个已安装 Insight Agent 的集群中都有 __insight-agent-otel-col__ 组件用于统一接收该集群的链路数据。 +因此,该组件作为用户接入侧的入口,需要先获取该地址。可以通过 AI 算力中心 界面获取该集群 Opentelemtry Collector 的地址, +比如 __insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317__ : + +![image](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/quickstart/images/get_insight_agent_otel_col_svc.png) + +除此之外,针对不同上报方式,有一些细微差别: + +## 客户应用通过 OTel Agent/SDK 上报链路给 Insight Agent Opentelemtry Collector + +为了能够将链路数据正常上报至 Insight 并能够在 Insight 正常展示,需要并建议通过如下环境变量提供 OTLP 所需的元数据 (Resource Attribute),有两种方式可实现: + +- 在部署文件 YAML 中手动添加,例如: + + ```yaml + ... + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317" + - name: "OTEL_SERVICE_NAME" + value: my-java-app-name + - name: "OTEL_K8S_NAMESPACE" + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)" + ``` + +- 利用 Insight Agent 自动注入如上元数据 (Resource Attribute) 能力 + + 确保 Insight Agent 正常工作并 [安装 Instrumentation CR](./operator.md#instrumentation-cr) 之后, + 只需要为 Pod 添加如下 Annotation 即可: + + ```console + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + + 举例: + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-deployment-with-aotu-instrumentation + spec: + selector: + matchLabels: + app.kubernetes.io/name: my-deployment-with-aotu-instrumentation-kuberntes + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: my-deployment-with-aotu-instrumentation-kuberntes + annotations: + sidecar.opentelemetry.io/inject: "false" + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + +## 通过 Opentelemtry Collector 将链路转发给 Insight Agent Opentelemtry Collector + +在保证应用添加了如上元数据之后,只需在客户 Opentelemtry Collector 里面新增一个 OTLP Exporter 将链路数据转发给 +Insight Agent Opentelemtry Collector 即可,如下 Opentelemtry Collector 配置文件所示: + +```yaml +... +exporters: + otlp/insight: + endpoint: insight-opentelemetry-collector.insight-system.svc.cluster.local:4317 +service: +... +pipelines: +... +traces: + exporters: + - otlp/insight +``` + +## 参考 + +- [通过 Operator 实现应用程序无侵入增强](./operator.md) +- [使用 OTel 赋予应用可观测性](./otel.md) diff --git a/docs/zh/docs/admin/insight/quickstart/other/install-agent-on-ocp.md b/docs/zh/docs/admin/insight/quickstart/other/install-agent-on-ocp.md new file mode 100644 index 0000000..bfc6782 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/other/install-agent-on-ocp.md @@ -0,0 +1,68 @@ +# OpenShift 安装 Insight Agent + +虽然 OpenShift 系统自带了一套监控系统,因为数据采集约定的一些规则,我们还是会安装 Insight Agent。 + +其中,安除了基础的安装配置之外,helm install 的时候还需要增加如下的参数: + +```bash +## 针对 fluentbit 相关的参数; +--set fluent-bit.ocp.enabled=true \ +--set fluent-bit.serviceAccount.create=false \ +--set fluent-bit.securityContext.runAsUser=0 \ +--set fluent-bit.securityContext.seLinuxOptions.type=spc_t \ +--set fluent-bit.securityContext.readOnlyRootFilesystem=false \ +--set fluent-bit.securityContext.allowPrivilegeEscalation=false \ + +## 启用适配 OpenShift4.x 的 Prometheus(CR) +--set compatibility.openshift.prometheus.enabled=true \ + +## 关闭高版本的 Prometheus 实例 +--set kube-prometheus-stack.prometheus.enabled=false \ +--set kube-prometheus-stack.kubeApiServer.enabled=false \ +--set kube-prometheus-stack.kubelet.enabled=false \ +--set kube-prometheus-stack.kubeControllerManager.enabled=false \ +--set kube-prometheus-stack.coreDns.enabled=false \ +--set kube-prometheus-stack.kubeDns.enabled=false \ +--set kube-prometheus-stack.kubeEtcd.enabled=false \ +--set kube-prometheus-stack.kubeEtcd.enabled=false \ +--set kube-prometheus-stack.kubeScheduler.enabled=false \ +--set kube-prometheus-stack.kubeStateMetrics.enabled=false \ +--set kube-prometheus-stack.nodeExporter.enabled=false \ + +## 限制 PrometheusOperator 处理的 namespace,避免与 OpenShift 自带的 PrometheusOperator 相互竞争 +--set kube-prometheus-stack.prometheusOperator.kubeletService.namespace="insight-system" \ +--set kube-prometheus-stack.prometheusOperator.prometheusInstanceNamespaces="insight-system" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[0]="openshift-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[1]="openshift-user-workload-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[2]="openshift-customer-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[3]="openshift-route-monitor-operator" \ +``` + +### 通过 OpenShift 自身机制,将系统监控数据写入 Prometheus 中 + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-monitoring-config + namespace: openshift-monitoring +data: + config.yaml: | + prometheusK8s: + remoteWrite: + - queueConfig: + batchSendDeadline: 60s + maxBackoff: 5s + minBackoff: 30ms + minShards: 1 + capacity: 5000 + maxSamplesPerSend: 1000 + maxShards: 100 + remoteTimeout: 30s + url: http://insight-agent-prometheus.insight-system.svc.cluster.local:9090/api/v1/write + writeRelabelConfigs: + - action: keep + regex: etcd|kubelet|node-exporter|apiserver|kube-state-metrics + sourceLabels: + - job +``` diff --git a/docs/zh/docs/admin/insight/quickstart/res-plan/index.md b/docs/zh/docs/admin/insight/quickstart/res-plan/index.md new file mode 100644 index 0000000..9504def --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/res-plan/index.md @@ -0,0 +1,19 @@ +# 部署容量规划 + +默认情况下,可观测性模块为了避免消耗过多资源,已经设置了资源上线(resource limit),可观测系统需要处理大量的数据,如果容量规划不合理,可能会导致系统负载过高,影响稳定性和可靠性。 + +## 观测组件的资源规划 + +可观测性模块包含 Insight 和 Insight Agent。其中,Insight 主要负责观测数据的存储,分析与展示。而 Insight Agent 包含了数据采集、数据处理、数据上传等功能。 + +### 存储组件的容量规划 + +Insight 的存储组件主要包括 ElasticSearch 和 VictoriaMetrics. 其中,ElasticSearch 主要负责存储和查询日志与链路数据,VictoriaMetrics 主要负责存储和查询指标数据。 + +* **VictoriaMetircs**: 其磁盘用量与存储的指标有关,根据 [vmstorage 的磁盘规划](./vms-res-plan.md) 预估容量后 [调整 vmstorage 磁盘](./modify-vms-disk.md)。 + +### 采集器的资源规划 + +Insight Agent 的采集器中包含 Proemtheus,虽然 Prometheus 本身是一个独立的组件,但是在 Insight Agent 中,Prometheus 会被用于采集数据,因此需要对 Prometheus 的资源进行规划。 + +* **Prometheus**:其资源用量与采集的指标量有关,可以参考 [Prometheus 资源规划](./prometheus-res.md) 进行调整。 diff --git a/docs/zh/docs/admin/insight/quickstart/res-plan/modify-vms-disk.md b/docs/zh/docs/admin/insight/quickstart/res-plan/modify-vms-disk.md new file mode 100644 index 0000000..0ac83ab --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/res-plan/modify-vms-disk.md @@ -0,0 +1,86 @@ +# vmstorge 磁盘扩容 + +本文描述了 vmstorge 磁盘扩容的方法, +vmstorge 磁盘规范请参考 [vmstorage 磁盘容量规划](../res-plan/vms-res-plan.md)。 + +## 操作步骤 + +### 开启存储池扩容 + +1. 以全局服务集群管理员权限登录 AI 算力中心 平台,点击 __容器管理__ -> __集群列表__ ,点击 __kpanda-global-cluster__ 集群。 + +1. 选择左侧导航 __容器存储__ -> __数据卷声明(PVC)__ ,找到 vmstorage 绑定的数据卷声明。 + + ![找到vmstorage](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk01.png) + +1. 点击某个 vmstorage PVC,进入 vmstorage 的数据卷声明详情,确认该 PVC 绑定的存储池。 + + ![修改磁盘](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk02.png) + +1. 选择左侧导航 __容器存储__ -> __存储池(SC)__ ,找到 __local-path__ ,点击目标右侧的 __┇__ ,在弹出菜单中选择 __编辑__ 。 + + ![编辑存储池](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk03.png) + +1. 开启 __扩容__ 后点击 __确定__ 。 + + ![开启扩容](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk04.png) + +### 更改 vmstorage 的磁盘容量 + +1. 以全局服务集群管理员权限登录 AI 算力中心 平台,进入 __kpanda-global-cluster__ 集群详情。 + +1. 选择左侧导航 __自定义资源__ ,找到 __vmcluster__ 的自定义资源。 + + ![vmcluster](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk05.png) + +1. 点击该 vmcluster 自定义资源进入详情页,切换到 __insight-system__ 命名空间下,从 __insight-victoria-metrics-k8s-stack__ 右侧菜单选择 __编辑 YAML__ 。 + + ![编辑 YAML](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk06.png) + +1. 根据图例修改后点击 __确定__ 。 + + ![修改 YAML](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk07.png) + +1. 再次选择左侧导航 __容器存储__ -> __数据卷声明(PVC)__ ,找到 vmstorage 绑定的数据卷声明确认修改已生效。在某个 PVC 详情页,点击关联存储源 (PV)。 + + ![关联存储源](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk08.png) + +1. 打开数据卷详情页,点击右上角 __更新__ 按钮。 + + ![更新](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk09.png) + +1. 修改 __容量__ 后点击 __确定__ ,稍等片刻等到扩容成功。 + + ![修改容量](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk10.png) + +### 克隆存储卷 + +若存储卷扩容失败,可参考以下方法克隆存储卷。 + +1. 以全局服务集群管理员权限登录 AI 算力中心 平台,进入 __kpanda-global-cluster__ 集群详情。 + +1. 选择左侧导航 __工作负载__ -> __有状态负载__ ,找到 __vmstorage__ 的有状态负载,点击目标右侧的 __┇__ ,在弹出菜单中选择 __状态__ -> __停止__ -> __确定__ 。 + + ![状态停止](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk11.png) + +1. 在命令行中登录 __kpanda-global-cluster__ 集群的 __master__ 节点后,执行以下命令复制 vmstorage 容器中的 vm-data 目录将指标信息存储在本地: + + ```bash + kubectl cp -n insight-system vmstorage-insight-victoria-metrics-k8s-stack-1:vm-data ./vm-data + ``` + +1. 登录 AI 算力中心 平台进入 __kpanda-global-cluster__ 集群详情,选择左侧导航 __容器存储__ -> __数据卷(PV)__ ,点击右上角的 __克隆__ ,并修改数据卷的容量。 + + ![克隆](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk15.png) + + ![修改容量](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk12.png) + +1. 删除之前 vmstorage 的数据卷。 + + ![删除数据卷](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk13.png) + +1. 稍等片刻,待存储卷声明跟克隆的数据卷绑定后,执行以下命令将第 3 步中导出的数据导入到对应的容器中,然后开启之前暂停的 __vmstorage__ 。 + + ```bash + kubectl cp -n insight-system ./vm-data vmstorage-insight-victoria-metrics-k8s-stack-1:vm-data + ``` diff --git a/docs/zh/docs/admin/insight/quickstart/res-plan/prometheus-res.md b/docs/zh/docs/admin/insight/quickstart/res-plan/prometheus-res.md new file mode 100644 index 0000000..ff5e759 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/res-plan/prometheus-res.md @@ -0,0 +1,49 @@ +# Prometheus 资源规划 + +Prometheus 在实际使用过程中,受到集群容器数量以及开启 Istio 的影响,会导致 Prometheus 的 CPU、内存等资源使用量超出设定的资源。 + +为了保证不同规模集群下 Prometheus 的正常运行,需要根据集群的实际规模对 Prometheus 进行资源调整。 + +## 参考资源规划 + +在未开启网格情况下,测试情况统计出系统 Job 指标量与 Pod 的关系为 **Series 数量 = 800 \* Pod 数量** + +在开启服务网格时,开启功能后 Pod 产生的 Istio 相关指标数量级为 **Series 数量 = 768 \* Pod 数量** + +### 当未开启服务网格时 + +以下资源规划为 **未开启服务网格** 场景下,Prometheus 的资源规划推荐: + +| 集群规模(Pod 数) | 指标量(未开启服务网格) | CPU(core) | 内存(GB) | +| ---------------- | ---------------------- | ------------------------ | ---------------------------- | +| 100 | 8w | Request: 0.5
Limit:1 | Request:2GB
Limit:4GB | +| 200 | 16w | Request:1
Limit:1.5 | Request:3GB
Limit:6GB | +| 300 | 24w | Request:1
Limit:2 | Request:3GB
Limit:6GB | +| 400 | 32w | Request:1
Limit:2 | Request:4GB
Limit:8GB | +| 500 | 40w | Request:1.5
Limit:3 | Request:5GB
Limit:10GB | +| 800 | 64w | Request:2
Limit:4 | Request:8GB
Limit:16GB | +| 1000 | 80w | Request:2.5
Limit:5 | Request:9GB
Limit:18GB | +| 2000 | 160w | Request:3.5
Limit:7 | Request:20GB
Limit:40GB | +| 3000 | 240w | Request:4
Limit:8 | Request:33GB
Limit:66GB | + +### 当开启服务网格功能时 + +以下资源规划为 **开启服务网格** 场景下,Prometheus 的资源规划推荐: + +| 集群规模(Pod 数) | 指标量(已开启服务网格) | CPU(core) | 内存(GB) | +| ---------------- | ---------------------- | ----------------------- | ----------------------------- | +| 100 | 15w | Request: 1
Limit:2 | Request:3GB
Limit:6GB | +| 200 | 31w | Request:2
Limit:3 | Request:5GB
Limit:10GB | +| 300 | 46w | Request:2
Limit:4 | Request:6GB
Limit:12GB | +| 400 | 62w | Request:2
Limit:4 | Request:8GB
Limit:16GB | +| 500 | 78w | Request:3
Limit:6 | Request:10GB
Limit:20GB | +| 800 | 125w | Request:4
Limit:8 | Request:15GB
Limit:30GB | +| 1000 | 156w | Request:5
Limit:10 | Request:18GB
Limit:36GB | +| 2000 | 312w | Request:7
Limit:14 | Request:40GB
Limit:80GB | +| 3000 | 468w | Request:8
Limit:16 | Request:65GB
Limit:130GB | + +!!! note + + 1. 表格中的 __Pod 数量__ 指集群中基本稳定运行的 Pod 数量,如出现大量的 Pod 重启,则会造成短时间内指标量的陡增,此时资源需要进行相应上调。 + 2. Prometheus 内存中默认保存两小时数据,且集群中开启了 [Remote Write 功能](https://prometheus.io/docs/practices/remote_write/#memory-usage)时,会占用一定内存,资源超配比建议配置为 2。 + 3. 表格中数据为推荐值,适用于通用情况。如环境有精确的资源要求,建议在集群运行一段时间后,查看对应 Prometheus 的资源占用量进行精确配置。 diff --git a/docs/zh/docs/admin/insight/quickstart/res-plan/vms-res-plan.md b/docs/zh/docs/admin/insight/quickstart/res-plan/vms-res-plan.md new file mode 100644 index 0000000..59aebc6 --- /dev/null +++ b/docs/zh/docs/admin/insight/quickstart/res-plan/vms-res-plan.md @@ -0,0 +1,74 @@ +# vmstorage 磁盘容量规划 + +vmstorage 是负责存储可观测性多集群指标。 +为保证 vmstorage 的稳定性,需要根据集群数量及集群规模调整 vmstorage 的磁盘容量。 +更多资料请参考:[vmstorage 保留期与磁盘空间](https://docs.victoriametrics.com/guides/understand-your-setup-size.html?highlight=datapoint#retention-perioddisk-space)。 + +## 测试结果 + +经过 14 天对不同规模的集群的 vmstorage 的磁盘观测, +我们发现 vmstorage 的磁盘用量与其存储的指标量和单个数据点占用磁盘正相关。 + +1. 瞬时存储的指标量 __increase(vm_rows{ type != "indexdb"}[30s])__ 以获取 30s 内增加的指标量 +2. 单个数据点 (datapoint) 的占用磁盘: __sum(vm_data_size_bytes{type!="indexdb"}) / sum(vm_rows{type != "indexdb"})__ + +## 计算方法 + +**磁盘用量** = 瞬时指标量 x 2 x 单个数据点的占用磁盘 x 60 x 24 x 存储时间 (天) + +**参数说明:** + +1. 磁盘用量单位为 __Byte__ 。 +2. __存储时长(天) x 60 x 24__ 将时间(天)换算成分钟以便计算磁盘用量。 +3. Insight Agent 中 Prometheus 默认采集时间为 30s ,故在 1 分钟内产生两倍的指标量。 +4. vmstorage 中默认存储时长为 1 个月,修改配置请参考[修改系统配置](../../system-config/modify-config.md)。 + +!!! warning + + 该公式为通用方案,建议在计算结果上预留冗余磁盘容量以保证 vmstorage 的正常运行。 + +## 参考容量 + +表格中数据是根据默认存储时间为一个月 (30 天),单个数据点 (datapoint) 的占用磁盘取 0.9 计算所得结果。 +多集群场景下,Pod 数量表示多集群 Pod 数量的总和。 + +### 当未开启服务网格时 + +| 集群规模 (Pod 数) | 指标量 | 磁盘容量 | +| ----------------- | ------ | -------- | +| 100 | 8w | 6 GiB | +| 200 | 16w | 12 GiB | +| 300 | 24w | 18 GiB | +| 400 | 32w | 24 GiB | +| 500 | 40w | 30 GiB | +| 800 | 64w | 48 GiB | +| 1000 | 80w | 60 GiB | +| 2000 | 160w | 120 GiB | +| 3000 | 240w | 180 GiB | + +### 当开启服务网格时 + +| 集群规模 (Pod 数) | 指标量 | 磁盘容量 | +| ----------------- | ------ | -------- | +| 100 | 15w | 12 GiB | +| 200 | 31w | 24 GiB | +| 300 | 46w | 36 GiB | +| 400 | 62w | 48 GiB | +| 500 | 78w | 60 GiB | +| 800 | 125w | 94 GiB | +| 1000 | 156w | 120 GiB | +| 2000 | 312w | 235 GiB | +| 3000 | 468w | 350 GiB | + +### 举例说明 + +AI 算力中心 平台中有两个集群,其中全局服务集群(开启服务网格)中运行 500 个 Pod,工作集群(未开启服务网格)运行了 1000 个 Pod,预期指标存 30 天。 + +- 全局服务集群中指标量为 800x500 + 768x500 = 784000 +- 工作集群指标量为 800x1000 = 800000 + +则当前 vmstorage 磁盘用量应设置为 (784000+80000)x2x0.9x60x24x31 = 124384896000 byte = 116 GiB + +!!! note + + 集群中指标量与 Pod 数量的关系可参考[Prometheus 资源规划](./prometheus-res.md)。 diff --git a/docs/zh/docs/admin/insight/reference/alertnotification.md b/docs/zh/docs/admin/insight/reference/alertnotification.md new file mode 100644 index 0000000..2f97d34 --- /dev/null +++ b/docs/zh/docs/admin/insight/reference/alertnotification.md @@ -0,0 +1,64 @@ +# 告警通知流程说明 + +在创建告警策略时,可观测性 Insight 支持为同策略下不同级别触发的告警配置不同的通知发送间隔,但由于在 Alertmanager 原生配置中存在 __group_interval__ 和 __repeat_interval__ 两个参数,会导致告警通知的实际发送间隔存在偏差。 + +## 参数配置 + +在 Alertmanager 配置如下: + +```yaml +route: + group_by: ["rulename"] + group_wait: 30s + group_interval: 5m + repeat_interval: 1h +``` + +**参数说明:** + +- __group_wait__ :用于设置告警通知的等待时间。当 Alertmanager 接收到一组告警时,如果在 __group_wait__ 指定的时间内没有更多的告警,则 Alertmanager 将等待一段时间以便收集到更多相同标签和内容的告警,并将所有符合条件的告警添加到同一通知中。 + +- __group_interval__ :用于设置一组告警在被合并成单一通知前等待的时间。如果在这个时间内没有收到更多的来自同一组的告警,则 Alertmanager 将发送一个包含所有已接收告警的通知。 + +- __repeat_interval__ :用于设置告警通知的重复发送间隔。当 Alertmanager 发送告警通知到接收器后,如果在 __repeat_interval__ 参数指定的时间内持续收到相同标签和内容的告警,则 Alertmanager 将重复发送告警通知。 + +当同时设置了 __group_wait__ 、 __group_interval__ 和 __repeat_interval__ 参数时,Alertmanager 将按照以下方式处理同一 group 下的告警通知: + +1. 当 Alertmanager 接收到符合条件的告警时,它将等待至少 __group_wait__ 参数中指定的时间以便收集更多相同标签和内容的告警,并将所有符合条件的告警添加到同一通知中。 + +2. 如果在 __group_wait__ 时间内没有接收到更多的告警,则在该时间之后,Alertmanager 会将所收到的所有此类警报发送到接收器。如果有其他符合条件的告警在此期间内到达,则 Alertmanager 将继续等待,直到收集到所有告警或超时。 + +3. 如果在 __group_interval__ 参数中指定的时间内接收到了更多的相同标签和内容的告警,则这些新告警也将被添加到先前的通知中并一起发送。如果在 __group_interval__ 时间结束后仍然有未发送的告警,Alertmanager 将会重新开始一个新的计时周期,并等待更多的告警,直到再次达到 __group_interval__ 时间或收到新的告警。 + +4. 如果在 __repeat_interval__ 参数中指定的时间内持续收到相同标签和内容的告警,则 Alertmanager 将重复发送之前已经发送过的警报通知。在重复发送警报通知时,Alertmanager 不再等待 __group_wait__ 或 __group_interval__ ,而是根据 __repeat_interval__ 指定的时间间隔进行重复通知。 + +5. 如果在 __repeat_interval__ 时间结束后仍有未发送的告警,则 Alertmanager 将重新开始一个新的计时周期,并继续等待相同标签和内容的新告警。这个过程将一直持续下去,直到没有新告警为止或 Alertmanager 被停止。 + +## 举例说明 + +在下述示例中,Alertmanager 将所有 CPU 使用率高于阈值的告警分配到一个名为“critical_alerts”的策略中。 + +```yaml +groups: +- name: critical_alerts + rules: + - alert: HighCPUUsage + expr: node_cpu_seconds_total{mode="idle"} < 50 + for: 5m + labels: + severity: critical + annotations: + summary: "High CPU usage detected on instance {{ $labels.instance }}" + group_by: [rulename] + group_wait: 30s + group_interval: 5m + repeat_interval: 1h +``` + +在这种情况下: + +- 当 Alertmanager 收到告警时,它将等待至少 30 秒以便收集更多相同标签和内容的告警,并将它们添加到同一通知中。 +- 如果在 5 分钟内接收到了更多相同标签和内容的告警,则这些新告警也将被添加到先前的通知中并一起发送。如果在 15分钟后仍有未发送的告警,则 Alertmanager 将重新开始一个新的计时周期,并等待更多的告警,直到再次达到 5 分钟或收到新告警。 +- 如果在 1 小时内持续收到相同标签和内容的告警,则 Alertmanager 将重复发送之前已经发送过的警报通知。 + + ![安装](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/alertnotifacation.png) diff --git a/docs/zh/docs/admin/insight/reference/lucene.md b/docs/zh/docs/admin/insight/reference/lucene.md new file mode 100644 index 0000000..453b954 --- /dev/null +++ b/docs/zh/docs/admin/insight/reference/lucene.md @@ -0,0 +1,176 @@ +# Lucene 语法使用方法 + +## Lucene 简介 + +Lucene 是 Apache 软件基金会 4 jakarta 项目组的一个子项目,是一个开放源代码的全文检索引擎工具包。 +Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能。 + +## Lucene 语法 + +Lucene 的语法搜索格式允许您以灵活的方式构建搜索查询,以满足不同的搜索需求。以下是 Lucene 的语法搜索格式的详细说明: + +### 关键字查询 + +要通过 Lucene 语法实现多个关键字的查询,您可以使用布尔逻辑操作符来组合多个关键字。Lucene 支持以下几种操作符: + +1. AND 操作符 + + - 使用  __AND__  或  __&&__  来表示逻辑与关系。 + - 例如: __term1 AND term2__  或  __term1 && term2__ + +2. OR 操作符 + + - 使用  __OR__  或  __||__  来表示逻辑或关系。 + - 例如: __term1 OR term2__  或  __term1 || term2__ + +3. NOT 操作符 + + - 使用  __NOT__  或 `` 来表示逻辑非关系。 + - 例如: __term1 NOT term2__  或  __term1 -term2__ + +4. 引号 + + - 您可以将一个短语括在引号中以进行精确匹配。 + - 例如: __"exact phrase"__ + +#### 举例 + +1. 指定字段 + + ```lucene + field1:keyword1 AND (field2:keyword2 OR field3:keyword3) NOT field4:keyword4 + ``` + + 解释如下: + + - 查询字段  __field1__  必须包含关键字  __keyword1__ 。 + - 同时,字段  __field2__  必须包含关键字  __keyword2__  或字段  __field3__  必须包含关键字  __keyword3__ 。 + - 最后,字段  __field4__  不得包含关键字  __keyword4__ 。 + +2. 不指定字段 + + ```lucene + keyword1 AND (keyword2 OR keyword3) NOT keyword4 + ``` + + 解释如下: + + - 查询关键字  __keyword1__  必须存在于任意可搜索的字段中。 + - 同时,关键字  __keyword2__  必须存在或关键字  __keyword3__  必须存在于任意可搜索的字段中。 + - 最后,关键字  __keyword4__  不得存在于任意可搜索的字段中。 + +### 模糊查询 + +在 Lucene 中,模糊查询可以通过波浪号 __~__ 来实现近似匹配。您可以指定一个编辑距离来限制匹配的相似度程度。 + +```lucene +term~ +``` + +在上述示例中, __term__ 是要进行模糊匹配的关键字。 + +请注意以下几点: + +- 波浪号  __~__  后面可以指定一个可选的参数,用于控制模糊查询的相似度。 +- 参数值范围为 0 到 2 之间,其中 0 表示完全匹配,1 表示一次编辑操作(如增加、删除或替换字符)内可以匹配,2 表示两次编辑操作内可以匹配。 +- 如果不指定参数值,默认使用 0.5 作为相似度阈值。 +- 模糊查询将返回与给定关键字相似的文档,但会有一定的性能开销,特别是对于较大的索引。 + +### 通配符 + +Lucene 支持以下两种通配符查询: + +1. `*` 通配符: `*` 用于匹配零个或多个字符。 + + 例如, __te*t__  可以匹配 "test"、"text"、"tempest" 等。 + +2. `?` 通配符: `?` 用于匹配单个字符。 + + 例如, __te?t__  可以匹配 "test"、"text" 等。 + +#### 举例说明 + +```lucene +te?t +``` + +在上述示例中, __te?t__ 表示匹配以 "te" 开头,接着是一个任意字符,然后以 "t" 结尾的词。这种查询可以匹配例如 "test"、"text"、"tent" 等。 + +需要注意的是,问号只能代表一个字符,如果想要匹配多个字符或者是可变长度的字符,可以使用星号 `*` 进行多字符通配符匹配。 +另外,问号不会匹配空字符串。 + +总结一下,Lucene 语法中的问号 `?` 用作单字符通配符,表示匹配任意一个字符。通过在搜索关键字中使用问号,您可以进行更灵活和具体的模式匹配。 + +### 范围查询 + +Lucene 语法支持范围查询,您可以使用方括号 __[ ]__ 或花括号 __{ }__ 来表示范围。以下是范围查询的示例: + +1. 包含边界的范围查询: + + - 方括号  __[ ]__  表示闭区间,包含边界值。 + - 例如: __field:[value1 TO value2]__  表示  __field__  的取值范围从  __value1__  到  __value2__ (包含两者)。 + +2. 排除边界的范围查询: + + - 花括号  __{ }__  表示开区间,排除边界值。 + - 例如: __field:{value1 TO value2}__  表示  __field__  的取值范围在  __value1__  和  __value2__  之间(不包含两者)。 + +3. 省略边界的范围查询: + + - 可以省略一个或两个边界值来指定无限范围。 + - 例如: __field:[value TO ]__  表示  __field__  的取值范围从  __value__  到正无穷, __field:[ TO value]__  表示  __field__  的取值范围从负无穷到  __value__ 。 + + !!! note + + 请注意,范围查询只适用于能够进行排序的字段类型,如数字、日期等。同时,确保在查询时将边界值正确地指定为字段的实际值类型。 + 如果您希望在整个索引中进行范围查询而不指定特定字段,可以使用通配符查询 `*` 来代替字段名。 + +#### 举例说明 + +1. 指定字段 + + ```lucene + timestamp:[2022-01-01 TO 2022-01-31] + ``` + + 这将检索 __timestamp__ 字段在 2022 年 1 月 1 日到 2022 年 1 月 31 日之间的数据。 + +2. 不指定字段 + + ```lucene + *:[value1 TO value2] + ``` + + 这将在整个索引中搜索取值范围从 __value1__ 到 __value2__ 的文档。 + +## Insight 常用关键字 + +## 容器日志 + +- kubernetes.container_image: 容器镜像名称 +- kubernetes.container_name: 容器名称 +- kubernetes.namespace_name: 命名空间名称 +- kubernetes.pod_name: Pod 名称 +- log: 日志内容 +- time: 日志时间戳 + +## 主机日志 + +- syslog.file: 日志文件路径 +- syslog.host: 主机名称 +- log: 日志内容 + +如果你想要精确匹配某个特定的值,可以在关键字后加入 `.keyword` 后缀,例如 `kubernetes.container_name.keyword`。 + +## 示例 + +1. 查询指定 Pod 中指定容器的日志 + + ```lucene + kubernetes.pod_name.keyword:nginx-pod AND kubernetes.container_name.keyword:nginx + ``` +2. 查询 Pod 名称中包含 `nginx-pod` 的容器日志 + + ```lucene + kubernetes.pod_name:nginx-pod + ``` \ No newline at end of file diff --git a/docs/zh/docs/admin/insight/reference/notify-helper.md b/docs/zh/docs/admin/insight/reference/notify-helper.md new file mode 100644 index 0000000..4928252 --- /dev/null +++ b/docs/zh/docs/admin/insight/reference/notify-helper.md @@ -0,0 +1,184 @@ +# 通知模板使用说明 + +## 模板语法(Go Template)说明 + +告警通知模板采用了 [Go Template](https://pkg.go.dev/text/template) 语法来渲染模板。 + +模板会基于下面的数据进行渲染。 + +```json +{ + "status": "firing", + "labels": { + "alertgroup": "test-group", // 告警策略名称 + "alertname": "test-rule", // 告警规则名称 + "cluster": "35b54a48-b66c-467b-a8dc-503c40826330", + "customlabel1": "v1", + "customlabel2": "v2", + "endpoint": "https", + "group_id": "01gypg06fcdf7rmqc4ksv97646", + "instance": "10.6.152.85:6443", + "job": "apiserver", + "namespace": "default", + "prometheus": "insight-system/insight-agent-kube-prometh-prometheus", + "prometheus_replica": "prometheus-insight-agent-kube-prometh-prometheus-0", + "rule_id": "01gypg06fcyn2g9zyehbrvcdfn", + "service": "kubernetes", + "severity": "critical", + "target": "35b54a48-b66c-467b-a8dc-503c40826330", + "target_type": "cluster" + }, + "annotations": { + "customanno1": "v1", + "customanno2": "v2", + "description": "这是一条测试规则,10.6.152.85:6443 down", + "value": "1" + }, + "startsAt": "2023-04-20T07:53:54.637363473Z", + "endsAt": "0001-01-01T00:00:00Z", + "generatorURL": "http://vmalert-insight-victoria-metrics-k8s-stack-df987997b-npsl9:8080/vmalert/alert?group_id=16797738747470868115&alert_id=10071735367745833597", + "fingerprint": "25c8d93d5bf58ac4" +} +``` + +### 使用说明 + +1. `.` 字符 + + 在当前作用域下渲染指定对象。 + + 示例 1: 取顶级作用域下的所有内容,即示例代码中上下文数据的全部内容。 + + ```go + {{ . }} + ``` + +2. 判断语句 __if / else__ + + 使用 if 检查数据,如果不满足可以执行 else。 + + ```go + {{if .Labels.namespace }}命名空间:{{ .Labels.namespace }} \n{{ end }} + ``` + +3. 循环函数 __for__ + + for 函数用于重复执行代码内容。 + + 示例 1: 遍历 labels 列表,获取告警的所有 label 内容。 + + ```go + {{ for .Labels}} \n {{end}} + ``` + +## 函数说明 FUNCTIONS + +Insight 的”通知模板“和”短信模板“支持 70 多个 [sprig](http://masterminds.github.io/sprig/) 函数,以及自研的函数。 + +### Sprig 函数 + +Sprig 内置了 70 多种常见的模板函数帮助渲染数据。以下列举常见函数: + +* [时间操作](http://masterminds.github.io/sprig/date.html) +* [字符串操作](http://masterminds.github.io/sprig/strings.html) +* [类型转换操作](http://masterminds.github.io/sprig/conversion.html) +* [整数的数学计算](http://masterminds.github.io/sprig/math.html) + +更多细节可以查看[官方文档](http://masterminds.github.io/sprig/)。 + +### 自研函数 + +#### toClusterName + +__toClusterName__ 函数根据“集群唯一标示 Id”查询“集群名”;如果查询不到对应的集群,将直接返回传入的集群的唯一标示。 + +```go +func toClusterName(id string) (string, error) +``` + +**示例:** + +```go-templates +{{ toClusterName "clusterId" }} +{{ "clusterId" | toClusterName }} +``` + +#### toClusterId + +__toClusterId__ 函数根据“集群名”查询“集群唯一标示 Id”;如果查询不到对应的集群,将直接返回传入的集群名。 + +```go +func toClusterId(name string) (string, error) +``` + +**示例:** + +```go-templates +{{ toClusterId "clusterName" }} +{{ "clusterName" | toClusterId }} +``` + +#### toDateInZone + +__toDateInZone__ 根据字符串时间转换成所需的时间,并进行格式化。 + +```go +func toDateInZone(fmt string, date interface{}, zone string) string +``` + +**示例 1**: + +```go-templates +{{ toDateInZone "2006-01-02T15:04:05" "2022-08-15T05:59:08.064449533Z" "Asia/Shanghai" }} +``` + +将获得返回值 __2022-08-15T13:59:08__ 。此外,也可以通过 sprig 内置的函数达到 __toDateInZone__ 的效果: + +```go-templates +{{ dateInZone "2006-01-02T15:04:05" (toDate "2006-01-02T15:04:05Z07:00" .StartsAt) "Asia/Shanghai" }} +``` + +**示例 2**: + +```go-templates +{{ toDateInZone "2006-01-02T15:04:05" .StartsAt "Asia/Shanghai" }} + +## 阈值模板说明 + +Insight 内置 Webhook 告警模板如下,其他如邮件、企业微信等内容相同,只是对换行进行相应调整。 + +```text +规则名称:{{ .Labels.alertname }} \n +策略名称:{{ .Labels.alertgroup }} \n +告警级别:{{ .Labels.severity }} \n +集群:{{ .Labels.cluster }} \n +{{if .Labels.namespace }}命名空间:{{ .Labels.namespace }} \n{{ end }} +{{if .Labels.node }}节点:{{ .Labels.node }} \n{{ end }} +资源类型:{{ .Labels.target_type }} \n +{{if .Labels.target }}资源名称:{{ .Labels.target }} \n{{ end }} +触发值:{{ .Annotations.value }} \n +发生时间:{{ .StartsAt }} \n +{{if ne "0001-01-01T00:00:00Z" .EndsAt }}结束时间:{{ .EndsAt }} \n{{ end }} +描述:{{ .Annotations.description }} \n +``` + +### 邮箱主题参数 + +由于 Insight 在发送告警消息时,会对同一时间同一条规则产生的消息进行合并发送, +所以 email 主题不同于上面四种模板,只会使用告警消息中的 commonLabels 内容对模板进行渲染。默认模板如下: + +```go +[{{ .status }}] [{{ .severity }}] 告警:{{ .alertname }} +``` + +其他可作为邮箱主题的字段如下: + +```text +{{ .status }} 告警消息的触发状态 +{{ .alertgroup }} 告警所属的策略名称 +{{ .alertname }} 告警所属的规则名称 +{{ .severity }} 告警级别 +{{ .target_type }} 告警资源类型 +{{ .target }} 告警资源对象 +{{ .规则其他自定义 label key }} +``` diff --git a/docs/zh/docs/admin/insight/reference/tailing-sidecar.md b/docs/zh/docs/admin/insight/reference/tailing-sidecar.md new file mode 100644 index 0000000..dc1b720 --- /dev/null +++ b/docs/zh/docs/admin/insight/reference/tailing-sidecar.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# 通过 Sidecar 采集容器日志 + +Tailing Sidecar 是一个[流式 Sidecar 容器](https://kubernetes.io/zh-cn/docs/concepts/cluster-administration/logging/#streaming-sidecar-container), +是 Kubernetes 集群级的日志代理。Tailing Sidercar 可以在容器无法写入标准输出或标准错误流时,无需更改,即可自动收取和汇总容器内日志文件。 + +Insight 支持通过 Sidercar 模式采集日志,即在每个 Pod 中运行一个 Sidecar 容器将日志数据输出到标准输出流,以便 FluentBit 收集容器日志。 + +Insight Agent 中默认安装了 __tailing-sidecar operator__ 。 +若您想开启采集容器内文件日志,请通过给 Pod 添加注解进行标记, __tailing-sidecar operator__ 将自动注入 Tailing Sidecar 容器, +被注入的 Sidecar 容器读取业务容器内的文件,并输出到标准输出流。 + +具体操作步骤如下: + +1. 修改 Pod 的 YAML 文件,在 __annotation__ 字段增加如下参数: + + ```yaml + metadata: + annotations: + tailing-sidecar: ::;:: + ``` + + 字段说明: + + - __sidecar-name-0__ :tailing sidecar 容器名称(可选,如果未指定容器名称将自动创建,它将以“tailing-sidecar”前缀开头) + - __volume-name-0__ :存储卷名称; + - __path-to-tail-0__ :日志的文件路径 + + !!! note + + 每个 Pod 可运行多个 Sidecar 容器,可以通过 __;__ 隔离,实现不同 Sidecar 容器采集多个文件到多个存储卷。 + +2. 重启 Pod,待 Pod 状态变成 __运行中__ 后,则可通过 __日志查询__ 界面,查找该 Pod 的容器内日志。 diff --git a/docs/zh/docs/admin/insight/reference/used-metric-in-insight.md b/docs/zh/docs/admin/insight/reference/used-metric-in-insight.md new file mode 100644 index 0000000..27b1e50 --- /dev/null +++ b/docs/zh/docs/admin/insight/reference/used-metric-in-insight.md @@ -0,0 +1,136 @@ +# Insight 参考指标说明 + +本文中的指标是基于社区的 kube-prometheus 的基础之上整理而成。 +目前涵盖了 Cluster、Node、Namespace、Workload 等多个层面的指标。 +本文枚举了一些常用的指标名、中文描述和单位,以便索引。 + +## 集群(Cluster) + +| 指标名 | 中文描述 | 单位 | +| ---------------------------------- | ----------------------------- | ------ | +| cluster_cpu_utilization | 集群 CPU 使用率 | | +| cluster_cpu_total | 集群 CPU 总量 | Core | +| cluster_cpu_usage | 集群 CPU 用量 | Core | +| cluster_cpu_requests_commitment | 集群 CPU 分配率 | | +| cluster_memory_utilization | 集群内存使用率 | | +| cluster_memory_usage | 集群内存使用量 | Byte | +| cluster_memory_available | 集群可用内存 | Byte | +| cluster_memory_requests_commitment | 集群内存分配率 | | +| cluster_memory_total | 集群内存可用量 | Byte | +| cluster_net_utilization | 集群网络数据传输速率 | Byte/s | +| cluster_net_bytes_transmitted | 集群网络数据发送 (上行) 速率 | Byte/s | +| cluster_net_bytes_received | 集群网络数据接受 (下行) 速率 | Byte/s | +| cluster_disk_read_iops | 集群磁盘每秒读次数 | 次/s | +| cluster_disk_write_iops | 集群磁盘每秒写次数 | 次/s | +| cluster_disk_read_throughput | 集群磁盘每秒读取数据量 | Byte/s | +| cluster_disk_write_throughput | 集群磁盘每秒写入数据量 | Byte/s | +| cluster_disk_size_capacity | 集群磁盘总容量 | Byte | +| cluster_disk_size_available | 集群磁盘可用大小 | Byte | +| cluster_disk_size_usage | 集群磁盘使用量 | Byte | +| cluster_disk_size_utilization | 集群磁盘使用率 | | +| cluster_node_total | 集群节点总数 | 个 | +| cluster_node_online | 集群节点总数 | 个 | +| cluster_node_offline_count | 集群失联的节点个数 | 个 | +| cluster_pod_count | 集群 Pod 总数 | 个 | +| cluster_pod_running_count | 集群正常运行 Pod 个数 | 个 | +| cluster_pod_abnormal_count | 集群异常运行 Pod 个数 | 个 | +| cluster_deployment_count | 集群 Deployment 总数 | 个 | +| cluster_deployment_normal_count | 集群正常的 Deployment 总数 | 个 | +| cluster_deployment_abnormal_count | 集群异常的 Deployment 总数 | 个 | +| cluster_statefulset_count | 集群 StatefulSet 个数 | 个 | +| cluster_statefulset_normal_count | 集群正常运行 StatefulSet 个数 | 个 | +| cluster_statefulset_abnormal_count | 集群异常运行 StatefulSet 个数 | 个 | +| cluster_daemonset_count | 集群 DaemonSet 个数 | 个 | +| cluster_daemonset_normal_count | 集群正常运行 DaemonSet 个数 | 个 | +| cluster_daemonset_abnormal_count | 集群异常运行 DaemonSet 个数 | 个 | +| cluster_job_count | 集群 Job 总数 | 个 | +| cluster_job_normal_count | 集群正常运行 Job 个数 | 个 | +| cluster_job_abnormal_count | 集群异常运行 Job 个数 | 个 | + +!!! tip + + 使用率一般是(0,1] 区间的数字(例如:0.21,而不是 21%) + +## 节点(Node) + +| 指标名 | 中文描述 | 单位 | +| ------------------------------- | -------------------------- | ------ | +| node_cpu_utilization | 节点 CPU 使用率 | | +| node_cpu_total | 节点 CPU 总量 | Core | +| node_cpu_usage | 节点 CPU 用量 | Core | +| node_cpu_requests_commitment | 节点 CPU 分配率 | | +| node_memory_utilization | 节点内存使用率 | | +| node_memory_usage | 节点内存使用量 | Byte | +| node_memory_requests_commitment | 节点内存分配率 | | +| node_memory_available | 节点可用内存 | Byte | +| node_memory_total | 节点内存可用量 | Byte | +| node_net_utilization | 节点网络数据传输速率 | Byte/s | +| node_net_bytes_transmitted | 节点网络数据发送 (上行) 速率 | Byte/s | +| node_net_bytes_received | 节点网络数据接受 (下行) 速率 | Byte/s | +| node_disk_read_iops | 节点磁盘每秒读次数 | 次/s | +| node_disk_write_iops | 节点磁盘每秒写次数 | 次/s | +| node_disk_read_throughput | 节点磁盘每秒读取数据量 | Byte/s | +| node_disk_write_throughput | 节点磁盘每秒写入数据量 | Byte/s | +| node_disk_size_capacity | 节点磁盘总容量 | Byte | +| node_disk_size_available | 节点磁盘可用大小 | Byte | +| node_disk_size_usage | 节点磁盘使用量 | Byte | +| node_disk_size_utilization | 节点磁盘使用率 | | + +## 工作负载(Workload) + +目前支持的工作负载类型包括:Deployment、StatefulSet、DaemonSet、Job 和 CronJob。 + +| 指标名 | 中文描述 | 单位 | +| ------------------------------ | ------------------------------ | ------ | +| workload_cpu_usage | 工作负载 CPU 用量 | Core | +| workload_cpu_limits | 工作负载 CPU 限制量 | Core | +| workload_cpu_requests | 工作负载 CPU 请求量 | Core | +| workload_cpu_utilization | 工作负载 CPU 使用率 | | +| workload_memory_usage | 工作负载内存使用量 | Byte | +| workload_memory_limits | 工作负载 内存 限制量 | Byte | +| workload_memory_requests | 工作负载 内存 请求量 | Byte | +| workload_memory_utilization | 工作负载内存使用率 | | +| workload_memory_usage_cached | 工作负载内存使用量(包含缓存) | Byte | +| workload_net_bytes_transmitted | 工作负载网络数据发送速率 | Byte/s | +| workload_net_bytes_received | 工作负载网络数据接受速率 | Byte/s | +| workload_disk_read_throughput | 工作负载磁盘每秒读取数据量 | Byte/s | +| workload_disk_write_throughput | 工作负载磁盘每秒写入数据量 | Byte/s | + +1. 此处计算 workload 总量 +2. 通过 `workload_cpu_usage{workload_type="deployment", workload="prometheus"}` 的方式获取指标 +3. `workload_pod_utilization` 计算规则: `workload_pod_usage / workload_pod_request` + +## 容器组(Pod) + +| 指标名 | 中文描述 | 单位 | +| ------------------------- | ---------------------------- | ------ | +| pod_cpu_usage | 容器组 CPU 用量 | Core | +| pod_cpu_limits | 容器组 CPU 限制量 | Core | +| pod_cpu_requests | 容器组 CPU 请求量 | Core | +| pod_cpu_utilization | 容器组 CPU 使用率 | | +| pod_memory_usage | 容器组内存使用量 | Byte | +| pod_memory_limits | 容器组内存限制量 | Byte | +| pod_memory_requests | 容器组内存请求量 | Byte | +| pod_memory_utilization | 容器组内存使用率 | | +| pod_memory_usage_cached | 容器组内存使用量(包含缓存) | Byte | +| pod_net_bytes_transmitted | 容器组网络数据发送速率 | Byte/s | +| pod_net_bytes_received | 容器组网络数据接受速率 | Byte/s | +| pod_disk_read_throughput | 容器组磁盘每秒读取数据量 | Byte/s | +| pod_disk_write_throughput | 容器组磁盘每秒写入数据量 | Byte/s | + +通过 `pod_cpu_usage{workload_type="deployment", workload="prometheus"}` 获取名为 prometheus 的 Deployment 所拥有的所有 Pod 的 CPU 使用率。 + +## Span 指标 + +| 指标名 | 中文描述 | 单位 | +|----------------------------------------------------|-----------------| ---- | +| calls_total | 服务请求总数 | | +| duration_milliseconds_bucket | 服务延时直方图 | | +| duration_milliseconds_sum | 服务总延时 | ms | +| duration_milliseconds_count | 服务延时记录条数 | | +| otelcol_processor_groupbytrace_spans_released | 采集到的 span 数 | | +| otelcol_processor_groupbytrace_traces_released | 采集到的 trace 数 | | +| traces_service_graph_request_total | 服务请求总数 (拓扑功能使用) | | +| traces_service_graph_request_server_seconds_sum | 服务总延时 (拓扑功能使用) | ms | +| traces_service_graph_request_server_seconds_bucket | 服务延时直方图 (拓扑功能使用) | | +| traces_service_graph_request_server_seconds_count | 服务请求总数 (拓扑功能使用) | | diff --git a/docs/zh/docs/admin/insight/system-config/modify-config.md b/docs/zh/docs/admin/insight/system-config/modify-config.md new file mode 100644 index 0000000..65bccdb --- /dev/null +++ b/docs/zh/docs/admin/insight/system-config/modify-config.md @@ -0,0 +1,190 @@ +# 修改系统配置 + +可观测性会默认持久化保存指标、日志、链路的数据,您可参阅本文修改系统配置。该文档仅适用于内置部署的 Elasticsearch,若使用外部 Elasticsearch 可自行调整。 + +## 如何修改指标数据保留期限 + +先 ssh 登录到对应的节点,参考以下步骤修改指标数据保留期限。 + +1. 执行以下命令: + + ```sh + kubectl edit vmcluster insight-victoria-metrics-k8s-stack -n insight-system + ``` + +2. 在 Yaml 文件中, __retentionPeriod__ 的默认值为 __14__ ,单位为 __天__ 。您可根据需求修改参数。 + + ```Yaml + apiVersion: operator.victoriametrics.com/v1beta1 + kind: VMCluster + metadata: + annotations: + meta.helm.sh/release-name: insight + meta.helm.sh/release-namespace: insight-system + creationTimestamp: "2022-08-25T04:31:02Z" + finalizers: + - apps.victoriametrics.com/finalizer + generation: 2 + labels: + app.kubernetes.io/instance: insight + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: victoria-metrics-k8s-stack + app.kubernetes.io/version: 1.77.2 + helm.sh/chart: victoria-metrics-k8s-stack-0.9.3 + name: insight-victoria-metrics-k8s-stack + namespace: insight-system + resourceVersion: "123007381" + uid: 55cee8d6-c651-404b-b2c9-50603b405b54 + spec: + replicationFactor: 1 + retentionPeriod: "14" + vminsert: + extraArgs: + maxLabelsPerTimeseries: "45" + image: + repository: docker.m.daocloud.io/victoriametrics/vminsert + tag: v1.80.0-cluster + replicaCount: 1 + ``` + +3. 保存修改后,负责存储指标的组件的容器组会自动重启,稍等片刻即可。 + +## 如何修改日志数据存储时长 + +先 ssh 登录到对应的节点,参考以下步骤修改日志数据保留期限: + +### 方法一:修改 Json 文件 + +1. 修改以下文件中 __rollover__ 字段中的 __max_age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。注意需要修改第一行中的 Elastic 用户名和密码、IP 地址和索引。 + + ```json + curl --insecure --location -u"elastic:amyVt4o826e322TUVi13Ezw6" -X PUT "https://172.30.47.112:30468/_ilm/policy/insight-es-k8s-logs-policy?pretty" -H 'Content-Type: application/json' -d' + { + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "set_priority": { + "priority": 100 + }, + "rollover": { + "max_age": "8d", + "max_size": "10gb" + } + } + }, + "warm": { + "min_age": "10d", + "actions": { + "forcemerge": { + "max_num_segments": 1 + } + } + }, + "delete": { + "min_age": "30d", + "actions": { + "delete": {} + } + } + } + } + }' + ``` + +2. 修改完后,执行以上命令。它会打印出如下所示内容,则修改成功。 + + ```json + { + "acknowledged" : true + } + ``` + +### 方法二:从 UI 修改 + +1. 登录 __kibana__ ,选择左侧导航栏 __Stack Management__ 。 + + ![Stack Management](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys01.png) + +2. 选择左侧导航 __Index Lifecycle Polices__ ,并找到索引 __insight-es-k8s-logs-policy__ ,点击进入详情。 + + ![索引](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys02.png) + +3. 展开 __Hot phase__ 配置面板,修改 __Maximum age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。 + + ![保留期限](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys03.png) + +4. 修改完后,点击页面底部的 __Save policy__ 即修改成功。 + + ![保存](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys04.png) + +## 如何修改链路数据存储时长 + +先 ssh 登录到对应的节点,参考以下步骤修改链路数据保留期限: + +### 方法一:修改 Json 文件 + +1. 修改以下文件中 __rollover__ 字段中的 __max_age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。注意需要修改第一行中的 Elastic 用户名和密码、IP 地址和索引。 + + ```json + curl --insecure --location -u"elastic:amyVt4o826e322TUVi13Ezw6" -X PUT "https://172.30.47.112:30468/_ilm/policy/jaeger-ilm-policy?pretty" -H 'Content-Type: application/json' -d' + { + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "set_priority": { + "priority": 100 + }, + "rollover": { + "max_age": "6d", + "max_size": "10gb" + } + } + }, + "warm": { + "min_age": "10d", + "actions": { + "forcemerge": { + "max_num_segments": 1 + } + } + }, + "delete": { + "min_age": "30d", + "actions": { + "delete": {} + } + } + } + } + }' + ``` + +2. 修改完后,在控制台执行以上命令。它会打印出如下所示内容,则修改成功。 + + ```json + { + "acknowledged" : true + } + ``` + +### 方法二:从 UI 修改 + +1. 登录 __kibana__ ,选择左侧导航栏 __Stack Management__ 。 + + ![Stack Management](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys01.png) + +2. 选择左侧导航 __Index Lifecycle Polices__ ,并找到索引 __jaeger-ilm-policy__ ,点击进入详情。 + + ![索引](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/trace02.png) + +3. 展开 __Hot phase__ 配置面板,修改 __Maximum age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。 + + ![保留期限](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/trace03.png) + +4. 修改完后,点击页面底部的 __Save policy__ 即修改成功。 + + ![保存](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/trace04.png) diff --git a/docs/zh/docs/admin/insight/system-config/system-component.md b/docs/zh/docs/admin/insight/system-config/system-component.md new file mode 100644 index 0000000..1aa71ea --- /dev/null +++ b/docs/zh/docs/admin/insight/system-config/system-component.md @@ -0,0 +1,27 @@ +# 系统组件 + +在系统组件页面可快速的查看可观测性模块中系统组件的运行状态,当系用组件发生故障时,会导致可观测模块中的部分功能不可用。 + +1. 进入 __可观测性__ 产品模块, +2. 在左边导航栏选择 __系统管理 -> 系统组件__ 。 + + ![系统组件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/system00.png) + +## 组件说明 + +|模块 | 组件名称 | 说明 | +| ----- | --------------- | ----------------------------------------------- | +|指标 | vminsert-insight-victoria-metrics-k8s-stack | 负责将各集群中 Prometheus 采集到的指标数据写入存储组件。该组件异常会导致无法写入工作集群的指标数据。 | +|指标 | vmalert-insight-victoria-metrics-k8s-stack | 负责生效 VM Rule 中配置的 recording 和 Alert 规则,并将触发的告警规则发送给 alertmanager。 | +|指标 | vmalertmanager-insight-victoria-metrics-k8s-stack | 负责在告警触时发送消息。该组件异常会导致无法发送告警信息。 | +|指标 | vmselect-insight-victoria-metrics-k8s-stack | 负责查询指标数据。该组件异常会导致无法查询指标。 | +|指标 | vmstorage-insight-victoria-metrics-k8s-stack | 负责存储多集群的指标数据。 | +|仪表盘 | grafana-deployment | 提供监控面板能力。该组件异常会导致无法查看内置的仪表盘。 | +|链路 | insight-jaeger-collector | 负责接收 opentelemetry-collector 中链路数据并将其进行存储。 | +|链路 | insight-jaeger-query | 负责查询各集群中采集到的链路数据。 | +|链路 | insight-opentelemetry-collector | 负责接收各子集群转发的链路数据 | +|日志 | elasticsearch | 负责存储各集群的日志数据。 | + +!!! note + + 若使用外部 Elasticsearch 可能无法获取部分数据以致于 Elasticsearch 的信息为空。 diff --git a/docs/zh/docs/admin/insight/system-config/system-config.md b/docs/zh/docs/admin/insight/system-config/system-config.md new file mode 100644 index 0000000..5291f47 --- /dev/null +++ b/docs/zh/docs/admin/insight/system-config/system-config.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# 系统配置 + + __系统配置__ 展示指标、日志、链路默认的保存时长以及默认的 Apdex 阈值。 + +1. 点击右侧导航栏,选择 __系统配置__。 + + ![系统配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/systemconfig00.png) + +2. 修改历史告警存储时长,点击 __编辑__ 输入目标时长。 + + 当存储时长设置为 "0" 将不清除历史告警。 + + ![系统配置](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/sysconfig02.png) + +3. 修改拓扑图渲染默认配置,点击 __编辑__ 根据需求定义系统中拓扑图阈值。 + + 阈值设置必须大于 0,前面填写的阈值必须小于后面填写的。且填写的阈值必须在最大和最小的范围之间。 + + ![拓扑配置](../../images/map-setting.png) + +!!! note + + 修改其他配置,请点击查看[如何修改系统配置?](modify-config.md) diff --git a/docs/zh/docs/admin/insight/trace/service.md b/docs/zh/docs/admin/insight/trace/service.md new file mode 100644 index 0000000..e715a53 --- /dev/null +++ b/docs/zh/docs/admin/insight/trace/service.md @@ -0,0 +1,56 @@ +# 服务监控 + +在 __可观测性 Insight__ 中服务是指使用 Opentelemtry SDK 接入链路数据,服务监控能够辅助运维过程中观察应用程序的性能和状态。 + +如何使用 OpenTelemetry 请参考[使用 OTel 赋予应用可观测性](../quickstart/otel/otel.md)。 + +## 名词解释 + +- **服务** :服务表示为传入请求提供相同行为的一组工作负载。您可以在使用 OpenTelemetry SDK 时定义服务名称或使用 Istio 中定义的名称。 +- **操作** :操作是指一个服务处理的特定请求或操作,每个 Span 都有一个操作名称。 +- **出口流量** :出口流量是指当前服务发起请求的所有流量。 +- **入口流量** :入口流量是指上游服务对当前服务发起请求的所有流量。 + +## 操作步骤 + +服务列表页面展示了集群中所有已接入链路数据的服务的吞吐率、错误率、请求延时等关键指标。 +您可以根据集群、命名空间对服务进行过滤,也可以按照吞吐率、错误率、请求延时对该列表进行排序。列表中的指标数据默认时间为 1 小时,您可以自定义时间范围。 + +请按照以下步骤查看服务监控指标: + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __链路追踪__ -> __服务__ 。 + + ![服务监控](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/service00.png){ width="1000"} + + !!! attention + + 1. 若列表中服务所在的命名空间为 __unknown__ 时,则表示该服务未规范接入,建议重新接入。 + 2. 若接入的服务存在同名且均未正确填写环境变量中的 __命名空间__ 时,列表及服务详情页中展示的监控数据为多个服务的汇总数据。 + +3. 点击服务名 (以 insight-server 为例),点击进入服务详情页,查看服务的详细指标和该服务的操作指标。 + + 1. 在服务拓扑模块中,您可以查看当前所选服务的上下各一层的服务拓扑,鼠标悬浮在节点上时可以查看节点的信息。 + 2. 在流量指标模块,您可查看到该服务默认一小时内全部请求(包含入口流量和出口流量)的监控指标。 + 3. 支持通过右上角的时间选择器快速选择时间范围,或自定义时间范围。 + 4. 在 __关联容器__ 模块点击容器组名称,可跳转至容器组详情页。 + + ![服务监控](../images/service.png){ width="1000"} + +4. 点击 Tab 切换到 __操作指标__ ,可查询多选服务相同操作的聚合起来的流量指标。 + + 1. 支持对操作指标中的吞吐率、错误率、请求延时等指标进行排序。 + 2. 点击单个操作后的图标,可跳转至 __调用链__ 快速查询相关链路。 + + ![服务监控](../images/service-1.png){ width="1000"} + +### 服务指标说明 + +| 参数 | 说明 | +| -------- | ---------------------------------------- | +| 吞吐率 | 单位时间内处理请求的数量。 | +| 错误率 | 查询时间范围内错误请求与请求总数的比值。 | +| P50 请求延时 | 在所有的请求中,有 50% 的请求响应时间小于或等于该值。 | +| P95 请求延时 | 在所有的请求中,有 95% 的请求响应时间小于或等于该值。 | +| P99 请求延时 | 在所有的请求中,有 95% 的请求响应时间小于或等于该值。 | diff --git a/docs/zh/docs/admin/insight/trace/topology.md b/docs/zh/docs/admin/insight/trace/topology.md new file mode 100644 index 0000000..3e2d4ce --- /dev/null +++ b/docs/zh/docs/admin/insight/trace/topology.md @@ -0,0 +1,53 @@ +# 服务拓扑 + +服务拓扑图是对服务之间连接、通信和依赖关系的可视化表示。通过可视化拓扑了解服务间的调用关系, +查看服务在指定时间内的调用及其性能状况。拓扑图的节点之间的联系代表两个服务在查询时间范围内服务之间的存在调用关系。 + +## 前提条件 + +1. 集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 +2. 服务已通过 [Operator](../quickstart/otel/operator.md) 或 + [Opentelemetry SDK](../quickstart/otel/golang/golang.md) 的方式接入链路。 + +## 操作步骤 + +1. 进入 __可观测性__ 模块 +2. 在左边导航栏选择 __链路追踪 -> 服务拓扑__ +3. 在拓扑图中,您可按需执行以下操作: + + - 单击 __节点__,从右侧划出服务的详情,可查看服务的请求延时、吞吐率、错误率的指标。点击服务名称可跳转至对应服务的详情页。 + - 鼠标悬浮在连线上时,可查看两个服务之间请求的流量指标。 + - 在 __显示设置__ 模块,可配置拓扑图中的显示元素。 + + ![服务拓扑](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/servicemap00.png){ width="1000"} + +4. 点击右下角 __图例__ ,可通过 __临时配置__ 修改当前的拓扑图定义的渲染阈值,跳出或关闭该页面即会丢失该配置。 + + 阈值设置必须大于 0,前面填写的阈值必须小于后面填写的。且填写的阈值必须在最大和最小的范围之间。 + + ![服务拓扑](../images/servicemap01.png){ width="1000"} + + ![服务拓扑](../images/servicemap02.png){ width="1000"} + +### 其他节点 + +在服务拓扑中会存在游离在集群之外的节点,这些游离在外的节点可分成三类: + +- 数据库 +- 消息队列 +- 虚拟节点 + +1. 若服务发起请求到`数据库`或`消息队列`时,拓扑图中会默认展示这两类节点。 + 而`虚拟服务`表示集群内服务请求了集群外的节点或者未接入链路的服务,拓扑图中默认不会展示 `虚拟服务`。 + +1. 当服务请求到 MySQL、PostgreSQL、Oracle Database 这三种数据库时,在拓扑图中可以看到请求的详细数据库类型。 + + ![数据库细节](../images/service-map.png) + +#### 开启虚拟节点 + +1. 更新 insight-server chart 的 values,找到下图所示参数,将 `false` 改为 `true`。 + + ![拓扑图](../images/servicemap.png) + +2. 在服务拓扑的显示设置中勾选 __虚拟服务__ 。 diff --git a/docs/zh/docs/admin/insight/trace/trace.md b/docs/zh/docs/admin/insight/trace/trace.md new file mode 100644 index 0000000..227f6e3 --- /dev/null +++ b/docs/zh/docs/admin/insight/trace/trace.md @@ -0,0 +1,56 @@ +# 链路查询 + +在链路查询页面,您可以过 TraceID 或精确查询调用链路详细情况或结合多种条件筛选查询调用链路。 + +## 名词解释 + +- TraceID:用于标识一个完整的请求调用链路。 +- 操作:描述 Span 所代表的具体操作或事件。 +- 入口 Span:入口 Span 代表了整个请求的第一个请求。 +- 延时:整个调用链从开始接收请求到完成响应的持续时间。 +- Span:整个链路中包含的 Span 个数。 +- 发生时间:当前链路开始的时间。 +- Tag:一组键值对构成的 Span 标签集合,Tag 是用来对 Span 进行简单的注解和补充,每个 Span 可以有多个简直对形式的 Tag。 + +## 操作步骤 + +请按照以下步骤查询链路: + +1. 进入 __可观测性__ 产品模块, +2. 在左边导航栏选择 __链路追踪__ -> __调用链__。 + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace00.png) + + !!! note + + 列表中支持对 Span 数、延时、发生时间进行排序。 + +3. 点击筛选栏中的 __TraceID 搜索__ 切换使用 TraceID 搜索链路。 + + - 使用 TraceID 搜索请输入完整的 TraceID。 + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace04.png) + +## 其他操作 + +### 查看链路详情 + +1. 点击链路列表中的某一链路的 TraceID,可查看该链路的详情调用情况。 + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace03.png) + +### 查看关联日志 + +1. 点击链路数据右侧的图标,可查询该链路的关联日志。 + + - 默认查询该链路的持续时间及其结束之后一分钟内的日志数据。 + - 查询的日志内容为日志文本中包含该链路的 TraceID 的日志和链路调用过程中相关的容器日志。 + +2. 点击 __查看更多__ 后可带条件跳转到 __日志查询__ 的页面。 +3. 默认搜索全部日志,但可下拉根据链路的 TraceID 或链路调用过程中相关的容器日志进行过滤。 + + ![tracelog](../images/tracelog.png) + + !!! note + + 由于链路会跨集群或跨命名空间,若用户权限不足,则无法查询该链路的关联日志。 diff --git a/docs/zh/docs/admin/k8s/add-node.md b/docs/zh/docs/admin/k8s/add-node.md new file mode 100644 index 0000000..b740ffa --- /dev/null +++ b/docs/zh/docs/admin/k8s/add-node.md @@ -0,0 +1,43 @@ +# 添加工作节点 + +如果节点不够用了,可以添加更多节点到集群中。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 有一个管理员帐号 +- [已创建带 GPU 节点的集群](./create-k8s.md) +- [准备一台云主机](../host/createhost.md) + +## 添加步骤 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. 导航至 **容器管理** -> **集群列表** ,点击目标集群的名称 + + ![clusters](../images/remove01.png) + +1. 进入集群概览页,点击 **节点管理** ,点击右侧的 **接入节点** 按钮 + + ![add](../images/add01.png) + +1. 按照向导,填写各项参数后点击 **确定** + + === "基本信息" + + ![basic](../images/add02.png) + + === "参数配置" + + ![arguments](../images/add03.png) + +1. 在弹窗中点击 **确定** + + ![ok](../images/add04.png) + +1. 返回节点列表,新接入的节点状态为 **接入中** ,等待几分钟后状态变为 **健康** 则表示接入成功。 + + ![success](../images/add05.png) + +!!! tip + + 对于刚接入成功的节点,可能还要等 2-3 分钟才能识别出 GPU。 diff --git a/docs/zh/docs/admin/k8s/create-k8s.md b/docs/zh/docs/admin/k8s/create-k8s.md new file mode 100644 index 0000000..16674d7 --- /dev/null +++ b/docs/zh/docs/admin/k8s/create-k8s.md @@ -0,0 +1,80 @@ +# 创建云上 Kubernetes 集群 + +部署 Kubernetes 集群是为了支持高效的 AI 算力调度和管理,实现弹性伸缩,提供高可用性,从而优化模型训练和推理过程。 + +## 前置条件 + +- 已安装 AI 算力平台已 +- 有一个管理员权限的账号 +- 准备一台带 GPU 的物理机 +- 分配两段 IP 地址(Pod CIDR 18 位、SVC CIDR 18 位,不能与现有网段冲突) + +## 创建步骤 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. [创建并启动 3 台不带 GPU 的云主机](../host/createhost.md)用作集群的 Master 节点 + + - 配置资源,CPU 16 核,内存 32 GB,系统盘 200 GB(ReadWriteOnce) + - 网络模式选择 **Bridge(桥接)** + - 设置 root 密码或添加 SSH 公钥,方便以 SSH 连接 + - 记录好 3 台主机的 IP + +1. 导航至 **容器管理** -> **集群列表** ,点击右侧的 **创建集群** 按钮 +1. 按照向导,配置集群的各项参数 + + === "基本信息" + + ![basic](../images/k8s01.png) + + === "节点配置" + + 配置完节点信息后,点击 **开始检查** , + + ![node](../images/k8s02.png) + ![node](../images/k8s03.png) + + === "网络配置" + + ![network](../images/k8s04.png) + + === "Addon 配置" + + ![addon](../images/k8s05.png) + + === "高级配置" + + 每个节点默认可运行 110 个 Pod(容器组),如果节点配置比较高,可以调整到 200 或 300 个 Pod。 + + ![basic](../images/k8s06.png) + +1. 等待集群创建完成。 + + ![done](../images/k8s08.png) + +1. 在集群列表中,找到刚创建的集群,点击集群名称,导航到 **Helm 应用** -> **Helm 模板** ,在搜索框内搜索 metax-gpu-extensions,点击卡片 + + ![cluster](../images/k8s09.png) + + ![helm](../images/k8s10.png) + +1. 点击右侧的 **安装** 按钮,开始安装 GPU 插件 + + === "应用设置" + + 输入名称,选择命名空间,在 YAMl 中修改镜像地址: + + ![app settings](../images/k8s11.png) + + === "Kubernetes 编排确认" + + ![confirm](../images/k8s12.png) + +1. 自动返回 Helm 应用列表,等待 metax-gpu-extensions 状态变为 **已部署** + + ![deployed](../images/k8s13.png) + +1. 到此集群创建成功,可以去查看集群所包含的节点。你可以去[创建 AI 工作负载并使用 GPU 了](../share/workload.md)。 + + ![nodes](../images/k8s14.png) + +下一步:[创建 AI 工作负载](../share/workload.md) diff --git a/docs/zh/docs/admin/k8s/remove-node.md b/docs/zh/docs/admin/k8s/remove-node.md new file mode 100644 index 0000000..5f5bd82 --- /dev/null +++ b/docs/zh/docs/admin/k8s/remove-node.md @@ -0,0 +1,37 @@ +# 移除 GPU 工作节点 + +GPU 资源的成本相对较高,如果暂时用不到 GPU,可以将带 GPU 的工作节点移除。 +以下步骤也同样适用于移除普通工作节点。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 有一个管理员帐号 +- [已创建带 GPU 节点的集群](./create-k8s.md) + +## 移除步骤 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. 导航至 **容器管理** -> **集群列表** ,点击目标集群的名称 + + ![clusters](../images/remove01.png) + +1. 进入集群概览页,点击 **节点管理** ,找到要移除的节点,点击列表右侧的 __┇__ ,在弹出菜单中选择 **移除节点** + + ![remove](../images/remove02.png) + +1. 在弹框中输入节点名称,确认无误后点击 **删除** + + ![confirm](../images/remove03.png) + +1. 自动返回节点列表,状态为 **移除中** ,几分钟后刷新页面,节点不在了,说明节点被成功移除 + + ![removed](../images/remove04.png) + +1. 从 UI 列表移除节点后,通过 SSH 登录到已移除的节点主机,执行关机命令。 + + ![shutdown](../images/remove05.png) + +!!! tip + + 在 UI 上移除节点并将其关机后,节点上的数据并未被立即删除,节点数据会被保留一段时间。 diff --git a/docs/zh/docs/admin/kpanda/backup/deployment.md b/docs/zh/docs/admin/kpanda/backup/deployment.md new file mode 100644 index 0000000..37e1149 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/backup/deployment.md @@ -0,0 +1,56 @@ +# 应用备份 + +本文介绍如何在算丰 AI 算力平台中为应用做备份,本教程中使用的演示应用名为 __dao-2048__ ,属于无状态工作负载。 + +## 前提条件 + +在对无状态工作负载进行备份前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- [安装 velero 组件](install-velero.md),且 velero 组件运行正常。 + +- [创建一个无状态工作负载](../workloads/create-deployment.md)(本教程中的负载名为 __dao-2048__ ),并为无状态工作负载打上 __app: dao-2048__ 的标签。 + +## 备份工作负载 + +参考以下步骤,备份无状态工作负载 __dao-2048__ 。 + +1. 在左侧导航栏, 点击 __容器管理__ -> __备份恢复__ 。 + + ![集群列表](../images/backupd20481.png) + +2. 进入 __应用备份__ 列表页面,从集群下拉列表中选择已安装了 velero 和 __dao-2048__ 的集群。 + 点击右侧的 __创建备份计划__ 按钮。 + + ![应用备份](../images/backupd20482.png) + +3. 参考下方说明填写备份配置。 + + ![操作菜单](../images/backupd20483.png) + +4. 参考下方说明设置备份执行频率,然后点击 __下一步__ 。 + + - 备份频率:基于分钟、小时、天、周、月设置任务执行的时间周期。支持用数字和 `*` 自定义 Cron 表达式,**输入表达式后下方会提示当前表达式的含义**。有关详细的表达式语法规则,可参考 [Cron 时间表语法](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax)。 + - 留存时长(天):设置备份资源保存的时间,默认为 30 天,过期后将会被删除。 + - 备份数据卷(PV):是否备份数据卷(PV)中的数据,支持直接复制和使用 CSI 快照两种方式。 + - 直接复制:直接复制数据卷(PV)中的数据用于备份; + - 使用 CSI 快照:使用 CSI 快照来备份数据卷(PV)。需要集群中有可用于备份的 CSI 快照类型。 + + ![操作菜单](../images/backupd20484.png) + +5. 点击 __确定__ ,页面会自动返回应用备份计划列表。您可以找到新建的 __dao-2048__ 备份计划,在右侧点击 __┇__ ,选择 __立即执行__ 开始备份。 + + ![操作菜单](../../../images/backupd20485.png) + +6. 此时集群的 __上一次执行状态__ 将转变为 __备份中__ 。等待备份完成后可以点击备份计划的名称,查看备份计划详情。 + + ![操作菜单](../../../images/backupd20486.png) + +!!! note + + 如果 Job 类型的工作负载状态为 **执行完成** ,则不支持备份。 diff --git a/docs/zh/docs/admin/kpanda/backup/etcd-backup.md b/docs/zh/docs/admin/kpanda/backup/etcd-backup.md new file mode 100644 index 0000000..2f28df3 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/backup/etcd-backup.md @@ -0,0 +1,128 @@ +# etcd 备份 + +etcd 备份是以集群数据为核心的备份。在硬件设备损坏,开发测试配置错误等场景中,可以通过 etcd 备份恢复集群数据。 + +本文介绍如何为集群制作 etcd 备份。 + +## 前提条件 + +- [接入](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限。详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +- 准备一个 MinIO 实例。 + +## 创建 etcd 备份 + +参照以下步骤创建 etcd 备份。 + +1. 进入 __容器管理__ -> __备份恢复__ -> __etcd 备份__ ,点击 __备份策略__ 页签,然后在右侧点击 __创建备份策略__ 。 + + ![备份策略列表](../../../images/etcd01.png) + +2. 参考以下说明填写 __基本信息__ 。填写完毕后点击 __下一步__ ,系统将自动校验 etcd 的联通性,校验通过之后可以进行下一步。 + + - 备份集群:选择需要备份哪个集群的 etcd 数据,并在终端登录 + - etcd 地址:格式为 `https://${节点IP}:${端口号}` + + - 在标准 Kubernetes 集群中,etcd 的默认端口号为 __2379__ + - 在公有云托管集群中,需要联系相关开发人员获取 etcd 的端口号。 + 这是因为公有云集群的控制面组件由云服务提供商维护和管理,用户无法直接访问或查看这些组件, + 也无法通过常规命令(如 kubectl)无法获取到控制面的端口等信息。 + + ??? note "获取端口号的方式" + + 1. 在 __kube-system__ 命名空间下查找 etcd Pod + + ```shell + kubectl get po -n kube-system | grep etcd + ``` + + 2. 获取 etcd Pod 的 __listen-client-urls__ 中的端口号 + + ```shell + kubectl get po -n kube-system ${etcd_pod_name} -oyaml | grep listen-client-urls # (1)! + ``` + + 1. 将 __etcd_pod_name__ 替换为实际的 Pod 名称 + + 预期输出结果如下,节点 IP 后的数字即为端口号: + + ```shell + - --listen-client-urls=https://127.0.0.1:2379,https://10.6.229.191:2379 + ``` + + - CA 证书:可通过如下命令查看证书,然后将证书内容复制粘贴到对应位置: + + ```shell + cat /etc/kubernetes/ssl/etcd/ca.crt + ``` + + - Cert 证书:可通过如下命令查看证书,然后将证书内容复制粘贴到对应位置: + + ```shell + cat /etc/kubernetes/ssl/apiserver-etcd-client.crt + ``` + + - Key:可通过如下命令查看证书,然后将证书内容复制粘贴到对应位置: + + ```shell + cat /etc/kubernetes/ssl/apiserver-etcd-client.key + ``` + + ![创建基本信息](../../../images/etcd-get01.png) + + !!! note + + 点击输入框下方的 __如何获取__ 可以在 UI 页面查看获取对应信息的方式。 + +3. 参考以下信息填写 __备份策略__ 。 + + - 备份方式:选择手动备份或定时备份 + + - 手动备份:基于备份配置立即执行一次 etcd 全量数据的备份。 + - 定时备份:按照设置的备份频率对 etcd 数据进行周期性全量备份。 + + - 备份链长度:最多保留多少条备份数据。默认为 30 条。 + - 备份频率:支持小时、日、周、月级别和自定义方式。 + + ![定时备份](../../../images/etcd04.png) + +4. 参考以下信息填写 __存储位置__ 。 + + - 存储供应商:默认选择 S3 存储 + - 对象存储访问地址:MinIO 的访问地址 + - 存储桶:在 MinIO 中创建一个 Bucket,填写 Bucket 的名称 + - 用户名:MinIO 的登录用户名 + - 密码:MinIO 的登录密码 + + ![存储位置](../../../images/etcd05.png) + +5. 点击 __确定__ 后页面自动跳转到备份策略列表,可以查看目前创建好的所有策略。 + + - 在策略右侧点击 __┇__ 操作按钮可以查看日志、查看 YAML、更新策略、停止策略、立即执行策略等。 + - 当备份方式为手动时,可以点击 __立即执行__ 进行备份。 + - 当备份方式为定时备份时,则会根据配置的时间进行备份。 + + ![成功创建](../../../images/etcd07.png) + +## 查看备份策略日志 + +点击 __日志__ 可以查看日志内容,默认展示 100 行。若想查看更多日志信息或者下载日志,可在日志上方根据提示前往可观测性模块。 + +![查看日志](../../../images/etcd06.png) + +## 查看备份策略详情 + +进入 __容器管理__ -> __备份恢复__ -> __etcd 备份__ ,点击 __备份策略__ 页签,接着点击策略名称可以查看策略详情。 + +![备份策略详情](../../../images/etcd09.png) + +## 查看备份点 + +1. 进入 __容器管理__ -> __备份恢复__ -> __etcd 备份__ ,点击 __备份点__ 页签。 +2. 选择目标集群后,可以查看该集群下所有备份信息。 + + 每执行一次备份,对应生成一个备份点,可通过成功状态的备份点快速恢复应用。 + + ![备份点](../../../images/etcd08.png) diff --git a/docs/zh/docs/admin/kpanda/backup/index.md b/docs/zh/docs/admin/kpanda/backup/index.md new file mode 100644 index 0000000..b2994ef --- /dev/null +++ b/docs/zh/docs/admin/kpanda/backup/index.md @@ -0,0 +1,30 @@ +--- +hide: + - toc +--- + +# 备份恢复 + +备份恢复分为备份和恢复两方面,实际应用时需要先备份系统在某一时点的数据,然后安全存储地备份数据。后续如果出现数据损坏、丢失、误删等事故,就可以基于之前的数据备份快速还原系统,**缩短故障时间,减少损失**。 + +- 在真实的生产环境中,服务可能分布式地部署在不同的云、不同区域或可用区,如果某一个基础设施自身出现故障,企业需要在其他可用环境中快速恢复应用。在这种情况下,跨云/跨集群的备份恢复显得非常重要。 +- 在大规模系统中往往有很多角色和用户,权限管理体系复杂,操作者众多,难免有人误操作导致系统故障。在这种情况下,也需要能够通过之前备份的数据快速回滚系统,否则如果依赖人为排查故障、修复故障、恢复系统就会耗费大量时间,系统不可用时间越长,企业的损失越大。 +- 此外,还有网络攻击、自然灾害、设备故障等各种因素也可能导致数据事故 + +因此,备份恢复非常重要,可以视之为维护系统稳定和数据安全的最后一道保险。 + +备份通常分为全量备份、增量备份、差异备份三种。算丰 AI 算力平台目前支持全量备份和增量备份。 + +算丰 AI 算力平台提供的备份恢复可以分为 **应用备份** 和 **ETCD 备份** 两种,支持手动备份,或基于 CronJob 定时自动备份。 + +- 应用备份 + + 应用备份指,备份集群中的某个工作负载的数据,然后将该工作负载的数据恢复到本集群或者其他集群。支持备份整个命名空间下的所有资源,也支持通过标签选择器过滤,仅备份带有特定标签的资源。 + + 应用备份支持跨集群备份有状态应用,具体步骤可参考[MySQL 应用及数据的跨集群备份恢复](../../best-practice/backup-mysql-on-nfs.md)。 + +- ETCD 备份 + + etcd 是 Kubernetes 的数据存储组件,Kubernetes 将自身的组件数据和其中的应用数据都存储在 etcd 中。因此,备份 etcd 就相当于备份整个集群的数据,可以在故障时快速将集群恢复到之前某一时点的状态。 + + 需要注意的是,目前仅支持将 etcd 备份数据恢复到同一集群(原集群)。 diff --git a/docs/zh/docs/admin/kpanda/backup/install-velero.md b/docs/zh/docs/admin/kpanda/backup/install-velero.md new file mode 100644 index 0000000..36e1351 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/backup/install-velero.md @@ -0,0 +1,107 @@ +# 安装 velero 插件 + +velero 是一个备份和恢复 Kubernetes 集群资源的开源工具。它可以将 Kubernetes +集群中的资源备份到云存储服务、本地存储或其他位置,并且可以在需要时将这些资源恢复到同一或不同的集群中。 + +本节介绍如何在算丰 AI 算力平台中使用 __Helm 应用__ 部署 velero 插件。 + +## 前提条件 + +安装 __velero__ 插件前,需要满足以下前提条件: + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建 __velero__ [命名空间](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +请执行如下步骤为集群安装 __velero__ 插件。 + +1. 在集群列表页面找到需要安装 __velero__ 插件的目标集群,点击集群名称,在左侧导航栏依次点击 __Helm 应用__ -> __Helm 模板__ ,在搜索栏输入 __velero__ 进行搜索。 + + ![备份恢复](../../../images/backup1.png) + +1. 阅读 __velero__ 插件相关介绍,选择版本后点击 __安装__ 按钮。本文将以 __4.0.2__ 版本为例进行安装,推荐安装 __4.0.2__ 或更高版本。 + + ![备份恢复](../../../images/backup2.png) + +1. 填写和配置参数后点击 __下一步__ + + === "基本参数" + + ![备份恢复](../../../images/backup3.png) + + - 名称:必填参数,输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 metrics-server-01。 + - 命名空间:插件安装的命名空间,默认为 __velero__ 命名空间。 + - 版本:插件的版本,此处以 __4.0.2__ 版本为例。 + - 就绪等待:可选参数,启用后,将等待应用下所有关联资源处于就绪状态,才会标记应用安装成功。 + - 失败删除:可选参数,开启后,将默认同步开启就绪等待。如果安装失败,将删除安装相关资源。 + - 详情日志:可选参数,开启后将输出安装过程的详细日志。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要经过较长时间才会被标记为 __运行中__ 状态。 + + === "参数配置" + + - S3 Credentials: + + - __Use secret__ :保持默认配置 __true__ 。 + - __Secret name__ :保持默认配置 __velero-s3-credential__ 。 + - __SecretContents.aws_access_key_id = __ :配置访问对象存储的用户名,替换 ____ 为真实参数。 + - __SecretContents.aws_secret_access_key = __ :配置访问对象存储的密码,替换 ____ 为真实参数。 + + ```config "SecretContents 样例" + [default] + aws_access_key_id = minio + aws_secret_access_key = minio123 + ``` + + - Velero Configuration: + + - __Backupstoragelocation__ :velero 备份数据存储的位置 + - __S3 bucket__ :用于保存备份数据的存储桶名称(需为 minio 已经存在的真实存储桶) + - __Is default BackupStorage__ :保持默认配置 __true__ + - __S3 access mode__ :velero 对数据的访问模式,可以选择 + - __ReadWrite__ :允许 velero 读写备份数据 + - __ReadOnly__ :允许 velero 读取备份数据,不能修改备份数据 + - __WriteOnly__ :只允许 velero 写入备份数据,不能读取备份数据 + - __S3 Configs__ :S3 存储(minio)的详细配置 + - __S3 region__ :云存储的地理区域。默认使用 __us-east-1__ 参数,由系统管理员提供 + - __S3 force path style__ :保持默认配置 __true__ + - __S3 server URL__ :对象存储(minio)的控制台访问地址,minio 一般提供了 UI 访问和控制台访问两个服务,此处请使用控制台访问的地址 + + !!! note + + 请确保 s3 存储服务时间跟备份还原集群时间差在10分钟以内,最好是时间保持同步,否则将无法执行备份操作。 + + - migration plugin configuration:启用之后,将在下一步的 YAML 代码段中新增: + + ```yaml + ... + initContainers: + - image: 'release.daocloud.io/kcoral/velero-plugin-for-migration:v0.3.0' + imagePullPolicy: IfNotPresent + name: velero-plugin-for-migration + volumeMounts: + - mountPath: /target + name: plugins + - image: 'docker.m.daocloud.io/velero/velero-plugin-for-csi:v0.7.0' + imagePullPolicy: IfNotPresent + name: velero-plugin-for-csi + volumeMounts: + - mountPath: /target + name: plugins + - image: 'docker.m.daocloud.io/velero/velero-plugin-for-aws:v1.9.0' + imagePullPolicy: IfNotPresent + name: velero-plugin-for-aws + volumeMounts: + - mountPath: /target + name: plugins + ... + ``` + +1. 确认 YAML 无误后点击 __确定__ ,完成 __velero__ 插件的安装。 + 之后系统将自动跳转至 __Helm 应用__ 列表页面,稍等几分钟后,为页面执行刷新操作,即可看到刚刚安装的应用。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/add-master-node.md b/docs/zh/docs/admin/kpanda/best-practice/add-master-node.md new file mode 100644 index 0000000..9f2dc0e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/add-master-node.md @@ -0,0 +1,184 @@ +# 对工作集群的控制节点扩容 + +本文将以一个单控制节点的工作集群为例,介绍如何手动为工作集群的控制节点进行扩容,以实现自建工作集群的高可用。 + +!!! note + + - 推荐在界面创建工作集群时即开启高可用模式,手动扩容工作集群的控制节点存在一定的操作风险,请谨慎操作。 + - 当工作集群的首个控制节点故障或异常时,如果您想替换或重新接入首个控制节点, + 请参考[替换工作集群的首个控制节点](../best-practice/replace-first-master-node.md) + +## 前提条件 + +- 已经通过 AI 算力中心平台创建好一个工作集群,可参考文档[创建工作集群](../clusters/create-cluster.md)。 +- 工作集群的被纳管集群存在当前平台中,并且状态运行正常。 + +!!! note + + 被纳管集群:在界面创建集群时指定的用来管理当前集群,并为当前集群提供 kubernetes 版本升级、节点扩缩容、卸载、操作记录等能力的集群。 + +## 修改主机清单文件 + +1. 登录到容器管理平台,进入需要进行控制节点扩容的集群概览页面,在 **基本信息** 处,找到当前集群的 **被纳管集群** , + 点击被纳管集群的名称,进入被纳管集群的概览界面。 + + ![找到被纳管集群](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/add-master-node01.png) + +2. 在被纳管集群的概览界面,点击 **控制台**,打开云终端控制台,并执行如下命令,找到待扩容工作集群的主机清单文件。 + + ```bash + kubectl get cm -n kubean-system ${ClusterName}-hosts-conf -oyaml + ``` + + `${ClusterName}`:为待扩容工作集群的名称。 + + ![控制台](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/add-master-node02.png) + +3. 参考下方示例修改主机清单文件,新增控制节点信息。 + + === "修改前" + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: tanghai-dev-hosts-conf + namespace: kubean-system + data: + hosts.yml: | + all: + hosts: + node1: + ip: 10.6.175.10 + access_ip: 10.6.175.10 + ansible_host: 10.6.175.10 + ansible_connection: ssh + ansible_user: root + ansible_password: password01 + children: + kube_control_plane: + hosts: + node1: + kube_node: + hosts: + node1: + etcd: + hosts: + node1: + k8s_cluster: + children: + kube_control_plane: + kube_node: + calico_rr: + hosts: {} + ...... + ``` + + === "修改后" + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: tanghai-dev-hosts-conf + namespace: kubean-system + data: + hosts.yml: | + all: + hosts: + node1: # 原集群中已存在的主节点 + ip: 10.6.175.10 + access_ip: 10.6.175.10 + ansible_host: 10.6.175.10 + ansible_connection: ssh + ansible_user: root + ansible_password: password01 + node2: # 集群扩容待新增的控制节点 + ip: 10.6.175.20 + access_ip: 10.6.175.20 + ansible_host: 10.6.175.20 + ansible_connection: ssh + ansible_user: root + ansible_password: password01 + node3: # 集群扩容待新增的控制节点 + ip: 10.6.175.30 + access_ip: 10.6.175.30 + ansible_host: 10.6.175.30 + ansible_connection: ssh + ansible_user: root + ansible_password: password01 + children: + kube_control_plane: + hosts: # 集群中的控制节点组 + node1: + node2: # 新增控制节点 node2 内容 + node3: # 新增控制节点 node3 内容 + kube_node: + hosts: # 集群中的工作节点组 + node1: + node2: # 新增控制节点 node2 内容 + node3: # 新增控制节点 node3 内容 + etcd: + hosts: # 集群中的 ETCD 节点组 + node1: + node2: # 新增控制节点 node2 内容 + node3: # 新增控制节点 node3 内容 + k8s_cluster: + children: + kube_control_plane: + kube_node: + calico_rr: + hosts: {} + ``` + +## 新增 ClusterOperation.yml 扩容任务 + +使用基于下面的 __ClusterOperation.yml__ 模板,新增一个集群控制节点扩容任务 __scale-master-node-ops.yaml__ 。 + +```yaml title="ClusterOperation.yml" +apiVersion: kubean.io/v1alpha1 +kind: ClusterOperation +metadata: + name: cluster1-online-install-ops +spec: + cluster: ${cluster-name} # (1)! + image: ghcr.m.daocloud.io/kubean-io/spray-job:v0.18.0 # (2)! + actionType: playbook + action: cluster.yml # (3)! + extraArgs: --limit=etcd,kube_control_plane -e ignore_assert_errors=yes + preHook: + - actionType: playbook + action: ping.yml + - actionType: playbook + action: disable-firewalld.yml + - actionType: playbook + action: enable-repo.yml # (4)! + extraArgs: | # 如果是离线环境,需要添加 enable-repo.yml,并且 extraArgs 参数填写相关 OS 的正确 repo_list + -e "{repo_list: ['http://172.30.41.0:9000/kubean/centos/\$releasever/os/\$basearch','http://172.30.41.0:9000/kubean/centos-iso/\$releasever/os/\$basearch']}" + postHook: + - actionType: playbook + action: upgrade-cluster.yml + extraArgs: --limit=etcd,kube_control_plane -e ignore_assert_errors=yes + - actionType: playbook + action: kubeconfig.yml + - actionType: playbook + action: cluster-info.yml +``` + +1. 指定 cluster name +2. 指定 kubean 任务运行的镜像,镜像地址要与之前执行部署时的 job 其内镜像保持一致 +3. 如果一次性添加 Master(etcd)节点超过(包含)三个,需在 cluster.yaml 追加额外参数 `-e etcd_retries=10` 以增大 etcd node join 重试次数 +4. 离线环境下需要添加此 yaml,并且设置正确的 repo-list(安装操作系统软件包),以下参数值仅供参考 + +然后创建并部署 scale-master-node-ops.yaml。 + +```bash +vi scale-master-node-ops.yaml +kubectl apply -f scale-master-node-ops.yaml -n kubean-system +``` + +执行完上述步骤,执行如下命令进行验证: + +```bash +kubectl get node +``` diff --git a/docs/zh/docs/admin/kpanda/best-practice/add-worker-node-on-global.md b/docs/zh/docs/admin/kpanda/best-practice/add-worker-node-on-global.md new file mode 100644 index 0000000..17c9bfa --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/add-worker-node-on-global.md @@ -0,0 +1,221 @@ +# 为全局服务集群的工作节点扩容 + +本文将介绍离线模式下,如何手动为全局服务集群的工作节点进行扩容。 +默认情况下,不建议在部署 AI 算力中心后对[全局服务集群](../clusters/cluster-role.md#_2)进行扩容,请在部署 AI 算力中心前做好资源规划。 + +!!! note + + 全局服务集群的控制节点不支持扩容。 + +## 前提条件 + +- 已经通过[火种节点](../../install/commercial/deploy-arch.md)完成 AI 算力中心平台的部署,并且火种节点上的 kind 集群运行正常。 +- 必须使用平台 Admin 权限的用户登录。 + +## 获取火种节点上 kind 集群的 kubeconfig + +1. 执行如下命令登录火种节点: + + ```bash + ssh root@火种节点 IP 地址 + ``` + +2. 在火种节点上执行如下命令获取 kind 集群的 `CONTAINER ID`: + + ```bash + [root@localhost ~]# podman ps + + # 预期输出如下: + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 220d662b1b6a docker.m.daocloud.io/kindest/node:v1.26.2 2 weeks ago Up 2 weeks 0.0.0.0:443->30443/tcp, 0.0.0.0:8081->30081/tcp, 0.0.0.0:9000-9001->32000-32001/tcp, 0.0.0.0:36674->6443/tcp my-cluster-installer-control-plane + ``` + +3. 执行如下命令,进入 kind 集群容器内: + + ```bash + podman exec -it {CONTAINER ID} bash + ``` + + `{CONTAINER ID}` 替换为您真实的容器 ID + +4. 在 kind 集群容器内执行如下命令获取 kind 集群的 kubeconfig 配置信息: + + ```bash + kubectl config view --minify --flatten --raw + ``` + +待控制台输出后,复制 kind 集群的 kubeconfig 配置信息,为下一步做准备。 + +## 在火种节点上 kind 集群内创建 `cluster.kubean.io` 资源 + +1. 使用 `podman exec -it {CONTAINER ID} bash` 命令进入 kind 集群容器内。 + +1. 在 kind 集群容器内,执行如下命令,获取 **kind 集群名称** : + + ```bash + kubectl get clusters + ``` + +1. 复制并执行如下命令,在 kind 集群内执行,以创建 `cluster.kubean.io` 资源: + + ```bash + kubectl apply -f - < + +1. 在 kind 集群内执行如下命令,重启 containerd 服务 + + ```bash + systemctl restart containerd + ``` + +## 将 kind 集群接入 AI 算力中心集群列表 + +1. 登录 AI 算力中心,进入容器管理,在集群列表页右侧点击 __接入集群__ 按钮,进入接入集群页面。 + +2. 在接入配置处,填入并编辑刚刚复制的 kind 集群的 kubeconfig 配置。 + + ```yaml + apiVersion: v1 + clusters: + - cluster: + insecure-skip-tls-verify: true # (1)! + certificate-authority-data: LS0TLSCFDFWEFEWFEWFGGEWGFWFEWGWEGFEWGEWGSDGFSDSD + server: https://my-cluster-installer-control-plane:6443 # (2)! + name: my-cluster-installer + contexts: + - context: + cluster: my-cluster-installer + user: kubernetes-admin + name: kubernetes-admin@my-cluster-installer + current-context: kubernetes-admin@my-cluster-installer + kind: Config + preferences: {} + users: + ``` + + 1. 跳过 tls 验证,这一行需要手动添加 + 2. 替换为火种节点的 IP,端口 6443 替换为在节点映射的端口(你可以执行 podman ps|grep 6443 命令查看映射的端口) + + ![kubeconfig](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/add-global-node01.png) + +3. 点击 __确认__ 按钮,完成 kind 集群的接入。 + +## 为全局服务集群添加标签 + +1. 登录 AI 算力中心,进入容器管理,找到 __kapnda-glabal-cluster__ 集群,在右侧操作列表找到 __基础配置__ 菜单项并进入基础配置界面。 + +2. 在基础配置页面,为全局服务集群添加的标签 `kpanda.io/managed-by=my-cluster`: + +!!! note + + 标签 `kpanda.io/managed-by=my-cluster` 中的 vaule 值为接入集群时指定的集群名称,默认为 `my-cluster`,具体依据您的实际情况。 + + ![标签](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/add-global-node02.png) + +## 为全局服务集群添加节点 + +1. 进入全局服务集群节点列表页,点击右侧的 __接入节点__ 按钮。 + +2. 填入待接入节点的 IP 和认证信息后点击 __开始检查__ ,通过节点检查后点击 __下一步__ 。 + +3. 在 __自定义参数__ 处添加如下自定义参数: + + ```console + download_run_once: false + download_container: false + download_force_cache: false + download_localhost: false + ``` + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/add-global-node03.png) + +4. 点击 __确定__ 等待节点添加完成。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/backup-mysql-on-nfs.md b/docs/zh/docs/admin/kpanda/best-practice/backup-mysql-on-nfs.md new file mode 100644 index 0000000..7da419c --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/backup-mysql-on-nfs.md @@ -0,0 +1,624 @@ +# MySQL 应用及数据的跨集群备份恢复 + +本次演示将基于 AI 算力中心的应用备份功能,实现一个有状态应用的跨集群备份迁移。 + +!!! note + + 当前操作者应具有 AI 算力中心平台管理员的权限。 + +## 准备演示环境 + +### 准备两个集群 + +__main-cluster__ 作为备份数据的源集群, __recovery-cluster__ 集群作为需要恢复数据的目标集群。 + +| 集群 | IP | 节点 | +| ---------------- | ------------ | ------ | +| main-cluster | 10.6.175.100 | 1 节点 | +| recovery-cluster | 10.6.175.110 | 1 节点 | + +### 搭建 MinIO 配置 + +| MinIO 服务器访问地址 | 存储桶 | 用户名 | 密码 | +| ------------------------ | ---------- | ---------- | -------- | +| http://10.7.209.110:9000 | mysql-demo | root | dangerous | + +### 在两个集群部署 NFS 存储服务 + +!!! note + + 需要在 **源集群和目标集群** 上的所有节点上部署 NFS 存储服务。 + +1. 在两个集群中的所有节点安装 NFS 所需的依赖。 + + ```yaml + yum install nfs-utils iscsi-initiator-utils nfs-utils iscsi-initiator-utils nfs-utils iscsi-initiator-utils -y + ``` + + 预期输出为: + + ```bash + [root@g-master1 ~]# kubectl apply -f nfs.yaml + clusterrole.rbac.authorization.k8s.io/nfs-provisioner-runner created + clusterrolebinding.rbac.authorization.k8s.io/run-nfs-provisioner created + role.rbac.authorization.k8s.io/leader-locking-nfs-provisioner created + rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-provisioner created + serviceaccount/nfs-provisioner created + service/nfs-provisioner created + deployment.apps/nfs-provisioner created + storageclass.storage.k8s.io/nfs created + ``` + +2. 为 MySQL 应用准备 NFS 存储服务。 + + 登录 __main-cluster__ 集群和 __recovery-cluster__ 集群的任一控制节点,使用 __vi nfs.yaml__ 命令在节点上创建一个 名为 __nfs.yaml__ 的文件,将下面的 YAML 内容复制到 __nfs.yaml__ 文件。 + +

+ 点击查看完整的 nfs.yaml + ```yaml title="nfs.yaml" + kind: ClusterRole + apiVersion: rbac.authorization.k8s.io/v1 + metadata: + name: nfs-provisioner-runner + namespace: nfs-system + rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "update", "patch"] + - apiGroups: [""] + resources: ["services", "endpoints"] + verbs: ["get"] + - apiGroups: ["extensions"] + resources: ["podsecuritypolicies"] + resourceNames: ["nfs-provisioner"] + verbs: ["use"] + --- + kind: ClusterRoleBinding + apiVersion: rbac.authorization.k8s.io/v1 + metadata: + name: run-nfs-provisioner + subjects: + - kind: ServiceAccount + name: nfs-provisioner + # replace with namespace where provisioner is deployed + namespace: default + roleRef: + kind: ClusterRole + name: nfs-provisioner-runner + apiGroup: rbac.authorization.k8s.io + --- + kind: Role + apiVersion: rbac.authorization.k8s.io/v1 + metadata: + name: leader-locking-nfs-provisioner + rules: + - apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + --- + kind: RoleBinding + apiVersion: rbac.authorization.k8s.io/v1 + metadata: + name: leader-locking-nfs-provisioner + subjects: + - kind: ServiceAccount + name: nfs-provisioner + # replace with namespace where provisioner is deployed + namespace: default + roleRef: + kind: Role + name: leader-locking-nfs-provisioner + apiGroup: rbac.authorization.k8s.io + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: nfs-provisioner + --- + kind: Service + apiVersion: v1 + metadata: + name: nfs-provisioner + labels: + app: nfs-provisioner + spec: + ports: + - name: nfs + port: 2049 + - name: nfs-udp + port: 2049 + protocol: UDP + - name: nlockmgr + port: 32803 + - name: nlockmgr-udp + port: 32803 + protocol: UDP + - name: mountd + port: 20048 + - name: mountd-udp + port: 20048 + protocol: UDP + - name: rquotad + port: 875 + - name: rquotad-udp + port: 875 + protocol: UDP + - name: rpcbind + port: 111 + - name: rpcbind-udp + port: 111 + protocol: UDP + - name: statd + port: 662 + - name: statd-udp + port: 662 + protocol: UDP + selector: + app: nfs-provisioner + --- + kind: Deployment + apiVersion: apps/v1 + metadata: + name: nfs-provisioner + spec: + selector: + matchLabels: + app: nfs-provisioner + replicas: 1 + strategy: + type: Recreate + template: + metadata: + labels: + app: nfs-provisioner + spec: + serviceAccount: nfs-provisioner + containers: + - name: nfs-provisioner + resources: + limits: + cpu: "1" + memory: "4294967296" + image: release.daocloud.io/velero/nfs-provisioner:v3.0.0 + ports: + - name: nfs + containerPort: 2049 + - name: nfs-udp + containerPort: 2049 + protocol: UDP + - name: nlockmgr + containerPort: 32803 + - name: nlockmgr-udp + containerPort: 32803 + protocol: UDP + - name: mountd + containerPort: 20048 + - name: mountd-udp + containerPort: 20048 + protocol: UDP + - name: rquotad + containerPort: 875 + - name: rquotad-udp + containerPort: 875 + protocol: UDP + - name: rpcbind + containerPort: 111 + - name: rpcbind-udp + containerPort: 111 + protocol: UDP + - name: statd + containerPort: 662 + - name: statd-udp + containerPort: 662 + protocol: UDP + securityContext: + capabilities: + add: + - DAC_READ_SEARCH + - SYS_RESOURCE + args: + - "-provisioner=example.com/nfs" + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_NAME + value: nfs-provisioner + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + imagePullPolicy: "IfNotPresent" + volumeMounts: + - name: export-volume + mountPath: /export + volumes: + - name: export-volume + hostPath: + path: /data + --- + kind: StorageClass + apiVersion: storage.k8s.io/v1 + metadata: + name: nfs + provisioner: example.com/nfs + mountOptions: + - vers=4.1 + ``` +
+ +3. 在两个集群的控制节点上执行 __nfs.yaml__ 文件。 + + ```bash + kubectl apply -f nfs.yaml + ``` + +4. 查看 NFS Pod 状态,等待其状态变为 __running__ (大约需要 2 分钟)。 + + ```bash + kubectl get pod -n nfs-system -owide + ``` + + 预期输出为: + + ```bash + [root@g-master1 ~]# kubectl get pod -owide + NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES + nfs-provisioner-7dfb9bcc45-74ws2 1/1 Running 0 4m45s 10.6.175.100 g-master1 + ``` + +### 部署 MySQL 应用 + +1. 为 MySQL 应用准备基于 NFS 存储的 PVC,用来存储 MySQL 服务内的数据。 + + 使用 __vi pvc.yaml__ 命令在节点上创建名为 __pvc.yaml__ 的文件,将下面的 YAML 内容复制到 __pvc.yaml__ 文件内。 + + ```yaml title="pvc.yaml" + apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: mydata + namespace: default + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: "1Gi" + storageClassName: nfs + volumeMode: Filesystem + ``` + + +2. 在节点上使用 kubectl 工具执行 __pvc.yaml__ 文件。 + + ```bash + kubectl apply -f pvc.yaml + ``` + + 预期输出为: + + ```bash + [root@g-master1 ~]# kubectl apply -f pvc.yaml + persistentvolumeclaim/mydata created + ``` + + +3. 部署 MySQL 应用。 + + 使用 __vi mysql.yaml__ 命令在节点上创建名为 __mysql.yaml__ 的文件,将下面的 YAML 内容复制到 __mysql.yaml__ 文件。 + +
+ 点击查看完整的 mysql.yaml + ```yaml title="nfs.yaml" + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app: mysql-deploy + name: mysql-deploy + namespace: default + spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: mysql-deploy + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + creationTimestamp: null + labels: + app: mysql-deploy + name: mysql-deploy + spec: + containers: + - args: + - --ignore-db-dir=lost+found + env: + - name: MYSQL_ROOT_PASSWORD + value: dangerous + image: release.daocloud.io/velero/mysql:5 + imagePullPolicy: IfNotPresent + name: mysql-deploy + ports: + - containerPort: 3306 + protocol: TCP + resources: + limits: + cpu: "1" + memory: "4294967296" + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: data + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 999 + terminationGracePeriodSeconds: 30 + volumes: + - name: data + persistentVolumeClaim: + claimName: mydata + ``` +
+ +4. 在节点上使用 kubectl 工具执行 __mysql.yaml__ 文件。 + + ```bash + kubectl apply -f mysql.yaml + ``` + + 预期输出为: + + ```bash + [root@g-master1 ~]# kubectl apply -f mysql.yaml + deployment.apps/mysql-deploy created + ``` + +5. 查看 MySQL Pod 状态。 + + 执行 __kubectl get pod | grep mysql__ 查看 MySQL Pod 状态,等待其状态变为 __running__ (大约需要 2 分钟)。 + + 预期输出为: + + ```bash + [root@g-master1 ~]# kubectl get pod |grep mysql + mysql-deploy-5d6f94cb5c-gkrks 1/1 Running 0 2m53s + ``` + + !!! note + + - 如果 MySQL Pod 状态长期处于非 running 状态,通常是因为没有在集群的所有节点上安装 NFS 依赖。 + - 执行 __kubectl describe pod ${mysql pod 名称}__ 查看 Pod 的详细信息。 + - 如果报错中有 __MountVolume.SetUp failed for volume "pvc-4ad70cc6-df37-4253-b0c9-8cb86518ccf8" : mount failed: exit status 32__ + 之类的信息,请分别执行 __kubectl delete -f nfs.yaml/pvc.yaml/mysql.yaml__ 删除之前的资源后,重新从部署 NFS 服务开始。 + +6. 向 MySQL 应用写入数据。 + + 为了便于后期验证迁移数据是否成功,可以使用脚本向 MySQL 应用中写入测试数据。 + + 1. 使用 __vi insert.sh__ 命令在节点上创建名为 __insert.sh__ 的脚本,将下面的 YAML 内容复制到该脚本。 + + ```shell title="insert.sh" + #!/bin/bash + + function rand(){ + min=$1 + max=$(($2-$min+1)) + num=$(date +%s%N) + echo $(($num%$max+$min)) + } + + function insert(){ + user=$(date +%s%N | md5sum | cut -c 1-9) + age=$(rand 1 100) + + sql="INSERT INTO test.users(user_name, age)VALUES('${user}', ${age});" + echo -e ${sql} + + kubectl exec deploy/mysql-deploy -- mysql -uroot -pdangerous -e "${sql}" + + } + + kubectl exec deploy/mysql-deploy -- mysql -uroot -pdangerous -e "CREATE DATABASE IF NOT EXISTS test;" + kubectl exec deploy/mysql-deploy -- mysql -uroot -pdangerous -e "CREATE TABLE IF NOT EXISTS test.users(user_name VARCHAR(10) NOT NULL,age INT UNSIGNED)ENGINE=InnoDB DEFAULT CHARSET=utf8;" + + while true;do + insert + sleep 1 + done + ``` + + 2. 为 __insert.sh__ 脚本添加权限并运行该脚本。 + + ```bash + [root@g-master1 ~]# chmod +x insert.sh + [root@g-master1 ~]# ./insert.sh + ``` + + 预期输出为: + + ```console + mysql: [Warning] Using a password on the command line interface can be insecure. + mysql: [Warning] Using a password on the command line interface can be insecure. + INSERT INTO test.users(user_name, age)VALUES('dc09195ba', 10); + mysql: [Warning] Using a password on the command line interface can be insecure. + INSERT INTO test.users(user_name, age)VALUES('80ab6aa28', 70); + mysql: [Warning] Using a password on the command line interface can be insecure. + INSERT INTO test.users(user_name, age)VALUES('f488e3d46', 23); + mysql: [Warning] Using a password on the command line interface can be insecure. + INSERT INTO test.users(user_name, age)VALUES('e6098695c', 93); + mysql: [Warning] Using a password on the command line interface can be insecure. + INSERT INTO test.users(user_name, age)VALUES('eda563e7d', 63); + mysql: [Warning] Using a password on the command line interface can be insecure. + INSERT INTO test.users(user_name, age)VALUES('a4d1b8d68', 17); + mysql: [Warning] Using a password on the command line interface can be insecure. + ``` + + 3. 在键盘上同时按下 __control__ 和 __c__ 暂停脚本的执行。 + + 4. 前往 MySQL Pod 查看 MySQL 中写入的数据。 + + ```bash + kubectl exec deploy/mysql-deploy -- mysql -uroot -pdangerous -e "SELECT * FROM test.users;" + ``` + + 预期输出为: + + ```console + mysql: [Warning] Using a password on the command line interface can be insecure. + user_name age + dc09195ba 10 + 80ab6aa28 70 + f488e3d46 23 + e6098695c 93 + eda563e7d 63 + a4d1b8d68 17 + ea47546d9 86 + a34311f2e 47 + 740cefe17 33 + ede85ea28 65 + b6d0d6a0e 46 + f0eb38e50 44 + c9d2f28f5 72 + 8ddaafc6f 31 + 3ae078d0e 23 + 6e041631e 96 + ``` + +### 在两个集群安装 velero 插件 + +!!! note + + 需要在 **源集群和目标集群** 上均安装 velero 插件。 + +参考[安装 velero 插件](../backup/install-velero.md)文档和下方的 MinIO 配置,在 __main-cluster__ 集群和 __recovery-cluster__ 集群上安装 velero 插件。 + +| minio 服务器访问地址 | 存储桶 | 用户名 | 密码 | +| ------------------------ | ---------- | ------ | --------- | +| `http://10.7.209.110:9000` | mysql-demo | root | dangerous | + +!!! note + + 安装插件时需要将 S3url 替换为此次演示准备的 MinIO 服务器访问地址,存储桶替换为 MinIO 中真实存在的存储桶。 + +## 备份 MySQL 应用及数据 + +1. 在备份前我们需要先保证数据库不能有新数据进来,所以要设置为只读模式: + + ```bash + mysql> set global read_only=1; #1是只读,0是读写 + mysql> show global variables like "%read_only%"; #查询状态 + ``` + +2. 为 MySQL 应用及 PVC 数据添加独有的标签: __backup=mysql__ ,便于备份时选择资源。 + + ```bash + kubectl label deploy mysql-deploy backup=mysql # 为 __mysql-deploy__ 负载添加标签 + kubectl label pod mysql-deploy-5d6f94cb5c-gkrks backup=mysql # 为 mysql pod 添加标签 + kubectl label pvc mydata backup=mysql # 为 mysql 的 pvc 添加标签 + ``` + +3. 参考[应用备份](../backup/deployment.md#_3)中介绍的步骤,以及下方的参数创建应用备份。 + + - 名称: __backup-mysql__ (可以自定义) + - 源集群: __main-cluster__ + - 命名空间:default + - 资源过滤-指定资源标签:backup:mysql + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/mysql03.png) + +4. 创建好备份计划之后页面会自动返回备份计划列表,找到新建的备份计划 __backup-mysq__ ,点击更多操作按钮 __...__ ,选择 __立即执行__ 执行新建的备份计划。 + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/mysql05.png) + +5. 等待备份计划执行完成后,即可执行后续操作。 + +## 跨集群恢复 MySQL 应用及数据 + +1. 登录 AI 算力中心平台,在左侧导航选择 __容器管理__ -> __备份恢复__ -> __应用备份__ 。 + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/mysql06.png) + +2. 在左侧功能栏选择 __恢复__ ,然后在右侧点击 __恢复备份__ 。 + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/mysql07.png) + +3. 查看以下说明填写参数: + + - 名称: __restore-mysql__ (可以自定义) + - 备份源集群: __main-cluster__ + - 备份计划: __backup-mysql__ + - 备份点:default + - 恢复目标集群: __recovery-cluster__ + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/mysql08.png) + +4. 刷新备份计划列表,等待备份计划执行完成。 + +## 验证数据是否成功恢复 + +1. 登录 __recovery-cluster__ 集群的控制节点,查看 __mysql-deploy__ 负载是否已经成功备份到当前集群。 + + ```bash + kubectl get pod + ``` + + 预期输出如下: + + ``` + NAME READY STATUS RESTARTS AGE + mysql-deploy-5798f5d4b8-62k6c 1/1 Running 0 24h + ``` + +2. 检查 MySQL 数据表中的数据是否恢复成功。 + + ```bash + kubectl exec deploy/mysql-deploy -- mysql -uroot -pdangerous -e "SELECT * FROM test.users;" + ``` + + 预期输出如下: + + ```console + mysql: [Warning] Using a password on the command line interface can be insecure. + user_name age + dc09195ba 10 + 80ab6aa28 70 + f488e3d46 23 + e6098695c 93 + eda563e7d 63 + a4d1b8d68 17 + ea47546d9 86 + a34311f2e 47 + 740cefe17 33 + ede85ea28 65 + b6d0d6a0e 46 + f0eb38e50 44 + c9d2f28f5 72 + 8ddaafc6f 31 + 3ae078d0e 23 + 6e041631e 96 + ``` + + !!! success + + 可以看到,Pod 中的数据和 __main-cluster__ 集群中 Pod 里面的数据一致。这说明已经成功地将 __main-cluster__ 中的 MySQL 应用及其数据跨集群恢复到了 __recovery-cluster__ 集群。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/co-located/index.md b/docs/zh/docs/admin/kpanda/best-practice/co-located/index.md new file mode 100644 index 0000000..aab89cd --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/co-located/index.md @@ -0,0 +1,296 @@ +# 在离线混部 + +企业中一般存在两种类型的工作负载:在线服务(latency-sensitive service)和离线任务(batch job)。 +在线服务如搜索/支付/推荐等,具有处理优先级高、时延敏感性高、错误容忍度低以及白天负载高晚上负载低等特点。 +而离线任务如 AI 训练/大数据处理等,具有处理优先级低、时延敏感性低、错误容忍度高以及运行时负载一直较高等特点。 +由于在线服务与离线任务这两类工作负载天然存在互补性,将在/离线业务混合部署是提高服务器资源利用率的有效途径。 + +* 可以将离线业务混部到在线业务的服务器上,让离线业务能够充分利用在线业务服务器的空闲资源,提高在线业务服务器资源利用率,实现降本增效。 + +* 当业务中临时需要大量的资源,这个时候可以将在线业务弹性混部到离线业务的服务器上,优先保证在线业务的资源需求,临时需求结束后再把资源归还给离线业务。 + +当前使用开源项目 [Koordinator](https://koordinator.sh) 作为在离线混部的解决方案。 + +Koordinator 是一个基于 QoS 的 Kubernetes 混合工作负载调度系统。 +它旨在提高对延迟敏感的工作负载和批处理作业的运行时效率和可靠性,简化与资源相关的配置调整的复杂性,并增加 Pod 部署密度以提高资源利用率。 + +## Koordinator QoS + +Koordinator 调度系统支持的 QoS 有五种类型: + +| QoS | 特点 | 说明| +|----------------------------------|------------------------------------| -------------| +| SYSTEM | 系统进程,资源受限 | 对于 DaemonSets 等系统服务,虽然需要保证系统服务的延迟,但也需要限制节点上这些系统服务容器的资源使用,以确保其不占用过多的资源| +| LSE(Latency Sensitive Exclusive) | 保留资源并组织同 QoS 的 Pod 共享资源 | 很少使用,常见于中间件类应用,一般在独立的资源池中使用| +| LSR(Latency Sensitive Reserved) | 预留资源以获得更好的确定性 | 类似于社区的 Guaranteed,CPU 核被绑定| +| LS(Latency Sensitive) | 共享资源,对突发流量有更好的弹性 | 微服务工作负载的典型QoS级别,实现更好的资源弹性和更灵活的资源调整能力| +| BE(Best Effort) | 共享不包括 LSE 的资源,资源运行质量有限,甚至在极端情况下被杀死 | 批量作业的典型 QoS 水平,在一定时期内稳定的计算吞吐量,低成本资源| + +### Koordinator QoS CPU 编排原则 + +- LSE/LSR Pod 的 Request 和 Limit 必须相等,CPU 值必须是 1000 的整数倍。 +- LSE Pod 分配的 CPU 是完全独占的,不得共享。如果节点是超线程架构,只保证逻辑核心维度是隔离的,但是可以通过 CPUBindPolicyFullPCPUs 策略获得更好的隔离。 +- LSR Pod 分配的 CPU 只能与 BE Pod 共享。 +- LS Pod 绑定了与 LSE/LSR Pod 独占之外的共享 CPU 池。 +- BE Pod 绑定使用节点中除 LSE Pod 独占之外的所有 CPU 。 +- 如果 kubelet 的 CPU 管理器策略为 static 策略,则已经运行的 K8s Guaranteed Pods 等价于 Koordinator LSR。 +- 如果 kubelet 的 CPU 管理器策略为 none 策略,则已经运行的 K8s Guaranteed Pods 等价于 Koordinator LS。 +- 新创建但未指定 Koordinator QoS 的 K8s Guaranteed Pod 等价于 Koordinator LS。 + +![koordinator_qos_cpu.png](../images/koordinator_qos_cpu.png) + +## 快速上手 + +### 前提条件 + +- 已经部署 AI 算力中心容器管理平台,且平台运行正常。 +- 容器管理模块已接入 Kubernetes 集群或者已创建 Kubernetes 集群,且能够访问集群的 UI 界面。 +- 当前集群已安装 koordinator 并正常运行,安装步骤可参考 [koordinator 离线安装](./install.md)。 + +### 操作步骤 + +以下示例中创建4个副本数为1的 deployment, 设置 QoS 类别为 LSE, LSR, LS, BE, 待 pod 创建完成后,观察各 pod 的 CPU 分配情况。 + +1. 创建名称为 nginx-lse 的 deployment,QoS 类别为 LSE, yaml 文件如下。 + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-lse + labels: + app: nginx-lse + spec: + replicas: 1 + selector: + matchLabels: + app: nginx-lse + template: + metadata: + name: nginx-lse + labels: + app: nginx-lse + koordinator.sh/qosClass: LSE # 设置 QoS 类别为 LSE + # 调度器将在物理内核之间均匀的分配逻辑 CPU + annotations: + scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy": "SpreadByPCPUs"}' + spec: + schedulerName: koord-scheduler # 使用 koord-scheduler 调度器 + containers: + - name: nginx + image: release.daocloud.io/kpanda/nginx:1.25.3-alpine + resources: + limits: + cpu: '2' + requests: + cpu: '2' + priorityClassName: koord-prod + + ``` + +2. 创建名称为 nginx-lsr 的 deployment,QoS 类别为 LSR, yaml 文件如下。 + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-lsr + labels: + app: nginx-lsr + spec: + replicas: 1 + selector: + matchLabels: + app: nginx-lsr + template: + metadata: + name: nginx-lsr + labels: + app: nginx-lsr + koordinator.sh/qosClass: LSR # 设置 QoS 类别为 LSR + # 调度器将在物理内核之间均匀的分配逻辑 CPU + annotations: + scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy": "SpreadByPCPUs"}' + spec: + schedulerName: koord-scheduler # 使用 koord-scheduler 调度器 + containers: + - name: nginx + image: release.daocloud.io/kpanda/nginx:1.25.3-alpine + resources: + limits: + cpu: '2' + requests: + cpu: '2' + priorityClassName: koord-prod + ``` + +3. 创建名称为 nginx-ls 的 deployment,QoS 类别为 LS, yaml 文件如下。 + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-ls + labels: + app: nginx-ls + spec: + replicas: 1 + selector: + matchLabels: + app: nginx-ls + template: + metadata: + name: nginx-ls + labels: + app: nginx-ls + koordinator.sh/qosClass: LS # 设置 QoS 类别为 LS + # 调度器将在物理内核之间均匀的分配逻辑 CPU + annotations: + scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy": "SpreadByPCPUs"}' + spec: + schedulerName: koord-scheduler + containers: + - name: nginx + image: release.daocloud.io/kpanda/nginx:1.25.3-alpine + resources: + limits: + cpu: '2' + requests: + cpu: '2' + priorityClassName: koord-prod + ``` + +4. 创建名称为 nginx-be 的 deployment,QoS 类别为 BE, yaml 文件如下。 + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-be + labels: + app: nginx-be + spec: + replicas: 1 + selector: + matchLabels: + app: nginx-be + template: + metadata: + name: nginx-be + labels: + app: nginx-be + koordinator.sh/qosClass: BE # 设置 QoS 类别为 BE + # 调度器将在物理内核之间均匀的分配逻辑 CPU + annotations: + scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy": "SpreadByPCPUs"}' + spec: + schedulerName: koord-scheduler # 使用 koord-scheduler 调度器 + containers: + - name: nginx + image: release.daocloud.io/kpanda/nginx:1.25.3-alpine + resources: + limits: + kubernetes.io/batch-cpu: 2k + requests: + kubernetes.io/batch-cpu: 2k + priorityClassName: koord-batch + ``` + + 查看 pod 状态,当 pod 处于 running 后,查看各 pod 的 CPU 分配情况。 + + ```shell + [root@controller-node-1 ~]# kubectl get pod + NAME READY STATUS RESTARTS AGE + nginx-be-577c946b89-js2qn 1/1 Running 0 4h41m + nginx-ls-54746c8cf8-rh4b7 1/1 Running 0 4h51m + nginx-lse-56c9cd77f5-cdqbd 1/1 Running 0 4h41m + nginx-lsr-c7fdb97d8-b58h8 1/1 Running 0 4h51m + ``` + + 本示例中使用 get_cpuset.sh 脚本查看 Pod 的 cpuset 信息,脚本内容如下。 + + ```shell + #!/bin/bash + + # 获取Pod的名称和命名空间作为输入参数 + POD_NAME=$1 + NAMESPACE=${2-default} + + # 确保提供了Pod名称和命名空间 + if [ -z "$POD_NAME" ] || [ -z "$NAMESPACE" ]; then + echo "Usage: $0 " + exit 1 + fi + + # 使用kubectl获取Pod的UID和QoS类别 + POD_INFO=$(kubectl get pod "$POD_NAME" -n "$NAMESPACE" -o jsonpath="{.metadata.uid} {.status.qosClass} {.status.containerStatuses[0].containerID}") + read -r POD_UID POD_QOS CONTAINER_ID <<< "$POD_INFO" + + # 检查UID和QoS类别是否成功获取 + if [ -z "$POD_UID" ] || [ -z "$POD_QOS" ]; then + echo "Failed to get UID or QoS Class for Pod $POD_NAME in namespace $NAMESPACE." + exit 1 + fi + + POD_UID="${POD_UID//-/_}" + CONTAINER_ID="${CONTAINER_ID//containerd:\/\//cri-containerd-}".scope + + # 根据QoS类别构建cgroup路径 + case "$POD_QOS" in + Guaranteed) + QOS_PATH="kubepods-pod.slice/$POD_UID.slice" + ;; + Burstable) + QOS_PATH="kubepods-burstable.slice/kubepods-burstable-pod$POD_UID.slice" + ;; + BestEffort) + QOS_PATH="kubepods-besteffort.slice/kubepods-besteffort-pod$POD_UID.slice" + ;; + *) + echo "Unknown QoS Class: $POD_QOS" + exit 1 + ;; + esac + + CPUGROUP_PATH="/sys/fs/cgroup/kubepods.slice/$QOS_PATH" + + # 检查路径是否存在 + if [ ! -d "$CPUGROUP_PATH" ]; then + echo "CPUs cgroup path for Pod $POD_NAME does not exist: $CPUGROUP_PATH" + exit 1 + fi + + # 读取并打印cpuset值 + CPUSET=$(cat "$CPUGROUP_PATH/$CONTAINER_ID/cpuset.cpus") + echo "CPU set for Pod $POD_NAME ($POD_QOS QoS): $CPUSET" + ``` + +查看各 Pod 的 cpuset 分配情况。 + +1. QoS 类型为 LSE 的 Pod, 独占 0-1 核,不与其他类型的 Pod 共享 CPU。 + + ```shell + [root@controller-node-1 ~]# ./get_cpuset.sh nginx-lse-56c9cd77f5-cdqbd + CPU set for Pod nginx-lse-56c9cd77f5-cdqbd (Burstable QoS): 0-1 + ``` + +2. QoS 类型为 LSR 的 Pod, 绑定 CPU 2-3 核,可与 BE 类型的 Pod 共享。 + + ```shell + [root@controller-node-1 ~]# ./get_cpuset.sh nginx-lsr-c7fdb97d8-b58h8 + CPU set for Pod nginx-lsr-c7fdb97d8-b58h8 (Burstable QoS): 2-3 + ``` + +3. QoS 类型为 LS 的 Pod, 使用 CPU 4-15 核,绑定了与 LSE/LSR Pod 独占之外的共享 CPU 池。 + + ```shell + [root@controller-node-1 ~]# ./get_cpuset.sh nginx-ls-54746c8cf8-rh4b7 + CPU set for Pod nginx-ls-54746c8cf8-rh4b7 (Burstable QoS): 4-15 + ``` + +4. QoS 类型为 BE 的 pod, 可使用 LSE Pod 独占之外的 CPU。 + + ```shell + [root@controller-node-1 ~]# ./get_cpuset.sh nginx-be-577c946b89-js2qn + CPU set for Pod nginx-be-577c946b89-js2qn (BestEffort QoS): 2,4-12 + ``` diff --git a/docs/zh/docs/admin/kpanda/best-practice/co-located/install.md b/docs/zh/docs/admin/kpanda/best-practice/co-located/install.md new file mode 100644 index 0000000..ca90db8 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/co-located/install.md @@ -0,0 +1,34 @@ +# Koordinator 离线安装 + +Koordinator 是一个基于 QoS 的 Kubernetes 混合工作负载调度系统。它旨在提高对延迟敏感的工作负载和批处理作业的运行时效率和可靠性, +简化与资源相关的配置调整的复杂性,并增加 Pod 部署密度以提高资源利用率。 + +AI 算力中心预置了 Koordinator v1.5.0 离线包。 + +本文介绍如何离线部署 Koordinator。 + +## 前提条件 + +1. 用户已经在平台上安装了 v0.20.0 及以上版本的 addon 离线包。 +2. 待安装集群的 Kubernetes version >= 1.18. +3. 为了最好的体验,推荐使用 linux kernel 4.19 或者更高版本。 + +## 操作步骤 + +参考如下步骤为集群安装 Koordinator 插件。 + +1. 登录平台,进入 __容器管理__ -> __待安装 Koordinator 的集群__ -> 进入集群详情。 + +2. 在 __Helm 模板__ 页面,选择 __全部仓库__ ,搜索 __koordinator__ 。 + +3. 选择 __koordinator__ ,点击 __安装__ 。 + + ![点击安装](../images/koordinator_helm.png) + +4. 进入 koordinator 安装页面,点击 __确定__,使用默认配置安装 koordinator。 + + ![使用默认配置](../images/koordinator_install.png) + +5. 查看 koordinator-system 命名空间下的 Pod 是否正常运行 + + ![查看Pod](../images/koordinator_system_pod.png) diff --git a/docs/zh/docs/admin/kpanda/best-practice/create-redhat9.2-on-centos-platform.md b/docs/zh/docs/admin/kpanda/best-practice/create-redhat9.2-on-centos-platform.md new file mode 100644 index 0000000..981c9fe --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/create-redhat9.2-on-centos-platform.md @@ -0,0 +1,78 @@ +# 在 CentOS 管理平台上创建 RedHat 9.2 工作集群 + +本文介绍如何在已有的 CentOS 管理平台上创建 RedHat 9.2 工作集群。 + +!!! note + + 本文仅针对离线模式下,使用 AI 算力中心平台创建工作集群,管理平台和待建工作集群的架构均为 AMD。 + 创建集群时不支持异构(AMD 和 ARM 混合)部署,您可以在集群创建完成后,通过接入异构节点的方式进行集群混合部署管理。 + +## 前提条件 + +已经部署好一个 AI 算力中心全模式,并且火种节点还存活,部署参考文档[离线安装 AI 算力中心商业版](../../install/commercial/start-install.md) + +## 下载并导入 RedHat 相关离线包 + +请确保已经登录到火种节点!并且之前部署 AI 算力中心时使用的 `clusterConfig.yaml` 文件还在。 + +### 下载 RedHat 相关离线包 + +下载所需的 RedHat OS package 包和 ISO 离线包: + +| 资源名 | 说明 | 下载地址 | +| ----- | --- | ------- | +| os-pkgs-redhat9-v0.9.3.tar.gz | RedHat9.2 OS-package 包 | https://github.com/kubean-io/kubean/releases/download/v0.9.3/os-pkgs-redhat9-v0.9.3.tar.gz | +| ISO 离线包 | ISO 包导入火种节点脚本 | 前往 [RedHat 官方地址登录下载](https://access.redhat.com/zh_CN/downloads) | +| import-iso | ISO 导入火种节点脚本 | https://github.com/kubean-io/kubean/releases/download/v0.9.3/import_iso.sh | + +### 导入 os pckage 离线包至火种节点的 minio + +**解压 RedHat os pckage 离线包** + +执行如下命令解压下载的 os pckage 离线包。此处我们下载的 RedHat os pckage 离线包。 + +```bash +tar -xvf os-pkgs-redhat9-v0.9.3.tar.gz +``` + +os package 解压后的文件内容如下: + +```text + os-pkgs + ├── import_ospkgs.sh # 该脚本用于导入 os packages 到 MinIO 文件服务 + ├── os-pkgs-amd64.tar.gz # amd64 架构的 os packages 包 + ├── os-pkgs-arm64.tar.gz # arm64 架构的 os packages 包 + └── os-pkgs.sha256sum.txt # os packages 包的 sha256sum 效验文件 +``` + +**导入 OS Package 至火种节点的 MinIO** + +执行如下命令,将 os packages 包到 MinIO 文件服务中: + +```bash +MINIO_USER=rootuser MINIO_PASS=rootpass123 ./import_ospkgs.sh http://127.0.0.1:9000 os-pkgs-redhat9-v0.9.3.tar.gz +``` + +!!! note + + 上述命令仅仅适用于火种节点内置的 MinIO 服务,如果使用外部 MinIO 请将 `http://127.0.0.1:9000` 替换为外部 MinIO 的访问地址。 + “rootuser” 和 “rootpass123” 是火种节点内置的 MinIO 服务的默认账户和密码。“os-pkgs-redhat9-v0.9.3.tar.gz“ + 为所下载的 os package 离线包的名称。 + +### 导入 ISO 离线包至火种节点的 MinIO + +执行如下命令, 将 ISO 包到 MinIO 文件服务中: + +```bash +MINIO_USER=rootuser MINIO_PASS=rootpass123 ./import_iso.sh http://127.0.0.1:9000 rhel-9.2-x86_64-dvd.iso +``` + +!!! note + + 上述命令仅仅适用于火种节点内置的 MinIO 服务,如果使用外部 MinIO 请将 `http://127.0.0.1:9000` 替换为外部 MinIO 的访问地址。 + “rootuser” 和 “rootpass123” 是火种节点内置的 MinIO 服务的默认账户和密码。 + “rhel-9.2-x86_64-dvd.iso“ 为所下载的 ISO 离线包。 + +## 前往 UI 界面创建集群 + +参考文档[创建工作集群](../clusters/create-cluster.md),创建 RedHat 9.2 集群。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/create-ubuntu-on-centos-platform.md b/docs/zh/docs/admin/kpanda/best-practice/create-ubuntu-on-centos-platform.md new file mode 100644 index 0000000..51c53d9 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/create-ubuntu-on-centos-platform.md @@ -0,0 +1,33 @@ +# 在 CentOS 管理平台上创建 Ubuntu 工作集群 + +本文介绍如何在已有的 CentOS 管理平台上创建 Ubuntu 工作集群。 + +!!! note + + 本文仅针对离线模式下,使用 AI 算力中心平台创建工作集群,管理平台和待建工作集群的架构均为 AMD。 + 创建集群时不支持异构(AMD 和 ARM 混合)部署,您可以在集群创建完成后,通过接入异构节点的方式进行集群混合部署管理。 + +## 前提条件 + +- 已经部署好一个 AI 算力中心全模式,并且火种节点还存活,部署参考文档[离线安装 AI 算力中心商业版](../../install/commercial/start-install.md) + +## 下载并导入 Ubuntu 相关离线包 + +请确保已经登录到火种节点!并且之前部署 AI 算力中心时使用的 clusterConfig.yaml 文件还在。 + +### 下载 Ubuntu 相关离线包 + +下载所需的 Ubuntu OS package 包和 ISO 离线包: + +| 资源名 | 说明 | 下载地址 | +| ----- | --- | ------- | +| os-pkgs-ubuntu2204-v0.18.2.tar.gz | Ubuntu1804 OS-package 包 | https://github.com/kubean-io/kubean/releases/download/v0.18.2/os-pkgs-ubuntu2204-v0.18.2.tar.gz | +| ISO 离线包 | ISO 包 | http://mirrors.melbourne.co.uk/ubuntu-releases/ | + +### 导入 OS Package 和 ISO 离线包至火种节点的 MinIO + +参考文档[离线资源导入](../../install/import.md#_5),导入离线资源至火种节点的 MinIO。 + +## 前往 UI 界面创建集群 + +参考文档[创建工作集群](../clusters/create-cluster.md),创建 Ubuntu 集群。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/etcd-backup.md b/docs/zh/docs/admin/kpanda/best-practice/etcd-backup.md new file mode 100644 index 0000000..58c03c9 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/etcd-backup.md @@ -0,0 +1,311 @@ +# ETCD 备份还原 + +使用 ETCD 备份功能创建备份策略,可以将指定集群的 etcd 数据定时备份到 S3 存储中。本文主要介绍如何将已经备份的数据还原到当前集群中。 + +!!! note + + - AI 算力中心ETCD 备份还原仅限于针对同一集群(节点数和 IP 地址没有变化)进行备份与还原。 + 例如,备份了 A 集群 的 etcd 数据后,只能将备份数据还原到 A 集群中,不能还原到 B 集群。 + - 对于跨集群的备份与还原,建议使用[应用备份还原](../backup/deployment.md)功能。 + - 首先创建备份策略,备份当前状态,建议参考[ETCD 备份](../backup/etcd-backup.md)功能。 + +下面通过具体的案例来说明备份还原的整个过程。 + +## 环境信息 + +首先介绍还原的目标集群和 S3 存储的基本信息。这里以 MinIo 作为 S3 存储,整个集群有 3 个控制面(3 个 etcd 副本)。 + +|IP|主机|角色|备注| +|--|--|--|--| +|10.6.212.10|host01|k8s-master01|k8s 节点 1| +|10.6.212.11|host02|k8s-master02|k8s 节点 2| +|10.6.212.12|host03|k8s-master03|k8s 节点 3| +|10.6.212.13|host04|minio|minio 服务| + +## 前提条件 + +### 安装 etcdbrctl 工具 + +为了实现 ETCD 数据备份还原,需要在上述任意一个 Kubernetes 节点上安装 etcdbrctl 开源工具。 +此工具暂时没有二进制文件,需要自行编译。编译方式请参考 +[Gardener / etcd-backup-restore 本地开发文档](https://github.com/gardener/etcd-backup-restore/blob/master/docs/development/local_setup.md#build)。 + +安装完成后用如下命令检查工具是否可用: + +```shell +etcdbrctl -v +``` + +预期输出如下: + +```none +INFO[0000] etcd-backup-restore Version: v0.23.0-dev +INFO[0000] Git SHA: b980beec +INFO[0000] Go Version: go1.19.3 +INFO[0000] Go OS/Arch: linux/amd64 +``` + +### 检查备份数据 + +还原之前需要检查下列事项: + +- 是否已经在 AI 算力中心中成功备份了数据 +- 检查 S3 存储中备份数据是否存在 + +!!! note + + AI 算力中心的备份是全量数据备份,还原时将还原最后一次备份的全量数据。 + +![minio](https://docs.daocloud.io/daocloud-docs-images/docs/kpanda/images/bp01.png) + +### 关闭集群 + +在备份之前,必须要先关闭集群。默认集群 __etcd__ 和 __kube-apiserver__ 都是以静态 Pod 的形式启动的。 +这里的关闭集群是指将静态 Pod manifest 文件移动到 __/etc/kubernetes/manifest__ 目录外,集群就会移除对应 Pod,达到关闭服务的作用。 + +1. 首先删除之前的备份数据,移除数据并非将现有 etcd 数据删除,而是指修改 etcd 数据目录的名称。 + 等备份还原成功之后再删除此目录。这样做的目的是,如果 etcd 备份还原失败,还可以尝试还原当前集群。此步骤每个节点均需执行。 + + ```shell + rm -rf /var/lib/etcd_bak + ``` + +2. 然后需要关闭 __kube-apiserver__ 的服务,确保 etcd 的数据没有新变化。此步骤每个节点均需执行。 + + ```shell + mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/kube-apiserver.yaml + ``` + +3. 同时还需要关闭 etcd 的服务。此步骤每个节点均需执行。 + + ```shell + mv /etc/kubernetes/manifests/etcd.yaml /tmp/etcd.yaml + ``` + +4. 确保所有控制平面的 __kube-apiserver__ 和 __etcd__ 服务都已经关闭。 + +5. 关闭所有的节点后,使用如下命令检查 __etcd__ 集群状态。此命令在任意一个节点执行即可。 + + > __endpoints__ 的值需要替换为实际节点名称 + + ```shell + etcdctl endpoint status --endpoints=controller-node-1:2379,controller-node-2:2379,controller-node-3:2379 -w table \ + --cacert="/etc/kubernetes/ssl/etcd/ca.crt" \ + --cert="/etc/kubernetes/ssl/apiserver-etcd-client.crt" \ + --key="/etc/kubernetes/ssl/apiserver-etcd-client.key" + ``` + + 预期输出如下,表示所有的 __etcd__ 节点都被销毁: + + ```none + {"level":"warn","ts":"2023-03-29T17:51:50.817+0800","logger":"etcd-client","caller":"v3@v3.5.6/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0001ba000/controller-node-1:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 10.5.14.31:2379: connect: connection refused\""} + Failed to get the status of endpoint controller-node-1:2379 (context deadline exceeded) + {"level":"warn","ts":"2023-03-29T17:51:55.818+0800","logger":"etcd-client","caller":"v3@v3.5.6/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0001ba000/controller-node-2:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 10.5.14.32:2379: connect: connection refused\""} + Failed to get the status of endpoint controller-node-2:2379 (context deadline exceeded) + {"level":"warn","ts":"2023-03-29T17:52:00.820+0800","logger":"etcd-client","caller":"v3@v3.5.6/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0001ba000/controller-node-1:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 10.5.14.33:2379: connect: connection refused\""} + Failed to get the status of endpoint controller-node-3:2379 (context deadline exceeded) + +----------+----+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | + +----------+----+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + +----------+----+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + ``` + +## 还原备份 + +只需要还原一个节点的数据,其他节点的 etcd 数据就会自动进行同步。 + +1. 设置环境变量 + + 使用 etcdbrctl 还原数据之前,执行如下命令将连接 S3 的认证信息设置为环境变量: + + ```shell + export ECS_ENDPOINT=http://10.6.212.13:9000 # (1)! + export ECS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE # (2)! + export ECS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY # (3)! + ``` + + 1. S3 存储的访问点 + 2. S3 存储的用户名 + 3. S3 存储的密码 + +2. 执行还原操作 + + 执行 etcdbrctl 命令行工具执行还原,这是最关键的一步。 + + ```shell + etcdbrctl restore --data-dir /var/lib/etcd/ --store-container="etcd-backup" \ + --storage-provider=ECS \ + --initial-cluster=controller-node1=https://10.6.212.10:2380 \ + --initial-advertise-peer-urls=https://10.6.212.10:2380 + ``` + + 参数说明如下: + + - --data-dir: etcd 数据目录,此目录必须跟 etcd 数据目录一致,etcd 才能正常加载数据。 + - --store-container:S3 存储的位置,MinIO 中对应的 bucket,必须跟数据备份的 bucket 相对应。 + - --initial-cluster:etcd 初始化配置, etcd 集群的名称必须跟原来一致。 + - --initial-advertise-peer-urls:etcd member 集群之间访问地址。必须跟 etcd 的配置保持一致。 + + 预期输出如下: + + ```none + INFO[0000] Finding latest set of snapshot to recover from... + INFO[0000] Restoring from base snapshot: Full-00000000-00111147-1679991074 actor=restorer + INFO[0001] successfully fetched data of base snapshot in 1.241380207 seconds actor=restorer + {"level":"info","ts":1680011221.2511616,"caller":"mvcc/kvstore.go:380","msg":"restored last compact revision","meta-bucket-name":"meta","meta-bucket-name-key":"finishedCompactRev","restored-compact-revision":110327} + {"level":"info","ts":1680011221.3045986,"caller":"membership/cluster.go:392","msg":"added member","cluster-id":"66638454b9dd7b8a","local-member-id":"0","added-peer-id":"123c2503a378fc46","added-peer-peer-urls":["https://10.6.212.10:2380"]} + INFO[0001] Starting embedded etcd server... actor=restorer + .... + + {"level":"info","ts":"2023-03-28T13:47:02.922Z","caller":"embed/etcd.go:565","msg":"stopped serving peer traffic","address":"127.0.0.1:37161"} + {"level":"info","ts":"2023-03-28T13:47:02.922Z","caller":"embed/etcd.go:367","msg":"closed etcd server","name":"default","data-dir":"/var/lib/etcd","advertise-peer-urls":["http://localhost:0"],"advertise-client-urls":["http://localhost:0"]} + INFO[0003] Successfully restored the etcd data directory. + ``` + + !!! note "可以查看 etcd 的 YAML 文件进行对照,以免配置错误" + + ```shell + cat /tmp/etcd.yaml | grep initial- + - --experimental-initial-corrupt-check=true + - --initial-advertise-peer-urls=https://10.6.212.10:2380 + - --initial-cluster=controller-node-1=https://10.6.212.10:2380 + ``` + +3. 以下命令在节点 01 上执行,为了恢复节点 01 的 etcd 服务。 + + 首先将 etcd 静态 Pod 的 manifest 文件移动到 __/etc/kubernetes/manifests__ 目录下,kubelet 将会重启 etcd: + + ```shell + mv /tmp/etcd.yaml /etc/kubernetes/manifests/etcd.yaml + ``` + + 然后等待 etcd 服务启动完成以后,检查 etcd 的状态,etcd 相关证书默认目录: __/etc/kubernetes/ssl__ 。如果集群证书存放在其他位置,请指定对应路径。 + + - 检查 etcd 集群列表: + + ```shell + etcdctl member list -w table \ + --cacert="/etc/kubernetes/ssl/etcd/ca.crt" \ + --cert="/etc/kubernetes/ssl/apiserver-etcd-client.crt" \ + --key="/etc/kubernetes/ssl/apiserver-etcd-client.key" + ``` + + 预期输出如下: + + ```none + +------------------+---------+-------------------+--------------------------+--------------------------+------------+ + | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER | + +------------------+---------+-------------------+--------------------------+--------------------------+------------+ + | 123c2503a378fc46 | started | controller-node-1 | https://10.6.212.10:2380 | https://10.6.212.10:2379 | false | + +------------------+---------+-------------------+--------------------------+--------------------------+------------+ + ``` + + - 查看 controller-node-1 状态: + + ```shell + etcdctl endpoint status --endpoints=controller-node-1:2379 -w table \ + --cacert="/etc/kubernetes/ssl/etcd/ca.crt" \ + --cert="/etc/kubernetes/ssl/apiserver-etcd-client.crt" \ + --key="/etc/kubernetes/ssl/apiserver-etcd-client.key" + ``` + + 预期输出如下: + + ```none + +------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | + +------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + | controller-node-1:2379 | 123c2503a378fc46 | 3.5.6 | 15 MB | true | false | 3 | 1200 | 1199 | | + +------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + ``` + +4. 恢复其他节点数据 + + 上述步骤已经还原了节点 01 的数据,若想要还原其他节点数据,只需要将 etcd 的 Pod 启动起来,让 etcd 自己完成数据同步。 + + - 在节点 02 和节点 03 都执行相同的操作: + + ```shell + mv /tmp/etcd.yaml /etc/kubernetes/manifests/etcd.yaml + ``` + + - etcd member 集群之间的数据同步需要一定的时间,可以查看 etcd 集群状态,确保所有 etcd 集群正常: + + 检查 etcd 集群状态是否正常: + + ```shell + etcdctl member list -w table \ + --cacert="/etc/kubernetes/ssl/etcd/ca.crt" \ + --cert="/etc/kubernetes/ssl/apiserver-etcd-client.crt" \ + --key="/etc/kubernetes/ssl/apiserver-etcd-client.key" + ``` + + 预期输出如下: + + ```none + +------------------+---------+-------------------+-------------------------+-------------------------+------------+ + | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER | + +------------------+---------+-------------------+-------------------------+-------------------------+------------+ + | 6ea47110c5a87c03 | started | controller-node-1 | https://10.5.14.31:2380 | https://10.5.14.31:2379 | false | + | e222e199f1e318c4 | started | controller-node-2 | https://10.5.14.32:2380 | https://10.5.14.32:2379 | false | + | f64eeda321aabe2d | started | controller-node-3 | https://10.5.14.33:2380 | https://10.5.14.33:2379 | false | + +------------------+---------+-------------------+-------------------------+-------------------------+------------+ + ``` + + 检查 3 个 member 节点是否正常: + + ```shell + etcdctl endpoint status --endpoints=controller-node-1:2379,controller-node-2:2379,controller-node-3:2379 -w table \ + --cacert="/etc/kubernetes/ssl/etcd/ca.crt" \ + --cert="/etc/kubernetes/ssl/apiserver-etcd-client.crt" \ + --key="/etc/kubernetes/ssl/apiserver-etcd-client.key" + ``` + + 预期输出如下: + + ```none + +------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | + +------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + | controller-node-1:2379 | 6ea47110c5a87c03 | 3.5.6 | 88 MB | true | false | 6 | 199008 | 199008 | | + | controller-node-2:2379 | e222e199f1e318c4 | 3.5.6 | 88 MB | false | false | 6 | 199114 | 199114 | | + | controller-node-3:2379 | f64eeda321aabe2d | 3.5.6 | 88 MB | false | false | 6 | 199316 | 199316 | | + +------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ + ``` + +## 恢复集群 + +等所有节点的 etcd 数据同步完成后,则可以将 kube-apiserver 进行重新启动,将整个集群恢复到可访问状态: + +1. 重新启动 node1 的 kube-apiserver 服务 + + ```shell + mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml + ``` + +2. 重新启动 node2 的 kube-apiserver 服务 + + ```shell + mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml + ``` + +3. 重新启动 node3 的 kube-apiserver 服务 + + ```shell + mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml + ``` + +4. 等待 kubelet 将 kube-apiserver 启动后,检查还原的 k8s 数据是否正常: + + ```shell + kubectl get nodes + ``` + + 预期输出如下: + + ```none + NAME STATUS ROLES AGE VERSION + controller-node-1 Ready 3h30m v1.25.4 + controller-node-3 Ready control-plane 3h29m v1.25.4 + controller-node-3 Ready control-plane 3h28m v1.25.4 + ``` diff --git a/docs/zh/docs/admin/kpanda/best-practice/hardening-cluster.md b/docs/zh/docs/admin/kpanda/best-practice/hardening-cluster.md new file mode 100644 index 0000000..b913694 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/hardening-cluster.md @@ -0,0 +1,77 @@ +# 如何加固自建工作集群 + +在 AI 算力中心中,使用 CIS Benchmark (CIS) 扫描使用界面创建的工作集群,有一些扫描项并没有通过扫描。 +本文将基于不同的 CIS Benchmark 版本进行加固说明。 + +## CIS Benchmark 1.27 + +扫描环境说明: + +- kubernetes version: 1.25.4 +- containerd: 1.7.0 +- kubean version: 0.4.9 +- kubespary version: v2.22 + +### 未通过扫描项 + +1. [FAIL] 1.2.5 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated) +2. [FAIL] 1.3.7 Ensure that the --bind-address argument is set to 127.0.0.1 (Automated) +3. [FAIL] 1.4.1 Ensure that the --profiling argument is set to false (Automated) +4. [FAIL] 1.4.2 Ensure that the --bind-address argument is set to 127.0.0.1 (Automated) + +### 扫描失败原因分析 + +1. [FAIL] 1.2.5 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated) + + **原因:** CIS 要求 kube-apiserver 必须指定 kubelet 的 CA 证书路径: + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening01.png) + +2. [FAIL] 1.3.7 Ensure that the --bind-address argument is set to 127.0.0.1 (Automated) + + **原因:** CIS 要求 kube-controller-manager 的 --bing-address=127.0.0.1 + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening02.png) + +3. [FAIL] 1.4.1 Ensure that the --profiling argument is set to false (Automated) + + **原因:** CIS 要求 kube-scheduler 设置 --profiling=false + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening03.png) + +4. [FAIL] 1.4.2 Ensure that the --bind-address argument is set to 127.0.0.1 (Automated) + + **原因:** CIS 要求 设置 kube-scheduler 的 --bind-address=127.0.0.1 + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening04.png) + +### 加固配置以通过 CIS 扫描 + +kubespray 官方为了解决这些安全扫描问题,在 v2.22 中添加默认值解决了一部分问题, +更多细节请参考 [kubespray 加固文档](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/hardening.md)。 + +- 通过修改 kubean var-config 配置文件来添加参数: + + ```yaml + kubernetes_audit: true + kube_controller_manager_bind_address: 127.0.0.1 + kube_scheduler_bind_address: 127.0.0.1 + kube_kubeadm_scheduler_extra_args: + profiling: false + kubelet_rotate_server_certificates: true + ``` + +- 在 AI 算力中心中,也提供了通过 UI 来配置高级参数的功能,在创建集群最后一步添加自定义参数: + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening05.png) + +- 设置自定义参数后,在 kubean 的 var-config 的 configmap 中添加了如下参数: + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening06.png) + +- 安装集群后进行扫描: + + ![img](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/hardening07.png) + +扫描后所有的扫描项都通过了扫描(WARN 和 INFO 计算为 PASS), +由于 CIS Benchmark 会不断更新,此文档的内容只适用于 CIS Benchmark 1.27。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/images/arm01.png b/docs/zh/docs/admin/kpanda/best-practice/images/arm01.png new file mode 100644 index 0000000..f93e765 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/best-practice/images/arm01.png differ diff --git a/docs/zh/docs/admin/kpanda/best-practice/images/arm02.png b/docs/zh/docs/admin/kpanda/best-practice/images/arm02.png new file mode 100644 index 0000000..15ac6cf Binary files /dev/null and b/docs/zh/docs/admin/kpanda/best-practice/images/arm02.png differ diff --git a/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_helm.png b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_helm.png new file mode 100644 index 0000000..0c33e80 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_helm.png differ diff --git a/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_install.png b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_install.png new file mode 100644 index 0000000..262eba3 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_install.png differ diff --git a/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_qos_cpu.png b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_qos_cpu.png new file mode 100644 index 0000000..592701f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_qos_cpu.png differ diff --git a/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_system_pod.png b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_system_pod.png new file mode 100644 index 0000000..e7c1f8b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/best-practice/images/koordinator_system_pod.png differ diff --git a/docs/zh/docs/admin/kpanda/best-practice/k3s-lcm.md b/docs/zh/docs/admin/kpanda/best-practice/k3s-lcm.md new file mode 100644 index 0000000..9465f80 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/k3s-lcm.md @@ -0,0 +1,430 @@ +# 边缘集群部署和管理实践 + +对于资源受限的边缘或物联网场景,Kubernetes 无法很好的满足资源要求,为此需要一个轻量化 Kubernetes 方案, +既能实现容器管理和编排能力,又能给业务应用预留更多资源空间。本文介绍边缘集群 k3s 的部署和全生命周期管理实践。 + +## 节点规划 + +**架构** + +- x86_64 +- armhf +- arm64/aarch64 + +**操作系统** + +- 可以在大多数现代 Linux 系统上工作 + +**CPU/内存** + +- 单节点 K3s 集群 + + | | 最小 CPU | 推荐 CPU | 最小内存 | 推荐内存 | + | :---------- | :------- | -------- | -------- | -------- | + | K3s cluster | 1 core | 2 cores | 1.5 GB | 2 GB | + +- 多节点 K3s 集群 + + | | 最小 CPU | 推荐 CPU | 最小内存 | 推荐内存 | + | :--------- | :------- | -------- | -------- | -------- | + | K3s server | 1 core | 2 cores | 1 GB | 1.5 GB | + | K3s agent | 1 core | 2 cores | 512 MB | 1 GB | + +- 节点入站规则 + + - 根据需要确保以下端口未被占用 + - 若有特殊要求不能关闭防火墙,需确保端口为放行 + + | 协议 | 端口 | 源 | 目的 | 描述 | + | :--- | :-------- | :-------- | :-------- | :-------------------------------------- | + | TCP | 2379-2380 | Servers | Servers | 适用于 HA与嵌入式etcd | + | TCP | 6443 | Agents | Servers | K3s supervisor 和 Kubernetes API Server | + | UDP | 8472 | All nodes | All nodes | 仅适用于Flannel VXLAN | + | TCP | 10250 | All nodes | All nodes | Kubelet metrics | + | UDP | 51820 | All nodes | All nodes | 仅适用于带有 IPv4的Flannel Wireguard | + | UDP | 51821 | All nodes | All nodes | 仅适用于带有 IPv6的Flannel Wireguard | + | TCP | 5001 | All nodes | All nodes | 仅适用于嵌入分布式注册表(Spegel) | + | TCP | 6443 | All nodes | All nodes | 仅适用于嵌入分布式注册表(Spegel) | + +- 节点角色 + + 登录用户需具备 root 权限 + + | server node | agent node | 描述 | + | :---------- | :--------- | :-------------------------------- | + | 1 | 0 | 一台 server 节点 | + | 1 | 2 | 一台 server 节点、两台 agent 节点 | + | 3 | 0 | 三台 server 节点 | + +## 前置准备 + +1. 保存安装脚本到安装节点(任意可以访问到集群节点的节点) + + ```shell + $ cat > k3slcm <<'EOF' + #!/bin/bash + set -e + + airgap_image=${K3S_AIRGAP_IMAGE:-} + k3s_bin=${K3S_BINARY:-} + install_script=${K3S_INSTALL_SCRIPT:-} + + servers=${K3S_SERVERS:-} + agents=${K3S_AGENTS:-} + ssh_user=${SSH_USER:-root} + ssh_password=${SSH_PASSWORD:-} + ssh_privatekey_path=${SSH_PRIVATEKEY_PATH:-} + extra_server_args=${EXTRA_SERVER_ARGS:-} + extra_agent_args=${EXTRA_AGENT_ARGS:-} + first_server=$(cut -d, -f1 <<<"$servers,") + other_servers=$(cut -d, -f2- <<<"$servers,") + + install_script_env="INSTALL_K3S_SKIP_SELINUX_RPM=true INSTALL_K3S_SELINUX_WARN=true " + [ -n "$K3S_VERSION" ] && install_script_env+="INSTALL_K3S_VERSION=$K3S_VERSION " + + ssh_opts="-q -o StrictHostkeyChecking=no -o UserKnownHostsFile=/dev/null -o ControlPath=/tmp/ssh_mux_%h_%p_%r -o ControlMaster=auto -o ControlPersist=10m" + + if [ -n "$ssh_privatekey_path" ]; then + ssh_opts+=" -i $ssh_privatekey_path" + elif [ -n "$ssh_password" ]; then + askpass=$(mktemp) + echo "echo -n $ssh_password" > $askpass + chmod 0755 $askpass + export SSH_ASKPASS=$askpass SSH_ASKPASS_REQUIRE=force + else + echo "SSH_PASSWORD or SSH_PRIVATEKEY_PATH must be provided" && exit 1 + fi + + log_info() { echo -e "\033[36m* $*\033[0m"; } + clean() { rm -f $askpass; } + trap clean EXIT + + IFS=',' read -ra all_nodes <<< "$servers,$agents" + if [ -n "$k3s_bin" ]; then + for node in ${all_nodes[@]}; do + chmod +x "$k3s_bin" "$install_script" + ssh $ssh_opts "$ssh_user@$node" "mkdir -p /usr/local/bin /var/lib/rancher/k3s/agent/images" + log_info "Copying $airgap_image to $node" + scp -O $ssh_opts "$airgap_image" "$ssh_user@$node:/var/lib/rancher/k3s/agent/images" + log_info "Copying $k3s_bin to $node" + scp -O $ssh_opts "$k3s_bin" "$ssh_user@$node:/usr/local/bin/k3s" + log_info "Copying $install_script to $node" + scp -O $ssh_opts "$install_script" "$ssh_user@$node:/usr/local/bin/k3s-install.sh" + done + install_script_env+="INSTALL_K3S_SKIP_DOWNLOAD=true " + else + for node in ${all_nodes[@]}; do + log_info "Downloading install script for $node" + ssh $ssh_opts "$ssh_user@$node" "curl -sSLo /usr/local/bin/k3s-install.sh https://get.k3s.io/ && chmod +x /usr/local/bin/k3s-install.sh" + done + fi + + restart_k3s() { + local node=$1 + previous_k3s_version=$(ssh $ssh_opts "$ssh_user@$first_server" "kubectl get no -o wide | awk '\$6==\"$node\" {print \$5}'") + [ -n "$previous_k3s_version" -a "$previous_k3s_version" != "$K3S_VERSION" -a -n "$k3s_bin" ] && return 0 || return 1 + } + + token=mynodetoken + install_script_env+=${K3S_INSTALL_SCRIPT_ENV:-} + if [ -z "$other_servers" ]; then + log_info "Installing on server node [$first_server]" + ssh $ssh_opts "$ssh_user@$first_server" "env $install_script_env /usr/local/bin/k3s-install.sh server --token $token $extra_server_args" + ! restart_k3s "$first_server" || ssh $ssh_opts "$ssh_user@$first_server" "systemctl restart k3s.service" + else + log_info "Installing on first server node [$first_server]" + ssh $ssh_opts "$ssh_user@$first_server" "env $install_script_env /usr/local/bin/k3s-install.sh server --cluster-init --token $token $extra_server_args" + ! restart_k3s "$first_server" || ssh $ssh_opts "$ssh_user@$first_server" "systemctl restart k3s.service" + IFS=',' read -ra other_server_nodes <<< "$other_servers" + for node in ${other_server_nodes[@]}; do + log_info "Installing on other server node [$node]" + ssh $ssh_opts "$ssh_user@$node" "env $install_script_env /usr/local/bin/k3s-install.sh server --server https://$first_server:6443 --token $token $extra_server_args" + ! restart_k3s "$node" || ssh $ssh_opts "$ssh_user@$node" "systemctl restart k3s.service" + done + fi + + if [ -n "$agents" ]; then + IFS=',' read -ra agent_nodes <<< "$agents" + for node in ${agent_nodes[@]}; do + log_info "Installing on agent node [$node]" + ssh $ssh_opts "$ssh_user@$node" "env $install_script_env K3S_TOKEN=$token K3S_URL=https://$first_server:6443 /usr/local/bin/k3s-install.sh agent --token $token $extra_agent_args" + ! restart_k3s "$node" || ssh $ssh_opts "$ssh_user@$node" "systemctl restart k3s-agent.service" + done + fi + EOF + ``` + +1. (可选)离线环境下,在一台可联网节点下载 K3s 相关离线资源,并拷贝到安装节点 + + ```shell + ## [联网节点执行] + + # 设置 K3s 版本为 v1.30.2+k3s1 + $ export k3s_version=v1.30.2+k3s1 + + # 离线镜像包 + # arm64链接为 https://github.com/k3s-io/k3s/releases/download/$k3s_version/k3s-airgap-images-arm64.tar.zst + $ curl -LO https://github.com/k3s-io/k3s/releases/download/$k3s_version/k3s-airgap-images-amd64.tar.zst + + # k3s 二进制文件 + # arm64链接为 https://github.com/k3s-io/k3s/releases/download/$k3s_version/k3s-arm64 + $ curl -LO https://github.com/k3s-io/k3s/releases/download/$k3s_version/k3s + + # 安装部署脚本 + $ curl -Lo k3s-install.sh https://get.k3s.io/ + + ## 上述资源拷贝到安装节点文件系统上 + + ## [安装节点执行] + $ export K3S_AIRGAP_IMAGE=<资源存放目录>/k3s-airgap-images-amd64.tar.zst + $ export K3S_BINARY=<资源存放目录>/k3s + $ export K3S_INSTALL_SCRIPT=<资源存放目录>/k3s-install.sh + ``` + +1. 关闭防火墙和 swap(若防火墙无法关闭,可放行上述入站端口) + + ```shell + # Ubuntu 关闭防火墙方法 + $ sudo ufw disable + # RHEL / CentOS / Fedora / SUSE 关闭防火墙方法 + $ systemctl disable firewalld --now + $ sudo swapoff -a + $ sudo sed -i '/swap/s/^/#/' /etc/fstab + ``` + +## 部署集群 + +下文测试环境信息为 Ubuntu 22.04 LTS, amd64,离线安装 + +1. 在安装节点根据部署规划设置节点信息,并导出环境变量,多个节点以半角逗号 `,` 分隔 + + === "1 server / 0 agent" + + ```shell + export K3S_SERVERS=172.30.41.5 $ export SSH_USER=root + # 若使用 public key 方式登录,确保已将公钥添加到各节点的 ~/.ssh/authorized_keys + + export SSH_PRIVATEKEY_PATH=<私钥路径> + export SSH_PASSWORD= + ``` + + === "1 server / 2 agent" + + ```shell + export K3S_SERVERS=172.30.41.5 + export K3S_AGENTS=172.30.41.6,172.30.41.7 + export SSH_USER=root + + # 若使用 public key 方式登录,确保已将公钥添加到各节点的 ~/.ssh/authorized_keys + export SSH_PRIVATEKEY_PATH=<私钥路径> + export SSH_PASSWORD= + ``` + + === "3 server / 0 agent" + + ```shell + export K3S_SERVERS=172.30.41.5,172.30.41.6,172.30.41.7 + export SSH_USER=root + + # 若使用 public key 方式登录,确保已将公钥添加到各节点的 ~/.ssh/authorized_keys + export SSH_PRIVATEKEY_PATH=<私钥路径> + export SSH_PASSWORD= + ``` + +1. 执行部署操作 + + 以 3 server / 0 agent 模式为例,每台机器必须有一个唯一的主机名 + + ```shell + # 若有更多 K3s 安装脚本环境变量设置需求,请设置 K3S_INSTALL_SCRIPT_ENV,其值参考 https://docs.k3s.io/reference/env-variables + # 若需对 server 或 agent 节点作出额外配置,请设置 EXTRA_SERVER_ARGS 或 EXTRA_AGENT_ARGS,其值参考 https://docs.k3s.io/cli/server https://docs.k3s.io/cli/agent + $ bash k3slcm + * Copying ./v1.30.2/k3s-airgap-images-amd64.tar.zst to 172.30.41.5 + * Copying ./v1.30.2/k3s to 172.30.41.5 + * Copying ./v1.30.2/k3s-install.sh to 172.30.41.5 + * Copying ./v1.30.2/k3s-airgap-images-amd64.tar.zst to 172.30.41.6 + * Copying ./v1.30.2/k3s to 172.30.41.6 + * Copying ./v1.30.2/k3s-install.sh to 172.30.41.6 + * Copying ./v1.30.2/k3s-airgap-images-amd64.tar.zst to 172.30.41.7 + * Copying ./v1.30.2/k3s to 172.30.41.7 + * Copying ./v1.30.2/k3s-install.sh to 172.30.41.7 + * Installing on first server node [172.30.41.5] + [INFO] Skipping k3s download and verify + [INFO] Skipping installation of SELinux RPM + [INFO] Creating /usr/local/bin/kubectl symlink to k3s + [INFO] Creating /usr/local/bin/crictl symlink to k3s + [INFO] Creating /usr/local/bin/ctr symlink to k3s + [INFO] Creating killall script /usr/local/bin/k3s-killall.sh + [INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh + [INFO] env: Creating environment file /etc/systemd/system/k3s.service.env + [INFO] systemd: Creating service file /etc/systemd/system/k3s.service + [INFO] systemd: Enabling k3s unit + Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service. + [INFO] systemd: Starting k3s + * Installing on other server node [172.30.41.6] + ...... + ``` + +1. 检查集群状态 + + ```shell + $ kubectl get no -owide + NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME + server1 Ready control-plane,etcd,master 3m51s v1.30.2+k3s1 172.30.41.5 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server2 Ready control-plane,etcd,master 3m18s v1.30.2+k3s1 172.30.41.6 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server3 Ready control-plane,etcd,master 3m7s v1.30.2+k3s1 172.30.41.7 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + + $ kubectl get pod --all-namespaces -owide + NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES + kube-system coredns-576bfc4dc7-z4x2s 1/1 Running 0 8m31s 10.42.0.3 server1 + kube-system helm-install-traefik-98kh5 0/1 Completed 1 8m31s 10.42.0.4 server1 + kube-system helm-install-traefik-crd-9xtfd 0/1 Completed 0 8m31s 10.42.0.5 server1 + kube-system local-path-provisioner-86f46b7bf7-qt995 1/1 Running 0 8m31s 10.42.0.6 server1 + kube-system metrics-server-557ff575fb-kptsh 1/1 Running 0 8m31s 10.42.0.2 server1 + kube-system svclb-traefik-f95cc81c-mgcjh 2/2 Running 0 6m28s 10.42.1.3 server2 + kube-system svclb-traefik-f95cc81c-xtb8f 2/2 Running 0 6m28s 10.42.2.2 server3 + kube-system svclb-traefik-f95cc81c-zcsxl 2/2 Running 0 6m28s 10.42.0.7 server1 + kube-system traefik-5fb479b77-6pbh5 1/1 Running 0 6m28s 10.42.1.2 server2 + ``` + +## 升级集群 + +1. 如升级到 `v1.30.3+k3s1` 版本,按照 `前置准备` 步骤 2 重新下载离线资源并拷贝到安装节点,同时在安装节点导出离线资源路径环境变量。(若为联网升级,则跳过此操作) +1. 执行升级操作 + + ```shell + $ export K3S_VERSION=v1.30.3+k3s1 + $ bash k3slcm + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.5 + * Copying ./v1.30.3/k3s to 172.30.41.5 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.5 + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.6 + * Copying ./v1.30.3/k3s to 172.30.41.6 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.6 + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.7 + * Copying ./v1.30.3/k3s to 172.30.41.7 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.7 + * Installing on first server node [172.30.41.5] + [INFO] Skipping k3s download and verify + [INFO] Skipping installation of SELinux RPM + [INFO] Skipping /usr/local/bin/kubectl symlink to k3s, already exists + [INFO] Skipping /usr/local/bin/crictl symlink to k3s, already exists + [INFO] Skipping /usr/local/bin/ctr symlink to k3s, already exists + [INFO] Creating killall script /usr/local/bin/k3s-killall.sh + [INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh + [INFO] env: Creating environment file /etc/systemd/system/k3s.service.env + [INFO] systemd: Creating service file /etc/systemd/system/k3s.service + [INFO] systemd: Enabling k3s unit + Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service. + [INFO] No change detected so skipping service start + * Installing on other server node [172.30.41.6] + ...... + ``` + +1. 检查集群状态 + + ```shell + $ kubectl get node -owide + NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME + server1 Ready control-plane,etcd,master 18m v1.30.3+k3s1 172.30.41.5 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server2 Ready control-plane,etcd,master 17m v1.30.3+k3s1 172.30.41.6 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server3 Ready control-plane,etcd,master 17m v1.30.3+k3s1 172.30.41.7 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + + $ kubectl get po --all-namespaces -owide + NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES + kube-system coredns-576bfc4dc7-z4x2s 1/1 Running 0 18m 10.42.0.3 server1 + kube-system helm-install-traefik-98kh5 0/1 Completed 1 18m server1 + kube-system helm-install-traefik-crd-9xtfd 0/1 Completed 0 18m server1 + kube-system local-path-provisioner-6795b5f9d8-t4rvm 1/1 Running 0 2m49s 10.42.2.3 server3 + kube-system metrics-server-557ff575fb-kptsh 1/1 Running 0 18m 10.42.0.2 server1 + kube-system svclb-traefik-f95cc81c-mgcjh 2/2 Running 0 16m 10.42.1.3 server2 + kube-system svclb-traefik-f95cc81c-xtb8f 2/2 Running 0 16m 10.42.2.2 server3 + kube-system svclb-traefik-f95cc81c-zcsxl 2/2 Running 0 16m 10.42.0.7 server1 + kube-system traefik-5fb479b77-6pbh5 1/1 Running 0 16m 10.42.1.2 server2 + ``` + +## 扩容集群 + +1. 如添加新的 agent 节点: + + ```shell + export K3S_AGENTS=172.30.41.8 + ``` + + 添加新的 server 节点如下: + + ```diff + < export K3S_SERVERS=172.30.41.5,172.30.41.6,172.30.41.7 + --- + > export K3S_SERVERS=172.30.41.5,172.30.41.6,172.30.41.7,172.30.41.8,172.30.41.9 + ``` + +1. 执行扩容操作(以添加 agent 节点为例) + + ```shell + $ bash k3slcm + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.5 + * Copying ./v1.30.3/k3s to 172.30.41.5 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.5 + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.6 + * Copying ./v1.30.3/k3s to 172.30.41.6 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.6 + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.7 + * Copying ./v1.30.3/k3s to 172.30.41.7 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.7 + * Copying ./v1.30.3/k3s-airgap-images-amd64.tar.zst to 172.30.41.8 + * Copying ./v1.30.3/k3s to 172.30.41.8 + * Copying ./v1.30.3/k3s-install.sh to 172.30.41.8 + * Installing on first server node [172.30.41.5] + [INFO] Skipping k3s download and verify + [INFO] Skipping installation of SELinux RPM + [INFO] Skipping /usr/local/bin/kubectl symlink to k3s, already exists + [INFO] Skipping /usr/local/bin/crictl symlink to k3s, already exists + [INFO] Skipping /usr/local/bin/ctr symlink to k3s, already exists + [INFO] Creating killall script /usr/local/bin/k3s-killall.sh + [INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh + [INFO] env: Creating environment file /etc/systemd/system/k3s.service.env + [INFO] systemd: Creating service file /etc/systemd/system/k3s.service + [INFO] systemd: Enabling k3s unit + Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service. + [INFO] No change detected so skipping service start + ...... + * Installing on agent node [172.30.41.8] + [INFO] Skipping k3s download and verify + [INFO] Skipping installation of SELinux RPM + [INFO] Creating /usr/local/bin/kubectl symlink to k3s + [INFO] Creating /usr/local/bin/crictl symlink to k3s + [INFO] Creating /usr/local/bin/ctr symlink to k3s + [INFO] Creating killall script /usr/local/bin/k3s-killall.sh + [INFO] Creating uninstall script /usr/local/bin/k3s-agent-uninstall.sh + [INFO] env: Creating environment file /etc/systemd/system/k3s-agent.service.env + [INFO] systemd: Creating service file /etc/systemd/system/k3s-agent.service + [INFO] systemd: Enabling k3s-agent unit + Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service → /etc/systemd/system/k3s-agent.service. + [INFO] systemd: Starting k3s-agent + ``` + +1. 检查集群状态 + + ```shell + $ kubectl get node -owide + NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME + agent1 Ready 57s v1.30.3+k3s1 172.30.41.8 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server1 Ready control-plane,etcd,master 12m v1.30.3+k3s1 172.30.41.5 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server2 Ready control-plane,etcd,master 11m v1.30.3+k3s1 172.30.41.6 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + server3 Ready control-plane,etcd,master 11m v1.30.3+k3s1 172.30.41.7 Ubuntu 22.04.3 LTS 5.15.0-78-generic containerd://1.7.17-k3s1 + ``` + +## 缩容集群 + +1. 仅在待删除节点执行 `k3s-uninstall.sh` 或 `k3s-agent-uninstall.sh` +1. 在任意 server 节点上执行: + + ```shell + kubectl delete node <节点名称> + ``` + +## 卸载集群 + +1. 在所有 server 节点手动执行 `k3s-uninstall.sh` +1. 在所有 agent 节点手动执行 `k3s-agent-uninstall.sh` diff --git a/docs/zh/docs/admin/kpanda/best-practice/kubean-low-version.md b/docs/zh/docs/admin/kpanda/best-practice/kubean-low-version.md new file mode 100644 index 0000000..988d28b --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/kubean-low-version.md @@ -0,0 +1,147 @@ +--- +title: 离线部署和升级向下兼容版本 +keyword: 兼容版本,向下兼容,部署和升级 Kubernetes,部署和升级 K8s,离线部署和升级,低版本 K8s,低版本 Kubernetes +--- + +# 离线场景 Kubean 向下兼容版本的部署与升级操作 + +为了满足客户对低版本的 K8s 集群的搭建,Kubean 提供了向下兼容并创建低版本的 K8s 集群能力,简称向下兼容版本的能力。 + +目前支持自建工作集群版本范围在 `v1.26-v1.28`,可以参阅 [AI 算力中心集群版本支持体系](../clusters/cluster-version.md)。 + +本文将演示如何部署低版本的 K8s 集群。 + +!!! note + + 本文演示的节点环境为: + + - X86 架构 + - CentOS 7 Linux 发行版 + +## 前提条件 + +- 准备一个 Kubean 所在的管理集群,并且当前环境已经部署支持 `podman` 、`skopeo`、`minio client` 命令。 + 如果不支持,可通过脚本进行安装依赖组件,[安装前置依赖](../../install/install-tools.md)。 + +- 前往 [kubean](https://github.com/kubean-io/kubean) 查看发布的[制品](https://kubean-io.github.io/kubean/zh/releases/artifacts/), + 并根据实际情况选择具体的制品版本。目前支持的制品版本及对应的集群版本范围如下: + + | 制品包版本 | 支持集群范围 | AI 算力中心支持情况 | + |--------------|-------------------|------------------| + | release-2.21 | v1.23.0 ~ v1.25.6 | 安装器 v0.14.0+ 已支持 | + | release-2.22 | v1.24.0 ~ v1.26.13 | 安装器 v0.15.0+ 已支持 | + | release-2.23 | v1.25.0 ~ v1.27.10 | 安装器 v0.16.0+ 已支持 | + | release-2.24 | v1.26.0 ~ v1.29.1 | 安装器 v0.17.0+ 已支持 | + | release-2.25 | v1.27.0 ~ v1.29.5 | 安装器 v0.20.0+ 已支持 | + +!!! tip + + 在选择制品版本时,不仅需要参考集群版本范围,还需判断该制品 manifest 资源中相应组件(如 calico、containerd)版本范围是否覆盖当前集群该组件版本! + + +本文演示离线部署 K8s 集群到 1.23.0 版本及离线升级 K8s 集群从 1.23.0 版本到 1.24.0 版本,所以选择 `release-2.21` 的制品。 + +## 操作步骤 + +### 准备 Kubespray Release 低版本的相关制品 + +将 spray-job 镜像导入到离线环境的 Registry(镜像仓库)中。 + +```bash +# 假设火种集群中的 registry 地址为 172.30.41.200 +REGISTRY_ADDR="172.30.41.200" + +# 镜像 spray-job 这里可以采用加速器地址,镜像地址根据选择制品版本来决定 +SPRAY_IMG_ADDR="ghcr.m.daocloud.io/kubean-io/spray-job:2.21-d6f688f" + +# skopeo 参数 +SKOPEO_PARAMS=" --insecure-policy -a --dest-tls-verify=false --retry-times=3 " + +# 在线环境:导出 release-2.21 版本的 spray-job 镜像,并将其转移到离线环境 +skopeo copy docker://${SPRAY_IMG_ADDR} docker-archive:spray-job-2.21.tar + +# 离线环境:导入 release-2.21 版本的 spray-job 镜像到火种 registry +skopeo copy ${SKOPEO_PARAMS} docker-archive:spray-job-2.21.tar docker://${REGISTRY_ADDR}/${SPRAY_IMG_ADDR/.m.daocloud/} +``` + +### 制作低版本 K8s 离线资源 + +1. 准备 manifest.yml 文件。 + + ```bash + cat > "manifest.yml" < __集群升级__ ,在页面右上角点击 __版本升级__ 。 + + ![cluster03](../images/cluster03.png) + +3. 选择可用的集群进行升级。 + + ![cluster04](../images/cluster04.png) diff --git a/docs/zh/docs/admin/kpanda/best-practice/limit-disk-usage-docker.md b/docs/zh/docs/admin/kpanda/best-practice/limit-disk-usage-docker.md new file mode 100644 index 0000000..c40c75f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/limit-disk-usage-docker.md @@ -0,0 +1,115 @@ +# 限制 Docker 单容器可占用的磁盘空间 + +Docker 在 17.07.0-ce 版本中引入 overlay2.zize,本文介绍如何使用 overlay2.zize 来限制 docker 单容器可占用的磁盘空间。 + +## 前提条件 + +在配置 docker overlay2.size 之前,需要调整操作系统中文件系统类型为 xfs 并使用 pquota 方式进行设备挂载。 + +格式化设备为 XFS 文件系统,可以执行以下命令: + +```shell +mkfs.xfs -f /dev/xxx +``` + +!!! note + + pquota 限制的是项目(project)磁盘配额。 + +## 设置单容器磁盘可占用空间 + +满足以上条件后,用户可以通过设置 docker overlay2.size 来限制单容器磁盘占用空间大小。命令行示例如下: + +```shell +sudo dockerd -s overlay2 --storage-opt overlay2.size=1G +``` + +## 场景演练 + +接下来以一个实际的例子来演练一下限制 docker 单容器可占用的磁盘空间整体实现流程。 + +### 目标 + +部署一个 Kubernetes 集群,并限制 docker 单容器可占用的磁盘空间大小为1G,超出1G将无法使用。 + +### 操作流程 + +1. 登录目标节点,查看 fstab 文件,获取当前设备的挂载情况。 + + ```shell + $ cat /etc/fstab + + # /etc/fstab + # Created by anaconda on Thu Mar 19 11:32:59 2020 + # + # Accessible filesystems, by reference, are maintained under '/dev/disk' + # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info + # + /dev/mapper/centos-root / xfs defaults 0 0 + UUID=3ed01f0e-67a1-4083-943a-343b7fed1708 /boot xfs defaults 0 0 + /dev/mapper/centos-swap swap swap defaults 0 0 + ``` + + 以图示节点设备为例,可以看到 XFS 格式设备 /dev/mapper/centos-root 以默认方式 defauls 挂载到 / 根目录. + +2. 配置 xfs 文件系统使用 pquota 方式挂载。 + + 1. 修改 fstab 文件,将挂载方式从 defaults 更新为 rw,pquota; + + ```shell + # 修改 fstab 配置 + $ vi /etc/fstab + - /dev/mapper/centos-root / xfs defaults 0 0 + + /dev/mapper/centos-root / xfs rw,pquota 0 0 + + # 验证配置是否有误 + $ mount -a + ``` + + 1. 查看 pquota 是否生效 + + ```shell + xfs_quota -x -c print + ``` + + ![看看 fstab 配置](../images/limit-disk-usage-docker-01.png) + + !!! note + + 如果 pquota 未生效,请检查操作系统是否开启 pquota 选项,如果未开启,需要在系统引导配置 /etc/grub2.cfg + 中添加 `rootflags=pquota` 参数,配置完成后,需要 reboot 重启操作系统。 + + ![操作系统开启 pquota 选项](../images/limit-disk-usage-docker-02.png) + +3. **创建集群** -> **高级配置** -> **自定义参数** 中添加 docker_storage_options 参数,设置单容器磁盘可占用空间。 + + ![添加自定义参数](../images/limit-disk-usage-docker-03.png) + + !!! note + + 也可以基于 kubean manifest 操作,在 vars conf 里添加 `docker_storage_options` 参数。 + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: sample-vars-conf + namespace: kubean-system + data: + group_vars.yml: | + unsafe_show_logs: true + container_manager: docker + + docker_storage_options: -s overlay2 --storage-opt overlay2.size=1G # 新增 docker_storage_options 参数 + kube_network_plugin: calico + kube_network_plugin_multus: false + kube_proxy_mode: iptables + etcd_deployment_type: kubeadm + override_system_hostname: true + ... + ``` + +4. 查看 dockerd 服务运行配置,检查磁盘限制是否设置成功。 + + ![检查容器磁盘限制](../images/limit-disk-usage-docker-04.png) + +以上,完成限制 docker 单容器可占用的磁盘空间整体实现流程。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/multi-arch.md b/docs/zh/docs/admin/kpanda/best-practice/multi-arch.md new file mode 100644 index 0000000..a2cc260 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/multi-arch.md @@ -0,0 +1,244 @@ +# 为工作集群添加异构节点 + +本文介绍如何为 AMD 架构,操作系统为 CentOS 7.9 的工作集群添加 ARM 架构,操作系统为 Kylin v10 sp2 的工作节点 + +!!! note + + 本文仅针对离线模式下,使用 AI 算力中心平台所创建的工作集群进行异构节点的添加,不包括接入的集群。 + +## 前提条件 + +- 已经部署好一个 AI 算力中心全模式,并且火种节点还存活,部署参考文档[离线安装 AI 算力中心商业版](../../install/commercial/start-install.md) +- 已经通过 AI 算力中心平台创建好一个 AMD 架构,操作系统为 CentOS 7.9 的工作集群,创建参考文档[创建工作集群](../clusters/create-cluster.md) + +## 操作步骤 + +### 下载并导入离线包 + +以 ARM 架构、操作系统 Kylin v10 sp2 为例。 + +请确保已经登录到火种节点!并且之前部署 AI 算力中心时使用的 clusterConfig.yaml 文件还在。 + +#### 离线镜像包 + +!!! note + + 可以在[下载中心](https://docs.daocloud.io/download/dce5/)下载最新版本。请确保在容器管理 v0.31 及以上版本使用该能力,对应安装器 v0.21.0 及以上版本 + +| CPU 架构 | 版本 | 下载地址 | +| :------ |:-----|:-------| +| AMD64 | v0.21.0 | | +| ARM64 | v0.21.0 | | + +下载完毕后解压离线包。此处我们下载 arm64 架构的离线包: + +```bash +tar -xvf offline-v0.21.0-arm64.tar +``` + +#### ISO 离线包(Kylin v10 sp2) + +| CPU 架构 | 操作系统版本 | 下载地址 | +| :------- | :-------- | :------ | +| ARM64 | Kylin Linux Advanced Server release V10 (Sword) SP2 | 申请地址: | + +!!! note + + 麒麟操作系统需要提供个人信息才能下载使用,下载时请选择 V10 (Sword) SP2。 + +#### osPackage 离线包 (Kylin v10 sp2) + +其中 [Kubean](https://github.com/kubean-io/kubean) 提供了不同操作系统的osPackage 离线包,可以前往 查看。 + +| 操作系统版本 | 下载地址 | +| :--------- |:----------------------------------------------------------------------------------------------------| +| Kylin Linux Advanced Server release V10 (Sword) SP2 | | + + +!!! note + + osPackage 离线包的具体对应版本请查看离线镜像包中 __offline/sample/clusterConfig.yaml__ 中对应的 kubean 版本 + +#### 导入离线包至火种节点 + +执行 import-artifact 命令: + +```bash +./offline/dce5-installer import-artifact -c clusterConfig.yaml \ + --offline-path=/root/offline \ + --iso-path=/root/Kylin-Server-10-SP2-aarch64-Release-Build09-20210524.iso \ + --os-pkgs-path=/root/os-pkgs-kylin-v10sp2-v0.18.5.tar.gz +``` + +!!! note + + 参数说明: + + - __-c clusterConfig.yaml__ 指定之前部署 AI 算力中心.0 时使用的 clusterConfig.yaml 文件 + - __--offline-path__ 指定下载的离线镜像包文件地址 + - __--iso-path__ 指定下载的 ISO 操作系统镜像文件地址 + - __--os-pkgs-path__ 指定下载的 osPackage 离线包文件地址 + +导入命令执行成功后,会将离线包上传到火种节点的 Minio 中。 + +### 添加异构工作节点 + +请确保已经登录到 AI 算力中心[管理集群](../clusters/cluster-role.md#_3)的管理节点上。 + +#### 修改主机清单文件 + +主机清单文件示例: + +=== "新增节点前" + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: ${cluster-name}-hosts-conf + namespace: kubean-system + data: + hosts.yml: | + all: + children: + etcd: + hosts: + centos-master: + k8s_cluster: + children: + kube_control_plane: + kube_node: + kube_control_plane: + hosts: + centos-master: + kube_node: + hosts: + centos-master: + hosts: + centos-master: + ip: 10.5.10.183 + access_ip: 10.5.10.183 + ansible_host: 10.5.10.183 + ansible_connection: ssh + ansible_user: root + ansible_ssh_pass: ****** + ansible_password: ****** + ansible_become_password: ****** + ``` + +=== "新增节点后" + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: ${cluster-name}-hosts-conf + namespace: kubean-system + data: + hosts.yml: | + all: + hosts: + centos-master: + ip: 10.5.10.183 + access_ip: 10.5.10.183 + ansible_host: 10.5.10.183 + ansible_connection: ssh + ansible_user: root + ansible_ssh_pass: ****** + ansible_password: ****** + ansible_become_password: ****** + # 添加异构节点信息 + kylin-worker: + ip: 10.5.10.181 + access_ip: 10.5.10.181 + ansible_host: 10.5.10.181 + ansible_connection: ssh + ansible_user: root + ansible_ssh_pass: ****** + ansible_password: ****** + ansible_become_password: ****** + children: + kube_control_plane: + hosts: + - centos-master + kube_node: + hosts: + - centos-master + - kylin-worker # 添加新增的异构节点名称 + etcd: + hosts: + - centos-master + k8s_cluster: + children: + - kube_control_plane + - kube_node + ``` + +按照上述的配置注释,添加新增的工作节点信息。 + +```shell +kubectl edit cm ${cluster-name}-hosts-conf -n kubean-system +``` + +__cluster-name__ 为工作集群的名称,通过容器管理创建集群时会默认生成。 + +#### 通过 ClusterOperation.yml 新增扩容任务 + +示例: + +```yaml title="ClusterOperation.yml" +apiVersion: kubean.io/v1alpha1 +kind: ClusterOperation +metadata: + name: add-worker-node +spec: + cluster: ${cluster-name} # 指定 cluster name + image: 10.5.14.30/ghcr.m.daocloud.io/kubean-io/spray-job:v0.18.5 + actionType: playbook + action: scale.yml + extraArgs: --limit=kylin-worker + preHook: + - actionType: playbook + action: ping.yml + - actionType: playbook + action: disable-firewalld.yml + - actionType: playbook + action: enable-repo.yml + extraArgs: | + -e "{repo_list: ["http://10.5.14.30:9000/kubean/kylin-iso/\$releasever/sp2/os/\$basearch","http://10.5.14.30:9000/kubean/kylin/\$releasever/sp2/os/\$basearch"]}" --limit=kylin-worker + postHook: + - actionType: playbook + action: cluster-info.yml +``` + +!!! note + + - spec.image 镜像地址要与之前执行部署时的 job 其内镜像保持一致 + - spec.action 设置为 scale.yml + - spec.extraArgs 设置为 --limit=g-worker + - spec.preHook 中的 enable-repo.yml 剧本参数,要填写相关OS的正确的 repo_list + +按照上述的配置,创建并部署 join-node-ops.yaml: + +```shell +vi join-node-ops.yaml +kubectl apply -f join-node-ops.yaml -n kubean-system +``` + +#### 检查任务执行状态 + +```shell +kubectl -n kubean-system get pod | grep add-worker-node +``` + +了解缩容任务执行进度,可查看该 Pod 日志。 + +### 前往界面验证 + +1. 前往 __容器管理__ -> __集群__ -> __节点管理__ + + ![节点管理](./images/arm01.png) + +2. 点击新增的节点,查看详情 + + ![节点详情](./images/arm02.png) diff --git a/docs/zh/docs/admin/kpanda/best-practice/replace-first-master-node.md b/docs/zh/docs/admin/kpanda/best-practice/replace-first-master-node.md new file mode 100644 index 0000000..c46d178 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/replace-first-master-node.md @@ -0,0 +1,211 @@ +# 替换工作集群的首个控制节点 + +本文将以一个高可用三控制节点的工作集群为例。 +当工作集群的首个控制节点故障或异常时,如何替换或重新接入首个控制节点。 + +本文的高可用集群有 3 个 Master 节点: + +- node1 (172.30.41.161) +- node2 (172.30.41.162) +- node3 (172.30.41.163) + +假设 node1 宕机,接下来介绍如何将宕机后恢复的 node1 重新接入工作集群。 + +## 准备工作 + +在执行替换操作之前,先获取集群资源基本信息,修改相关配置时会用到。 + +!!! note + + 以下获取集群资源信息的命令均在管理集群中执行。 + +1. 获取集群名称 + + 执行如下命令,找到集群对应的 `clusters.kubean.io` 资源: + + ```shell + # 比如 clusters.kubean.io 的资源名称为 cluster-mini-1 + # 则获取集群的名称 + CLUSTER_NAME=$(kubectl get clusters.kubean.io cluster-mini-1 -o=jsonpath="{.metadata.name}{'\n'}") + ``` + +1. 获取集群的主机清单 configmap + + ```shell + kubectl get clusters.kubean.io cluster-mini-1 -o=jsonpath="{.spec.hostsConfRef}{'\n'}" + {"name":"mini-1-hosts-conf","namespace":"kubean-system"} + ``` + +1. 获取集群的配置参数 configmap + + ```shell + kubectl get clusters.kubean.io cluster-mini-1 -o=jsonpath="{.spec.varsConfRef}{'\n'}" + {"name":"mini-1-vars-conf","namespace":"kubean-system"} + ``` + +## 操作步骤 + +1. 调整控制平面节点顺序 + + 重置 node1 节点使其恢复到安装集群之前的状态(或使用新的节点),保持 node1 节点的网络连通性。 + + 调整主机清单中 node1 节点在 kube_control_plane 、kube_node、etcd 中的顺序 + (node1/node2/node3 -> node2/node3/node1): + + ```yaml + function change_control_plane_order() { + cat << EOF | kubectl apply -f - + --- + apiVersion: v1 + kind: ConfigMap + metadata: + name: mini-1-hosts-conf + namespace: kubean-system + data: + hosts.yml: | + all: + hosts: + node1: + ip: "172.30.41.161" + access_ip: "172.30.41.161" + ansible_host: "172.30.41.161" + ansible_connection: ssh + ansible_user: root + ansible_password: dangerous + node2: + ip: "172.30.41.162" + access_ip: "172.30.41.162" + ansible_host: "172.30.41.162" + ansible_connection: ssh + ansible_user: root + ansible_password: dangerous + node3: + ip: "172.30.41.163" + access_ip: "172.30.41.163" + ansible_host: "172.30.41.163" + ansible_connection: ssh + ansible_user: root + ansible_password: dangerous + children: + kube_control_plane: + hosts: + node2: + node3: + node1: + kube_node: + hosts: + node2: + node3: + node1: + etcd: + hosts: + node2: + node3: + node1: + k8s_cluster: + children: + kube_control_plane: + kube_node: + calico_rr: + hosts: {} + EOF + } + + change_control_plane_order + ``` + +1. 移除异常状态的首个 master 节点 + + 调整主机清单的节点顺序后,移除 K8s 控制平面异常状态的 node1。 + + !!! note + + 如果 node1 离线或故障,则 extraArgs 须添加以下配置项,node1 在线时不需要添加。 + + ```toml + reset_nodes=false # 跳过重置节点操作 + allow_ungraceful_removal=true # 允许非优雅的移除操作 + ``` + + ```bash + # 镜像 spray-job 这里可以采用加速器地址 + + SPRAY_IMG_ADDR="ghcr.m.daocloud.io/kubean-io/spray-job" + SPRAY_RLS_2_22_TAG="2.22-336b323" + KUBE_VERSION="v1.24.14" + CLUSTER_NAME="cluster-mini-1" + REMOVE_NODE_NAME="node1" + + cat << EOF | kubectl apply -f - + --- + apiVersion: kubean.io/v1alpha1 + kind: ClusterOperation + metadata: + name: cluster-mini-1-remove-node-ops + spec: + cluster: ${CLUSTER_NAME} + image: ${SPRAY_IMG_ADDR}:${SPRAY_RLS_2_22_TAG} + actionType: playbook + action: remove-node.yml + extraArgs: -e node=${REMOVE_NODE_NAME} -e reset_nodes=false -e allow_ungraceful_removal=true -e kube_version=${KUBE_VERSION} + postHook: + - actionType: playbook + action: cluster-info.yml + EOF + ``` + +1. 手动修改集群配置,编辑更新 cluster-info + + ```bash + # 编辑 cluster-info + kubectl -n kube-public edit cm cluster-info + + # 1. 若 ca.crt 证书更新,则需要更新 certificate-authority-data 字段的内容 + # 查看 ca 证书的 base64 编码: + cat /etc/kubernetes/ssl/ca.crt | base64 | tr -d '\n' + + # 2. 需改 server 字段的 IP 地址为新 first master IP, 本文档场景将使用 node2 的 IP 地址 172.30.41.162 + ``` + +1. 手动修改集群配置,编辑更新 kubeadm-config + + ```bash + # 编辑 kubeadm-config + kubectl -n kube-system edit cm kubeadm-config + + # 修改 controlPlaneEndpoint 为新 first master IP, 本文档场景将使用 node2 的 IP 地址 172.30.41.162 + ``` + +1. 重新扩容 master 节点并更新集群 + + !!! note + + - 使用 `--limit` 限制更新操作仅作用于 etcd 和 kube_control_plane 节点组。 + - 如果是离线环境,spec.preHook 需要添加 enable-repo.yml,并且 extraArgs 参数填写相关 OS 的正确 repo_list。 + - 扩容完成后,node2 变更为首个 master + + ```bash + cat << EOF | kubectl apply -f - + --- + apiVersion: kubean.io/v1alpha1 + kind: ClusterOperation + metadata: + name: cluster-mini-1-update-cluster-ops + spec: + cluster: ${CLUSTER_NAME} + image: ${SPRAY_IMG_ADDR}:${SPRAY_RLS_2_22_TAG} + actionType: playbook + action: cluster.yml + extraArgs: --limit=etcd,kube_control_plane -e kube_version=${KUBE_VERSION} + preHook: + - actionType: playbook + action: enable-repo.yml # 离线环境下需要添加此 yaml,并且设置正确的 repo-list(安装操作系统软件包),以下参数值仅供参考 + extraArgs: | + -e "{repo_list: ['http://172.30.41.0:9000/kubean/centos/\$releasever/os/\$basearch','http://172.30.41.0:9000/kubean/centos-iso/\$releasever/os/\$basearch']}" + postHook: + - actionType: playbook + action: cluster-info.yml + EOF + ``` + +至此,完成了首个 Master 节点的替换。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/update-offline-cluster.md b/docs/zh/docs/admin/kpanda/best-practice/update-offline-cluster.md new file mode 100644 index 0000000..d3a6795 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/update-offline-cluster.md @@ -0,0 +1,159 @@ +# 工作集群离线部署/升级指南 + +!!! note + + 本文仅针对离线模式下,使用 AI 算力中心平台所创建的工作集群的 kubernetes 的版本进行部署或升级, + 不包括其它 kubeneters 组件的部署或升级。 + +本文适用以下离线场景: + +- 用户可以通过以下操作指南,部署 AI 算力中心平台所创建的非界面中推荐的 Kubernetes 版本。 +- 用户可以通过制作增量离线包的方式对使用 AI 算力中心平台所创建的工作集群的 kubernetes 的版本进行升级。 + +整体的思路为: + +1. 在联网节点构建离线包 +2. 将离线包导入火种节点 +3. 更新[全局服务集群](../clusters/cluster-role.md#_2)的 Kubernetes 版本清单 +4. 使用平台 UI 创建工作集群或升级工作集群的 kubernetes 版本 + +!!! note + + 目前支持构建的离线 kubernetes 版本,请参考 [kubean 支持的 kubernetes 版本列表](../../community/kubean.md#kubernetes)。 + +## 在联网节点构建离线包 + +由于离线环境无法联网,用户需要事先准备一台能够 **联网的节点** 来进行增量离线包的构建,并且在这个节点上启动 Docker 或者 podman 服务。 +参阅[如何安装 Docker?](../../blogs/230315-install-on-linux.md) + +1. 检查联网节点的 Docker 服务运行状态 + + ```bash + ps aux|grep docker + ``` + + 预期输出如下: + + ```console + root 12341 0.5 0.2 654372 26736 ? Ssl 23:45 0:00 /usr/bin/docked + root 12351 0.2 0.1 625080 13740 ? Ssl 23:45 0:00 docker-containerd --config /var/run/docker/containerd/containerd.toml + root 13024 0.0 0.0 112824 980 pts/0 S+ 23:45 0:00 grep --color=auto docker + ``` + +2. 在联网节点的 __/root__ 目录下创建一个名为 __manifest.yaml__ 的文件,命令如下: + + ```bash + vi manifest.yaml + ``` + + __manifest.yaml__ 内容如下: + + ```yaml title="manifest.yaml" + image_arch: + - "amd64" + kube_version: # 填写待升级的集群版本 + - "v1.28.0" + ``` + + - __image_arch__ 用于指定 CPU 的架构类型,可填入的参数为 __amd64__ 和 __arm64__ 。 + - __kube_version__ 用于指定需要构建的 kubernetes 离线包版本,可参考上文的支持构建的离线 kubernetes 版本。 + +3. 在 __/root__ 目录下新建一个名为 __/data__ 的文件夹来存储增量离线包。 + + ```bash + mkdir data + ``` + + 执行如下命令,使用 kubean `airgap-patch` 镜像生成离线包。 + `airgap-patch` 镜像 tag 与 Kubean 版本一致,需确保 Kubean 版本覆盖需要升级的 Kubernetes 版本。 + + ```bash + # 假设 kubean 版本为 v0.13.9 + docker run --rm -v $(pwd)/manifest.yml:/manifest.yml -v $(pwd)/data:/data ghcr.m.daocloud.io/kubean-io/airgap-patch:v0.13.9 + ``` + + 等待 Docker 服务运行完成后,检查 __/data__ 文件夹下的文件,文件目录如下: + + ```console + data + ├── amd64 + │   ├── files + │   │   ├── import_files.sh + │   │   └── offline-files.tar.gz + │   ├── images + │   │   ├── import_images.sh + │   │   └── offline-images.tar.gz + │   └── os-pkgs + │   └── import_ospkgs.sh + └── localartifactset.cr.yaml + ``` + +## 将离线包导入火种节点 + +1. 将联网节点的 __/data__ 文件拷贝至火种节点的 __/root__ 目录下,在 **联网节点** 执行如下命令: + + ```bash + scp -r data root@x.x.x.x:/root + ``` + + `x.x.x.x` 为火种节点 IP 地址 + +2. 在火种节点上将 __/data__ 文件内的镜像文件拷贝至火种节点内置的 docker resgitry 仓库。登录火种节点后执行如下命令: + + 1. 进入镜像文件所在的目录 + + ```bash + cd data/amd64/images + ``` + + 2. 执行 __import_images.sh__ 脚本将镜像导入火种节点内置的 Docker Resgitry 仓库。 + + ```bash + REGISTRY_ADDR="127.0.0.1" ./import_images.sh + ``` + + !!! note + + 上述命令仅仅适用于火种节点内置的 Docker Resgitry 仓库,如果使用外部仓库请使用如下命令: + + ```shell + REGISTRY_SCHEME=https REGISTRY_ADDR=${registry_address} REGISTRY_USER=${username} REGISTRY_PASS=${password} ./import_images.sh + ``` + + - REGISTRY_ADDR 是镜像仓库的地址,比如1.2.3.4:5000 + - 当镜像仓库存在用户名密码验证时,需要设置 REGISTRY_USER 和 REGISTRY_PASS + +3. 在火种节点上将 __/data__ 文件内的二进制文件拷贝至火种节点内置的 Minio 服务上。 + + 1. 进入二进制文件所在的目录 + + ```bash + cd data/amd64/files/ + ``` + + 2. 执行 import_files.sh 脚本将二进制文件导入火种节点内置的 Minio 服务上。 + + ```bash + MINIO_USER=rootuser MINIO_PASS=rootpass123 ./import_files.sh http://127.0.0.1:9000 + ``` + +!!! note + + 上述命令仅仅适用于火种节点内置的 Minio 服务,如果使用外部 Minio 请将 `http://127.0.0.1:9000` 替换为外部 Minio 的访问地址。 + “rootuser” 和 “rootpass123”是火种节点内置的 Minio 服务的默认账户和密码。 + +## 更新全局服务集群的 kubernetes 版本清单 + +火种节点上执行如下命令,将 `localartifactset` 资源部署到全局服务集群: + +```bash +kubectl apply -f data/kubeanofflineversion.cr.patch.yaml +``` + +## 下一步 + +登录 AI 算力中心的 UI 管理界面,您可以继续执行以下操作: + +1. 参照[创建集群的文档](../clusters/create-cluster.md)进行工作集群创建,此时可以选择 Kubernetes 增量版本。 + +2. 参照[升级集群的文档](../clusters/upgrade-cluster.md)对自建的工作集群进行升级。 diff --git a/docs/zh/docs/admin/kpanda/best-practice/use-otherlinux-create-custer.md b/docs/zh/docs/admin/kpanda/best-practice/use-otherlinux-create-custer.md new file mode 100644 index 0000000..a36f03c --- /dev/null +++ b/docs/zh/docs/admin/kpanda/best-practice/use-otherlinux-create-custer.md @@ -0,0 +1,57 @@ +# 在非主流操作系统上创建集群 + +本文介绍离线模式下如何在 **未声明支持的 OS** 上创建工作集群。AI 算力中心声明支持的 OS 范围请参考 +[AI 算力中心支持的操作系统](../../install/commercial/deploy-requirements.md) + +离线模式下在未声明支持的 OS 上创建工作集群,主要的流程如下图: + +![流程](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/kpanda/images/otherlinux.png) + +接下来,本文将以 openAnolis 操作系统为例,介绍如何在非主流操作系统上创建集群。 + +## 前提条件 + +- 已经部署好一个 AI 算力中心全模式,部署参考文档[离线安装 AI 算力中心商业版](../../install/commercial/start-install.md) +- 至少拥有一台可以联网的同架构同版本的节点。 + +## 在线节点构建离线包 + +找到一个和待建集群节点架构和 OS 均一致的在线环境,本文以 [AnolisOS 8.8 GA](https://openanolis.cn/download) 为例。执行如下命令,生成离线 os-pkgs 包。 + +```bash +# 下载相关脚本并构建 os packages 包 +curl -Lo ./pkgs.yml https://raw.githubusercontent.com/kubean-io/kubean/main/build/os-packages/others/pkgs.yml +curl -Lo ./other_os_pkgs.sh https://raw.githubusercontent.com/kubean-io/kubean/main/build/os-packages/others/other_os_pkgs.sh && chmod +x other_os_pkgs.sh +./other_os_pkgs.sh build # 构建离线包 +``` + +执行完上述命令后,预期将在当前路径下生成一个名为 __os-pkgs-anolis-8.8.tar.gz__ 的压缩包。当前路径下文件目录大概如下: + +```console + . + ├── other_os_pkgs.sh + ├── pkgs.yml + └── os-pkgs-anolis-8.8.tar.gz +``` + +## 离线节点安装离线包 + +将在线节点中生成的 __other_os_pkgs.sh__ 、 __pkgs.yml__ 、 __os-pkgs-anolis-8.8.tar.gz__ 三个文件拷贝至离线环境中的待建集群的**所有**节点上。 + +登录离线环境中,任一待建集群的其中一个节点上,执行如下命令,为节点安装 os-pkg 包。 + +```bash +# 配置环境变量 +export PKGS_YML_PATH=/root/workspace/os-pkgs/pkgs.yml # 当前离线节点 pkgs.yml 文件的路径 +export PKGS_TAR_PATH=/root/workspace/os-pkgs/os-pkgs-anolis-8.8.tar.gz # 当前离线节点 os-pkgs-anolis-8.8.tar.gz 的路径 +export SSH_USER=root # 当前离线节点的用户名 +export SSH_PASS=dangerous # 当前离线节点的密码 +export HOST_IPS='172.30.41.168' # 当前离线节点的 IP +./other_os_pkgs.sh install #安装离线包 +``` + +执行完成上述命令后,等待界面提示: __All packages for node (X.X.X.X) have been installed__ 即表示安装完成。 + +## 下一步 + +参考文档[创建工作集群](../clusters/create-cluster.md),在 UI 界面上创建 openAnolis 集群。 diff --git a/docs/zh/docs/admin/kpanda/clusterops/cluster-oversold.md b/docs/zh/docs/admin/kpanda/clusterops/cluster-oversold.md new file mode 100644 index 0000000..58c84f4 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusterops/cluster-oversold.md @@ -0,0 +1,50 @@ +# 集群动态资源超卖 + +目前,许多业务存在峰值和低谷的现象。为了确保服务的性能和稳定性,在部署服务时,通常会根据峰值需求来申请资源。 +然而,峰值期可能非常短暂,导致在非峰值期时资源被浪费。 +**集群资源超卖** 就是将这些申请了而未使用的资源(即申请量与使用量的差值)利用起来,从而提升集群资源利用率,减少资源浪费。 + +本文主要介绍如何使用集群动态资源超卖功能。 + +## 前提条件 + +- 容器管理模块已[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者已[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已完成一个[命名空间的创建](../namespaces/createns.md),并为用户授予 [Cluster Admin](../permissions/permission-brief.md) , + 详情可参考[集群授权](../permissions/cluster-ns-auth.md)。 + +## 开启集群超卖 + +1. 点击左侧导航栏上的 **集群列表** ,然后点击目标集群的名称,进入 **集群详情** 页面 + + ![集群列表](../images/cluster-oversold-01.png) + +1. 在集群详情页面,点击左侧导航栏的 **集群运维** -> **集群设置** ,然后选择 **高级配置** 页签 + + ![高级设置](../images/cluster-oversold-02.png) + +1. 打开集群超卖,设置超卖比 + + - 若未安装 cro-operator 插件,点击 **立即安装** 按钮,安装流程参考[管理 Helm 应用](../helm/helm-app.md) + - 若已安装 cro-operator 插件,打开集群超卖开关,则可以开始使用集群超卖功能。 + + !!! note + + 需要在集群下对应的 namespace 打上如下标签,集群超卖策略才能生效。 + + ```shell + clusterresourceoverrides.admission.autoscaling.openshift.io/enabled: "true" + ``` + + ![集群超卖](../images/cluster-oversold-03.png) + +## 使用集群超卖 + +设置好集群动态资源超卖比后,会在工作负载运行时生效。下文以 niginx 为例,验证使用资源超卖能力。 + +1. 创建工作负载 nginx 并设置对应的资源限制值,创建流程参考[创建无状态负载(Deployment)](../workloads/create-deployment.md) + + ![创建工作负载](../images/cluster-oversold-04.png) + +1. 查看工作负载的 Pod 资源申请值与限制值的比值是否符合超售比 + + ![查看 Pod 资源](../images/cluster-oversold-05.png) diff --git a/docs/zh/docs/admin/kpanda/clusterops/cluster-settings.md b/docs/zh/docs/admin/kpanda/clusterops/cluster-settings.md new file mode 100644 index 0000000..df276c6 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusterops/cluster-settings.md @@ -0,0 +1,18 @@ +--- +hide: + - toc +--- + +# 集群设置 + +集群设置用于为您的集群自定义高级特性设置,包括是否启用 GPU、Helm 仓库刷新周期、Helm 操作记录保留等。 + +- 启用 GPU:需要预先在集群上安装 GPU 卡及对应驱动插件。 + + 点击目标集群的名称,在左侧导航栏点击 __最近操作__ -> __集群设置__ -> __Addon 插件__ 。 + + ![配置gpu](../../../images/settings01.png) + +- Helm 操作基础镜像、仓库刷新周期、操作记录保留条数、是否开启集群删除保护(开启后集群将不能直接卸载) + + ![高级配置](../../../images/Advanced-Configuration.png) diff --git a/docs/zh/docs/admin/kpanda/clusterops/latest-operations.md b/docs/zh/docs/admin/kpanda/clusterops/latest-operations.md new file mode 100644 index 0000000..17578c0 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusterops/latest-operations.md @@ -0,0 +1,22 @@ +--- +hide: + - toc +--- + +# 最近操作 + +在该页面可以查看最近的集群操作记录和 Helm 操作记录,以及各项操作的 YAML 文件和日志,也可以删除某一条记录。 + +![操作记录](../../../images/operations01.png) + +设置 Helm 操作的保留条数: + +系统默认保留最近 100 条 Helm 操作记录。若保留条数太多,可能会造成数据冗余,保留条数太少可能会造成您所需要的关键操作记录的缺失。需要根据实际情况设置合理的保留数量。具体步骤如下: + +1. 点击目标集群的名称,在左侧导航栏点击 __最近操作__ -> __Helm 操作__ -> __设置保留条数__ 。 + + ![保留条数](../../../images/operations02.png) + +2. 设置需要保留多少条 Helm 操作记录,并点击 __确定__ 。 + + ![保留条数](../../../images/operations03.png) diff --git a/docs/zh/docs/admin/kpanda/clusters/access-cluster.md b/docs/zh/docs/admin/kpanda/clusters/access-cluster.md new file mode 100644 index 0000000..2cb4ba4 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/access-cluster.md @@ -0,0 +1,59 @@ +# 访问集群 + +使用算丰 AI 算力平台容器管理平台接入或创建的集群,不仅可以通过 UI 界面直接访问,也可以通过其他两种方式进行访问控制: + +- 通过 CloudShell 在线访问 +- 下载集群证书后通过 kubectl 进行访问 + +!!! note + + 访问集群时,用户应具有 [Cluster Admin](../permissions/permission-brief.md) 权限或更高权限。 + +## 通过 CloudShell 访问 + +1. 在 __集群列表__ 页选择需要通过 CloudShell 访问的集群,点击右侧的 __┇__ 操作图标并在下拉列表中点击 __控制台__ 。 + + ![调用 CloudShell 控制台](../../../images/access-cloudshell.png) + +2. 在 CloudShell 控制台执行 __kubectl get node__ 命令,验证 CloudShell 与集群的连通性。如图,控制台将返回集群下的节点信息。 + + ![验证连通性](../../../images/access-get-node.png) + +现在,您可以通过 CloudShell 来访问并管理该集群了。 + +## 通过 kubectl 访问 + +通过本地节点访问并管理云端集群时,需要满足以下条件: + +- 本地节点和云端集群的网络互联互通。 +- 已经将集群证书下载到了本地节点。 +- 本地节点已经安装了 kubectl 工具。关于详细的安装方式,请参阅安装 [kubectl](https://kubernetes.io/zh-cn/docs/tasks/tools/)。 + +满足上述条件后,按照下方步骤从本地访问云端集群: + +1. 在 __集群列表__ 页选择需要下载证书的集群,点击右侧的 __┇__ ,并在弹出菜单中点击 __证书获取__ 。 + + ![进入下载证书页面](../../../images/access-get-cert.png) + +2. 选择证书有效期并点击 __下载证书__ 。 + + ![下载证书](../../../images/access-download-cert.png) + +3. 打开下载好的集群证书,将证书内容复制至本地节点的 __config__ 文件。 + + kubectl 工具默认会从本地节点的 __$HOME/.kube__ 目录下查找名为 __config__ 的文件。该文件存储了相关集群的访问凭证,kubectl 可以凭该配置文件连接至集群。 + +4. 在本地节点上执行如下命令验证集群的连通性: + + ```sh + kubectl get pod -n default + ``` + + 预期的输出类似于: + + ```none + NAME READY STATUS RESTARTS AGE + dao-2048-2048-58c7f7fc5-mq7h4 1/1 Running 0 30h + ``` + +现在您可以在本地通过 kubectl 访问并管理该集群了。 diff --git a/docs/zh/docs/admin/kpanda/clusters/cluster-role.md b/docs/zh/docs/admin/kpanda/clusters/cluster-role.md new file mode 100644 index 0000000..2f4532b --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/cluster-role.md @@ -0,0 +1,67 @@ +# 集群角色 + +算丰 AI 算力平台基于集群的不同功能定位对集群进行了角色分类,帮助用户更好地管理 IT 基础设施。 + +## 全局服务集群 + +此集群用于运行算丰 AI 算力平台组件,例如容器管理、全局管理、可观测性、镜像仓库等。 +一般不承载业务负载。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 1.22+ | +| 操作系统 | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| 集群全生命周期管理 | 支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | Calico、Cillium、Multus 和其它 CNI | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +## 管理集群 + +此集群用于管理工作集群,一般不承载业务负载。 + +- 经典模式将全局服务集群和管理集群部署在不同的集群,适用于企业多数据中心、多架构的场景。 +- 简约模式将管理集群和全局服务集群部署在同一个集群内。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 1.22+ | +| 操作系统 | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| 集群全生命周期管理 | 支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | Calico、Cillium、Multus 和其它 CNI | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +## 工作集群 + +这是使用容器管理创建的集群,主要用于承载业务负载。该集群由管理集群进行管理。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 支持 K8s 1.22 及以上版本 | +| 操作系统 | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| 集群全生命周期管理 | 支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | Calico、Cillium、Multus 和其它 CNI | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +## 接入集群 + +此集群用于接入已有的标准 K8s 集群,包括但不限于本地数据中心自建集群、公有云厂商提供的集群、私有云厂商提供的集群、边缘集群、信创集群、异构集群。主要用于承担业务负载。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 1.18+ | +| 支持友商 | Vmware Tanzu、Amazon EKS、Redhat Openshift、SUSE Rancher、阿里 ACK、华为 CCE、腾讯 TKE、标准 K8s 集群、算丰 AI 算力平台 | +| 集群全生命周期管理 | 不支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | 依赖于接入集群发行版网络模式 | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +!!! note + + 一个集群可以有多个集群角色,例如一个集群既可以是全局服务集群,也可以是管理集群或工作集群。 diff --git a/docs/zh/docs/admin/kpanda/clusters/cluster-scheduler-plugin.md b/docs/zh/docs/admin/kpanda/clusters/cluster-scheduler-plugin.md new file mode 100644 index 0000000..6716f2d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/cluster-scheduler-plugin.md @@ -0,0 +1,156 @@ +# 如何在集群中部署第二调度器 scheduler-plugins + +本文介绍如何在集群中部署第二个调度器 scheduler-plugins。 + +## 为什么需要 scheduler-plugins? + +通过平台创建的集群中会安装 K8s 原生的调度器,但是原生的调度器存在很多的局限性: + +- 原生的调度器无法满足调度需求,你可以选择使用 + [CoScheduling](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/pkg/coscheduling)、 + [CapacityScheduling](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/pkg/capacityscheduling) + 等 scheduler-plugins 插件。 +- 在特殊的场景,需要新的调度器来完成调度任务而不影响原生调度器的流程。 +- 区分不同功能的调度器,通过切换调度器名称来实现不同的调度场景。 + +本文以使用 vgpu 调度器的同时,想结合 scheduler-plugins 的 coscheduling 插件能力的场景为示例,介绍如何安装并使用 scheduler-plugins。 + +## 安装 scheduler-plugins + +### 前置条件 + +- kubean 是在 v0.13.0 版本推出的新功能,选择管理集群时请确保版本不低于此版本。 +- 安装 scheduler-plugins 版本为 v0.27.8,请确保集群版本是否与它兼容。 + 参考文档 [Compatibility Matrix](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master?tab=readme-ov-file#compatibility-matrix)。 + +### 安装流程 + +1. 在 **创建集群** -> **高级配置** -> **自定义参数** 中添加 scheduler-plugins 参数 + + ```yaml + scheduler_plugins_enabled:true + scheduler_plugins_plugin_config: + - name: Coscheduling + args: + permitWaitingTimeSeconds: 10 # default is 60 + ``` + + 参数说明: + + - `scheduler_plugins_enabled` 设置为 true 时,开启 scheduler-plugins 插件能力。 + - 您可以通过设置 `scheduler_plugins_enabled_plugins` 或 `scheduler_plugins_disabled_plugins` 选项来启用或禁用某些插件。 + 参阅 [K8s 官方插件名称](https://github.com/kubernetes-sigs/scheduler-plugins?tab=readme-ov-file#plugins)。 + - 如果需要设置自定义插件的参数请配置 scheduler_plugins_plugin_config,例如:设置 coscheduling 的 permitWaitingTimeoutSeconds 参数。 + 参阅 [K8s 官方插件配置项](https://github.com/kubernetes-sigs/scheduler-plugins/blob/master/manifests/coscheduling/scheduler-config.yaml) + +2. 集群创建成功后系统会自动安装 scheduler-plugins 和 controller 组件负载,可以在对应集群的无状态负载中查看负载状态。 + +## 使用 scheduler-plugins + +以下以使用 vgpu 调度器的同时,想结合 scheduler-plugins 的 coscheduling 插件能力场景为示例,介绍如何使用 scheduler-plugins。 + +1. 在 Helm 模板中安装 vgpu,设置 values.yaml 参数。 + + - `schedulerName: scheduler-plugins-scheduler`,这是 kubean 默认安装的 scheduler-plugins 的 scheduler 名称,目前不能修改。 + - `scheduler.kubeScheduler.enabled: false`,不安装 kube-scheduler,将 vgpu-scheduler 作为单独的 extender。 + +1. 在 scheduler-plugins 上扩展 vgpu-scheduler。 + + ```bash + [root@master01 charts]# kubectl get cm -n scheduler-plugins scheduler-config -ojsonpath="{.data.scheduler-config\.yaml}" + ``` + + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1 + kind: KubeSchedulerConfiguration + leaderElection: + leaderElect: false + profiles: + # Compose all plugins in one profile + - schedulerName: scheduler-plugins-scheduler + plugins: + multiPoint: + enabled: + - name: Coscheduling + - name: CapacityScheduling + - name: NodeResourceTopologyMatch + - name: NodeResourcesAllocatable + disabled: + - name: PrioritySort + pluginConfig: + - args: + permitWaitingTimeSeconds: 10 + name: Coscheduling + ``` + + 修改 scheduler-plugins 的 scheduler-config 的 configmap 参数,如下: + + ```bash + [root@master01 charts]# kubectl get cm -n scheduler-plugins scheduler-config -ojsonpath="{.data.scheduler-config\.yaml}" + ``` + + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1 + kind: KubeSchedulerConfiguration + leaderElection: + leaderElect: false + profiles: + # Compose all plugins in one profile + - schedulerName: scheduler-plugins-scheduler + plugins: + multiPoint: + enabled: + - name: Coscheduling + - name: CapacityScheduling + - name: NodeResourceTopologyMatch + - name: NodeResourcesAllocatable + disabled: + - name: PrioritySort + pluginConfig: + - args: + permitWaitingTimeSeconds: 10 + name: Coscheduling + extenders: + - urlPrefix: "${urlPrefix}" + filterVerb: filter + bindVerb: bind + nodeCacheCapable: true + ignorable: true + httpTimeout: 30s + weight: 1 + enableHTTPS: true + tlsConfig: + insecure: true + managedResources: + - name: nvidia.com/vgpu + ignoredByScheduler: true + - name: nvidia.com/gpumem + ignoredByScheduler: true + - name: nvidia.com/gpucores + ignoredByScheduler: true + - name: nvidia.com/gpumem-percentage + ignoredByScheduler: true + - name: nvidia.com/priority + ignoredByScheduler: true + - name: cambricon.com/mlunum + ignoredByScheduler: true + ``` + +1. 安装完 vgpu-scheduler 后,系统会自动创建 svc,urlPrefix 指定 svc 的 URL。 + + !!! note + + - svc 指 pod 服务负载,您可以到安装了 nvidia-vgpu 插件的命名空间下通过以下命令拿到 443 端口对应的外部访问信息。 + + ```shell + kubectl get svc -n ${namespace} + ``` + + - urlprifix 格式为 `https://${ip 地址}:${端口}` + + +1. 将 scheduler-plugins 的 scheduler Pod 重启,加载新的配置文件。 + + !!! note + + 在创建 vgpu 应用时不需要指定调度器名称,vgpu-scheduler 的 Webhook 会自动将 Scheduler 的名称修改为 scheduler-plugins-scheduler,不用手动指定。 diff --git a/docs/zh/docs/admin/kpanda/clusters/cluster-status.md b/docs/zh/docs/admin/kpanda/clusters/cluster-status.md new file mode 100644 index 0000000..161dc2c --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/cluster-status.md @@ -0,0 +1,26 @@ +# 集群状态 + +容器管理模块支持纳管两种类型的集群:接入集群和自建集群。 +关于集群纳管类型的更多信息,请参见[集群角色](cluster-role.md)。 + +这两种集群的状态如下所述。 + +## 接入集群 + +| 状态 | 描述 | +| ---------------------- | ------------------------------------------------------------ | +| 接入中(Joining) | 集群正在接入 | +| 解除接入中(Removing) | 集群正在解除接入 | +| 运行中(Running) | 集群正常运行 | +| 未知(Unknown) | 集群已失联,系统展示数据为失联前缓存数据,不代表真实数据,同时失联状态下执行的任何操作都将不生效,请检查集群网络连通性或主机状态。 | + +## 自建集群 + +| 状态 | 描述 | +| ------------------------------------------ | ------------------------------------------------------------ | +| 创建中(Creating) | 集群正在创建 | +| 更新中(Updating) | 更新集群 Kubernetes 版本 | +| 删除中(Deleting) | 集群正在删除 | +| 运行中(Running) | 集群正常运行 | +| 未知(Unknown) | 集群已失联,系统展示数据为失联前缓存数据,不代表真实数据,同时失联状态下执行的任何操作都将不生效,请检查集群网络连通性或主机状态。 | +| 创建失败(Failed) | 集群创建失败,请查看日志以获取详细失败原因 | diff --git a/docs/zh/docs/admin/kpanda/clusters/cluster-version.md b/docs/zh/docs/admin/kpanda/clusters/cluster-version.md new file mode 100644 index 0000000..eac297e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/cluster-version.md @@ -0,0 +1,49 @@ +# 集群版本支持范围 + +在算丰 AI 算力平台中,[接入型集群](cluster-status.md)和[自建集群](cluster-status.md)采取不同的版本支持机制。 + +本文主要介绍自建集群的版本支持机制。 + +Kubernetes 社区支持 3 个版本范围,如 1.26、1.27、1.28。当社区新版本发布之后,支持的版本范围将会进行递增。 +如社区最新的 1.29 版本已经发布,此时社区支持的版本范围是 1.27、1.28、1.29。 + +例如,社区支持的版本范围是 1.25、1.26、1.27,则在算丰 AI 算力平台中使用界面创建工作集群的版本范围是 1.24、1.25、1.26,并且会为用户推荐一个稳定的版本,如 1.24.7。 + +除此之外,算丰 AI 算力平台中使用界面创建工作集群的版本范围与社区保持高度同步,当社区版本进行递增后,算丰 AI 算力平台中使用界面创建工作集群的版本范围也会同步递增一个版本。 + +## Kubernetes 版本支持范围 + + + + + + + + + + + + + + + + + + + + +
Kubernetes 社区版本范围自建工作集群版本范围自建工作集群推荐版本算丰 AI 算力平台安装器发布时间
+
    +
  • 1.26
  • +
  • 1.27
  • +
  • 1.28
  • +
+
+
    +
  • 1.25
  • +
  • 1.26
  • +
  • 1.27
  • +
+
1.27.5v0.13.02023.11.30
+ +![版本支持机制](../../../images/cluster-version.png) diff --git a/docs/zh/docs/admin/kpanda/clusters/create-cluster.md b/docs/zh/docs/admin/kpanda/clusters/create-cluster.md new file mode 100644 index 0000000..eda0c8d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/create-cluster.md @@ -0,0 +1,105 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# 创建工作集群 + +在算丰 AI 算力平台容器管理模块中,[集群角色](cluster-role.md)分四类:全局服务集群、管理集群、工作集群、接入集群。 +其中,接入集群只能从第三方厂商接入,参见[接入集群](./integrate-cluster.md)。 + +本页介绍如何创建工作集群,默认情况下,新建工作集群的工作节点 OS 类型和 CPU 架构需要与全局服务集群保持一致。 +如需使用区别于全局服务集群 OS 或架构的节点创建集群,参阅[在 centos 管理平台上创建 ubuntu 工作集群](../../best-practice/create-ubuntu-on-centos-platform.md)进行创建。 + +推荐使用 [算丰 AI 算力平台支持的操作系统](../../../install/commercial/deploy-requirements.md)来创建集群。 +如您本地节点不在上述支持范围,可参考[在非主流操作系统上创建集群](../../best-practice/use-otherlinux-create-custer.md)进行创建。 + +## 前提条件 + +创建集群之前需要满足一定的前提条件: + +- 根据业务需求准备一定数量的节点,且节点 OS 类型和 CPU 架构一致。 +- 推荐 Kubernetes 版本 1.29.5,具体版本范围,参阅 [算丰 AI 算力平台集群版本支持体系](./cluster-version.md), + 目前算丰 AI 算力平台支持自建工作集群版本范围在 `v1.28.0-v1.30.2`。如需创建低版本的集群,请参考[集群版本支持范围](./cluster-version.md)、[部署与升级 Kubean 向下兼容版本](../../best-practice/kubean-low-version.md)。 +- 目标主机需要允许 IPv4 转发。如果 Pod 和 Service 使用的是 IPv6,则目标服务器需要允许 IPv6 转发。 +- 算丰 AI 算力平台暂不提供对防火墙的管理功能,您需要预先自行定义目标主机防火墙规则。为了避免创建集群的过程中出现问题,建议禁用目标主机的防火墙。 +- 参阅[节点可用性检查](../nodes/node-check.md)。 + +## 操作步骤 + +1. 在 __集群列表__ 页面中,点击 __创建集群__ 按钮。 + + ![创建集群按钮](../../../images/create001.png) + +2. 参考下列要求填写集群基本信息,并点击 __下一步__ 。 + + - 集群名称:名称只包含小写字母、数字和连字符("-"),必须以小写字母或者数字开头和结尾,最长 63 个字符。 + - 被纳管:选择由哪个集群来管理此集群,例如在集群生命周期中创建、升级、节点扩缩容、删除集群等。 + - 运行时:选择集群的运行时环境,目前支持 containerd 和 docker,[如何选择容器运行时](runtime.md)。 + - Kubernetes 版本:支持 3 个版本跨度,具体取决于被纳管集群所支持的版本。 + + ![填写基本信息](../../../images/create002.png) + +3. 填写节点配置信息,并点击 __下一步__ 。 + + - 高可用:开启后需要提供至少 3 个控制器节点。关闭后,只提供 1 个控制器节点即可。 + + > 生产环境中建议使用高可用模式。 + + - 认证方式:选择通过用户名/密码还是公私钥访问节点。 + + > 如果使用公私钥方式访问节点,需要预先配置节点的 SSH 密钥。参阅[使用 SSH 密钥认证节点](../nodes/node-authentication.md)。 + + - 使用统一的密码:开启后集群中所有节点的访问密码都相同,需要在下方输入访问所有节点的统一密码。如果关闭,则可以为每个节点设置单独的用户名和密码。 + + - 节点信息:填写节点名称和 IP 地址。 + - 自定义参数:设置变量控制 Ansible 与远程主机交互。可设置变量参考[连接到主机:行为清单参数](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters) + - NTP 时间同步:开启后会自动同步各个节点上的时间,需要提供 NTP 服务器地址。 + + ![节点配置](../../../images/createnew01.png) + +4. 在页面底部点击节点检查。如果检查通过则继续下一步操作。如果检查未通过,则更新 __节点信息__ 并再次执行检查。 + +5. 填写网络配置信息,并点击 __下一步__ 。 + + - 网络插件:负责为集群内的 Pod 提供网络服务,**创建集群后不可更改网络插件**。支持 cilium 和 calico。选择 __none__ 表示暂不安装网络插件。 + + - 容器网段:集群下容器使用的网段,决定集群下容器的数量上限。创建后不可修改。 + - 服务网段:同一集群下容器互相访问时使用的 Service 资源的网段,决定 Service 资源的上限。创建后不可修改。 + + ![网络配置1](../../../images/creatnew03.png) + + ![网络配置2](../../../images/creatnew04.png) + +6. 填写插件配置信息,并点击 __下一步__ 。 + + ![插件配置](../../../images/creatnew05.png) + +7. 填写高级配置信息,并点击 __确定__ 。 + + - __kubelet_max_pods__ :设置每个节点的最大 Pod 数量,默认为 110 个。 + - __hostname_overide__ :重置主机名,建议使用默认值,采用系统默认生成的名称作为主机名称。 + - __kubernetes_audit__ :Kubernetes 的审计日志,默认开启。 + - __auto_renew_certificate__ :在每月第一个星期一自动更新 Kubernetes 控制平面证书,默认开启。 + - __disable_firewalld&ufw__ :禁用防火墙,避免节点在安装过程中无法被访问。 + - __Insecure_registries__ :私有镜像仓库配置。使用私有镜像仓库创建集群时,为了避免证书问题导致容器引擎拒绝访问,需要在这里填写私有镜像仓库地址,以绕过容器引擎的证书认证而获取镜像。 + - __yum_repos__ :填写 Yum 源仓库地址。离线环境下,默认给出的地址选项仅供参考,请根据实际情况填写。 + + ![高级配置](../../../images/creatnew06.png) + +!!! success + + - 填写正确信息并完成上述步骤后,页面会提示集群正在创建中。 + - 创建集群耗时较长,需要耐心等待。其间,可以点击 __返回集群列表__ 按钮让安装过程后台运行。 + - 如需查看当前状态,可点击 __实时日志__ 。 + + ![查看实时日志](../../../images/create009.png) + +!!! note + + - 当集群出现未知状态时,表示当前集群已失联。 + - 系统展示数据为失联前缓存数据,不代表真实数据。 + - 同时失联状态下执行的任何操作都将不生效,请检查集群网络连通性或主机状态。 + + ![未知状态](../../../images/createnew07.png) diff --git a/docs/zh/docs/admin/kpanda/clusters/delete-cluster.md b/docs/zh/docs/admin/kpanda/clusters/delete-cluster.md new file mode 100644 index 0000000..ec0c3d3 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/delete-cluster.md @@ -0,0 +1,57 @@ +--- +hide: + - toc +--- + +# 卸载/解除接入集群 + +通过算丰 AI 算力平台容器管理平台 **创建的集群** 支持 __卸载集群__ 或 __解除接入__ 操作,从其他环境直接 **接入的集群** 仅支持 __解除接入__ 操作。 + +!!! info + + 如果想彻底删除一个接入的集群,需要前往创建该集群的原始平台操作。算丰 AI 算力平台不支持删除接入的集群。 + +在算丰 AI 算力平台中, __卸载集群__ 和 __解除接入__ 的区别在于: + +- __卸载集群__ 操作会销毁该集群,并重置集群下所有节点的数据。所有数据都将被销毁,建议做好备份。后期需要时必须重新创建一个集群。 +- __解除接入__ 操作会将当前集群从平台中移除,不会摧毁集群,也不会销毁数据。 + +## 卸载集群 + +!!! note + + - 当前操作用户应具备 Admin 或 Kpanda Owner 权限才能执行卸载集群的操作。 + - 卸载集群之前,应该先在集群列表中点击某个集群名称,在 __集群运维__ -> __集群设置__ -> __高级配置__ 中关闭 __集群删除保护__ , + 否则不显示 __卸载集群__ 的选项。 + - __全局服务集群__ 不支持卸载或移除操作。 + +1. 在 __集群列表__ 页找到需要卸载集群,点击右侧的 __┇__ 并在下拉列表中点击 __卸载集群__ 。 + +2. 输入集群名称进行确认,然后点击 __删除__ 。 + + 如果提示集群中还有一些残留的资源,则需要按提示删除相关资源后才能执行卸载操作。 + +3. 返回 __集群列表__ 页可以看到该集群的状态已经变成 __删除中__ 。卸载集群可能需要一段时间,请您耐心等候。 + +## 解除接入集群 + +!!! note + + - 当前操作用户应具备 Admin 或 Kpanda Owner 权限才能执行解除接入的操作。 + - __全局服务集群__ 不支持解除接入。 + +1. 在 __集群列表__ 页找到需要卸载集群,点击右侧的 __┇__ 并在下拉列表中点击 __解除接入__ 。 + +2. 输入集群名称进行确认,然后点击 __解除接入__ 。 + + 如果提示集群中还有一些残留的资源,则需要按提示删除相关资源后才能解除接入。 + +## 清理解除接入集群配置数据 + +集群被移除后,集群中原有的管理平台数据不会被自动清除,如需将集群接入至新管理平台则需要手动执行如下操作: + +删除 kpanda-system、insight-system 命名空间 + +```shell +kubectl delete ns kpanda-system insight-system +``` diff --git a/docs/zh/docs/admin/kpanda/clusters/integrate-cluster.md b/docs/zh/docs/admin/kpanda/clusters/integrate-cluster.md new file mode 100644 index 0000000..ae3d40e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/integrate-cluster.md @@ -0,0 +1,42 @@ +--- +hide: + - toc +--- + +# 接入集群 + +通过接入集群操作,能够对众多云服务平台集群和本地私有物理集群进行统一纳管,形成统一治理平台,有效避免了被厂商锁定风险,助力企业业务安全上云。 + +容器管理模块支持接入多种主流的容器集群,例如 Redhat Openshift, SUSE Rancher, VMware Tanzu, Amazon EKS, Aliyun ACK, Huawei CCE, Tencent TKE, 标准 Kubernetes 集群。 + +## 前提条件 + +- 准备一个待接入的集群,确保容器管理集群和待接入集群之间网络通畅,并且集群的 Kubernetes 版本 1.22+。 +- 当前操作用户应具有 [Kpanda Owner](../permissions/permission-brief.md) 或更高权限。 + +## 操作步骤 + +1. 进入 __集群列表__ 页面,点击右上角的 __接入集群__ 按钮。 + + ![接入集群](../../../images/join001.png) + +2. 填写基本信息。 + + - 集群名称:名称应具有唯一性,设置后不可更改。最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾。 + - 集群别名:可输入任意字符,不超过 60 个字符。 + - 发行版:集群的发行厂商,包括市场主流云厂商和本地私有物理集群。 + +3. 填写目标集群的 KubeConfig,点击 __验证 Config__ ,验证通过后才能成功接入集群。 + + > 如果不知道如何获取集群的 KubeConfig 文件,可以在输入框右上角点击 __如何获取 kubeConfig__ 查看对应步骤。 + + ![接入集群](../../../images/join003.png) + +4. 确认所有参数填写正确,在页面右下角点击 __确定__ 。 + + ![接入集群](../../../images/join002.png) + +!!! note + + - 新接入的集群状态为 __接入中__ ,接入成功后变为 __运行中__ 。 + - 如果集群状态一直处于 __接入中__ ,请确认接入脚本是否在对应集群上执行成功。有关集群状态的更多详情,请参考[集群状态](cluster-status.md)。 diff --git a/docs/zh/docs/admin/kpanda/clusters/integrate-rancher-cluster.md b/docs/zh/docs/admin/kpanda/clusters/integrate-rancher-cluster.md new file mode 100644 index 0000000..83e1f74 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/integrate-rancher-cluster.md @@ -0,0 +1,216 @@ +# 接入 rancher 集群 + +本文介绍如何接入 rancher 集群。 + +## 前提条件 + +- 准备一个具有管理员权限的待接入 ranhcer 集群,确保容器管理集群和待接入集群之间网络通畅。 +- 当前操作用户应具有 [Kpanda Owner](../permissions/permission-brief.md) 或更高权限。 + +## 操作步骤 + +### 步骤一:在 rancher 集群创建具有管理员权限的 ServiceAccount 用户 + +1. 使用具有管理员权限的角色进入 rancher 集群,并使用终端新建一个名为 __sa.yaml__ 的文件。 + + ```bash + vi sa.yaml + ``` + + 然后按下 i 键进入插入模式,输入以下内容: + + ```yaml title="sa.yaml" + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: rancher-rke + rules: + - apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' + - nonResourceURLs: + - '*' + verbs: + - '*' + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: rancher-rke + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rancher-rke + subjects: + - kind: ServiceAccount + name: rancher-rke + namespace: kube-system + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: rancher-rke + namespace: kube-system + ``` + + 按下 __esc__ 键退出插入模式,然后输入 __ :wq__ 保存并退出。 + +2. 在当前路径下执行如下命令,新建名为 __rancher-rke__ 的 ServiceAccount(以下简称为 __SA__ ): + + ```bash + kubectl apply -f sa.yaml + ``` + + 预期输出如下: + + ```console + clusterrole.rbac.authorization.k8s.io/rancher-rke created + clusterrolebinding.rbac.authorization.k8s.io/rancher-rke created + serviceaccount/rancher-rke created + ``` + +3. 创建名为 __rancher-rke-secret__ 的密钥,并将密钥和 __rancher-rke__ SA 绑定。 + + ```bash + kubectl apply -f - < + Annotations: kubernetes.io/service-account.name: rancher-rke + kubernetes.io/service-account.uid: d83df5d9-bd7d-488d-a046-b740618a0174 + + Type: kubernetes.io/service-account-token + + Data + ==== + ca.crt: 570 bytes + namespace: 11 bytes + token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjUtNE9nUWZLRzVpbEJORkZaNmtCQXhqVzRsZHU4MHhHcDBfb0VCaUo0V1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJyYW5jaGVyLXJrZS1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicmFuY2hlci1ya2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkODNkZjVkOS1iZDdkLTQ4OGQtYTA0Ni1iNzQwNjE4YTAxNzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cmFuY2hlci1ya2UifQ.VNsMtPEFOdDDeGt_8VHblcMRvjOwPXMM-79o9UooHx6q-VkHOcIOp3FOT2hnEdNnIsyODZVKCpEdCgyozX-3y5x2cZSZpocnkMcBbQm-qfTyUcUhAY7N5gcYUtHUhvRAsNWJcsDCn6d96gT_qo-ddo_cT8Ri39Lc123FDYOnYG-YGFKSgRQVy7Vyv34HIajZCCjZzy7i--eE_7o4DXeTjNqAFMFstUxxHBOXI3Rdn1zKQKqh5Jhg4ES7X-edSviSUfJUX-QV_LlAw5DuAyGPH7bDH4QaQ5k-p6cIctmpWZE-9wRDlKA4LYRblKE7MJcI6OmM4ldlMM0Jc8N-gCtl4w + ``` + +### 步骤二:在本地使用 rancher-rke SA 的认证信息更新 kubeconfig 文件 + +在任意一台安装了 __kubelet__ 的本地节点执行如下操作: + +1. 配置 kubelet token: + + ```bash + kubectl config set-credentials rancher-rke --token=`rancher-rke-secret` 里面的 token 信息 + ``` + + 例如: + + ``` + kubectl config set-credentials eks-admin --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjUtNE9nUWZLRzVpbEJORkZaNmtCQXhqVzRsZHU4MHhHcDBfb0VCaUo0V1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJyYW5jaGVyLXJrZS1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicmFuY2hlci1ya2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkODNkZjVkOS1iZDdkLTQ4OGQtYTA0Ni1iNzQwNjE4YTAxNzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cmFuY2hlci1ya2UifQ.VNsMtPEFOdDDeGt_8VHblcMRvjOwPXMM-79o9UooHx6q-VkHOcIOp3FOT2hnEdNnIsyODZVKCpEdCgyozX-3y5x2cZSZpocnkMcBbQm-qfTyUcUhAY7N5gcYUtHUhvRAsNWJcsDCn6d96gT_qo-ddo_cT8Ri39Lc123FDYOnYG-YGFKSgRQVy7Vyv34HIajZCCjZzy7i--eE_7o4DXeTjNqAFMFstUxxHBOXI3Rdn1zKQKqh5Jhg4ES7X-edSviSUfJUX-QV_LlAw5DuAyGPH7bDH4QaQ5k-p6cIctmpWZE-9wRDlKA4LYRblKE7MJcI6OmM4ldlMM0Jc8N-gCtl4w + ``` + +2. 配置 kubelet APIServer 信息: + + ```bash + kubectl config set-cluster {集群名} --insecure-skip-tls-verify=true --server={APIServer} + ``` + + - __{集群名}__ :指 rancher 集群的名称。 + - __{APIServer}__ :指集群的访问地址,一般为集群控制节点 IP + 6443 端口,如 `https://10.X.X.X:6443` + + 例如: + + ```bash + kubectl config set-cluster rancher-rke --insecure-skip-tls-verify=true --server=https://10.X.X.X:6443 + ``` + +3. 配置 kubelet 上下文信息: + + ```bash + kubectl config set-context {上下文名称} --cluster={集群名} --user={SA 用户名} + ``` + + 例如: + + ```bash + kubectl config set-context rancher-rke-context --cluster=rancher-rke --user=rancher-rke + ``` + +4. 在 kubelet 中指定我们刚刚新建的上下文 __rancher-rke-context__ : + + ```bash + kubectl config use-context rancher-rke-context + ``` + +5. 获取上下文 __rancher-rke-context__ 中的 kubeconfig 信息。 + + ```bash + kubectl config view --minify --flatten --raw + ``` + + 预期输出: + + ```yaml + apiVersion: v1 + clusters: + - cluster: + insecure-skip-tls-verify: true + server: https://77C321BCF072682C70C8665ED4BFA10D.gr7.ap-southeast-1.eks.amazonaws.com + name: joincluster + contexts: + - context: + cluster: joincluster + user: eks-admin + name: ekscontext + current-context: ekscontext + kind: Config + preferences: {} + users: + - name: eks-admin + user: + token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImcxTjJwNkktWm5IbmRJU1RFRExvdWY1TGFWVUtGQ3VIejFtNlFQcUNFalEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2V + ``` + +### 步骤三:算丰 AI 算力平台界面接入集群 + +使用刚刚获取的 kubeconfig 文件,参考[接入集群](./integrate-cluster.md)文档,将 rancher 集群接入全局服务集群。 diff --git a/docs/zh/docs/admin/kpanda/clusters/k8s-cert.md b/docs/zh/docs/admin/kpanda/clusters/k8s-cert.md new file mode 100644 index 0000000..acabcdb --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/k8s-cert.md @@ -0,0 +1,122 @@ +# Kubernetes 集群证书更新 + +为保证 Kubernetes 各组件之间的通信安全,组件之间的调用会进行 TLS 身份验证,执行验证操作需要配置集群 PKI 证书。 + +集群证书有效期为1年,为避免证书过期导致业务无法使用,请及时更新证书。 + +本文介绍如何手动进行证书更新。 + +## 检查证书是否过期 + +您可以执行以下命令查看证书是否过期: + +```shell +kubeadm certs check-expiration +``` + +输出类似于以下内容: + +```output +CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED +admin.conf Dec 14, 2024 07:26 UTC 204d no +apiserver Dec 14, 2024 07:26 UTC 204d ca no +apiserver-etcd-client Dec 14, 2024 07:26 UTC 204d etcd-ca no +apiserver-kubelet-client Dec 14, 2024 07:26 UTC 204d ca no +controller-manager.conf Dec 14, 2024 07:26 UTC 204d no +etcd-healthcheck-client Dec 14, 2024 07:26 UTC 204d etcd-ca no +etcd-peer Dec 14, 2024 07:26 UTC 204d etcd-ca no +etcd-server Dec 14, 2024 07:26 UTC 204d etcd-ca no +front-proxy-client Dec 14, 2024 07:26 UTC 204d front-proxy-ca no +scheduler.conf Dec 14, 2024 07:26 UTC 204d no + +CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED +ca Dec 12, 2033 07:26 UTC 9y no +etcd-ca Dec 12, 2033 07:26 UTC 9y no +front-proxy-ca Dec 12, 2033 07:26 UTC 9y no +``` + +## 手动更新证书 + +您可以通过以下命令手动更新证书,只需带上合适的命令行选项。更新证书前请先备份当前证书。 + +更新指定证书: + +```shell +kubeadm certs renew +``` + +更新全部证书: + +```shell +kubeadm certs renew all +``` + +更新后的证书可以在 `/etc/kubernetes/pki` 目录下查看,有效期延续 1 年。 +以下对应的几个配置文件也会同步更新: + +- /etc/kubernetes/admin.conf +- /etc/kubernetes/controller-manager.conf +- /etc/kubernetes/scheduler.conf + +!!! note + + - 如果您部署的是一个高可用集群,这个命令需要在所有控制节点上执行。 + - 此命令用 CA(或者 front-proxy-CA )证书和存储在 `/etc/kubernetes/pki` 中的密钥执行更新。 + +## 重启服务 + +执行更新操作之后,你需要重启控制面 Pod。因为动态证书重载目前还不被所有组件和证书支持,所有这项操作是必须的。 + +静态 Pod 是被本地 kubelet 而不是 API 服务器管理,所以 kubectl 不能用来删除或重启他们。 + +要重启静态 Pod,你可以临时将清单文件从 `/etc/kubernetes/manifests/` 移除并等待 20 秒。 +参考 [KubeletConfiguration 结构](https://kubernetes.io/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/)中的 fileCheckFrequency 值。 + +如果 Pod 不在清单目录里,kubelet 将会终止它。 +在另一个 fileCheckFrequency 周期之后你可以将文件移回去,kubelet 可以完成 Pod 的重建,而组件的证书更新操作也得以完成。 + +```shell +mv ./manifests/* ./temp/ +mv ./temp/* ./manifests/ +``` + +!!! note + + 如果容器服务使用的是 Docker,为了让证书生效,可以使用以下命令对涉及到证书使用的几个服务进行重启: + + ```shell + docker ps | grep -E 'k8s_kube-apiserver|k8s_kube-controller-manager|k8s_kube-scheduler|k8s_etcd_etcd' | awk -F ' ' '{print $1}' | xargs docker restart + ``` + +## 更新 KubeConfig + +构建集群时通常会将 **admin.conf** 证书复制到 **$HOME/.kube/config** 中,为了在更新 admin.conf 后更新 $HOME/.kube/config 的内容, 必须运行以下命令: + +```shell +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +## 为 kubelet 配置证书轮换 + +完成以上操作后,基本完成了集群所有证书的更新,但不包括 kubelet。 + +因为 kubernetes 包含特性 kubelet 证书轮换, 在当前证书即将过期时, 将自动生成新的秘钥,并从 Kubernetes API 申请新的证书。 一旦新的证书可用,它将被用于与 Kubernetes API 间的连接认证。 + +!!! note + + 此特性适用于 Kubernetes 1.8.0 或更高的版本。 + +启用客户端证书轮换,配置参数如下: + +- kubelet 进程接收 --rotate-certificates 参数,该参数决定 kubelet 在当前使用的 证书即将到期时,是否会自动申请新的证书。 + +- kube-controller-manager 进程接收 --cluster-signing-duration 参数 + (在 1.19 版本之前为 --experimental-cluster-signing-duration),用来控制签发证书的有效期限。 + +更多详情参考[为 kubelet 配置证书轮换](https://kubernetes.io/zh-cn/docs/tasks/tls/certificate-rotation/)。 + +## 自动更新证书 + +为了更高效便捷处理已过期或者即将过期的 kubernetes 集群证书,可参考 +[k8s 版本集群证书更新](https://github.com/yuyicai/update-kube-cert/blob/master/README-zh_CN.md)。 diff --git a/docs/zh/docs/admin/kpanda/clusters/runtime.md b/docs/zh/docs/admin/kpanda/clusters/runtime.md new file mode 100644 index 0000000..ab5220d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/runtime.md @@ -0,0 +1,22 @@ +# 如何选择容器运行时 + +容器运行时是 kubernetes 中对容器和容器镜像生命周期进行管理的重要组件。 +kubernetes 在 1.19 版本中将 containerd 设为默认的容器运行时,并在 1.24 版本中移除了 Dockershim 组件的支持。 + +因此相较于 Docker 运行时,我们更加 **推荐您使用轻量的 containerd 作为您的容器运行时**,因为这已经成为当前主流的运行时选择。 + +除此之外,一些操作系统发行厂商对 Docker 运行时的兼容也不够友好,不同操作系统对运行时的支持如下表: + +## 不同操作系统和推荐的运行时版本对应关系 + +| 操作系统 | 推荐的 containerd 版本 | 推荐的 Docker 版本 | +|-------------|---------------|------------| +| CentOS | 1.7.5 | 20.10 | +| RedHatOS |1.7.5 | 20.10 | +| KylinOS | 1.7.5 | 19.03(仅 ARM 架构支持 ,在 x86 架构下不支持使用 Docker 作为运行时)| + +更多支持的运行时版本信息,请参考 [RedHatOS 支持的运行时版本](https://github.com/kubernetes-sigs/kubespray/blob/master/roles/container-engine/docker/vars/redhat.yml/) 和 [KylinOS 支持的运行时版本](https://github.com/kubernetes-sigs/kubespray/blob/master/roles/container-engine/docker/vars/kylin.yml) + +!!! note + + 在离线安装模式下,需要提前准备相关操作系统的运行时离线包。 diff --git a/docs/zh/docs/admin/kpanda/clusters/upgrade-cluster.md b/docs/zh/docs/admin/kpanda/clusters/upgrade-cluster.md new file mode 100644 index 0000000..61caae5 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/clusters/upgrade-cluster.md @@ -0,0 +1,59 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# 集群升级 + +Kubernetes 社区每个季度都会发布一次小版本,每个版本的维护周期大概只有 9 个月。 +版本停止维护后就不会再更新一些重大漏洞或安全漏洞。手动升级集群操作较为繁琐,给管理人员带来了极大的工作负担。 + +本节将介绍如何在通过 Web UI 界面一键式在线升级工作集群 Kubernetes 版本, +如需离线升级工作集群的 kubernetes 版本,请参阅[工作集群离线升级指南](../../best-practice/update-offline-cluster.md)进行升级。 + +!!! danger + + 版本升级后将无法回退到之前的版本,请谨慎操作。 + +!!! note + + - Kubernetes 版本以 __x.y.z__ 表示,其中 __x__ 是主要版本, __y__ 是次要版本, __z__ 是补丁版本。 + - 不允许跨次要版本对集群进行升级,例如不能从 1.23 直接升级到 1.25。 + - __接入集群__ 不支持版本升级。如果左侧导航栏没有 __集群升级__ ,请检查该集群是否为 __接入集群__ 。 + - 全局服务集群只能通过终端进行升级。 + - 升级工作集群时,该工作集群的[管理集群](cluster-role.md#_3)应该已经接入容器管理模块,并且处于正常运行中。 + - 如果需要修改集群参数,可以通过升级相同版本的方式实现,具体操作参考下文。 + +1. 在集群列表中点击目标集群的名称。 + + ![升级集群](../../../images/upgradeclsuter00.png) + +2. 然后在左侧导航栏点击 __集群运维__ -> __集群升级__ ,在页面右上角点击 __版本升级__ 。 + + ![升级集群](../../../images/upgradecluster01.png) + +3. 选择可升级的版本,输入集群名称进行确认。 + + ![可升级版本](../../../images/upgradecluster02.png) + + !!! note + + 如果您是想通过升级方式来修改集群参数,请参考以下步骤: + + 1. 找到集群对应的 ConfigMap,您可以登录控制节点执行如下命令,找到 varsConfRef 中的 ConfigMap 名称。 + + ```shell + kubectl get cluster.kubean.io -o yaml + ``` + 2. 根据需要,修改 ConfigMap 中的参数信息。 + + 3. 在此处选择相同版本进行升级操作,升级完成即可成功更新对应的集群参数。 + +4. 点击 __确定__ 后,可以看到集群的升级进度。 + + ![升级进度](../../../images/upgradecluster03.png) + +5. 集群升级预计需要 30 分钟,可以点击 __实时日志__ 按钮查看集群升级的详细日志。 + + ![实时日志](../../../images/createcluster07.png) diff --git a/docs/zh/docs/admin/kpanda/configmaps-secrets/configmap-hot-loading.md b/docs/zh/docs/admin/kpanda/configmaps-secrets/configmap-hot-loading.md new file mode 100644 index 0000000..5266d4f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/configmaps-secrets/configmap-hot-loading.md @@ -0,0 +1,29 @@ +# configmap/secret 热加载 + +configmap/secret 热加载是指将 configmap/secret 作为数据卷挂载在容器中挂载时,当配置发生改变时,容器将自动读取 configmap/secret 更新后的配置,而无需重启 Pod。 + +## 操作步骤 + +1. 参考创建工作负载 - [容器配置](../workloads/create-deployment.md#_4),配置容器数据存储,选择 __Configmap__ 、 __Configmap Key__ 、 __Secret__ 、 __Secret Key__ 作为数据卷挂载至容器。 + + ![使用 config 作为数据卷](../../../images/user_configmap_to_volume.jpg) + + !!! note + + 使用子路径(SubPath)方式挂载的配置文件不支持热加载。 + +2. 进入【配置与密钥】页面,进入配置项详情页面,在【关联资源】中找到对应的 __container__ 资源,点击 __立即加载__ 按钮,进入配置热加载页面。 + + ![使用 config 作为数据卷](../../../images/configmap-hot-loading03.png) + + !!! note + + 如果您的应用支持自动读取 configmap/secret 更新后的配置,则无需手动执行热加载操作。 + +3. 在热加载配置弹窗中,输入进入容器内的 __执行命令__ 并点击 __确定__ 按钮,以重载配置。例如,在 nginx 容器中,以 root 用户权限,执行 __nginx -s reload__ 命令来重载配置。 + + ![使用 config 作为数据卷](../../../images/configmap-hot-loading02.png) + +4. 在界面弹出的 web 终端中查看应用重载情况。 + + ![使用 config 作为数据卷](../../../images/configmap-hot-loading.jpg) diff --git a/docs/zh/docs/admin/kpanda/configmaps-secrets/create-configmap.md b/docs/zh/docs/admin/kpanda/configmaps-secrets/create-configmap.md new file mode 100644 index 0000000..c4f0326 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/configmaps-secrets/create-configmap.md @@ -0,0 +1,80 @@ +# 创建配置项 + +配置项(ConfigMap)以键值对的形式存储非机密性数据,实现配置数据和应用代码相互解耦的效果。配置项可用作容器的环境变量、命令行参数或者存储卷中的配置文件。 + +!!! note + + - 在配置项中保存的数据不可超过 1 MiB。如果需要存储体积更大的数据,建议挂载存储卷或者使用独立的数据库或者文件服务。 + + - 配置项不提供保密或者加密功能。如果要存储加密数据,建议使用[密钥](use-secret.md),或者其他第三方工具来保证数据的私密性。 + +支持两种创建方式: + +- 图形化表单创建 +- YAML 创建 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 图形化表单创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_10.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __配置项__ ,点击右上角 __创建配置项__ 按钮。 + + ![创建配置项](../../../images/configmap01.png) + +3. 在 __创建配置项__ 页面中填写配置信息,点击 __确定__ 。 + + !!! note + + 点击 __上传文件__ 可以从本地导入已有的文件,快速创建配置项。 + + ![创建配置项](../../../images/configmap03.png) + +4. 创建完成后在配置项右侧点击更多可以,可以编辑 YAML、更新、导出、删除等操作。 + + ![创建配置项](../../../images/configmap04.png) + +## YAML 创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_10.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __配置项__ ,点击右上角 __YAML 创建__ 按钮。 + + ![创建配置项](../../../images/configmap02.png) + +3. 填写或粘贴事先准备好的配置文件,然后在弹框右下角点击 __确定__ 。 + + !!! note + + - 点击 __导入__ 可以从本地导入已有的文件,快速创建配置项。 + - 填写数据之后点击 __下载__ 可以将配置文件保存在本地。 + + ![创建配置项](../images/create-configmap.png) + +4. 创建完成后在配置项右侧点击更多可以,可以编辑 YAML、更新、导出、删除等操作。 + + ![创建配置项](../../../images/configmap04.png) + +## 配置项 YAML 示例 + + ```yaml + kind: ConfigMap + apiVersion: v1 + metadata: + name: kube-root-ca.crt + namespace: default + annotations: + data: + version: '1.0' + ``` + +[下一步:使用配置项](use-configmap.md){ .md-button .md-button--primary } diff --git a/docs/zh/docs/admin/kpanda/configmaps-secrets/create-secret.md b/docs/zh/docs/admin/kpanda/configmaps-secrets/create-secret.md new file mode 100644 index 0000000..0305c93 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/configmaps-secrets/create-secret.md @@ -0,0 +1,80 @@ +# 创建密钥 + +密钥是一种用于存储和管理密码、OAuth 令牌、SSH、TLS 凭据等敏感信息的资源对象。使用密钥意味着您不需要在应用程序代码中包含敏感的机密数据。 + +密钥使用场景: + +- 作为容器的环境变量使用,提供容器运行过程中所需的一些必要信息。 +- 使用密钥作为 Pod 的数据卷。 +- 在 kubelet 拉取容器镜像时作为镜像仓库的身份认证凭证。 + +支持两种创建方式: + +- 图形化表单创建 +- YAML 创建 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) ,详情可参考[集群和命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 图形化表单创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_12.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __密钥__ ,点击右上角 __创建密钥__ 按钮。 + + ![创建密钥](../../../images/secret01_1.png) + +3. 在 __创建密钥__ 页面中填写配置信息,点击 __确定__ 。 + + ![创建密钥](../../../images/secret02_1.png) + + 填写配置时需要注意: + + - 密钥的名称在同一个命名空间中必须具有唯一性 + - 密钥类型: + - 默认(Opaque):Kubernetes 默认的密钥类型,支持用户定义的任意数据。 + - TLS (kubernetes.io/tls):用于 TLS 客户端或者服务器端数据访问的凭证。 + - 镜像仓库信息 (kubernetes.io/dockerconfigjson):用于镜像仓库访问的凭证。 + - 用户名和密码(kubernetes.io/basic-auth):用于基本身份认证的凭证。 + - 自定义:用户根据业务需要自定义的类型。 + - 密钥数据:密钥所存储的数据,不同数据需要填写的参数有所不同 + - 当密钥类型为默认(Opaque)/自定义:可以填入多个键值对数据。 + - 当密钥类型为 TLS (kubernetes.io/tls):需要填入证书凭证和私钥数据。证书是自签名或 CA 签名过的凭据,用来进行身份认证。证书请求是对签名的请求,需要使用私钥进行签名。 + - 当密钥类型为镜像仓库信息 (kubernetes.io/dockerconfigjson):需要填入私有镜像仓库的账号和密码。 + - 当密钥类型为用户名和密码(kubernetes.io/basic-auth):需要指定用户名和密码。 + +## YAML 创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_12.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __密钥__ ,点击右上角 __YAML 创建__ 按钮。 + + ![YAML 创建](../../../images/secret03_1.png) + +3. 在 __YAML 创建__ 页面中填写 YAML 配置,点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![YAML 创建](../images/secret04.png) + +## 密钥 YAML 示例 + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: secretdemo + type: Opaque + data: + username: ****** + password: ****** + ``` + +[下一步:使用密钥](use-secret.md){ .md-button .md-button--primary } diff --git a/docs/zh/docs/admin/kpanda/configmaps-secrets/use-configmap.md b/docs/zh/docs/admin/kpanda/configmaps-secrets/use-configmap.md new file mode 100644 index 0000000..252bf57 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/configmaps-secrets/use-configmap.md @@ -0,0 +1,147 @@ +# 使用配置项 + +配置项(ConfigMap)是 Kubernetes 的一种 API 对象,用来将非机密性的数据保存到键值对中,可以存储其他对象所需要使用的配置。 +使用时, 容器可以将其用作环境变量、命令行参数或者存储卷中的配置文件。通过使用配置项,能够将配置数据和应用程序代码分开,为应用配置的修改提供更加灵活的途径。 + +!!! note + + 配置项并不提供保密或者加密功能。如果要存储的数据是机密的,请使用[密钥](use-secret.md),或者使用其他第三方工具来保证数据的私密性,而不是用配置项。 + 此外在容器里使用配置项时,容器和配置项必须处于同一集群的命名空间中。 + +## 使用场景 + +您可以在 Pod 中使用配置项,有多种使用场景,主要包括: + +- 使用配置项设置容器的环境变量 + +- 使用配置项设置容器的命令行参数 + +- 使用配置项作为容器的数据卷 + +## 设置容器的环境变量 + +您可以通过图形化界面或者终端命令行来使用配置项作为容器的环境变量。 + +!!! note + + 配置项导入是将配置项作为环境变量的值;配置项键值导入是将配置项中某一参数作为环境变量的值。 + +### 图形化界面操作 + +通过镜像创建工作负载时,可以在 __环境变量__ 界面通过选择 __配置项导入__ 或 __配置项键值导入__ 为容器设置环境变量。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面中,在 __容器配置__ 这一步中,选择 __环境变量__ 配置,点击 __添加环境变量__ 按钮。 + + ![添加环境变量](../../../images/config05.png) + +2. 在环境变量类型处选择 __配置项导入__ 或 __配置项键值导入__ 。 + + - 当环境变量类型选择为 __配置项导入__ 时,依次输入 __变量名__ 、 __前缀__ 名称、 __配置项__ 的名称。 + + - 当环境变量类型选择为 __配置项键值导入__ 时,依次输入 __变量名__ 、 __配置项__ 名称、 __键__ 的名称。 + +### 命令行操作 + +您可以在创建工作负载时将配置项设置为环境变量,使用 valueFrom 参数引用 ConfigMap 中的 Key/Value。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod-1 +spec: + containers: + - name: test-container + image: busybox + command: [ "/bin/sh", "-c", "env" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: # (1)! + configMapKeyRef: + name: kpanda-configmap # (2)! + key: SPECIAL_LEVEL # (3)! + restartPolicy: Never +``` + +1. 使用 __valueFrom__ 来指定 env 引用配置项的 value 值 +2. 引用的配置文件名称 +3. 引用的配置项 key + +## 设置容器的命令行参数 + +您可以使用配置项设置容器中的命令或者参数值,使用环境变量替换语法 __$(VAR_NAME)__ 来进行。如下所示。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod-3 +spec: + containers: + - name: test-container + image: busybox + command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: + configMapKeyRef: + name: kpanda-configmap + key: SPECIAL_LEVEL + - name: SPECIAL_TYPE_KEY + valueFrom: + configMapKeyRef: + name: kpanda-configmap + key: SPECIAL_TYPE + restartPolicy: Never +``` + +这个 Pod 运行后,输出如下内容。 + +```none +Hello Kpanda +``` + +## 用作容器数据卷 + +您可以通过图形化界面或者终端命令行来使用配置项作为容器的环境变量。 + +### 图形化操作 + +在通过镜像创建工作负载时,您可以通过在 __数据存储__ 界面选择存储类型为 __配置项__ ,将配置项作为容器的数据卷。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面中,在 __容器配置__ 这一步中,选择 __数据存储__ 配置,在 __节点路径映射__ 列表点击 __添加__ 按钮。 + + ![添加环境变量](../images/config06.png) + +2. 在存储类型处选择 __配置项__ ,并依次输入 __容器路径__ 、 __子路径__ 等信息。 + +### 命令行操作 + +要在一个 Pod 的存储卷中使用 ConfigMap。 + +下面是一个将 ConfigMap 以卷的形式进行挂载的 Pod 示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + configMap: + name: myconfigmap +``` + +如果 Pod 中有多个容器,则每个容器都需要自己的 __volumeMounts__ 块,但针对每个 ConfigMap,您只需要设置一个 __spec.volumes__ 块。 + +!!! note + + 将配置项作为容器挂载的数据卷时,配置项只能作为只读文件进行读取。 diff --git a/docs/zh/docs/admin/kpanda/configmaps-secrets/use-secret.md b/docs/zh/docs/admin/kpanda/configmaps-secrets/use-secret.md new file mode 100644 index 0000000..4662828 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/configmaps-secrets/use-secret.md @@ -0,0 +1,141 @@ +# 使用密钥 + +密钥是一种用于存储和管理密码、OAuth 令牌、SSH、TLS 凭据等敏感信息的资源对象。使用密钥意味着您不需要在应用程序代码中包含敏感的机密数据。 + +## 使用场景 + +您可以在 Pod 中使用密钥,有多种使用场景,主要包括: + +- 作为容器的环境变量使用,提供容器运行过程中所需的一些必要信息。 +- 使用密钥作为 Pod 的数据卷。 +- 在 kubelet 拉取容器镜像时用作镜像仓库的身份认证凭证使用。 + +## 使用密钥设置容器的环境变量 + +您可以通过图形化界面或者终端命令行来使用密钥作为容器的环境变量。 + +!!! note + + 密钥导入是将密钥作为环境变量的值;密钥键值导入是将密钥中某一参数作为环境变量的值。 + +### 图形界面操作 + +在通过镜像创建工作负载时,您可以在 __环境变量__ 界面通过选择 __密钥导入__ 或 __密钥键值导入__ 为容器设置环境变量。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面。 + + ![创建 deployment](../../../images/secret05.png) + +2. 在 __容器配置__ 选择 __环境变量__ 配置,点击 __添加环境变量__ 按钮。 + + ![添加环境变量](../../../images/secret06.png) + +3. 在环境变量类型处选择 __密钥导入__ 或 __密钥键值导入__ 。 + + ![密钥导入](../../../images/secret07.png) + + - 当环境变量类型选择为 __密钥导入__ 时,依次输入 __变量名__ 、 __前缀__ 、 __密钥__ 的名称。 + + - 当环境变量类型选择为 __密钥键值导入__ 时,依次输入 __变量名__ 、 __密钥__ 、 __键__ 的名称。 + +### 命令行操作 + +如下例所示,您可以在创建工作负载时将密钥设置为环境变量,使用 __valueFrom__ 参数引用 Secret 中的 Key/Value。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: secret-env-pod +spec: + containers: + - name: mycontainer + image: redis + env: + - name: SECRET_USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + optional: false # (1)! + - name: SECRET_PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + optional: false # (2)! + +``` + +1. 此值为默认值;意味着 "mysecret",必须存在且包含名为 "username" 的主键 +2. 此值为默认值;意味着 "mysecret",必须存在且包含名为 "password" 的主键 + +## 使用密钥作为 Pod 的数据卷 + +### 图形界面操作 + +在通过镜像创建工作负载时,您可以通过在 __数据存储__ 界面选择存储类型为 __密钥__ ,将密钥作为容器的数据卷。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面。 + + ![创建deployment](../../../images/secret05.png) + +2. 在 __容器配置__ 选择 __数据存储__ 配置,在 __节点路径映射__ 列表点击 __添加__ 按钮。 + + ![创建deployment](../images/secret08.png) + +3. 在存储类型处选择 __密钥__ ,并依次输入 __容器路径__ 、 __子路径__ 等信息。 + +### 命令行操作 + +下面是一个通过数据卷来挂载名为 __mysecret__ 的 Secret 的 Pod 示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + optional: false # (1)! +``` + +1. 默认设置,意味着 "mysecret" 必须已经存在 + +如果 Pod 中包含多个容器,则每个容器需要自己的 __volumeMounts__ 块,不过针对每个 Secret 而言,只需要一份 `.spec.volumes` 设置。 + +## 在 kubelet 拉取容器镜像时用作镜像仓库的身份认证凭证 + +您可以通过图形化界面或者终端命令行来使用密钥作为镜像仓库身份认证凭证。 + +### 图形化操作 + +在通过镜像创建工作负载时,您可以通过在 __数据存储__ 界面选择存储类型为 __密钥__ ,将密钥作为容器的数据卷。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面。 + + ![创建deployment](../../../images/secret05.png) + +2. 在第二步 __容器配置__ 时选择 __基本信息__ 配置,点击 __选择镜像__ 按钮。 + + ![选择镜像](../../../images/secret09.png) + +3. 在弹框的 __镜像仓库__ 下拉选择私有镜像仓库名称。关于私有镜像密钥创建请查看[创建密钥](create-secret.md)了解详情。 + + ![选择镜像](../../../images/secret10.png) + +4. 输入私有仓库内的镜像名称,点击 __确定__ ,完成镜像选择。 + +!!! note + + 创建密钥时,需要确保输入正确的镜像仓库地址、用户名称、密码并选择正确的镜像名称,否则将无法获取镜像仓库中的镜像。 diff --git a/docs/zh/docs/admin/kpanda/custom-resources/create.md b/docs/zh/docs/admin/kpanda/custom-resources/create.md new file mode 100644 index 0000000..60ebd4d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/custom-resources/create.md @@ -0,0 +1,103 @@ +# 创建自定义资源 (CRD) + +在 Kubernetes 中一切对象都被抽象为资源,如 Pod、Deployment、Service、Volume 等是 Kubernetes 提供的默认资源, +这为我们的日常运维和管理工作提供了重要支撑,但是在一些特殊的场景中,现有的预置资源并不能满足业务的需要, +因此我们希望去扩展 Kubernetes API 的能力,自定义资源(CustomResourceDefinition, CRD)正是基于这样的需求应运而生。 + +容器管理模块支持对自定义资源的界面化管理,主要功能如下: + +- 获取集群下自定义资源列表和详细信息 +- 基于 YAML 创建自定资源 +- 基于 YAML 创建自定义资源示例 CR(Custom Resource) +- 删除自定义资源 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并将用户授权为 [Cluster Admin](../permissions/permission-brief.md#cluster-admin) 角色 ,详情可参考[集群和命名空间授权](../permissions/cluster-ns-auth.md) + +## 通过 YAML 创建自定义资源 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd-cluster-list.png) + +2. 在左侧导航栏,点击 __自定义资源__ ,点击右上角 __YAML 创建__ 按钮。 + + ![点击创建按钮](../images/crd-list-01.png) + +3. 在 __YAML 创建__ 页面中,填写 YAML 语句后,点击 __确定__ 。 + + ![填写 yaml](../../../images/crd03.png) + +4. 返回自定义资源列表页,即可查看刚刚创建的名为 `crontabs.stable.example.com` 的自定义资源。 + + ![查看](../images/crd-list-02.png) + +**自定义资源示例:** + +```yaml title="CRD example" +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + cronSpec: + type: string + image: + type: string + replicas: + type: integer + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct +``` + +## 通过 YAML 创建自定义资源示例 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd-cluster-list.png) + +2. 在左侧导航栏,点击 __自定义资源__ ,进入自定义资源列表页面。 + + ![点击创建按钮](../images/crd-list-03.png) + +3. 点击名为 `crontabs.stable.example.com` 的自定义资源,进入详情,点击右上角 __YAML 创建__ 按钮。 + + ![点击创建按钮](../images/crd-instance-list.png) + +4. 在 __YAML 创建__ 页面中,填写 YAML 语句后,点击 __确定__ 。 + + ![填写 yaml](../../../images/crd06.png) + +5. 返回 `crontabs.stable.example.com` 的详情页面,即可查看刚刚创建的名为 __my-new-cron-object__ 的自定义资源。 + +**CR 示例:** + +```yaml title="CR example" +apiVersion: "stable.example.com/v1" +kind: CronTab +metadata: + name: my-new-cron-object +spec: + cronSpec: "* * * * */5" + image: my-awesome-cron-image +``` diff --git a/docs/zh/docs/admin/kpanda/gpu/FAQ.md b/docs/zh/docs/admin/kpanda/gpu/FAQ.md new file mode 100644 index 0000000..be7159f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/FAQ.md @@ -0,0 +1,16 @@ +--- +hide: + - toc +--- + +# GPU 相关 FAQ + +## Pod 内 nvidia-smi 看不到 GPU 进程 + +Q: 在使用 GPU 的 Pod 内执行 `nvidia-smi` 命令看不到使用 GPU 的进程信息,包括整卡模式、vGPU 模式等。 + +A: 因为有 `PID namespace` 隔离,导致在 Pod 内查看不到 GPU 进程,如果要查看 GPU 进程有如下几种方法: + +- 在使用 GPU 的工作负载配置 `hostPID: true`,使其可以查看到宿主机上的 PID +- 在 gpu-operator 的 driver Pod 中执行 `nvidia-smi` 命令查看进程 +- 在宿主机上执行 `chroot /run/nvidia/driver nvidia-smi` 命令查看进程 diff --git a/docs/zh/docs/admin/kpanda/gpu/Iluvatar_usage.md b/docs/zh/docs/admin/kpanda/gpu/Iluvatar_usage.md new file mode 100644 index 0000000..a49f737 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/Iluvatar_usage.md @@ -0,0 +1,64 @@ +# App 使用天数智芯(Iluvatar)GPU + +本节介绍如何在算丰 AI 算力平台使用天数智芯虚拟 GPU。 + +## 前提条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 当前集群已安装天数智芯 GPU 驱动,驱动安装请参考[天数智芯官方文档](https://support.iluvatar.com/#/login)。 +- 当前集群内 GPU 卡未进行任何虚拟化操作且未被其它 App 占用。 + +## 操作步骤 + +### 使用界面配置 + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Iluvatar__ 。 + + ![集群设置](../../../images/cluster-setting-iluvatar-gpu.jpg) + +2. 部署工作负载。点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Iluvatar)之后,需要配置 App 使用的 GPU 资源: + + - 物理卡数量(iluvatar.ai/vcuda-core):表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且 **小于等于** 宿主机上的卡数量。 + - 显存使用数量(iluvatar.ai/vcuda-memory):表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值。 + + ![负载使用](../../../images/workload_iluvatargpu_userguide.jpg) + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 + +### 使用 YAML 配置 + +创建工作负载申请 GPU 资源,在资源申请和限制配置中增加`iluvatar.ai/vcuda-core: 1`、`iluvatar.ai/vcuda-memory: 200` 参数,配置 App 使用物理卡的资源。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-iluvatar-gpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-iluvatar-gpu-demo + template: + metadata: + labels: + app: full-iluvatar-gpu-demo + spec: + containers: + - image: nginx:perl + name: container-0 + resources: + limits: + cpu: 250m + iluvatar.ai/vcuda-core: '1' + iluvatar.ai/vcuda-memory: '200' + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + imagePullSecrets: + - name: default-secret +``` diff --git a/docs/zh/docs/admin/kpanda/gpu/ascend/ascend_driver_install.md b/docs/zh/docs/admin/kpanda/gpu/ascend/ascend_driver_install.md new file mode 100644 index 0000000..e565b13 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/ascend/ascend_driver_install.md @@ -0,0 +1,161 @@ +# 昇腾 NPU 组件安装 + +本章节提供昇腾 NPU 驱动、Device Plugin、NPU-Exporter 等组件的安装指导。 + +## 前提条件 + +1. 安装前请确认支持的 NPU 型号,详情请参考[昇腾 NPU 矩阵](../gpu_matrix.md) +2. 请确认 对应 NPU 型号所要求的内核版本是否匹配,详情请参考[昇腾 NPU 矩阵](../gpu_matrix.md) +3. 准备 Kubernetes 基础环境 + +## 安装步骤 + +使用 NPU 资源之前,需要完成固件安装、NPU 驱动安装、 Docker Runtime 安装、用户创建、日志目录创建以及 NPU Device Plugin 安装,详情参考如下步骤。 + +### 安装固件 + +1. 安装前请确认内核版本在“二进制安装”安装方式对应的版本范围内,则可以直接安装NPU驱动固件。 +2. 固件与驱动下载请参考[固件下载地址](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=15&cann=6.3.RC2.alpha005&driver=1.0.20.alpha) +3. 固件安装请参考[安装 NPU 驱动固件](https://www.hiascend.com/document/detail/zh/quick-installation/23.0.RC2/quickinstg/800_3000/quickinstg_800_3000_0001.html) + +### 安装 NPU 驱动 + +1. 如驱动未安装,请参考昇腾官方文档进行安装。例如 Ascend910,参考 + [910 驱动安装文档](https://www.hiascend.com/document/detail/zh/Atlas%20200I%20A2/23.0.RC3/EP/installationguide/Install_87.html)。 +2. 运行 __npu-smi info__ 命令,并且能够正常返回 NPU 信息,表示 NPU 驱动与固件已就绪。 + +![昇腾信息](../../../../images/npu-smi-info.png) + +### 安装 Docker Runtime + +1. 下载 Ascend Docker Runtime + + 社区版下载地址:https://www.hiascend.com/zh/software/mindx-dl/community + + ```sh + wget -c https://mindx.obs.cn-south-1.myhuaweicloud.com/OpenSource/MindX/MindX%205.0.RC2/MindX%20DL%205.0.RC2/Ascend-docker-runtime_5.0.RC2_linux-x86_64.run + ``` + + 安装到指定路径下,依次执行以下两条命令,参数为指定的安装路径: + + ```sh + chmod u+x Ascend-docker-runtime_5.0.RC2_linux-x86_64.run + ./Ascend-docker-runtime_{version}_linux-{arch}.run --install --install-path= + ``` + +2. 修改 containerd 配置文件 + + containerd 无默认配置文件时,依次执行以下3条命令,创建配置文件: + + ```bash + mkdir /etc/containerd + containerd config default > /etc/containerd/config.toml + vim /etc/containerd/config.toml + ``` + + containerd 有配置文件时: + + ```bash + vim /etc/containerd/config.toml + ``` + + 根据实际情况修改 runtime 的安装路径,主要修改 runtime 字段: + + ```toml + ... + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + [plugins."io.containerd.runtime.v1.linux"] + shim = "containerd-shim" + runtime = "/usr/local/Ascend/Ascend-Docker-Runtime/ascend-docker-runtime" + runtime_root = "" + no_shim = false + shim_debug = false + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + ... + ``` + + 执行以下命令,重启 containerd: + + ```bash + systemctl restart containerd + ``` + +### 用户创建 + +在对应组件安装的节点上执行以下命令创建用户。 + +```sh +# Ubuntu 操作系统 +useradd -d /home/hwMindX -u 9000 -m -s /usr/sbin/nologin hwMindX +usermod -a -G HwHiAiUser hwMindX +# Centos 操作系统 +useradd -d /home/hwMindX -u 9000 -m -s /sbin/nologin hwMindX +usermod -a -G HwHiAiUser hwMindX +``` + +### 日志目录创建 + +在对应节点创建组件日志父目录和各组件的日志目录,并设置目录对应属主和权限。执行下述命令,创建组件日志父目录。 + +```bash +mkdir -m 755 /var/log/mindx-dl +chown root:root /var/log/mindx-dl +``` + +执行下述命令,创建 Device Plugin 组件日志目录。 + +```bash +mkdir -m 750 /var/log/mindx-dl/devicePlugin +chown root:root /var/log/mindx-dl/devicePlugin +``` + +!!! note + + 请分别为所需组件创建对应的日志目录,当前案例中只需要 Device Plugin 组件。 + 如果有其他组件需求请参考[官方文档](https://www.hiascend.com/document/detail/zh/mindx-dl/50rc3/clusterscheduling/clusterschedulingig/dlug_installation_016.html) + +### 创建节点 Label + +参考下述命令在对应节点上创建 Label: + +```shell +# 在安装了驱动的计算节点创建此标签 +kubectl label node {nodename} huawei.com.ascend/Driver=installed +kubectl label node {nodename} node-role.kubernetes.io/worker=worker +kubectl label node {nodename} workerselector=dls-worker-node +kubectl label node {nodename} host-arch=huawei-arm //或者host-arch=huawei-x86 ,根据实际情况选择 +kubectl label node {nodename} accelerator=huawei-Ascend910 //根据实际情况进行选择 +# 在控制节点创建此标签 +kubectl label node {nodename} masterselector=dls-master-node +``` + +### 安装 Device Plugin 和 NpuExporter + +功能模块路径: __容器管理__ -> __集群管理__ ,点击目标集群的名称,从左侧导航栏点击 __Helm 应用__ -> __Helm 模板__ -> 搜索 __ascend-mindxdl__ 。 + +![找到 ascend-mindxdl](../images/ascend-mindxdl.png) + +![ascend-mindxdl详情](../images/detail-ascend.png) + +- __DevicePlugin__ :通过提供通用设备插件机制和标准的设备API接口,供Kubernetes使用设备。建议使用默认的镜像及版本。 +- __NpuExporter__ :基于Prometheus/Telegraf生态,该组件提供接口,帮助用户能够关注到昇腾系列AI处理器以及容器级分配状态。建议使用默认的镜像及版本。 +- __ServiceMonitor__ :默认不开启,开启后可前往可观测性模块查看 NPU 相关监控。如需开启,请确保 insight-agent 已安装并处于运行状态,否则将导致 ascend-mindxdl 安装失败。 +- __isVirtualMachine__ :默认不开启,如果 NPU 节点为云主机场景,请开启 isVirtualMachine 参数。 + +安装成功后,对应命名空间下会出现两个组件,如下图: + +![ascend-mindxdl列表](../images/list-ascend-mindxdl.png) + +同时节点信息上也会出现对应 NPU 的信息: + +![节点标签](../images/label-ascend-mindxdl.png) + +一切就绪后,我们通过页面创建工作负载时,就能够选择到对应的 NPU 设备,如下图: + +![使用 NPU](../images/use-ascend-mindxdl.png) + +!!! note + + 有关详细使用步骤,请参照[应用使用昇腾(Ascend)NPU](./ascend_usage.md)。 diff --git a/docs/zh/docs/admin/kpanda/gpu/ascend/ascend_usage.md b/docs/zh/docs/admin/kpanda/gpu/ascend/ascend_usage.md new file mode 100644 index 0000000..9647012 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/ascend/ascend_usage.md @@ -0,0 +1,162 @@ +# 应用使用昇腾(Ascend)NPU + +本节介绍如何在算丰 AI 算力平台使用昇腾 GPU。 + +## 前提条件 + +- 当前 NPU 节点已安装昇腾 (Ascend)驱动。 +- 当前 NPU 节点已安装 Ascend-Docker-Runtime 组件。 +- 当前集群已安装 NPU MindX DL 套件。 +- 当前集群内 NPU 卡未进行任何虚拟化操作或被其它应用占用。 + +请参考[昇腾 NPU 组件安装文档](ascend_driver_install.md)安装基础环境。 + +## 快速使用 + +本文使用昇腾示例库中的 [AscentCL 图片分类应用](https://gitee.com/ascend/samples/tree/master/inference/modelInference/sampleResnetQuickStart/python)示例。 + +1. 下载昇腾代码库 + + 运行以下命令下载昇腾 Demo 示例代码库,并且请记住代码存放的位置,后续需要使用。 + + ```git + git clone https://gitee.com/ascend/samples.git + ``` + +2. 准备基础镜像 + + 此例使用 Ascent-pytorch 基础镜像,可访问[昇腾镜像仓库](https://www.hiascend.com/developer/ascendhub)获取。 + +3. 准备 YAML + + ```yaml title="ascend-demo.yaml" + apiVersion: batch/v1 + kind: Job + metadata: + name: resnetinfer1-1-1usoc + spec: + template: + spec: + containers: + - image: ascendhub.huawei.com/public-ascendhub/ascend-pytorch:23.0.RC2-ubuntu18.04 # Inference image name + imagePullPolicy: IfNotPresent + name: resnet50infer + securityContext: + runAsUser: 0 + command: + - "/bin/bash" + - "-c" + - | + source /usr/local/Ascend/ascend-toolkit/set_env.sh && + TEMP_DIR=/root/samples_copy_$(date '+%Y%m%d_%H%M%S_%N') && + cp -r /root/samples "$TEMP_DIR" && + cd "$TEMP_DIR"/inference/modelInference/sampleResnetQuickStart/python/model && + wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/003_Atc_Models/resnet50/resnet50.onnx && + atc --model=resnet50.onnx --framework=5 --output=resnet50 --input_shape="actual_input_1:1,3,224,224" --soc_version=Ascend910 && + cd ../data && + wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg && + cd ../scripts && + bash sample_run.sh + resources: + requests: + huawei.com/Ascend910: 1 # Number of the Ascend 910 Processors + limits: + huawei.com/Ascend910: 1 # The value should be the same as that of requests + volumeMounts: + - name: hiai-driver + mountPath: /usr/local/Ascend/driver + readOnly: true + - name: slog + mountPath: /var/log/npu/conf/slog/slog.conf + - name: localtime # The container time must be the same as the host time + mountPath: /etc/localtime + - name: dmp + mountPath: /var/dmp_daemon + - name: slogd + mountPath: /var/slogd + - name: hbasic + mountPath: /etc/hdcBasic.cfg + - name: sys-version + mountPath: /etc/sys_version.conf + - name: aicpu + mountPath: /usr/lib64/aicpu_kernels + - name: tfso + mountPath: /usr/lib64/libtensorflow.so + - name: sample-path + mountPath: /root/samples + volumes: + - name: hiai-driver + hostPath: + path: /usr/local/Ascend/driver + - name: slog + hostPath: + path: /var/log/npu/conf/slog/slog.conf + - name: localtime + hostPath: + path: /etc/localtime + - name: dmp + hostPath: + path: /var/dmp_daemon + - name: slogd + hostPath: + path: /var/slogd + - name: hbasic + hostPath: + path: /etc/hdcBasic.cfg + - name: sys-version + hostPath: + path: /etc/sys_version.conf + - name: aicpu + hostPath: + path: /usr/lib64/aicpu_kernels + - name: tfso + hostPath: + path: /usr/lib64/libtensorflow.so + - name: sample-path + hostPath: + path: /root/samples + restartPolicy: OnFailure + ``` + + 以上 YAML 中有一些字段需要根据实际情况进行修改: + + 1. __atc ... --soc_version=Ascend910__ 使用的是 __Ascend910__ ,请以实际情况为主 + 您可以使用 __npu-smi info__ 命令查看显卡型号然后加上 Ascend 前缀即可 + 2. __samples-path__ 以实际情况为准 + 3. __resources__ 以实际情况为准 + +4. 部署 Job 并查看结果 + + 使用如下命令创建 Job: + + ```shell + kubectl apply -f ascend-demo.yaml + ``` + + 查看 Pod 运行状态: + + ![昇腾 Pod 状态](../../../../images/ascend-demo-pod-status.png) + + Pod 成功运行后,查看日志结果。在屏幕上的关键提示信息示例如下图,提示信息中的 Label 表示类别标识, + Conf 表示该分类的最大置信度,Class 表示所属类别。这些值可能会根据版本、环境有所不同,请以实际情况为准: + + ![昇腾 demo 运行结果](../../../../images/ascend-demo-pod-result.png) + + 结果图片展示: + + ![昇腾 demo 运行结果图片](../../../../images/ascend-demo-infer-result.png) + +## 界面使用 + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Ascend__ 。 + + ![集群设置](../../../../images/cluster-setting-ascend-gpu.jpg) + +2. 部署工作负载,点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Ascend)之后,需要配置应用使用的物理卡数量: + + **物理卡数量(huawei.com/Ascend910)** :表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且**小于等于**宿主机上的卡数量。 + + ![负载使用](../../../../images/workload_ascendgpu_userguide.jpg) + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 diff --git a/docs/zh/docs/admin/kpanda/gpu/ascend/vnpu.md b/docs/zh/docs/admin/kpanda/gpu/ascend/vnpu.md new file mode 100644 index 0000000..e26c866 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/ascend/vnpu.md @@ -0,0 +1,78 @@ +# 启用昇腾虚拟化 + +昇腾虚拟化分为动态虚拟化和静态虚拟化,本文介绍如何开启并使用昇腾静态虚拟化能力。 + +## 前提条件 + +- Kubernetes 集群环境搭建。 +- 当前 NPU 节点已安装昇腾 (Ascend)驱动。 +- 当前 NPU 节点已安装 Ascend-Docker-Runtime 组件。 +- 当前集群已安装 NPU MindX DL 套件。 +- 支持的 NPU 卡型号: + + - Ascend 310P,已验证 + - Ascend 910b(20 核),已验证 + - Ascend 910(32 核),官方介绍支持,未实际验证 + - Ascend 910(30 核),官方介绍支持,未实际验证 + + 更多细节参阅[官方虚拟化硬件说明](https://www.hiascend.com/document/detail/zh/mindx-dl/50rc1/AVI/cpaug/cpaug_0005.html)。 + +请参考[昇腾 NPU 组件安装文档](./ascend_driver_install.md)安装基础环境。 + +## 开启虚拟化能力 + +开启虚拟化能力需要手动修改 ascend-device-plugin-daemonset 组件的启动参数,参考下述命令: + +```init +- device-plugin -useAscendDocker=true -volcanoType=false -presetVirtualDevice=true +- logFile=/var/log/mindx-dl/devicePlugin/devicePlugin.log -logLevel=0 +``` + +### 切分 VNPU 实例 + +静态虚拟化需要手动对 VNPU 实例的切分,请参考下述命令: + +``` bash +npu-smi set -t create-vnpu -i 13 -c 0 -f vir02 +``` + +- `i` 指的是 card id +- `c` 指的是 chip id +- `vir02` 指的是切分规格模板 + +关于 card id 和 chip id,可以通过 npu-smi info 查询,切分规格可通过 +[ascend 官方模板](https://www.hiascend.com/document/detail/zh/mindx-dl/500/AVI/cpaug/cpaug_006.html)进行查询。 + +切分实例过后可通过下述命令查询切分结果: + +```bash +npu-smi info -t info-vnpu -i 13 -c 0 +``` + +查询结果如下: + +![vnpu1](../images/vnpu1.png) + +### 重启 ascend-device-plugin-daemonset + +切分实例后手动重启 device-plugin pod,然后使用 `kubectl describe` 命令查看已注册 node 的资源: + +```bash +kubectl describe node {{nodename}} +``` + +![vnpu2](../images/vnpu2.png) + +## 如何使用设备 + +在创建应用时,指定资源 key,参考下述 YAML: + +```yaml +...... +resources: + requests: + huawei.com/Ascend310P-2c: 1 + limits: + huawei.com/Ascend310P-2c: 1 +...... +``` diff --git a/docs/zh/docs/admin/kpanda/gpu/dynamic-regulation.md b/docs/zh/docs/admin/kpanda/gpu/dynamic-regulation.md new file mode 100644 index 0000000..b3434cb --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/dynamic-regulation.md @@ -0,0 +1,115 @@ +# GPU 资源动态调节 + +提供 GPU 资源动态调整功能,允许您在无需重新加载、重置或重启整个运行环境的情况下,对已经分配的 vGPU 资源进行实时、动态的调整。 +这一功能旨在最大程度地减少对业务运行的影响,确保您的业务能够持续稳定地运行,同时根据实际需求灵活调整 GPU 资源。 + +## 使用场景 + +- **弹性资源分配** :当业务需求或工作负载发生变化时,可以快速调整 GPU 资源以满足新的性能要求。 +- **即时响应** :在面对突发的高负载或业务需求时,可以迅速增加 GPU 资源而无需中断业务运行,以确保服务的稳定性和性能。 + +## 操作步骤 + +以下是一个具体的操作示例,展示如何在不重启 vGPU Pod 的情况下动态调整 vGPU 的算力和显存资源: + +### 创建一个 vGPU Pod + +首先,我们使用以下 YAML 创建一个 vGPU Pod,其算力初始不限制,显存限制为 200Mb。 + +```yaml +kind: Deployment +apiVersion: apps/v1 +metadata: + name: gpu-burn-test + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: gpu-burn-test + template: + metadata: + creationTimestamp: null + labels: + app: gpu-burn-test + spec: + containers: + - name: container-1 + image: docker.io/chrstnhntschl/gpu_burn:latest + command: + - sleep + - '100000' + resources: + limits: + cpu: 1m + memory: 1Gi + nvidia.com/gpucores: '0' + nvidia.com/gpumem: '200' + nvidia.com/vgpu: '1' +``` + +调整前查看 `Pod` 中的资源 `GPU` 分配资源: + +![gpu-dynamic-regulation-before.png](./images/gpu-dynamic-regulation-before.png) + + +### 动态调整算力 + +如果需要修改算力为 10%,可以按照以下步骤操作: + +1. 进入容器: + + ```bash + kubectl exec -it -- /bin/bash + ``` + +1. 执行: + + ```bash + export CUDA_DEVICE_SM_LIMIT=10 + ``` + +1. 在当前终端直接运行: + + ```bash + ./gpu_burn 60 + ``` + + 程序即可生效。注意,不能退出当前 Bash 终端。 + +### 动态调整显存 + +如果需要修改显存为 300 MB,可以按照以下步骤操作: + +1. 进入容器: + + ```bash + kubectl exec -it -- /bin/bash + ``` + +1. 执行以下命令来设置显存限制: + + ```bash + export CUDA_DEVICE_MEMORY_LIMIT_0=300m + export CUDA_DEVICE_MEMORY_SHARED_CACHE=/usr/local/vgpu/d.cache + ``` + + + !!! note + + 每次修改显存大小时,`d.cache` 这个文件名字都需要修改,比如改为 `a.cache`、`1.cache` 等,以避免缓存冲突。 + +1. 在当前终端直接运行: + + ```bash + ./gpu_burn 60 + ``` + + 程序即可生效。同样地,不能退出当前 Bash 终端。 + +调整后查看 `Pod` 中的资源 `GPU` 分配资源: + +![gpu-dynamic-regulation-after.png](./images/gpu-dynamic-regulation-after.png) + + +通过上述步骤,您可以在不重启 vGPU Pod 的情况下动态地调整其算力和显存资源,从而更灵活地满足业务需求并优化资源利用。 diff --git a/docs/zh/docs/admin/kpanda/gpu/gpu_matrix.md b/docs/zh/docs/admin/kpanda/gpu/gpu_matrix.md new file mode 100644 index 0000000..8e1b175 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/gpu_matrix.md @@ -0,0 +1,55 @@ +--- +hide: + - toc +--- + +# GPU 支持矩阵 + +本页说明算丰 AI 算力平台支持的 GPU 及操作系统所对应的矩阵。 + +## NVIDIA GPU + +| GPU 厂商及类型 | 支持 GPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| NVIDIA GPU(整卡/vGPU) | NVIDIA Fermi (2.1) 架构 | CentOS 7 | Kernel 3.10.0-123 ~ 3.10.0-1160内核参考文档建议使用操作系统对应 Kernel 版本 | 操作系统:CentOS 7.9;内核版本: 3.10.0-1160 | GPU Operator 离线安装 | +| | NVIDIA GeForce 400 系列 | CentOS 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | +| | NVIDIA Quadro 4000 系列 | Ubuntu 20.04 | Kernel 5.4 | | | +| | NVIDIA Tesla 20 系列 | Ubuntu 22.04 | Kernel 5.19 | | | +| | NVIDIA Ampere 架构系列(A100;A800;H100) | RHEL 7 | Kernel 3.10.0-123 ~ 3.10.0-1160 | | | +| | | RHEL 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | +| NVIDIA MIG | NVIDIA Ampere 架构系列(A100、A800、H100) | CentOS 7 | Kernel 3.10.0-123 ~ 3.10.0-1160 | 操作系统:CentOS 7.9;内核版本:3.10.0-1160 | GPU Operator 离线安装 | +| | | CentOS 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | +| | | Ubuntu 20.04 | Kernel 5.4 | | | +| | | Ubuntu 22.04 | Kernel 5.19 | | | +| | | RHEL 7 | Kernel 3.10.0-123 ~ 3.10.0-1160 | | | +| | | RHEL 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | + +## 昇腾(Ascend)NPU + + | GPU 厂商及类型 | 支持 NPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| 昇腾(Ascend 310) | Ascend 310 | Ubuntu 20.04 | 详情参考:内核版本要求 | 操作系统:CentOS 7.9;内核版本:3.10.0-1160 | 300 和 310P 驱动文档 | +| | Ascend 310P; | CentOS 7.6 | | | | +| | | CentOS 8.2 | | | | +| | | KylinV10SP1 操作系统 | | | | +| | | openEuler 操作系统 | | | | +| 昇腾(Ascend 910) | Ascend 910B | Ubuntu 20.04 | 详情参考内核版本要求 | 操作系统:CentOS 7.9;内核版本:3.10.0-1160 | 910 驱动文档 | +| | | CentOS 7.6 | | | | +| | | CentOS 8.2 | | | | +| | | KylinV10SP1 操作系统 | | | | +| | | openEuler 操作系统 | | | | + +## 天数智芯(Iluvatar)GPU + + | GPU 厂商及类型 | 支持的 GPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| 天数智芯(Iluvatar vGPU) | BI100 | CentOS 7 | Kernel 3.10.0-957.el7.x86_64 ~ 3.10.0-1160.42.2.el7.x86_64 | 操作系统:CentOS 7.9;内核版本: 3.10.0-1160 | 补充中 | +| | MR100; | CentOS 8 | Kernel 4.18.0-80.el8.x86_64 ~ 4.18.0-305.19.1.el8_4.x86_64 | | | +| | | Ubuntu 20.04 | Kernel 4.15.0-20-generic ~ 4.15.0-160-generic Kernel 5.4.0-26-generic ~ 5.4.0-89-generic Kernel 5.8.0-23-generic ~ 5.8.0-63-generic | | | +| | | Ubuntu 21.04 | Kernel 4.15.0-20-generic ~ 4.15.0-160-generic Kernel 5.4.0-26-generic ~ 5.4.0-89-generic Kernel 5.8.0-23-generic ~ 5.8.0-63-generic | | | +| | | openEuler 22.03 LTS | Kernel 版本大于等于 5.1 且小于等于 5.10 | | | + +## 沐曦(Metax)GPU +| GPU 厂商及类型 | 支持的 GPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| 沐曦Metax(整卡/vGPU) | 曦云 C500 | | | | [沐曦 GPU 安装使用](./metax/usemetax.md) | diff --git a/docs/zh/docs/admin/kpanda/gpu/gpu_scheduler_config.md b/docs/zh/docs/admin/kpanda/gpu/gpu_scheduler_config.md new file mode 100644 index 0000000..4c31d6a --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/gpu_scheduler_config.md @@ -0,0 +1,60 @@ +# GPU 调度配置(Binpack 和 Spread ) + +本文介绍使用 NVIDIA vGPU 时,如何通过 Binpack 和 Spread 的 GPU 调度配置减少 GPU 资源碎片、防止单点故障等,实现 vGPU 的高级调度。 +算丰 AI 算力平台提供了集群和工作负载两种维度的 Binpack 和 Spread 调度策略,分别满足不同场景下的使用需求。 + +## 前置条件 + +- 集群节点上已正确安装 GPU 设备。 +- 集群中已正确安装 [gpu-operator 组件](./nvidia/install_nvidia_driver_of_operator.md) 和 + [Nvidia-vgpu 组件](./nvidia/vgpu/vgpu_addon.md)。 +- 集群节点列表中,GPU 模式下存在 NVIDIA-vGPU 类型。 + +## 使用场景 + +- 基于 GPU 卡维度调度策略 + + - Binpack:优先选择节点的同一张 GPU 卡,适用于提高 GPU 利用率,减少资源碎片。 + - Spread:多个 Pod 会分散在节点的不同 GPU 卡上,适用于高可用场景,避免单卡故障。 + +- 基于节点维度的调度策略 + + - Binpack: 多个 Pod 会优先选择同一个节点,适用于提高 GPU 利用率,减少资源碎片。 + - Spread:多个 Pod 会分散在不同节点上,适用于高可用场景,避免单节点故障。 + +## 集群维度使用 Binpack 和 Spread 调度配置 + +!!! note + + 默认情况下,工作负载会遵循集群级别的 Binpack 和 Spread 调度配置。 + 若工作负载单独设置了与集群不一致的 Binpack 和 Spread 调度策略,则该工作负载优先遵循其本身的调度策略。 + +1. 在 __集群列表__ 页选择需要调整 Binpack 和 Spread 调度策略的集群,点击右侧的 __┇__ 操作图标并在下拉列表中点击 __GPU 调度配置__ 。 + + ![集群列表](images/gpu-scheduler-clusterlist.png) + +2. 根据业务场景调整 GPU 调度配置,并点击 __确定__ 后保存。 + + ![binpack配置](images/gpu-scheduler-clusterrule.png) + +## 工作负载维度使用 Binpack 和 Spread 调度配置 + +!!! note + + 当工作负载维度的 Binpack 和 Spread 调度策略与集群级别的配置冲突时,优先遵循工作负载维度的配置。 + +参考以下步骤,使用镜像创建一个无状态负载,并在工作负载中配置 Binpack 和 Spread 调度策略 。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群list](images/clusterlist1.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __无状态负载__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![创建工作负载](images/gpu-createdeploy.png) + +3. 依次填写[基本信息](../workloads/create-deployment.md#_3)、[容器配置](../workloads/create-deployment.md#_4),并在 __容器配置__ 中启用 GPU 配置,选择 GPU 类型为 NVIDIA vGPU, + 点击 __高级设置__ ,启用 Binpack / Spread 调度策略,根据业务场景调整 GPU 调度配置。配置完成后点击 __下一步__ , + 进入 [服务配置](../workloads/create-deployment.md#_5)、[高级配置](../workloads/create-deployment.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + ![配置binpack](images/gpu-deploybipack.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/gpu/images/ascend-mindxdl.png b/docs/zh/docs/admin/kpanda/gpu/images/ascend-mindxdl.png new file mode 100644 index 0000000..3ed8510 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/ascend-mindxdl.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/clusterlist1.png b/docs/zh/docs/admin/kpanda/gpu/images/clusterlist1.png new file mode 100644 index 0000000..6504daa Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/clusterlist1.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/config.png b/docs/zh/docs/admin/kpanda/gpu/images/config.png new file mode 100644 index 0000000..441d162 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/config.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/create-gpu-alarm.png b/docs/zh/docs/admin/kpanda/gpu/images/create-gpu-alarm.png new file mode 100644 index 0000000..4836dc1 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/create-gpu-alarm.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/detail-ascend.png b/docs/zh/docs/admin/kpanda/gpu/images/detail-ascend.png new file mode 100644 index 0000000..df1e75a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/detail-ascend.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/driveimage.png b/docs/zh/docs/admin/kpanda/gpu/images/driveimage.png new file mode 100644 index 0000000..d858b44 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/driveimage.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/driver.jpg b/docs/zh/docs/admin/kpanda/gpu/images/driver.jpg new file mode 100644 index 0000000..5b886b9 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/driver.jpg differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-details.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-details.png new file mode 100644 index 0000000..2841326 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-details.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-details2.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-details2.png new file mode 100644 index 0000000..57ccd25 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-details2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-message.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-message.png new file mode 100644 index 0000000..efb1a7c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-message.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-message2.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-message2.png new file mode 100644 index 0000000..f349466 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-alarm-message2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-createdeploy.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-createdeploy.png new file mode 100644 index 0000000..c9d2728 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-createdeploy.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-deploybipack.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-deploybipack.png new file mode 100644 index 0000000..015d8f0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-deploybipack.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-dynamic-regulation-after.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-dynamic-regulation-after.png new file mode 100644 index 0000000..450a773 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-dynamic-regulation-after.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-dynamic-regulation-before.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-dynamic-regulation-before.png new file mode 100644 index 0000000..6f9db7b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-dynamic-regulation-before.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-operator-mig.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-operator-mig.png new file mode 100644 index 0000000..14493ed Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-operator-mig.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-scheduler-clusterlist.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-scheduler-clusterlist.png new file mode 100644 index 0000000..3fb8947 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-scheduler-clusterlist.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/gpu-scheduler-clusterrule.png b/docs/zh/docs/admin/kpanda/gpu/images/gpu-scheduler-clusterrule.png new file mode 100644 index 0000000..4506326 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/gpu-scheduler-clusterrule.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/image-1.png b/docs/zh/docs/admin/kpanda/gpu/images/image-1.png new file mode 100644 index 0000000..d0ad415 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/image-1.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/image-2.png b/docs/zh/docs/admin/kpanda/gpu/images/image-2.png new file mode 100644 index 0000000..a0ceafc Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/image-2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/image.png b/docs/zh/docs/admin/kpanda/gpu/images/image.png new file mode 100644 index 0000000..4613049 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/image.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/kubean.png b/docs/zh/docs/admin/kpanda/gpu/images/kubean.png new file mode 100644 index 0000000..6cc2768 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/kubean.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/label-ascend-mindxdl.png b/docs/zh/docs/admin/kpanda/gpu/images/label-ascend-mindxdl.png new file mode 100644 index 0000000..2327825 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/label-ascend-mindxdl.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/list-ascend-mindxdl.png b/docs/zh/docs/admin/kpanda/gpu/images/list-ascend-mindxdl.png new file mode 100644 index 0000000..e52b242 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/list-ascend-mindxdl.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/metax-node.png b/docs/zh/docs/admin/kpanda/gpu/images/metax-node.png new file mode 100644 index 0000000..86d66ed Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/metax-node.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/metax-node1.png b/docs/zh/docs/admin/kpanda/gpu/images/metax-node1.png new file mode 100644 index 0000000..ba4fc16 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/metax-node1.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/metax-use.png b/docs/zh/docs/admin/kpanda/gpu/images/metax-use.png new file mode 100644 index 0000000..2227e78 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/metax-use.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/metax-use2.png b/docs/zh/docs/admin/kpanda/gpu/images/metax-use2.png new file mode 100644 index 0000000..414b50e Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/metax-use2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/mig-select.png b/docs/zh/docs/admin/kpanda/gpu/images/mig-select.png new file mode 100644 index 0000000..74f2efa Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/mig-select.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/miggpuoperator.png b/docs/zh/docs/admin/kpanda/gpu/images/miggpuoperator.png new file mode 100644 index 0000000..197737c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/miggpuoperator.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/migoperator.png b/docs/zh/docs/admin/kpanda/gpu/images/migoperator.png new file mode 100644 index 0000000..659b262 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/migoperator.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/migpolicy.png b/docs/zh/docs/admin/kpanda/gpu/images/migpolicy.png new file mode 100644 index 0000000..6c0d9e5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/migpolicy.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/mixed.png b/docs/zh/docs/admin/kpanda/gpu/images/mixed.png new file mode 100644 index 0000000..f59cd4e Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/mixed.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/mlu1.PNG b/docs/zh/docs/admin/kpanda/gpu/images/mlu1.PNG new file mode 100644 index 0000000..690b3e9 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/mlu1.PNG differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/mlu2.png b/docs/zh/docs/admin/kpanda/gpu/images/mlu2.png new file mode 100644 index 0000000..b446e68 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/mlu2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/mlu3.png b/docs/zh/docs/admin/kpanda/gpu/images/mlu3.png new file mode 100644 index 0000000..a52096b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/mlu3.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/node-gpu.png b/docs/zh/docs/admin/kpanda/gpu/images/node-gpu.png new file mode 100644 index 0000000..9c6bf7d Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/node-gpu.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/node-mig.png b/docs/zh/docs/admin/kpanda/gpu/images/node-mig.png new file mode 100644 index 0000000..7184ab6 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/node-mig.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/nvidia-gpu-driver-tag.jpg b/docs/zh/docs/admin/kpanda/gpu/images/nvidia-gpu-driver-tag.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/admin/kpanda/gpu/images/operator-mig.png b/docs/zh/docs/admin/kpanda/gpu/images/operator-mig.png new file mode 100644 index 0000000..6a5ce29 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/operator-mig.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/pod-mig.png b/docs/zh/docs/admin/kpanda/gpu/images/pod-mig.png new file mode 100644 index 0000000..5efbbe0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/pod-mig.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/redhat0.12.2.png b/docs/zh/docs/admin/kpanda/gpu/images/redhat0.12.2.png new file mode 100644 index 0000000..01bbb7c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/redhat0.12.2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/rhel7.9.png b/docs/zh/docs/admin/kpanda/gpu/images/rhel7.9.png new file mode 100644 index 0000000..f740e56 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/rhel7.9.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/use-ascend-mindxdl.png b/docs/zh/docs/admin/kpanda/gpu/images/use-ascend-mindxdl.png new file mode 100644 index 0000000..da3c80a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/use-ascend-mindxdl.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/usemig.png b/docs/zh/docs/admin/kpanda/gpu/images/usemig.png new file mode 100644 index 0000000..47805ca Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/usemig.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/usemig1.png b/docs/zh/docs/admin/kpanda/gpu/images/usemig1.png new file mode 100644 index 0000000..1e501c1 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/usemig1.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/vgpu-addon.png b/docs/zh/docs/admin/kpanda/gpu/images/vgpu-addon.png new file mode 100644 index 0000000..3241a80 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/vgpu-addon.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/vgpu-sc.png b/docs/zh/docs/admin/kpanda/gpu/images/vgpu-sc.png new file mode 100644 index 0000000..a9ef974 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/vgpu-sc.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/vnpu1.png b/docs/zh/docs/admin/kpanda/gpu/images/vnpu1.png new file mode 100644 index 0000000..d395dda Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/vnpu1.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/vnpu2.png b/docs/zh/docs/admin/kpanda/gpu/images/vnpu2.png new file mode 100644 index 0000000..5fd547c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/vnpu2.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/volcano-binpack1.png b/docs/zh/docs/admin/kpanda/gpu/images/volcano-binpack1.png new file mode 100644 index 0000000..461c38d Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/volcano-binpack1.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/images/volcano-binpacknode.png b/docs/zh/docs/admin/kpanda/gpu/images/volcano-binpacknode.png new file mode 100644 index 0000000..17bbcff Binary files /dev/null and b/docs/zh/docs/admin/kpanda/gpu/images/volcano-binpacknode.png differ diff --git a/docs/zh/docs/admin/kpanda/gpu/index.md b/docs/zh/docs/admin/kpanda/gpu/index.md new file mode 100644 index 0000000..f1746ea --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/index.md @@ -0,0 +1,40 @@ +--- +hide: + - toc +--- + +# GPU 管理概述 + +本文介绍 算丰 AI 算力容器管理平台对 GPU为代表的异构资源统一运维管理能力。 + +## 背景 + +随着 AI 应用、大模型、人工智能、自动驾驶等新兴技术的快速发展,企业面临着越来越多的计算密集型任务和数据处理需求。 +以 CPU 为代表的传统计算架构已无法满足企业日益增长的计算需求。此时,以 GPU 为代表的异构计算因在处理大规模数据、进行复杂计算和实时图形渲染方面具有独特的优势被广泛应用。 + +与此同时,由于缺乏异构资源调度管理等方面的经验和专业的解决方案,导致了 GPU 设备的资源利用率极低,给企业带来了高昂的 AI 生产成本。 +如何降本增效,提高 GPU 等异构资源的利用效率,成为了当前众多企业亟需跨越的一道难题。 + +## GPU 能力介绍 + +算丰 AI 算力容器管理平台支持对 GPU、NPU 等异构资源进行统一调度和运维管理,充分释放 GPU 资源算力,加速企业 AI 等新兴应用发展。GPU 管理能力如下: + +- 支持统一纳管 NVIDIA、华为昇腾、天数等国内外厂商的异构计算资源。 +- 支持同一集群多卡异构调度,并支持集群 GPU 卡自动识别。 +- 支持 NVIDIA GPU、vGPU、MIG 等 GPU 原生管理方案,并提供云原生能力。 +- 支持单块物理卡切分给不同的租户使用,并支持对租户和容器使用 GPU 资源按照算力、显存进行 GPU 资源配额。 +- 支持集群、节点、应用等多维度 GPU 资源监控,帮助运维人员管理 GPU 资源。 +- 兼容 TensorFlow、pytorch 等多种训练框架。 + +## GPU Operator 介绍 + +同普通计算机硬件一样,NVIDIA GPU 卡作为物理硬件,必须安装 NVIDIA GPU 驱动后才能使用。 +为了降低用户在 kuberneets 上使用 GPU 的成本,NVIDIA 官方提供了 NVIDIA GPU Operator 组件来管理使用 NVIDIA GPU 所依赖的各种组件。 +这些组件包括 NVIDIA 驱动程序(用于启用 CUDA)、NVIDIA 容器运行时、GPU 节点标记、基于 DCGM 的监控等。 +理论上来说用户只需要将 GPU 卡插在已经被 kubernetes 所纳管的计算设备上,然后通过 GPU Operator 就能使用 NVIDIA GPU 的所有能力了。 +了解更多 NVIDIA GPU Operator 相关信息,请参考 [NVIDIA 官方文档](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/index.html)。 +如何部署请参考 [GPU Operator 离线安装](nvidia/install_nvidia_driver_of_operator.md) + +NVIDIA GPU Operator 架构图: + +![NVIDIA GPU Operator 架构图](../../../images/nvidia-gpu-operator-image.jpg) diff --git a/docs/zh/docs/admin/kpanda/gpu/metax/usemetax.md b/docs/zh/docs/admin/kpanda/gpu/metax/usemetax.md new file mode 100644 index 0000000..5a3d831 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/metax/usemetax.md @@ -0,0 +1,88 @@ +# 沐曦 GPU 组件安装与使用 + +本章节提供沐曦 gpu-extensions、gpu-operator 等组件的安装指导和沐曦 GPU 整卡和 vGPU 两种模式的使用方法。 + +## 前提条件 + +1. 已在[沐曦软件中心](https://sw-download.metax-tech.com/software-list)下载并安装所需的 tar 包, + 本文以 metax-gpu-k8s-package.0.7.10.tar.gz 为例。 +1. 准备 Kubernetes 基础环境 + +## 组件介绍 + +Metax 提供了两个 helm-chart 包,一个是 metax-extensions,一个是 gpu-operator,根据使用场景可选择安装不同的组件。 + +1. Metax-extensions:包含 gpu-device 和 gpu-label 两个组件。在使用 Metax-extensions 方案时,用户的应用容器镜像需要基于 MXMACA® 基础镜像构建。且 Metax-extensions 仅适用于 GPU 整卡使用场景。 +2. gpu-operator:包含 gpu-device、gpu-label、driver-manager、container-runtime、operator-controller 这些组件。 + 使用 gpu-operator 方案时,用户可选择制作不包含 MXMACA® SDK 的应用容器镜像。gpu-operator 适用于 GPU 整卡和 vGPU 场景。 + +## 操作步骤 + +1. 从 `/home/metax/metax-docs/k8s/metax-gpu-k8s-package.0.7.10.tar.gz` 文件中解压出 + + - deploy-gpu-extensions.yaml # 部署yaml + - metax-gpu-extensions-0.7.10.tgz、metax-operator-0.7.10.tgz # helm chart文件 + - metax-k8s-images.0.7.10.run # 离线镜像 + +2. 查看系统是否安装驱动 + + ```bash + $ lsmod | grep metax + metax 1605632 0 + ttm 86016 3 drm_vram_helper,metax,drm_ttm_helper + drm 618496 7 drm_kms_helper,drm_vram_helper,ast,metax,drm_ttm_helper,ttm + ``` + + - 如没有内容显示,就表示没有安装过软件包。如有内容显示,则表示安装过软件包。 + - 使用 metax-opeartor 时,不推荐在工作节点预安装 MXMACA 内核态驱动,若已安装也无需卸载。 + +3. 安装驱动 + +### gpu-extensions + +1. 推送镜像 + + ```bash + tar -xf metax-gpu-k8s-package.0.7.10.tar.gz + ./metax-k8s-images.0.7.10.run push {registry}/metax + ``` + +2. 推送 Helm Chart + + ```bash + helm plugin install https://github.com/chartmuseum/helm-push + helm repo add --username rootuser --password rootpass123 metax http://172.16.16.5:8081 + helm cm-push metax-operator-0.7.10.tgz metax + helm cm-push metax-gpu-extensions-0.7.10.tgz metax + ``` + +3. 在算丰 AI 算力平台上安装 metax-gpu-extensions + + 部署成功之后,可以在节点上查看到资源。 + + ![查看资源](../images/metax-node.png) + + +4. 修改成功之后就可以在节点上看到带有 `Metax GPU` 的标签 + + ![metax节点标签](../images/metax-node1.png) + +### gpu-operator + +安装 `gpu-opeartor` 时的已知问题: + +1. `metax-operator`、`gpu-label`、`gpu-device` 、`container-runtime` 这几个组件镜像要带有 `amd64` 后缀。 + +2. `metax-maca` 组件的镜像不在 `metax-k8s-images.0.7.13.run` 包里面,需要单独下载 `maca-mxc500-2.23.0.23-ubuntu20.04-x86_64.tar.xz` 这类镜像,`load` 之后重新修改 `metax-maca` 组件的镜像。 + +3. `metax-driver` 组件的镜像需要从 `https://pub-docstore.metax-tech.com:7001` 这个网站下载 `k8s-driver-image.2.23.0.25.run` 文件,然后执行 `k8s-driver-image.2.23.0.25.run push {registry}/metax` 命令把镜像推送到镜像仓库。推送之后修改 `metax-driver` 组件的镜像地址。 + +## 使用 GPU + +安装后可在工作负载中[使用沐曦 GPU](../../workloads/create-deployment.md#_5)。注意启用 GPU 后,需选择GPU类型为 Metax GPU + +![使用 GPU](../images/metax-use.png) + +进入容器,执行 mx-smi 可查看 GPU 的使用情况. + +![使用 GPU](../images/metax-use2.png) diff --git a/docs/zh/docs/admin/kpanda/gpu/mlu/use-mlu.md b/docs/zh/docs/admin/kpanda/gpu/mlu/use-mlu.md new file mode 100644 index 0000000..fbf49ed --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/mlu/use-mlu.md @@ -0,0 +1,67 @@ +# 使用寒武纪 GPU + +本文介绍如何在算丰 AI 算力平台中使用寒武纪 GPU。 + +## 前置条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 当前集群已安装寒武纪固件、驱动以及DevicePlugin组件,安装详情请参考官方文档: + - [驱动固件安装](https://www.cambricon.com/docs/sdk_1.15.0/driver_5.10.22/user_guide/index.html) + - [DevicePlugin 安装](https://github.com/Cambricon/cambricon-k8s-device-plugin/blob/master/device-plugin/README.md) + +在安装 DevicePlugin 时请关闭 **--enable-device-type** 参数,否则算丰 AI 算力平台将无法正确识别寒武纪 GPU。 + +## 寒武纪 GPU 模式介绍 + +寒武纪 GPU 有以下几种模式: + +- 整卡模式:将寒武纪GPU以整卡的方式注册到集群当中进行使用。 +- Share 模式:可以将一张寒武纪GPU共享给多个 Pod 进行使用,可以通过 virtualization-num 参数进行设置可共享容器的数量。 +- Dynamic smlu 模式:进一步对资源进行了细化,可以控制分配给容器的显存、算力的大小。 +- Mim 模式:可以将寒武纪 GPU 按照固定的规格切分成多张 GPU 进行使用。 + +## 算丰 AI 算力平台使用寒武纪 + +这里以 Dynamic smlu 模式为例: + +1. 在正确安装 DevicePlugin 等组件后,点击对应 **集群** -> **集群运维**-> **集群设置** -> **Addon 插件** ,查看是否已自动启用并自动检测对应 GPU 类型。 + + ![mlu类型](../images/mlu1.PNG) + +1. 点击节点管理页面,查看节点是否已经正确识别到对应的GPU类型。 + + ![节点列表](../images/mlu2.png) + +1. 部署工作负载。点击对应 **集群** -> **工作负载** ,通过镜像方式部署工作负载,选择类型(MLU VGPU)之后,需要配置 App 使用的 GPU 资源: + + - GPU 算力(cambricon.com/mlu.smlu.vcore):表示当前 Pod 需要使用核心的百分比数量。 + - GPU 显存(cambricon.com/mlu.smlu.vmemory):表示当前Pod需要使用显存的大小,单位是MB。 + + ![使用mlu](../images/mlu3.png) + +## 使用 YAML 配置 + +参考 YAML 文件如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: pod1 +spec: + restartPolicy: OnFailure + containers: + - image: ubuntu:16.04 + name: pod1-ctr + command: ["sleep"] + args: ["100000"] + resources: + limits: + cambricon.com/mlu: "1" # use this when device type is not enabled, else delete this line. + #cambricon.com/mlu: "1" #uncomment to use when device type is enabled + #cambricon.com/mlu.share: "1" #uncomment to use device with env-share mode + #cambricon.com/mlu.mim-2m.8gb: "1" #uncomment to use device with mim mode + #cambricon.com/mlu.smlu.vcore: "100" #uncomment to use device with mim mode + #cambricon.com/mlu.smlu.vmemory: "1024" #uncomment to use device with mim mode +``` diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/full_gpu_userguide.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/full_gpu_userguide.md new file mode 100644 index 0000000..e370255 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/full_gpu_userguide.md @@ -0,0 +1,67 @@ +# 应用使用 GPU 整卡 + +本节介绍如何在算丰 AI 算力平台将整个 NVIDIA GPU 卡分配给单个应用。 + +## 前提条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 当前集群已离线安装 GPU Operator 并已启用 NVIDIA DevicePlugin ,可参考 [GPU Operator 离线安装](install_nvidia_driver_of_operator.md)。 +- 当前集群内 GPU 卡未进行任何虚拟化操作或被其它应用占用。 + +## 操作步骤 + +### 使用 UI 界面配置 + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Nvidia GPU__ 。 + + ![集群设置](../../../../images/cluster-setting-gpu.jpg) + +2. 部署工作负载,点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Nvidia GPU)之后,需要配置应用使用的物理卡数量: + + **物理卡数量(nvidia.com/gpu)** :表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且 **小于等于** 宿主机上的卡数量。 + + ![集群设置](../../../../images/workload_gpu_userguide.jpg) + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 + +### 使用 YAML 配置 + +创建工作负载申请 GPU 资源,在资源申请和限制配置中增加 __nvidia.com/gpu: 1__ 参数配置应用使用物理卡的数量。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-gpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-gpu-demo + template: + metadata: + labels: + app: full-gpu-demo + spec: + containers: + - image: chrstnhntschl/gpu_burn + name: container-0 + resources: + requests: + cpu: 250m + memory: 512Mi + nvidia.com/gpu: 1 # 申请 GPU 的数量 + limits: + cpu: 250m + memory: 512Mi + nvidia.com/gpu: 1 # GPU 数量的使用上限 + imagePullSecrets: + - name: default-secret +``` + +!!! note + + 使用 __nvidia.com/gpu__ 参数指定 GPU 数量时,requests 和 limits 值需要保持一致。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md new file mode 100644 index 0000000..4af9f2f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md @@ -0,0 +1,65 @@ +# GPU 告警规则 + +本文介绍如何在算丰 AI 算力平台设置 GPU 相关的告警规则。 + +## 前置条件 + +- 集群节点上已正确安装 GPU 设备 +- 集群中已正确安装 [gpu-operator 组件](../install_nvidia_driver_of_operator.md) +- 如果用到了 vGPU 还需要在集群中安装 [Nvidia-vgpu 组件](../vgpu/vgpu_addon.md),并且开启 servicemonitor +- 集群正确安装了 insight-agent 组件 + +## 告警常用 GPU 指标 + +本节介绍 GPU 告警常用的指标,分为两个部分: + +- GPU 卡纬度的指标,主要反应单个 GPU 设备的运行状态。 +- 应用纬度的指标,主要反应 Pod 在 GPU 上的运行状态。 + +### GPU 卡指标 + +| 指标名称 | 指标单位 | 说明 | +| --- | --- | --- | +| DCGM_FI_DEV_GPU_UTIL | % | GPU 利用率 | +| DCGM_FI_DEV_MEM_COPY_UTIL | % | 显存利用率 | +| DCGM_FI_DEV_ENC_UTIL | % | 编码器利用率 | +| DCGM_FI_DEV_DEC_UTIL | % | 解码器利用率 | +| DCGM_FI_DEV_FB_FREE | MB | 表示显存剩余量 | +| DCGM_FI_DEV_FB_USED | MB | 表示显存使用量 | +| DCGM_FI_DEV_GPU_TEMP | 摄氏度 | 表示当前 GPU 的温度度数 | +| DCGM_FI_DEV_POWER_USAGE | W | 设备电源使用情况 | +| DCGM_FI_DEV_XID_ERRORS | - | 表示一段时间内,最后发生的 XID 错误号。XID 提供 GPU 硬件、NVIDIA 软件或应用中的错误类型、错误位置、错误代码等信息,更多 [XID 信息](./gpu-metrics.md#_2) | + +### 应用维度的指标 + +| 指标名称 | 指标单位 | 说明 | +| --- | --- | --- | +| kpanda_gpu_pod_utilization | % | 表示 Pod 对 GPU 的使用率 | +| kpanda_gpu_mem_pod_usage | MB | 表示 Pod 对 GPU 显存的使用量 | +| kpanda_gpu_mem_pod_utilization | % | 表示 Pod 对 GPU 显存的使用率 | + +## 设置告警规则 + +这里会介绍如何设置 GPU 告警规则,使用 GPU 卡利用率指标作为案例,请用户根据实际的业务场景选择指标以及编写 promql。 + +目标:当GPU卡利用率在五秒钟内一直保持 80% 的利用率时发出告警 + +1. 在可观测页面,点击 __告警__ -> __告警策略__ -> __创建告警策略__ + + ![创建告警规则](../../images/create-gpu-alarm.png) + +2. 填写基本信息 + + ![填写告警规则](../../images/gpu-alarm-details.png) + +3. 添加规则 + + ![填写告警规则2](../../images/gpu-alarm-details2.png) + +4. 选择通知方式 + + ![通知方式](../../images/gpu-alarm-message.png) + +5. 设置完成后,当一个 GPU 在 5s 内一直保持 80% 的利用率,会收到如下的告警信息。 + + ![告警信息](../../images/gpu-alarm-message2.png) diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md new file mode 100644 index 0000000..0ee5fd1 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md @@ -0,0 +1,96 @@ +# GPU 监控指标 + +本页列出一些常用的 GPU 监控指标。 + +## 集群维度 + +| 指标名称 | 描述 | +| ------- | ------ | +| GPU 卡数 | 集群下所有的 GPU 卡数量 | +| GPU 平均使用率 | 集群下所有 GPU 卡的平均算力使用率 | +| GPU 平均显存使用率 | 集群下所有 GPU 卡的平均显存使用率 | +| GPU 卡功率 | 集群下所有 GPU 卡的功率 | +| GPU 卡温度 | 集群下所有 GPU 卡的温度 | +| GPU 算力使用率细节 | 24 小时内,集群下所有 GPU 卡的使用率细节(包含 max、avg、current) | +| GPU 显存使用量细节 | 24 小时内,集群下所有 GPU 卡的显存使用量细节(包含 min、max、avg、current) | +| GPU 显存带宽使用率 | 表示内存带宽利用率。以 Nvidia GPU V100 为例,其最大内存带宽为 900 GB/sec,如果当前的内存带宽为 450 GB/sec,则内存带宽利用率为 50% | + +## 节点维度 + +| 指标名称 | 描述 | +| ------- | --- | +| GPU 模式 | 节点上 GPU 卡的使用模式,包含整卡模式、MIG 模式、vGPU 模式 | +| GPU 物理卡数 | 节点上所有的 GPU 卡数量 | +| GPU 虚拟卡数 | 节点上已经被创建出来的 vGPU 设备数量 | +| GPU MIG 实例数 | 节点上已经被创建出来的 MIG 实例数 | +| GPU 显存分配率 | 节点上所有 GPU 卡的显存分配率 | +| GPU 算力平均使用率 | 节点上所有 GPU 卡的算力平均使用率 | +| GPU 显存平均使用率 | 节点上所有 GPU 卡的平均显存使用率 | +| GPU 驱动版本 | 节点上 GPU 卡驱动的版本信息 | +| GPU 算力使用率细节 | 24 小时内,节点上每张 GPU 卡的算力使用率细节(包含 max、avg、current) | +| GPU 显存使用量 | 24 小时内,节点上每张 GPU 卡的显存使用量细节(包含 min、max、avg、current) | + +**根据 XID 状态排查 GPU 相关问题** + +XID 消息是 NVIDIA 驱动程序向操作系统的内核日志或事件日志打印的错误报告。XID 消息用于标识 GPU 错误事件, +提供 GPU 硬件、NVIDIA 软件或应用中的错误类型、错误位置、错误代码等信息。 +如检查项 GPU 节点上的 XID 异常为空,表明无 XID 消息;如有,您可按照下表自助排查并解决问题, +或查看[更多 XID 消息](https://docs.nvidia.com/deploy/xid-errors/index.html#topic_4)。 + +| XID | 消息 | 说明 | +| --- | --- | --- | +| 13 | Graphics Engine Exception. | 通常是数组越界、指令错误,小概率是硬件问题。 | +| 31 | GPU memory page fault. | 通常是应用程序的非法地址访问,极小概率是驱动或者硬件问题。 | +| 32 | Invalid or corrupted push buffer stream. | 事件由 PCIE 总线上管理 NVIDIA 驱动和 GPU 之间通信的 DMA 控制器上报,通常是 PCI 质量问题导致,而非您的程序产生。 | +| 38 | Driver firmware error. | 通常是驱动固件错误而非硬件问题。 | +| 43 | GPU stopped processing. | 通常是您应用自身错误,而非硬件问题。 | +| 45 | Preemptive cleanup, due to previous errors -- Most likely to see when running multiple cuda applications and hitting a DBE. | 通常是您手动退出或者其他故障(硬件、资源限制等)导致的 GPU 应用退出,XID 45 只提供一个结果,具体原因通常需要进一步分析日志。 | +| 48 | Double Bit ECC Error (DBE). | 当 GPU 发生不可纠正的错误时,会上报此事件,该错误也会同时反馈给您的应用程序。通常需要重置 GPU 或重启节点来清除这个错误。 | +| 61 | Internal micro-controller breakpoint/warning. | GPU 内部引擎停止工作,您的业务已经受到影响。 | +| 62 | Internal micro-controller halt. | 与 XID 61 的触发场景类似。 | +| 63 | ECC page retirement or row remapping recording event. | 当应用程序遭遇到 GPU 显存硬件错误时,NVIDIA 自纠错机制会将错误的内存区域 retire 或者 remap,retirement 和 remapped 信息需记录到 infoROM 中才能永久生效。Volt 架构:成功记录 ECC page retirement 事件到 infoROM。Ampere 架构:成功记录 row remapping 事件到 infoROM。 | +| 64 | ECC page retirement or row remapper recording failure. | 与 XID 63 的触发场景类似。但 XID 63 代表 retirement 和 remapped 信息成功记录到了 infoROM,XID 64 代表该记录操作失败。 | +| 68 | NVDEC0 Exception. | 通常是硬件或驱动问题。 | +| 74 | NVLINK Error. | NVLink 硬件错误产生的 XID,表明 GPU 已经出现严重硬件故障,需要下线维修。 | +| 79 | GPU has fallen off the bus. | GPU 硬件检测到掉卡,总线上无法检测该 GPU,表明该 GPU 已经出现严重硬件故障,需要下线维修。 | +| 92 | High single-bit ECC error rate. | 硬件或驱动故障。 | +| 94 | Contained ECC error. | 当应用程序遭遇到 GPU 不可纠正的显存 ECC 错误时,NVIDIA 错误抑制机制会尝试将错误抑制在发生硬件故障的应用程序,避免该错误影响 GPU 节点上运行的其他应用程序。当抑制机制成功抑制错误时,会产生该事件,仅出现不可纠正 ECC 错误的应用程序受到影响。 | +| 95 | Uncontained ECC error. | 与 XID 94 的触发场景类似。但 XID 94 代表抑制成功,而 XID 95 代表抑制失败,表明运行在该 GPU 上的所有应用程序都已受到影响。 | + +## Pod 维度 + +| 分类 | 指标名称 | 描述 | +| --- | ------- | ---- | +| 应用概览 GPU 卡 - 算力 & 显存 | Pod GPU 算力使用率 | 当前 Pod 所使用到的 GPU 卡的算力使用率 | +| | Pod GPU 显存使用率 | 当前 Pod 所使用到的 GPU 卡的显存使用率 | +| | Pod 显存使用量 | 当前 Pod 所使用到的 GPU 卡的显存使用量 | +| | 显存分配量 | 当前 Pod 所使用到的 GPU 卡的显存分配量 | +| | Pod GPU 显存复制使用率 | 当前 Pod 所使用到的 GPU 卡的显存显存复制比率 | +| GPU 卡 - 引擎概览 | GPU 图形引擎活动百分比 | 表示在一个监控周期内,Graphics 或 Compute 引擎处于 Active 的时间占总的时间的比例 | +| | GPU 内存带宽利用率 | 表示内存带宽利用率(Memory BW Utilization)将数据发送到设备内存或从设备内存接收数据的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。较高的值表示设备内存的利用率较高。
该值为 1(100%)表示在整个时间间隔内的每个周期执行一条 DRAM 指令(实际上,峰值约为 0.8 (80%) 是可实现的最大值)。
假设该值为 0.2(20%),表示 20% 的周期在时间间隔内读取或写入设备内存。 | +| | Tensor 核心引擎使用率 | 表示在一个监控周期内,Tensor Core 管道(Pipe)处于 Active 时间占总时间的比例 | +| | FP16 引擎使用率 | 表示在一个监控周期内,FP16 管道处于 Active 的时间占总的时间的比例 | +| | FP32 引擎使用率 | 表示在一个监控周期内,FP32 管道处于 Active 的时间占总的时间的比例 | +| | FP64 引擎使用率 | 表示在一个监控周期内,FP64 管道处于 Active 的时间占总的时间的比例 | +| | GPU 解码使用率 | GPU 卡解码引擎比率 | +| | GPU 编码使用率 | GPU 卡编码引擎比率 | +| GPU 卡 - 温度 & 功耗 | GPU 卡温度 | 集群下所有 GPU 卡的温度 | +| | GPU 卡功率 | 集群下所有 GPU 卡的功率 | +| | GPU 卡 - 总耗能 | GPU 卡总共消耗的能量 | +| GPU 卡 - Clock | GPU 卡内存频率 | 内存频率 | +| | GPU 卡应用SM 时钟频率 | 应用的 SM 时钟频率 | +| | GPU 卡应用内存频率 | 应用内存频率 | +| | GPU 卡视频引擎频率 | 视频引擎频率 | +| | GPU 卡降频原因 | 降频原因 | +| GPU 卡 - 其他细节 | 图形引擎活动 | 图形或计算引擎的任何部分处于活动状态的时间比例。如果图形/计算上下文已绑定且图形/计算管道繁忙,则图形引擎处于活动状态。该值表示时间间隔内的平均值,而不是瞬时值。 | +| | SM活动 | 多处理器上至少一个 Warp 处于活动状态的时间比例,所有多处理器的平均值。请注意,“活动”并不一定意味着 Warp 正在积极计算。例如,等待内存请求的 Warp 被视为活动状态。该值表示时间间隔内的平均值,而不是瞬时值。0.8 或更大的值是有效使用 GPU 的必要条件,但还不够。小于 0.5 的值可能表示 GPU 使用效率低下。给出一个简化的 GPU 架构视图,如果 GPU 有 N 个 SM,则使用 N 个块并在整个时间间隔内运行的内核将对应于活动 1(100%)。使用 N/5 个块并在整个时间间隔内运行的内核将对应于活动 0.2(20%)。使用 N 个块并运行五分之一时间间隔的内核,如果 SM 处于空闲状态,则活动也将为 0.2(20%)。该值与每个块的线程数无关(参见DCGM_FI_PROF_SM_OCCUPANCY)。 | +| | SM 入住率 | 多处理器上驻留 Warp 的比例,相对于多处理器上支持的最大并发 Warp 数。该值表示时间间隔内的平均值,而不是瞬时值。占用率越高并不一定表示 GPU 使用率越高。对于 GPU 内存带宽受限的工作负载(参见DCGM_FI_PROF_DRAM_ACTIVE),占用率越高表明 GPU 使用率越高。但是,如果工作负载是计算受限的(即不受 GPU 内存带宽或延迟限制),则占用率越高并不一定与 GPU 使用率越高相关。计算占用率并不简单,它取决于 GPU 属性、每个块的线程数、每个线程的寄存器以及每个块的共享内存等因素。使用[CUDA 占用率计算器](https://docs.nvidia.com/cuda/cuda-occupancy-calculator/index.html) 探索各种占用率场景。 | +| | 张量活动 | 张量 (HMMA / IMMA) 管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,张量核心的利用率越高。活动 1 (100%) 相当于在整个时间间隔内每隔一个周期发出一个张量指令。活动 0.2 (20%) 可能表示 20% 的 SM 在整个时间段内的利用率为 100%,100% 的 SM 在整个时间段内的利用率为 20%,100% 的 SM 在 20% 的时间段内的利用率为 100%,或者介于两者之间的任何组合(请参阅DCGM_FI_PROF_SM_ACTIVE以帮助消除这些可能性的歧义)。| +| | FP64 引擎活动 |FP64(双精度)管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,FP64 核心的利用率越高。活动量 1(100%)相当于整个时间间隔内 Volta 上[每四个周期的每个 SM](https://docs.nvidia.com/cuda/volta-tuning-guide/index.html#sm-scheduling)上执行一条 FP64 指令 。活动量 0.2(20%)可能表示 20% 的 SM 在整个时间段内利用率为 100%,100% 的 SM 在整个时间段内利用率为 20%,100% 的 SM 在 20% 的时间段内利用率为 100%,或者介于两者之间的任何组合(请参阅 DCGM_FI_PROF_SM_ACTIVE 以帮助消除这些可能性的歧义)。 | +| | FP32 引擎活动 | FMA(FP32(单精度)和整数)管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,FP32 核心的利用率越高。活动量 1(100%)相当于整个时间间隔内每隔一个周期执行一次 FP32 指令。活动量 0.2(20%)可能表示 20% 的 SM 在整个时间段内利用率为 100%,100% 的 SM 在整个时间段内利用率为 20%,100% 的 SM 在 20% 的时间段内利用率为 100%,或者两者之间的任何组合(请参阅DCGM_FI_PROF_SM_ACTIVE以帮助消除这些可能性的歧义)。 | +| | FP16 引擎活动 | FP16(半精度)管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,FP16 核心的利用率越高。活动量 1(100%)相当于整个时间间隔内每隔一个周期执行一次 FP16 指令。活动量 0.2(20%)可能表示 20% 的 SM 在整个时间段内利用率为 100%,100% 的 SM 在整个时间段内利用率为 20%,100% 的 SM 在 20% 的时间段内利用率为 100%,或者介于两者之间的任何组合(请参阅DCGM_FI_PROF_SM_ACTIVE以帮助消除这些可能性的歧义)。 | +| | 内存带宽利用率 | 向设备内存发送数据或从设备内存接收数据的周期比例。该值表示时间间隔内的平均值,而不是瞬时值。值越高,设备内存的利用率越高。活动率为 1 (100%) 相当于整个时间间隔内每个周期执行一条 DRAM 指令(实际上,峰值约为 0.8 (80%) 是可实现的最大值)。活动率为 0.2 (20%) 表示在时间间隔内有 20% 的周期正在读取或写入设备内存。 | +| | NVLink 带宽 | 通过 NVLink 传输/接收的数据速率(不包括协议标头),以每秒字节数为单位。该值表示一段时间内的平均值,而不是瞬时值。速率是一段时间内的平均值。例如,如果 1 秒内传输了 1 GB 的数据,则无论数据是以恒定速率还是突发速率传输,速率都是 1 GB/s。理论上,每个链路每个方向的最大 NVLink Gen2 带宽为 25 GB/s。 | +| | PCIe 带宽 | 通过 PCIe 总线传输/接收的数据速率,包括协议标头和数据有效负载,以字节/秒为单位。该值表示一段时间内的平均值,而不是瞬时值。该速率是一段时间内的平均值。例如,如果 1 秒内传输了 1 GB 的数据,则无论数据是以恒定速率还是突发速率传输,速率都是 1 GB/s。理论上最大 PCIe Gen3 带宽为每通道 985 MB/s。 | +| | PCIe 传输速率 | 节点 GPU 卡通过 PCIe 总线传输的数据速率 | +| | PCIe 接收速率 | 节点 GPU 卡通过 PCIe 总线接收的数据速率 | diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/index.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/index.md new file mode 100644 index 0000000..e2f495a --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/index.md @@ -0,0 +1,45 @@ +# NVIDIA GPU 卡使用模式 + +NVIDIA 作为业内知名的图形计算供应商,为算力的提升提供了诸多软硬件解决方案,其中 NVIDIA 在 GPU 的使用方式上提供了如下三种解决方案: + +#### 整卡(Full GPU) + +整卡是指将整个 NVIDIA GPU 分配给单个用户或应用程序。在这种配置下,应用可以完全占用 GPU 的所有资源, +并获得最大的计算性能。整卡适用于需要大量计算资源和内存的工作负载,如深度学习训练、科学计算等。 + +#### vGPU(Virtual GPU) + +vGPU 是一种虚拟化技术,允许将一个物理 GPU 划分为多个虚拟 GPU,每个虚拟 GPU 分配给不同的云主机或用户。 +vGPU 使多个用户可以共享同一台物理 GPU,并在各自的虚拟环境中独立使用 GPU 资源。 +每个虚拟 GPU 可以获得一定的计算能力和显存容量。vGPU 适用于虚拟化环境和云计算场景,可以提供更高的资源利用率和灵活性。 + +#### MIG(Multi-Instance GPU) + +MIG 是 NVIDIA Ampere 架构引入的一项功能,它允许将一个物理 GPU 划分为多个物理 GPU 实例,每个实例可以独立分配给不同的用户或工作负载。 +每个 MIG 实例具有自己的计算资源、显存和 PCIe 带宽,就像一个独立的虚拟 GPU。 +MIG 提供了更细粒度的 GPU 资源分配和管理,可以根据需求动态调整实例的数量和大小。 +MIG 适用于多租户环境、容器化应用程序和批处理作业等场景。 + +无论是在虚拟化环境中使用 vGPU,还是在物理 GPU 上使用 MIG,NVIDIA 为用户提供了更多的选择和优化 GPU 资源的方式。 +算丰 AI 算力容器管理平台全面兼容了上述 NVIDIA 的能力特性,用户只需通过简单的界面操作,就能够获得全部 NVIDIA GPU 的计算能力,从而提高资源利用率并降低成本。 + +- **Single 模式**,节点仅在其所有 GPU 上公开单一类型的 MIG 设备,节点上的所有 GPU 必须: + - 属于同一个型号(例如 A100-SXM-40GB),只有同一型号 GPU 的 MIG Profile 才是一样的 + - 启用 MIG 配置,需要重启机器才能生效 + - 为在所有产品中公开“完全相同”的 MIG 设备类型,创建相同的GI 和 CI +- **Mixed 模式**,节点在其所有 GPU 上公开混合 MIG 设备类型。请求特定的 MIG 设备类型需要设备类型提供的计算切片数量和内存总量。 + - 节点上的所有 GPU 必须:属于同一产品线(例如 A100-SXM-40GB) + - 每个 GPU 可启用或不启用 MIG,并且可以自由配置任何可用 MIG 设备类型的混合搭配。 + - 在节点上运行的 k8s-device-plugin 将: + - 使用传统的 __nvidia.com/gpu__ 资源类型公开任何不处于 MIG 模式的 GPU + - 使用遵循架构 __nvidia.com/mig-g.gb__ 的资源类型公开各个 MIG 设备 + +开启配置详情参考 [GPU Operator 离线安装](install_nvidia_driver_of_operator.md)。 + +## 如何使用 + +您可以参考以下链接,快速使用算丰 AI 算力平台关于 NVIDIA GPU 卡的管理能力。 + +- **[NVIDIA GPU 整卡使用](full_gpu_userguide.md)** +- **[NVIDIA vGPU 使用](vgpu/vgpu_user.md)** +- **[NVIDIA MIG 使用](mig/mig_usage.md)** diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md new file mode 100644 index 0000000..2f80028 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md @@ -0,0 +1,107 @@ +# GPU Operator 离线安装 + +算丰 AI 算力平台预置了 Ubuntu22.04、Ubuntu20.04、CentOS 7.9 这三个操作系统的 Driver 镜像,驱动版本是 535.104.12; +并且内置了各操作系统所需的 Toolkit 镜像,用户不再需要手动离线 Toolkit 镜像。 + +本文使用 AMD 架构的 CentOS 7.9(3.10.0-1160)进行演示。如需使用 Red Hat 8.4 部署, +请参考[向火种节点仓库上传 Red Hat GPU Opreator 离线镜像](./push_image_to_repo.md)和[构建 Red Hat 8.4 离线 yum 源](./upgrade_yum_source_redhat8_4.md)。 + +## 前提条件 + +- 待部署 gpu-operator 的集群节点内核版本必须完全一致。节点所在的发行版和 GPU 卡型号在 [GPU 支持矩阵](../gpu_matrix.md)的范围内。 +- 安装 gpu-operator 时选择 v23.9.0+2 及以上版本 + +## 操作步骤 + +参考如下步骤为集群安装 gpu-operator 插件。 + +1. 登录平台,进入 __容器管理__ -> __待安装 gpu-operator 的集群__ -> 进入集群详情。 + +2. 在 __Helm 模板__ 页面,选择 __全部仓库__ ,搜索 __gpu-operator__ 。 + +3. 选择 __gpu-operator__ ,点击 __安装__ 。 + +4. 参考下文参数配置,配置 __gpu-operator__ 安装参数,完成 __gpu-operator__ 的安装。 + +## 参数配置 + +- __systemOS__ :选择机器的操作系统,当前内置了 `Ubuntu 22.04`、`Ubuntu20.04`、`Centos7.9` 、`other` 四个选项,请正确的选择操作系统。 + +### 基本参数配置 + +- __名称__ :输入插件名称。 +- __命名空间__ :选择将插件安装的命名空间。 +- __版本__ :插件的版本,此处以 __v23.9.0+2__ 版本为例。 +- __失败删除__ :安装失败,则删除已经安装的关联资源。开启后,将默认同步开启 __就绪等待__ 。 +- __就绪等待__ :启用后,所有关联资源都处于就绪状态,才会标记应用安装成功。 +- __详情日志__ :开启后,将记录安装过程的详细日志。 + +### 高级参数配置 + +#### Operator 参数配置 + +- __InitContainer.image__ :配置 CUDA 镜像,推荐默认镜像: __nvidia/cuda__ +- __InitContainer.repository__ :CUDA 镜像所在的镜像仓库,默认为 __nvcr.m.daocloud.io__ 仓库 +- __InitContainer.version__ : CUDA 镜像的版本,请使用默认参数 + +#### Driver 参数配置 + +- __Driver.enable__ :配置是否在节点上部署 NVIDIA 驱动,默认开启,如果您在使用 GPU Operator 部署前,已经在节点上部署了 NVIDIA 驱动程序,请关闭。(若手动部署驱动程序需要关注 CUDA Toolkit 与 Toolkit Driver Version 的[适配关系](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#id5),通过 GPU operator 安装则无需关注)。 +- __Driver.usePrecompiled__ :启用预编译的GPU驱动 +- __Driver.image__ :配置 GPU 驱动镜像,推荐默认镜像: __nvidia/driver__ 。 +- __Driver.repository__ :GPU 驱动镜像所在的镜像仓库,默认为 nvidia 的 __nvcr.io__ 仓库。 +- __Driver.usePrecompiled__ :开启预编译模式安装驱动。 +- __Driver.version__ :GPU 驱动镜像的版本,离线部署请使用默认参数,仅在线安装时需配置。不同类型操作系统的 Driver 镜像的版本存在如下差异, + 详情可参考:[Nvidia GPU Driver 版本](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags)。 + 如下不同操作系统的 `Driver Version` 示例: + + !!! note + + 使用内置的操作系统版本无需修改镜像版本,其他操作系统版本请参考[向火种节点仓库上传镜像](./push_image_to_repo.md)。 + 注意版本号后无需填写 Ubuntu、CentOS、Red Hat 等操作系统名称,若官方镜像含有操作系统后缀,请手动移除。 + + - Red Hat 系统,例如 `525.105.17` + - Ubuntu 系统,例如 `535-5.15.0-1043-nvidia` + - CentOS 系统,例如 `525.147.05` + +- __Driver.RepoConfig.ConfigMapName__ :用来记录 GPU Operator 的离线 yum 源配置文件名称, + 当使用预置的离线包时,各类型的操作系统请参考如下的文档。 + + - [构建 CentOS 7.9 离线 yum 源](./upgrade_yum_source_centos7_9.md) + - [构建 Red Hat 8.4 离线 yum 源](./upgrade_yum_source_redhat8_4.md) + +#### Toolkit 配置参数 + +__Toolkit.enable__ :默认开启,该组件让 conatainerd/docker 支持运行需要 GPU 的容器。 + +#### MIG 配置参数 + +详细配置方式请参考[开启 MIG 功能](mig/create_mig.md) + +**MigManager.Config.name** :MIG 的切分配置文件名,用于定义 MIG 的(GI, CI)切分策略。 +默认为 __default-mig-parted-config__ 。自定义参数参考[开启 MIG 功能](mig/create_mig.md)。 + +### 下一步操作 + +完成上述相关参数配置和创建后: + +- 如果使用 **整卡模式**,[应用创建时可使用 GPU 资源](full_gpu_userguide.md) + +- 如果使用 **vGPU 模式** ,完成上述相关参数配置和创建后,下一步请完成 [vGPU Addon 安装](vgpu/vgpu_addon.md) + +- 如果使用 **MIG 模式**,并且需要给个别 GPU 节点按照某种切分规格进行使用, + 否则按照 `MigManager.Config` 中的 __default__ 值进行切分。 + + - **single** 模式请给对应节点打上如下 Label: + + ```sh + kubectl label nodes {node} nvidia.com/mig.config="all-1g.10gb" --overwrite + ``` + + - **mixed** 模式请给对应节点打上如下 Label: + + ```sh + kubectl label nodes {node} nvidia.com/mig.config="custom-config" --overwrite + ``` + +​ 切分后,应用可[使用 MIG GPU 资源](mig/mig_usage.md)。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/create_mig.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/create_mig.md new file mode 100644 index 0000000..07d0132 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/create_mig.md @@ -0,0 +1,124 @@ +# 开启 MIG 功能 + +本章节介绍如何开启 NVIDIA MIG 功能方式,NVIDIA 当前提供两种在 Kubernetes 节点上公开 MIG 设备的策略: + +- **Single 模式**,节点仅在其所有 GPU 上公开单一类型的 MIG 设备。 +- **Mixed 模式**,节点在其所有 GPU 上公开混合 MIG 设备类型。 + +详情参考 [NVIDIA GPU 卡使用模式](../index.md)。 + +## 前提条件 + +- 待安装 GPU 驱动节点系统要求请参考:[GPU 支持矩阵](../../gpu_matrix.md) +- 确认集群节点上具有对应型号的 GPU 卡([NVIDIA H100](https://www.nvidia.com/en-us/data-center/h100/)、 + [A100](https://www.nvidia.com/en-us/data-center/a100/) 和 + [A30](https://www.nvidia.com/en-us/data-center/products/a30-gpu/) Tensor Core GPU), + 详情参考 [GPU 支持矩阵](../../gpu_matrix.md)。 +- 节点上的所有 GPU 必须:属于同一产品线(例如 A100-SXM-40GB) + +## 安装 gpu-operator Addon + +### 参数配置 + +[安装 Operator](../install_nvidia_driver_of_operator.md) 时需要对应设置 MigManager Config 参数, +默认为 **default-mig-parted-config** ,同时也可以自定义切分策略配置文件: + +![single](../../images/gpu-operator-mig.png) + +### 自定义切分策略 + +```yaml + ## 自定义切分 GI 实例配置 + all-disabled: + - devices: all + mig-enabled: false + all-enabled: + - devices: all + mig-enabled: true + mig-devices: {} + all-1g.10gb: + - devices: all + mig-enabled: true + mig-devices: + 1g.5gb: 7 + all-1g.10gb.me: + - devices: all + mig-enabled: true + mig-devices: + 1g.10gb+me: 1 + all-1g.20gb: + - devices: all + mig-enabled: true + mig-devices: + 1g.20gb: 4 + all-2g.20gb: + - devices: all + mig-enabled: true + mig-devices: + 2g.20gb: 3 + all-3g.40gb: + - devices: all + mig-enabled: true + mig-devices: + 3g.40gb: 2 + all-4g.40gb: + - devices: all + mig-enabled: true + mig-devices: + 4g.40gb: 1 + all-7g.80gb: + - devices: all + mig-enabled: true + mig-devices: + 7g.80gb: 1 + all-balanced: + - device-filter: ["0x233110DE", "0x232210DE", "0x20B210DE", "0x20B510DE", "0x20F310DE", "0x20F510DE"] + devices: all + mig-enabled: true + mig-devices: + 1g.10gb: 2 + 2g.20gb: 1 + 3g.40gb: 1 + # 设置后会按照设置规格切分 CI 实例 + custom-config: + - devices: all + mig-enabled: true + mig-devices: + 3g.40gb: 2 +``` + +在上述的 **YAML** 中设置 **custom-config** ,设置后会按照规格切分 **CI** 实例。 + +```yaml +custom-config: + - devices: all + mig-enabled: true + mig-devices: + 1c.3g.40gb: 6 +``` + +设置完成后,在确认部署应用时即可[使用 GPU MIG 资源](mig_usage.md)。 + +## 切换节点 GPU 模式 + +!!! note + + 切换 GPU 模式或者修改切分规格后需要重启 nvidia-mig-manager。 + +当我们成功安装 gpu-operator 之后,节点默认是整卡模式,在节点管理页面会有标识,如下图所示: + +![mixed](../../images/node-gpu.png) + +点击节点列表右侧的 __┇__ ,选择 **GPU 模式切换** ,然后选择对应的 MIG 模式以及切分的策略,这里以 MIXED 模式为例: + +![mig](../../images/mig-select.png) + +这里一共有两个配置: + +1. MIg 策略:Mixed 以及 Single 。 +2. 切分策略:这里的策略需要与 **default-mig-parted-config** + (或者用户自定义的切分策略)配置文件中的 key 保持一致。 + +点击 **确定** 按钮后,等待约一分钟左右刷新页面,MIG 模式切换成: + +![切换 mig](../../images/node-mig.png) diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/index.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/index.md new file mode 100644 index 0000000..852b6b6 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/index.md @@ -0,0 +1,95 @@ +# NVIDIA 多实例 GPU(MIG) 概述 + +## MIG 场景 + +- **多租户云环境** + + MIG 允许云服务提供商将一块物理 GPU 划分为多个独立的 GPU 实例,每个实例可以独立分配给不同的租户。这样可以实现资源的隔离和独立性,满足多个租户对 GPU 计算能力的需求。 + +- **容器化应用程序** + + MIG 可以在容器化环境中实现更细粒度的 GPU 资源管理。通过将物理 GPU 划分为多个 MIG 实例,可以为每个容器分配独立的 GPU 计算资源,提供更好的性能隔离和资源利用。 + +- **批处理作业** + + 对于需要大规模并行计算的批处理作业,MIG 可以提供更高的计算性能和更大的显存容量。每个 MIG 实例可以利用物理 GPU 的一部分计算资源,从而加速大规模计算任务的处理。 + +- **AI/机器学习训练** + + MIG 可以在训练大规模深度学习模型时提供更大的计算能力和显存容量。将物理 GPU 划分为多个 MIG 实例,每个实例可以独立进行模型训练,提高训练效率和吞吐量。 + +总体而言,NVIDIA MIG 适用于需要更细粒度的GPU资源分配和管理的场景,可以实现资源的隔离、提高性能利用率,并且满足多个用户或应用程序对 GPU 计算能力的需求。 + +## MIG 概述 + +NVIDIA 多实例 GPU(Multi-Instance GPU,简称 MIG)是 NVIDIA 在 H100,A100,A30 系列 GPU 卡上推出的一项新特性, +旨在将一块物理 GPU 分割为多个 GPU 实例,以提供更细粒度的资源共享和隔离。MIG 最多可将一块 GPU 划分成七个 GPU 实例, +使得一个 物理 GPU 卡可为多个用户提供单独的 GPU 资源,以实现最佳 GPU 利用率。 + +这个功能使得多个应用程序或用户可以同时共享GPU资源,提高了计算资源的利用率,并增加了系统的可扩展性。 + +通过 MIG,每个 GPU 实例的处理器在整个内存系统中具有独立且隔离的路径——芯片上的交叉开关端口、L2 +高速缓存组、内存控制器和 DRAM 地址总线都唯一分配给单个实例。 + +这确保了单个用户的工作负载能够以可预测的吞吐量和延迟运行,并具有相同的二级缓存分配和 DRAM 带宽。 +MIG 可以划分可用的 GPU 计算资源(包括流多处理器或 SM 和 GPU 引擎,如复制引擎或解码器)进行分区, +以便为不同的客户端(如云主机、容器或进程)提供定义的服务质量(QoS)和故障隔离)。 +MIG 使多个 GPU 实例能够在单个物理 GPU 上并行运行。 + +MIG 允许多个 vGPU(以及云主机)在单个 GPU 实例上并行运行,同时保留 vGPU 提供的隔离保证。 +有关使用 vGPU 和 MIG 进行 GPU 分区的详细信息,请参阅 +[NVIDIA Multi-Instance GPU and NVIDIA Virtual Compute Server](https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/solutions/resources/documents1/TB-10226-001_v01.pdf)。 + +## MIG 架构 + +如下是一个 MIG 的概述图,可以看出 MIG 将一张物理 GPU 卡虚拟化成了 7 个 GPU 实例,这些 GPU 实例能够可以被多个 User 使用。 + +![img](../../../../../images/mig_overview.png) + +## 重要概念 + +* __SM__ :流式多处理器(Streaming Multiprocessor),GPU 的核心计算单元,负责执行图形渲染和通用计算任务。 + 每个 SM 包含一组 CUDA 核心,以及共享内存、寄存器文件和其他资源,可以同时执行多个线程。 + 每个 MIG 实例都拥有一定数量的 SM 和其他相关资源,以及被划分出来的显存。 +* __GPU Memory Slice__ :GPU 内存切片,GPU 内存切片是 GPU 内存的最小部分,包括相应的内存控制器和缓存。 + GPU 内存切片大约是 GPU 内存资源总量的八分之一,包括容量和带宽。 +* __GPU SM Slice__ :GPU SM 切片是 GPU 上 SM 的最小计算单位。在 MIG 模式下配置时, + GPU SM 切片大约是 GPU 中可用 SMS 总数的七分之一。 +* __GPU Slice__ :GPU 切片是 GPU 中由单个 GPU 内存切片和单个 GPU SM 切片组合在一起的最小部分。 +* __GPU Instance__ :GPU 实例 (GI) 是 GPU 切片和 GPU 引擎(DMA、NVDEC 等)的组合。 + GPU 实例中的任何内容始终共享所有 GPU 内存切片和其他 GPU 引擎,但它的 SM 切片可以进一步细分为计算实例(CI)。 + GPU 实例提供内存 QoS。每个 GPU 切片都包含专用的 GPU 内存资源,这些资源会限制可用容量和带宽,并提供内存 QoS。 + 每个 GPU 内存切片获得总 GPU 内存资源的八分之一,每个 GPU SM 切片获得 SM 总数的七分之一。 +* __Compute Instance__ :GPU 实例的计算切片可以进一步细分为多个计算实例 (CI),其中 CI 共享父 + GI 的引擎和内存,但每个 CI 都有专用的 SM 资源。 + +### GPU 实例(GI) + +本节介绍如何在 GPU 上创建各种分区。将使用 A100-40GB 作为示例演示如何对单个 GPU 物理卡上进行分区。 + +GPU 的分区是使用内存切片进行的,因此可以认为 A100-40GB GPU 具有 8x5GB 内存切片和 7 个 GPU SM 切片,如下图所示,展示了 A100 上可用的内存切片。 + +![img](../../../../../images/mig_7m.png) + +如上所述,创建 GPU 实例 (GI) 需要将一定数量的内存切片与一定数量的计算切片相结合。 +在下图中,一个 5GB 内存切片与 1 个计算切片相结合,以创建 __1g.5gb__ GI 配置文件: + +![img](../../../../../images/mig_1g5gb.png) + +同样,4x5GB 内存切片可以与 4x1 计算切片结合使用以创建 __4g.20gb__ 的 GI 配置文件: + +![img](../../../../../images/mig_4g20gb.png) + +### 计算实例(CI) + +GPU 实例的计算切片(GI)可以进一步细分为多个计算实例(CI),其中 CI 共享父 GI 的引擎和内存, +但每个 CI 都有专用的 SM 资源。使用上面的相同 __4g.20gb__ 示例,可以创建一个 CI 以仅使用第一个计算切片的 __1c.4g.20gb__ 计算配置,如下图蓝色部分所示: + +![img](../../../../../images/mig_1c.4g.20gb.png) + +在这种情况下,可以通过选择任何计算切片来创建 4 个不同的 CI。还可以将两个计算切片组合在一起以创建 __2c.4g.20gb__ 的计算配置): + +![img](../../../../../images/mig2c.4g.20gb.png) + +除此之外,还可以组合 3 个计算切片以创建计算配置文件,或者可以组合所有 4 个计算切片以创建 __3c.4g.20gb__ 、 __4c.4g.20gb__ 计算配置文件。 +合并所有 4 个计算切片时,配置文件简称为 __4g.20gb__ 。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/mig_command.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/mig_command.md new file mode 100644 index 0000000..d42cda7 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/mig_command.md @@ -0,0 +1,25 @@ +# MIG 相关命令 + +GI 相关命名: + +| 子命令 | 说明 | +| --------------------------------------- | ----------------------------- | +| nvidia-smi mig -lgi | 查看创建 GI 实例列表 | +| nvidia-smi mig -dgi -gi {Instance ID} | 删除指定的 GI 实例 | +| nvidia-smi mig -lgip | 查看 GI 的 __profile__ | +| nvidia-smi mig -cgi {profile id} | 通过指定 profile 的 ID 创建 GI | + +CI 相关命令: + +| 子命令 | 说明 | +| ------------------------------------------------------- | ------------------------------------------------------------ | +| nvidia-smi mig -lcip { -gi {gi Instance ID}} | 查看 CI 的 __profile__ ,指定 __-gi__ 可以查看特定 GI 实例可以创建的 CI | +| nvidia-smi mig -lci | 查看创建的 CI 实例列表 | +| nvidia-smi mig -cci {profile id} -gi {gi instance id} | 指定的 GI 创建 CI 实例 | +| nvidia-smi mig -dci -ci {ci instance id} | 删除指定 CI 实例 | + +GI+CI 相关命令: + +| 子命令 | 说明 | +| ------------------------------------------------------------ | -------------------- | +| nvidia-smi mig -i 0 -cgi {gi profile id} -C {ci profile id} | 直接创建 GI + CI 实例 | diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/mig_usage.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/mig_usage.md new file mode 100644 index 0000000..4b00ee6 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/mig/mig_usage.md @@ -0,0 +1,100 @@ +# 使用 MIG GPU 资源 + +本节介绍应用如何使用 MIG GPU 资源。 + +## 前提条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../../../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../../../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已安装 [GPU Operator](../install_nvidia_driver_of_operator.md)。 +- 集群节点上具有[对应型号的 GPU 卡](../../gpu_matrix.md) + +## UI 界面使用 MIG GPU + +1. 确认集群是否已识别 GPU 卡类型 + + 进入 __集群详情__ -> __节点管理__ ,查看是否已正确识别为 MIG 模式。 + + ![gpu](../../images/node-mig.png) + +2. 通过镜像部署应用,可选择并使用 NVIDIA MIG 资源。 + + - MIG Single 模式示例(与整卡使用方式相同): + + !!! note + + MIG single 策略允许用户以与 GPU 整卡相同的方式(`nvidia.com/gpu`)请求和使用GPU资源,不同的是这些资源可以是 GPU 的一部分(MIG设备),而不是整个GPU。了解更多 [GPU MIG 模式设计](../../../../../images/edit) + + ![usemig](../../images/usemig.png) + + - MIG Mixed 模式示例: + + ![mig02](../../images/pod-mig.png) + +## YAML 配置使用 MIG + +**MIG Single 模式:** + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mig-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: mig-demo + template: + metadata: + creationTimestamp: null + labels: + app: mig-demo + spec: + containers: + - name: mig-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/gpu: 2 # (1)! + imagePullPolicy: Always + restartPolicy: Always +``` + +1. 申请 MIG GPU 的数量 + +**MIG Mixed 模式:** + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mig-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: mig-demo + template: + metadata: + creationTimestamp: null + labels: + app: mig-demo + spec: + containers: + - name: mig-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/mig-4g.20gb: 1 # (1)! + imagePullPolicy: Always + restartPolicy: Always +``` + +1. 通过 nvidia.com/mig-g.gb 的资源类型公开各个 MIG 设备 + +进入容器后可以查看只使用了一个 MIG 设备。 + +![mig03](../../../../../images/gpu_mig03.png) diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/push_image_to_repo.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/push_image_to_repo.md new file mode 100644 index 0000000..d406b14 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/push_image_to_repo.md @@ -0,0 +1,89 @@ +# 向火种节点仓库上传 Red Hat GPU Opreator 离线镜像 + +本文以 Red Hat 8.4 的 `nvcr.io/nvidia/driver:525.105.17-rhel8.4` 离线驱动镜像为例,介绍如何向火种节点仓库上传离线镜像。 + +## 前提条件 + +1. 火种节点及其组件状态运行正常。 +1. 准备一个能够访问互联网和火种节点的节点,且节点上已经完成 + Docker 的安装。 + +## 操作步骤 + +### 在联网节点获取离线镜像 + +以下操作在联网节点上进行。 + +1. 在联网机器上拉取 `nvcr.io/nvidia/driver:525.105.17-rhel8.4` 离线驱动镜像: + + ```bash + docker pull nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +2. 镜像拉取完成后,打包镜像为 `nvidia-driver.tar` 压缩包: + + ```bash + docker save nvcr.io/nvidia/driver:525.105.17-rhel8.4 > nvidia-driver.tar + ``` + +3. 拷贝 `nvidia-driver.tar` 镜像压缩包到火种节点: + + ```bash + scp nvidia-driver.tar user@ip:/root + ``` + + 例如: + + ```bash + scp nvidia-driver.tar root@10.6.175.10:/root + ``` + +### 推送镜像到火种节点仓库 + +以下操作在火种节点上进行。 + +1. 登录火种节点,将联网节点拷贝的镜像压缩包 `nvidia-driver.tar` 导入本地: + + ```bash + docker load -i nvidia-driver.tar + ``` + +2. 查看刚刚导入的镜像: + + ```bash + docker images -a |grep nvidia + ``` + + 预期输出: + + ```bash + nvcr.io/nvidia/driver e3ed7dee73e9 1 days ago 1.02GB + ``` + +3. 重新标记镜像,使其与远程 Registry 仓库中的目标仓库对应: + + ```bash + docker tag /: + ``` + + - `` 是上一步 nvidia 镜像的名称, + - `` 是火种节点上 Registry 服务的地址, + - `` 是您要推送到的仓库名称, + - `` 是您为镜像指定的标签。 + + 例如: + + ```bash + registry:docker tag nvcr.io/nvidia/driver 10.6.10.5/nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +4. 将镜像推送到火种节点镜像仓库: + + ```bash + docker push {ip}/nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +## 接下来 + +参考[构建 Red Hat 8.4 离线 yum 源](./upgrade_yum_source_redhat8_4.md)和 +[GPU Operator 离线安装](./install_nvidia_driver_of_operator.md)来为集群部署 GPU Operator。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md new file mode 100644 index 0000000..d0504a2 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md @@ -0,0 +1,861 @@ +# RHEL 9.2 离线安装 gpu-operator 驱动 + +前提条件:已安装 gpu-operator v23.9.0+2 及更高版本 + +RHEL 9.2 驱动镜像不能直接安装,官方的驱动脚本存在一点问题,在官方修复之前,提供如下的步骤来实现离线安装驱动。 + +## 禁用nouveau驱动 + +在 RHEL 9.2 中存在 `nouveau` 非官方的 `Nvidia` 驱动,因此需要先禁用。 + +```shell +# 创建一个新的文件 +sudo vi /etc/modprobe.d/blacklist-nouveau.conf +# 添加以下两行内容: +blacklist nouveau +options nouveau modeset=0 +# 禁用Nouveau +sudo dracut --force +# 重启vm +sudo reboot +# 检查是否已经成功禁用 +lsmod | grep nouveau +``` + +## 自定义驱动镜像 + +先在本地创建 `nvidia-driver` 文件: + +
+点击查看完整的 nvidia-driver 文件内容 + +```shell +#! /bin/bash -x +# Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + +set -eu + +RUN_DIR=/run/nvidia +PID_FILE=${RUN_DIR}/${0##*/}.pid +DRIVER_VERSION=${DRIVER_VERSION:?"Missing DRIVER_VERSION env"} +KERNEL_UPDATE_HOOK=/run/kernel/postinst.d/update-nvidia-driver +NUM_VGPU_DEVICES=0 +NVIDIA_MODULE_PARAMS=() +NVIDIA_UVM_MODULE_PARAMS=() +NVIDIA_MODESET_MODULE_PARAMS=() +NVIDIA_PEERMEM_MODULE_PARAMS=() +TARGETARCH=${TARGETARCH:?"Missing TARGETARCH env"} +USE_HOST_MOFED="${USE_HOST_MOFED:-false}" +DNF_RELEASEVER=${DNF_RELEASEVER:-""} +RHEL_VERSION=${RHEL_VERSION:-""} +RHEL_MAJOR_VERSION=9 + +OPEN_KERNEL_MODULES_ENABLED=${OPEN_KERNEL_MODULES_ENABLED:-false} +[[ "${OPEN_KERNEL_MODULES_ENABLED}" == "true" ]] && KERNEL_TYPE=kernel-open || KERNEL_TYPE=kernel + +DRIVER_ARCH=${TARGETARCH/amd64/x86_64} && DRIVER_ARCH=${DRIVER_ARCH/arm64/aarch64} +echo "DRIVER_ARCH is $DRIVER_ARCH" + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source $SCRIPT_DIR/common.sh + +_update_package_cache() { + if [ "${PACKAGE_TAG:-}" != "builtin" ]; then + echo "Updating the package cache..." + if ! yum -q makecache; then + echo "FATAL: failed to reach RHEL package repositories. "\ + "Ensure that the cluster can access the proper networks." + exit 1 + fi + fi +} + +_cleanup_package_cache() { + if [ "${PACKAGE_TAG:-}" != "builtin" ]; then + echo "Cleaning up the package cache..." + rm -rf /var/cache/yum/* + fi +} + +_get_rhel_version_from_kernel() { + local rhel_version_underscore rhel_version_arr + rhel_version_underscore=$(echo "${KERNEL_VERSION}" | sed 's/.*el\([0-9]\+_[0-9]\+\).*/\1/g') + # For e.g. :- from the kernel version 4.18.0-513.9.1.el8_9, we expect to extract the string "8_9" + if [[ ! ${rhel_version_underscore} =~ ^[0-9]+_[0-9]+$ ]]; then + echo "Unable to resolve RHEL version from kernel version" >&2 + return 1 + fi + IFS='_' read -r -a rhel_version_arr <<< "$rhel_version_underscore" + if [[ ${#rhel_version_arr[@]} -ne 2 ]]; then + echo "Unable to resolve RHEL version from kernel version" >&2 + return 1 + fi + RHEL_VERSION="${rhel_version_arr[0]}.${rhel_version_arr[1]}" + echo "RHEL VERSION successfully resolved from kernel: ${RHEL_VERSION}" + return 0 +} + +_resolve_rhel_version() { + _get_rhel_version_from_kernel || RHEL_VERSION="${RHEL_MAJOR_VERSION}" + # set dnf release version as rhel version by default + if [[ -z "${DNF_RELEASEVER}" ]]; then + DNF_RELEASEVER="${RHEL_VERSION}" + fi + return 0 +} + +# Resolve the kernel version to the form major.minor.patch-revision. +_resolve_kernel_version() { + echo "Resolving Linux kernel version..." + local version=$(yum -q list available --showduplicates kernel-headers | + awk -v arch=$(uname -m) 'NR>1 {print $2"."arch}' | tac | grep -E -m1 "^${KERNEL_VERSION/latest/.*}") + + if [ -z "${version}" ]; then + echo "Could not resolve Linux kernel version" >&2 + return 1 + fi + KERNEL_VERSION="${version}" + echo "Proceeding with Linux kernel version ${KERNEL_VERSION}" + return 0 +} + +# Install the kernel modules header/builtin/order files and generate the kernel version string. +_install_prerequisites() ( + local tmp_dir=$(mktemp -d) + + trap "rm -rf ${tmp_dir}" EXIT + cd ${tmp_dir} + + echo "Installing elfutils..." + if ! dnf install -q -y elfutils-libelf.$DRIVER_ARCH; then + echo "FATAL: failed to install elfutils packages. RHEL entitlement may be improperly deployed." + exit 1 + fi + if ! dnf install -q -y elfutils-libelf-devel.$DRIVER_ARCH; then + echo "FATAL: failed to install elfutils packages. RHEL entitlement may be improperly deployed." + exit 1 + fi + + rm -rf /lib/modules/${KERNEL_VERSION} + mkdir -p /lib/modules/${KERNEL_VERSION}/proc + + echo "Enabling RHOCP and EUS RPM repos..." + if [ -n "${OPENSHIFT_VERSION:-}" ]; then + dnf config-manager --set-enabled rhocp-${OPENSHIFT_VERSION}-for-rhel-9-$DRIVER_ARCH-rpms || true + if ! dnf makecache --releasever=${DNF_RELEASEVER}; then + dnf config-manager --set-disabled rhocp-${OPENSHIFT_VERSION}-for-rhel-9-$DRIVER_ARCH-rpms || true + fi + fi + + dnf config-manager --set-enabled rhel-9-for-$DRIVER_ARCH-baseos-eus-rpms || true + if ! dnf makecache --releasever=${DNF_RELEASEVER}; then + dnf config-manager --set-disabled rhel-9-for-$DRIVER_ARCH-baseos-eus-rpms || true + fi + + # try with EUS disabled, if it does not work, then try just major version + if ! dnf makecache --releasever=${DNF_RELEASEVER}; then + # If pointing to DNF_RELEASEVER does not work, we point to the RHEL_MAJOR_VERSION as a last resort + if ! dnf makecache --releasever=${RHEL_MAJOR_VERSION}; then + echo "FATAL: failed to update the dnf metadata cache after multiple attempts with releasevers ${DNF_RELEASEVER}, ${RHEL_MAJOR_VERSION}" + exit 1 + else + DNF_RELEASEVER=${RHEL_MAJOR_VERSION} + fi + fi + + echo "Installing Linux kernel headers..." + dnf -q -y --releasever=${DNF_RELEASEVER} install kernel-headers-${KERNEL_VERSION} kernel-devel-${KERNEL_VERSION} --allowerasing > /dev/null + ln -s /usr/src/kernels/${KERNEL_VERSION} /lib/modules/${KERNEL_VERSION}/build + + echo "Installing Linux kernel module files..." + dnf -q -y --releasever=${DNF_RELEASEVER} install kernel-core-${KERNEL_VERSION} > /dev/null + + # Prevent depmod from giving a WARNING about missing files + touch /lib/modules/${KERNEL_VERSION}/modules.order + touch /lib/modules/${KERNEL_VERSION}/modules.builtin + + depmod ${KERNEL_VERSION} + + echo "Generating Linux kernel version string..." + if [ "$TARGETARCH" = "arm64" ]; then + gunzip -c /lib/modules/${KERNEL_VERSION}/vmlinuz | strings | grep -E '^Linux version' | sed 's/^\(.*\)\s\+(.*)$/\1/' > version + else + extract-vmlinux /lib/modules/${KERNEL_VERSION}/vmlinuz | strings | grep -E '^Linux version' | sed 's/^\(.*\)\s\+(.*)$/\1/' > version + fi + if [ -z "$(&2 + return 1 + fi + mv version /lib/modules/${KERNEL_VERSION}/proc + + # Parse gcc version + # gcc_version is expected to match x.y.z + # current_gcc is expected to match 'gcc-x.y.z-rel.el8.x86_64 + local gcc_version=$(cat /lib/modules/${KERNEL_VERSION}/proc/version | grep -Eo "gcc \(GCC\) ([0-9\.]+)" | grep -Eo "([0-9\.]+)") + local current_gcc=$(rpm -qa gcc) + echo "kernel requires gcc version: 'gcc-${gcc_version}', current gcc version is '${current_gcc}'" + + if ! [[ "${current_gcc}" =~ "gcc-${gcc_version}"-.* ]]; then + dnf install -q -y --releasever=${DNF_RELEASEVER} "gcc-${gcc_version}" + fi +) + +# Cleanup the prerequisites installed above. +_remove_prerequisites() { + true + if [ "${PACKAGE_TAG:-}" != "builtin" ]; then + dnf -q -y remove kernel-headers-${KERNEL_VERSION} kernel-devel-${KERNEL_VERSION} > /dev/null + # TODO remove module files not matching an existing driver package. + fi +} + +# Check if the kernel version requires a new precompiled driver packages. +_kernel_requires_package() { + local proc_mount_arg="" + + echo "Checking NVIDIA driver packages..." + + [[ ! -d /usr/src/nvidia-${DRIVER_VERSION}/${KERNEL_TYPE} ]] && return 0 + cd /usr/src/nvidia-${DRIVER_VERSION}/${KERNEL_TYPE} + + proc_mount_arg="--proc-mount-point /lib/modules/${KERNEL_VERSION}/proc" + for pkg_name in $(ls -d -1 precompiled/** 2> /dev/null); do + is_match=$(../mkprecompiled --match ${pkg_name} ${proc_mount_arg}) + if [ "${is_match}" == "kernel interface matches." ]; then + echo "Found NVIDIA driver package ${pkg_name##*/}" + return 1 + fi + done + return 0 +} + +# Compile the kernel modules, optionally sign them, and generate a precompiled package for use by the nvidia-installer. +_create_driver_package() ( + local pkg_name="nvidia-modules-${KERNEL_VERSION%%-*}${PACKAGE_TAG:+-${PACKAGE_TAG}}" + local nvidia_sign_args="" + local nvidia_modeset_sign_args="" + local nvidia_uvm_sign_args="" + + trap "make -s -j ${MAX_THREADS} SYSSRC=/lib/modules/${KERNEL_VERSION}/build clean > /dev/null" EXIT + + echo "Compiling NVIDIA driver kernel modules..." + cd /usr/src/nvidia-${DRIVER_VERSION}/${KERNEL_TYPE} + + if _gpu_direct_rdma_enabled; then + ln -s /run/mellanox/drivers/usr/src/ofa_kernel /usr/src/ + # if arch directory exists(MOFED >=5.5) then create a symlink as expected by GPU driver installer + # This is required as currently GPU driver installer doesn't expect headers in x86_64 folder, but only in either default or kernel-version folder. + # ls -ltr /usr/src/ofa_kernel/ + # lrwxrwxrwx 1 root root 36 Dec 8 20:10 default -> /etc/alternatives/ofa_kernel_headers + # drwxr-xr-x 4 root root 4096 Dec 8 20:14 x86_64 + # lrwxrwxrwx 1 root root 44 Dec 9 19:05 5.4.0-90-generic -> /usr/src/ofa_kernel/x86_64/5.4.0-90-generic/ + if [[ -d "/run/mellanox/drivers/usr/src/ofa_kernel/$(uname -m)/$(uname -r)" ]]; then + if [[ ! -e "/usr/src/ofa_kernel/$(uname -r)" ]]; then + ln -s "/run/mellanox/drivers/usr/src/ofa_kernel/$(uname -m)/$(uname -r)" /usr/src/ofa_kernel/ + fi + fi + fi + + make -s -j ${MAX_THREADS} SYSSRC=/lib/modules/${KERNEL_VERSION}/build nv-linux.o nv-modeset-linux.o > /dev/null + + echo "Relinking NVIDIA driver kernel modules..." + rm -f nvidia.ko nvidia-modeset.ko + ld -d -r -o nvidia.ko ./nv-linux.o ./nvidia/nv-kernel.o_binary + ld -d -r -o nvidia-modeset.ko ./nv-modeset-linux.o ./nvidia-modeset/nv-modeset-kernel.o_binary + + if [ -n "${PRIVATE_KEY}" ]; then + echo "Signing NVIDIA driver kernel modules..." + donkey get ${PRIVATE_KEY} sh -c "PATH=${PATH}:/usr/src/linux-headers-${KERNEL_VERSION}/scripts && \ + sign-file sha512 \$DONKEY_FILE pubkey.x509 nvidia.ko nvidia.ko.sign && \ + sign-file sha512 \$DONKEY_FILE pubkey.x509 nvidia-modeset.ko nvidia-modeset.ko.sign && \ + sign-file sha512 \$DONKEY_FILE pubkey.x509 nvidia-uvm.ko" + nvidia_sign_args="--linked-module nvidia.ko --signed-module nvidia.ko.sign" + nvidia_modeset_sign_args="--linked-module nvidia-modeset.ko --signed-module nvidia-modeset.ko.sign" + nvidia_uvm_sign_args="--signed" + fi + + echo "Building NVIDIA driver package ${pkg_name}..." + ../mkprecompiled --pack ${pkg_name} --description ${KERNEL_VERSION} \ + --proc-mount-point /lib/modules/${KERNEL_VERSION}/proc \ + --driver-version ${DRIVER_VERSION} \ + --kernel-interface nv-linux.o \ + --linked-module-name nvidia.ko \ + --core-object-name nvidia/nv-kernel.o_binary \ + ${nvidia_sign_args} \ + --target-directory . \ + --kernel-interface nv-modeset-linux.o \ + --linked-module-name nvidia-modeset.ko \ + --core-object-name nvidia-modeset/nv-modeset-kernel.o_binary \ + ${nvidia_modeset_sign_args} \ + --target-directory . \ + --kernel-module nvidia-uvm.ko \ + ${nvidia_uvm_sign_args} \ + --target-directory . + mkdir -p precompiled + mv ${pkg_name} precompiled +) + +_assert_nvswitch_system() { + [ -d /proc/driver/nvidia-nvswitch ] || return 1 + entries=$(ls -1 /proc/driver/nvidia-nvswitch/devices/*) + if [ -z "${entries}" ]; then + return 1 + fi + return 0 +} + +# For each kernel module configuration file mounted into the container, +# parse the file contents and extract the custom module parameters that +# are to be passed as input to 'modprobe'. +# +# Assumptions: +# - Configuration files are named .conf (i.e. nvidia.conf, nvidia-uvm.conf). +# - Configuration files are mounted inside the container at /drivers. +# - Each line in the file contains at least one parameter, where parameters on the same line +# are space delimited. It is up to the user to properly format the file to ensure +# the correct set of parameters are passed to 'modprobe'. +_get_module_params() { + local base_path="/drivers" + # nvidia + if [ -f "${base_path}/nvidia.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia.conf" + echo "Module parameters provided for nvidia: ${NVIDIA_MODULE_PARAMS[@]}" + fi + # nvidia-uvm + if [ -f "${base_path}/nvidia-uvm.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_UVM_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia-uvm.conf" + echo "Module parameters provided for nvidia-uvm: ${NVIDIA_UVM_MODULE_PARAMS[@]}" + fi + # nvidia-modeset + if [ -f "${base_path}/nvidia-modeset.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_MODESET_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia-modeset.conf" + echo "Module parameters provided for nvidia-modeset: ${NVIDIA_MODESET_MODULE_PARAMS[@]}" + fi + # nvidia-peermem + if [ -f "${base_path}/nvidia-peermem.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_PEERMEM_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia-peermem.conf" + echo "Module parameters provided for nvidia-peermem: ${NVIDIA_PEERMEM_MODULE_PARAMS[@]}" + fi +} + +# Load the kernel modules and start persistenced. +_load_driver() { + echo "Parsing kernel module parameters..." + _get_module_params + + local nv_fw_search_path="$RUN_DIR/driver/lib/firmware" + local set_fw_path="true" + local fw_path_config_file="/sys/module/firmware_class/parameters/path" + for param in "${NVIDIA_MODULE_PARAMS[@]}"; do + if [[ "$param" == "NVreg_EnableGpuFirmware=0" ]]; then + set_fw_path="false" + fi + done + + if [[ "$set_fw_path" == "true" ]]; then + echo "Configuring the following firmware search path in '$fw_path_config_file': $nv_fw_search_path" + if [[ ! -z $(grep '[^[:space:]]' $fw_path_config_file) ]]; then + echo "WARNING: A search path is already configured in $fw_path_config_file" + echo " Retaining the current configuration" + else + echo -n "$nv_fw_search_path" > $fw_path_config_file || echo "WARNING: Failed to configure the firmware search path" + fi + fi + + echo "Loading ipmi and i2c_core kernel modules..." + modprobe -a i2c_core ipmi_msghandler ipmi_devintf + + echo "Loading NVIDIA driver kernel modules..." + set -o xtrace +o nounset + modprobe nvidia "${NVIDIA_MODULE_PARAMS[@]}" + modprobe nvidia-uvm "${NVIDIA_UVM_MODULE_PARAMS[@]}" + modprobe nvidia-modeset "${NVIDIA_MODESET_MODULE_PARAMS[@]}" + set +o xtrace -o nounset + + if _gpu_direct_rdma_enabled; then + echo "Loading NVIDIA Peer Memory kernel module..." + set -o xtrace +o nounset + modprobe -a nvidia-peermem "${NVIDIA_PEERMEM_MODULE_PARAMS[@]}" + set +o xtrace -o nounset + fi + + echo "Starting NVIDIA persistence daemon..." + nvidia-persistenced --persistence-mode + + if [ "${DRIVER_TYPE}" = "vgpu" ]; then + echo "Copying gridd.conf..." + cp /drivers/gridd.conf /etc/nvidia/gridd.conf + if [ "${VGPU_LICENSE_SERVER_TYPE}" = "NLS" ]; then + echo "Copying ClientConfigToken..." + mkdir -p /etc/nvidia/ClientConfigToken/ + cp /drivers/ClientConfigToken/* /etc/nvidia/ClientConfigToken/ + fi + + echo "Starting nvidia-gridd.." + LD_LIBRARY_PATH=/usr/lib64/nvidia/gridd nvidia-gridd + + # Start virtual topology daemon + _start_vgpu_topology_daemon + fi + + if _assert_nvswitch_system; then + echo "Starting NVIDIA fabric manager daemon..." + nv-fabricmanager -c /usr/share/nvidia/nvswitch/fabricmanager.cfg + fi +} + +# Stop persistenced and unload the kernel modules if they are currently loaded. +_unload_driver() { + local rmmod_args=() + local nvidia_deps=0 + local nvidia_refs=0 + local nvidia_uvm_refs=0 + local nvidia_modeset_refs=0 + local nvidia_peermem_refs=0 + + echo "Stopping NVIDIA persistence daemon..." + if [ -f /var/run/nvidia-persistenced/nvidia-persistenced.pid ]; then + local pid=$(< /var/run/nvidia-persistenced/nvidia-persistenced.pid) + + kill -SIGTERM "${pid}" + for i in $(seq 1 50); do + kill -0 "${pid}" 2> /dev/null || break + sleep 0.1 + done + if [ $i -eq 50 ]; then + echo "Could not stop NVIDIA persistence daemon" >&2 + return 1 + fi + fi + + if [ -f /var/run/nvidia-gridd/nvidia-gridd.pid ]; then + echo "Stopping NVIDIA grid daemon..." + local pid=$(< /var/run/nvidia-gridd/nvidia-gridd.pid) + + kill -SIGTERM "${pid}" + for i in $(seq 1 10); do + kill -0 "${pid}" 2> /dev/null || break + sleep 0.1 + done + if [ $i -eq 10 ]; then + echo "Could not stop NVIDIA Grid daemon" >&2 + return 1 + fi + fi + + if [ -f /var/run/nvidia-fabricmanager/nv-fabricmanager.pid ]; then + echo "Stopping NVIDIA fabric manager daemon..." + local pid=$(< /var/run/nvidia-fabricmanager/nv-fabricmanager.pid) + + kill -SIGTERM "${pid}" + for i in $(seq 1 50); do + kill -0 "${pid}" 2> /dev/null || break + sleep 0.1 + done + if [ $i -eq 50 ]; then + echo "Could not stop NVIDIA fabric manager daemon" >&2 + return 1 + fi + fi + + echo "Unloading NVIDIA driver kernel modules..." + if [ -f /sys/module/nvidia_modeset/refcnt ]; then + nvidia_modeset_refs=$(< /sys/module/nvidia_modeset/refcnt) + rmmod_args+=("nvidia-modeset") + ((++nvidia_deps)) + fi + if [ -f /sys/module/nvidia_uvm/refcnt ]; then + nvidia_uvm_refs=$(< /sys/module/nvidia_uvm/refcnt) + rmmod_args+=("nvidia-uvm") + ((++nvidia_deps)) + fi + if [ -f /sys/module/nvidia/refcnt ]; then + nvidia_refs=$(< /sys/module/nvidia/refcnt) + rmmod_args+=("nvidia") + fi + if [ -f /sys/module/nvidia_peermem/refcnt ]; then + nvidia_peermem_refs=$(< /sys/module/nvidia_peermem/refcnt) + rmmod_args+=("nvidia-peermem") + ((++nvidia_deps)) + fi + if [ ${nvidia_refs} -gt ${nvidia_deps} ] || [ ${nvidia_uvm_refs} -gt 0 ] || [ ${nvidia_modeset_refs} -gt 0 ] || [ ${nvidia_peermem_refs} -gt 0 ]; then + echo "Could not unload NVIDIA driver kernel modules, driver is in use" >&2 + return 1 + fi + + if [ ${#rmmod_args[@]} -gt 0 ]; then + rmmod ${rmmod_args[@]} + fi + return 0 +} + +# Link and install the kernel modules from a precompiled package using the nvidia-installer. +_install_driver() { + local install_args=() + + echo "Installing NVIDIA driver kernel modules..." + cd /usr/src/nvidia-${DRIVER_VERSION} + rm -rf /lib/modules/${KERNEL_VERSION}/video + + if [ "${ACCEPT_LICENSE}" = "yes" ]; then + install_args+=("--accept-license") + fi + IGNORE_CC_MISMATCH=1 nvidia-installer --kernel-module-only --no-drm --ui=none --no-nouveau-check -m=${KERNEL_TYPE} ${install_args[@]+"${install_args[@]}"} + # May need to add no-cc-check for Rhel, otherwise it complains about cc missing in path + # /proc/version and lib/modules/KERNEL_VERSION/proc are different, by default installer looks at /proc/ so, added the proc-mount-point + # TODO: remove the -a flag. its not needed. in the new driver version, license-acceptance is implicit + #nvidia-installer --kernel-module-only --no-drm --ui=none --no-nouveau-check --no-cc-version-check --proc-mount-point /lib/modules/${KERNEL_VERSION}/proc ${install_args[@]+"${install_args[@]}"} +} + +# Mount the driver rootfs into the run directory with the exception of sysfs. +_mount_rootfs() { + echo "Mounting NVIDIA driver rootfs..." + mount --make-runbindable /sys + mount --make-private /sys + mkdir -p ${RUN_DIR}/driver + mount --rbind / ${RUN_DIR}/driver + + echo "Check SELinux status" + if [ -e /sys/fs/selinux ]; then + echo "SELinux is enabled" + echo "Change device files security context for selinux compatibility" + chcon -R -t container_file_t ${RUN_DIR}/driver/dev + else + echo "SELinux is disabled, skipping..." + fi +} + +# Unmount the driver rootfs from the run directory. +_unmount_rootfs() { + echo "Unmounting NVIDIA driver rootfs..." + if findmnt -r -o TARGET | grep "${RUN_DIR}/driver" > /dev/null; then + umount -l -R ${RUN_DIR}/driver + fi +} + +# Write a kernel postinst.d script to automatically precompile packages on kernel update (similar to DKMS). +_write_kernel_update_hook() { + if [ ! -d ${KERNEL_UPDATE_HOOK%/*} ]; then + return + fi + + echo "Writing kernel update hook..." + cat > ${KERNEL_UPDATE_HOOK} <<'EOF' +#!/bin/bash + +set -eu +trap 'echo "ERROR: Failed to update the NVIDIA driver" >&2; exit 0' ERR + +NVIDIA_DRIVER_PID=$(< /run/nvidia/nvidia-driver.pid) + +export "$(grep -z DRIVER_VERSION /proc/${NVIDIA_DRIVER_PID}/environ)" +nsenter -t "${NVIDIA_DRIVER_PID}" -m -- nvidia-driver update --kernel "$1" +EOF + chmod +x ${KERNEL_UPDATE_HOOK} +} + +_shutdown() { + if _unload_driver; then + _unmount_rootfs + rm -f ${PID_FILE} ${KERNEL_UPDATE_HOOK} + return 0 + fi + return 1 +} + +_find_vgpu_driver_version() { + local count="" + local version="" + local drivers_path="/drivers" + + if [ "${DISABLE_VGPU_VERSION_CHECK}" = "true" ]; then + echo "vgpu version compatibility check is disabled" + return 0 + fi + # check if vgpu devices are present + count=$(vgpu-util count) + if [ $? -ne 0 ]; then + echo "cannot find vgpu devices on host, pleae check /var/log/vgpu-util.log for more details..." + return 0 + fi + NUM_VGPU_DEVICES=$(echo "$count" | awk -F= '{print $2}') + if [ $NUM_VGPU_DEVICES -eq 0 ]; then + # no vgpu devices found, treat as passthrough + return 0 + fi + echo "found $NUM_VGPU_DEVICES vgpu devices on host" + + # find compatible guest driver using driver catalog + if [ -d "/mnt/shared-nvidia-driver-toolkit/drivers" ]; then + drivers_path="/mnt/shared-nvidia-driver-toolkit/drivers" + fi + version=$(vgpu-util match -i "${drivers_path}" -c "${drivers_path}/vgpuDriverCatalog.yaml") + if [ $? -ne 0 ]; then + echo "cannot find match for compatible vgpu driver from available list, please check /var/log/vgpu-util.log for more details..." + return 1 + fi + DRIVER_VERSION=$(echo "$version" | awk -F= '{print $2}') + echo "vgpu driver version selected: ${DRIVER_VERSION}" + return 0 +} + +_start_vgpu_topology_daemon() { + type nvidia-topologyd > /dev/null 2>&1 || return 0 + echo "Starting nvidia-topologyd.." + nvidia-topologyd +} + +_prepare() { + if [ "${DRIVER_TYPE}" = "vgpu" ]; then + _find_vgpu_driver_version || exit 1 + fi + + # Install the userspace components and copy the kernel module sources. + sh NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION.run -x && \ + cd NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION && \ + sh /tmp/install.sh nvinstall && \ + mkdir -p /usr/src/nvidia-$DRIVER_VERSION && \ + mv LICENSE mkprecompiled ${KERNEL_TYPE} /usr/src/nvidia-$DRIVER_VERSION && \ + sed '9,${/^\(kernel\|LICENSE\)/!d}' .manifest > /usr/src/nvidia-$DRIVER_VERSION/.manifest + + echo -e "\n========== NVIDIA Software Installer ==========\n" + echo -e "Starting installation of NVIDIA driver version ${DRIVER_VERSION} for Linux kernel version ${KERNEL_VERSION}\n" +} + +_prepare_exclusive() { + _prepare + + exec 3> ${PID_FILE} + if ! flock -n 3; then + echo "An instance of the NVIDIA driver is already running, aborting" + exit 1 + fi + echo $$ >&3 + + trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM + trap "_shutdown" EXIT + + _unload_driver || exit 1 + _unmount_rootfs +} + +_build() { + # Install dependencies + if _kernel_requires_package; then + _update_package_cache + _install_prerequisites + _create_driver_package + #_remove_prerequisites + _cleanup_package_cache + fi + + # Build the driver + _install_driver +} + +_load() { + _load_driver + _mount_rootfs + _write_kernel_update_hook + + echo "Done, now waiting for signal" + sleep infinity & + trap "echo 'Caught signal'; _shutdown && { kill $!; exit 0; }" HUP INT QUIT PIPE TERM + trap - EXIT + while true; do wait $! || continue; done + exit 0 +} + +init() { + _prepare_exclusive + + _build + + _load +} + +build() { + _prepare + + _build +} + +load() { + _prepare_exclusive + + _load +} + +update() { + exec 3>&2 + if exec 2> /dev/null 4< ${PID_FILE}; then + if ! flock -n 4 && read pid <&4 && kill -0 "${pid}"; then + exec > >(tee -a "/proc/${pid}/fd/1") + exec 2> >(tee -a "/proc/${pid}/fd/2" >&3) + else + exec 2>&3 + fi + exec 4>&- + fi + exec 3>&- + + # vgpu driver version is chosen dynamically during runtime, so pre-compile modules for + # only non-vgpu driver types + if [ "${DRIVER_TYPE}" != "vgpu" ]; then + # Install the userspace components and copy the kernel module sources. + if [ ! -e /usr/src/nvidia-${DRIVER_VERSION}/mkprecompiled ]; then + sh NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION.run -x && \ + cd NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION && \ + sh /tmp/install.sh nvinstall && \ + mkdir -p /usr/src/nvidia-$DRIVER_VERSION && \ + mv LICENSE mkprecompiled ${KERNEL_TYPE} /usr/src/nvidia-$DRIVER_VERSION && \ + sed '9,${/^\(kernel\|LICENSE\)/!d}' .manifest > /usr/src/nvidia-$DRIVER_VERSION/.manifest + fi + fi + + echo -e "\n========== NVIDIA Software Updater ==========\n" + echo -e "Starting update of NVIDIA driver version ${DRIVER_VERSION} for Linux kernel version ${KERNEL_VERSION}\n" + + trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM + + _update_package_cache + _resolve_kernel_version || exit 1 + _install_prerequisites + if _kernel_requires_package; then + _create_driver_package + fi + _remove_prerequisites + _cleanup_package_cache + + echo "Done" + exit 0 +} + +# Wait for MOFED drivers to be loaded and load nvidia-peermem whenever it gets unloaded during MOFED driver updates +reload_nvidia_peermem() { + if [ "$USE_HOST_MOFED" = "true" ]; then + until lsmod | grep mlx5_core > /dev/null 2>&1 && [ -f /run/nvidia/validations/.driver-ctr-ready ]; + do + echo "waiting for mellanox ofed and nvidia drivers to be installed" + sleep 10 + done + else + # use driver readiness flag created by MOFED container + until [ -f /run/mellanox/drivers/.driver-ready ] && [ -f /run/nvidia/validations/.driver-ctr-ready ]; + do + echo "waiting for mellanox ofed and nvidia drivers to be installed" + sleep 10 + done + fi + # get any parameters provided for nvidia-peermem + _get_module_params && set +o nounset + if chroot /run/nvidia/driver modprobe nvidia-peermem "${NVIDIA_PEERMEM_MODULE_PARAMS[@]}"; then + if [ -f /sys/module/nvidia_peermem/refcnt ]; then + echo "successfully loaded nvidia-peermem module, now waiting for signal" + sleep inf + trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM + fi + fi + echo "failed to load nvidia-peermem module" + exit 1 +} + +# probe by gpu-operator for liveness/startup checks for nvidia-peermem module to be loaded when MOFED drivers are ready +probe_nvidia_peermem() { + if lsmod | grep mlx5_core > /dev/null 2>&1; then + if [ ! -f /sys/module/nvidia_peermem/refcnt ]; then + echo "nvidia-peermem module is not loaded" + return 1 + fi + else + echo "MOFED drivers are not ready, skipping probe to avoid container restarts..." + fi + return 0 +} + +usage() { + cat >&2 < + +使用官方的镜像来二次构建自定义镜像,如下是一个 `Dockerfile` 文件的内容: + +```dockerfile +FROM nvcr.io/nvidia/driver:535.183.06-rhel9.2 +COPY nvidia-driver /usr/local/bin +RUN chmod +x /usr/local/bin/nvidia-driver +CMD ["/bin/bash", "-c"] +``` + +构建命令并推送到火种集群: + +```bash +docker build -t {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535.183.06-01-rhel9.2 -f Dockerfile . +docker push {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535.183.06-01-rhel9.2 +``` + +## 安装驱动 + +1. 安装 gpu-operator addon +2. 设置 `driver.version=535.183.06-01` diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md new file mode 100644 index 0000000..49dee9b --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md @@ -0,0 +1,36 @@ +# Ubuntu22.04 离线安装 gpu-operator 驱动 + +前提条件:已安装 gpu-operator v23.9.0+2 及更高版本 + +## 准备离线镜像 + +1. 查看内核版本 + + ```bash + $ uname -r + 5.15.0-78-generic + ``` + +1. 查看内核对应的 GPU Driver 镜像版本, + `https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags`。 + 使用内核查询镜像版本,通过 `ctr export` 保存镜像。 + + ```bash + ctr i pull nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ctr i export --all-platforms driver.tar.gz nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ``` + +1. 把镜像导入到火种集群的镜像仓库中 + + ```bash + ctr i import driver.tar.gz + ctr i tag nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ctr i push {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 --skip-verify=true + ``` + +## 安装驱动 + +1. 安装 gpu-operator addon +2. 若使用预编译模式,则设置 `driver.usePrecompiled=true`,并设置 `driver.version=535`,这里要注意,写的是 535,不是 535.104.12。(非预编译模式跳过此步,直接安装即可) + +![安装驱动](../images/driver.jpg) diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/upgrade_yum_source_centos7_9.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/upgrade_yum_source_centos7_9.md new file mode 100644 index 0000000..c87f4dd --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/upgrade_yum_source_centos7_9.md @@ -0,0 +1,248 @@ +# 构建 CentOS 7.9 离线 yum 源 + +## 使用场景介绍 + +当工作节点的内核版本与全局服务集群的控制节点内核版本或 OS 类型不一致时,需要用户手动构建离线 yum 源。 + +本文介绍如何构建离线 yum 源, 并在安装 Gpu Operator 时,通过 `RepoConfig.ConfigMapName` 参数来使用。 + +## 前提条件 + +1. 用户已经在平台上安装了 v0.12.0 及以上版本的 addon 离线包。 +1. 准备一个能够和待部署 GPU Operator 的集群网络能够联通的文件服务器,如 nginx 或 minio。 +1. 准备一个能够访问互联网、待部署 GPU Operator 的集群和文件服务器的节点, + 且节点上已经完成 Docker 的安装。 + +## 操作步骤 + +本文以内核版本为 `3.10.0-1160.95.1.el7.x86_64` 的 CentOS 7.9 节点为例,介绍如何构建 GPU operator 离线包的 yum 源。 + +### 检查集群节点的 OS 和内核版本 + +分别在全局服务集群的控制节点和待部署 GPU Operator 的节点执行如下命令,若两个节点的 OS 和内核版本一致则无需构建 yum 源, +可参考[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 文档直接安装;若两个节点的 OS 或内核版本不一致,请执行[下一步](#yum)。 + +1. 执行如下命令,查看集群下待部署 GPU Operator 节点的发行版名称和版本号。 + + ```bash + cat /etc/redhat-release + ``` + + 预期输出如下: + + ```console + CentOS Linux release 7.9 (Core) + ``` + + 输出结果为当前节点内核版本 `CentOS 7.9` 。 + +2. 执行如下命令,查看集群下待部署 GPU Operator 节点的内核版本。 + + ```bash + uname -a + ``` + + 预期输出如下: + + ```console + Linux localhost.localdomain 3.10.0-1160.95.1.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux + ``` + + 输出结果为当前节点内核版本 `3.10.0-1160.el7.x86_64`。 + +### 制作离线 yum 源 + +在一个能够访问互联网和文件服务器的节点上进行操作。 + +1. 在一个能够访问互联网和文件服务器的节点上执行如下命令新建一个名为 __yum.sh__ 的脚本文件。 + + ```bash + vi yum.sh + ``` + + 然后按下 **i** 键进入插入模式,输入以下内容: + + ```bash + export TARGET_KERNEL_VERSION=$1 + + cat >> run.sh << \EOF + #! /bin/bash + echo "start install kernel repo" + echo ${KERNEL_VERSION} + mkdir centos-base + + if [ "$OS" -eq 7 ]; then + yum install --downloadonly --downloaddir=./centos-base perl + yum install --downloadonly --downloaddir=./centos-base elfutils-libelf.x86_64 + yum install --downloadonly --downloaddir=./redhat-base elfutils-libelf-devel.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-headers-${KERNEL_VERSION}.el7.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-devel-${KERNEL_VERSION}.el7.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-${KERNEL_VERSION}.el7.x86_64 + yum install -y --downloadonly --downloaddir=./centos-base groff-base + elif [ "$OS" -eq 8 ]; then + yum install --downloadonly --downloaddir=./centos-base perl + yum install --downloadonly --downloaddir=./centos-base elfutils-libelf.x86_64 + yum install --downloadonly --downloaddir=./redhat-base elfutils-libelf-devel.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-headers-${KERNEL_VERSION}.el8.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-devel-${KERNEL_VERSION}.el8.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-${KERNEL_VERSION}.el8.x86_64 + yum install -y --downloadonly --downloaddir=./centos-base groff-base + else + echo "Error os version" + fi + + createrepo centos-base/ + ls -lh centos-base/ + tar -zcf centos-base.tar.gz centos-base/ + echo "end install kernel repo" + EOF + + cat >> Dockerfile << EOF + FROM centos:7 + ENV KERNEL_VERSION="" + ENV OS=7 + RUN yum install -y createrepo + COPY run.sh . + ENTRYPOINT ["/bin/bash","run.sh"] + EOF + + docker build -t test:v1 -f Dockerfile . + docker run -e KERNEL_VERSION=$TARGET_KERNEL_VERSION --name centos7.9 test:v1 + docker cp centos7.9:/centos-base.tar.gz . + tar -xzf centos-base.tar.gz + ``` + + 按下 __esc__ 键退出插入模式,然后输入 __ :wq__ 保存并退出。 + +2. 运行 __yum.sh__ 文件: + + ```bash + bash -x yum.sh TARGET_KERNEL_VERSION + ``` + + `TARGET_KERNEL_VERSION` 参数用于指定集群节点的内核版本,注意:发行版标识符(如 __ .el7.x86_64 __ )无需输入。 + 例如: + + ```bash + bash -x yum.sh 3.10.0-1160.95.1 + ``` + +至此,您已经生成了内核为 __3.10.0-1160.95.1.el7.x86_64__ 的离线的 yum 源: __centos-base__ 。 + +### 上传离线 yum 源到文件服务器 + +在一个能够访问互联网和文件服务器的节点上进行操作。主要用于将上一步中生成的 yum +源上传到可以被待部署 GPU Operator 的集群进行访问的文件服务器中。 +文件服务器可以为 Nginx 、 Minio 或其它支持 Http 协议的文件服务器。 + +本操作示例采用的是算丰 AI 算力平台火种节点内置的 Minio 作为文件服务器,Minio 相关信息如下: + +- 访问地址: `http://10.5.14.200:9000(一般为{火种节点 IP} + {9000 端口})` +- 登录用户名:rootuser +- 登录密码:rootpass123 + +1. 在节点当前路径下,执行如下命令将节点本地 mc 命令行工具和 minio 服务器建立链接。 + + ```bash + mc config host add minio http://10.5.14.200:9000 rootuser rootpass123 + ``` + + 预期输出如下: + + ```bash + Added `minio` successfully. + ``` + + mc 命令行工具是 Minio 文件服务器提供的客户端命令行工具,详情请参考: + [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html)。 + +2. 在节点当前路径下,新建一个名为 __centos-base__ 的存储桶(bucket)。 + + ```bash + mc mb -p minio/centos-base + ``` + + 预期输出如下: + + ```bash + Bucket created successfully __minio/centos-base__ . + ``` + +3. 将存储桶 __centos-base__ 的访问策略设置为允许公开下载。以便在后期安装 GPU-operator 时能够被访问。 + + ```bash + mc anonymous set download minio/centos-base + ``` + + 预期输出如下: + + ```bash + Access permission for `minio/centos-base` is set to `download` + ``` + +4. 在节点当前路径下,将步骤二生成的离线 yum 源文件 __centos-base__ 复制到 minio 服务器的 __minio/centos-base__ 存储桶中。 + + ```bash + mc cp centos-base minio/centos-base --recursive + ``` + +### 在集群创建配置项用来保存 yum 源信息 + +在待部署 GPU Operator 集群的控制节点上进行操作。 + +1. 执行如下命令创建名为 __CentOS-Base.repo__ 的文件,用来指定 yum 源存储的配置信息。 + + ```bash + # 文件名称必须为 CentOS-Base.repo,否则安装 gpu-operator 时无法被识别 + cat > CentOS-Base.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/centos-base/centos-base #步骤三中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/centos-base/centos-base #步骤三中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. 基于创建的 __CentOS-Base.repo__ 文件,在 gpu-operator 命名空间下,创建名为 __local-repo-config__ 的配置文件: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=CentOS-Base.repo=/etc/yum.repos.d/extension.repo + ``` + + 预期输出如下: + + ```console + configmap/local-repo-config created + ``` + + __local-repo-config__ 配置文件用于在安装 gpu-operator 时,提供 `RepoConfig.ConfigMapName` 参数的值,配置文件名称用户可自定义。 + +3. 查看 __local-repo-config__ 的配置文件的内容: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + + 预期输出如下: + + ```yaml + apiVersion: v1 + data: + CentOS-Base.repo: "[extension-0]\nbaseurl = http://10.6.232.5:32618/centos-base#步骤二中,放置 yum 源的文件服务器路径\ngpgcheck = 0\nname = kubean extension 0\n \n[extension-1]\nbaseurl + = http://10.6.232.5:32618/centos-base #步骤二中,放置 yum 源的文件服务器路径\ngpgcheck = 0\nname + = kubean extension 1\n" + kind: ConfigMap + metadata: + creationTimestamp: "2023-10-18T01:59:02Z" + name: local-repo-config + namespace: gpu-operator + resourceVersion: "59445080" + uid: c5f0ebab-046f-442c-b932-f9003e014387 + ``` + +至此,您已成功为待部署 GPU Operator 的集群创建了离线 yum 源配置文件。 +通过在[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 时通过 `RepoConfig.ConfigMapName` 参数来使用。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md new file mode 100644 index 0000000..0294059 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md @@ -0,0 +1,217 @@ +# 构建 Red Hat 8.4 离线 yum 源 + +算丰 AI 算力平台预置了 CentOS 7.9,内核为 3.10.0-1160 的 GPU operator 离线包。其它 OS 类型的节点或内核需要用户手动构建离线 yum 源。 + +本文介绍如何基于全局服务集群任意节点构建 Red Hat 8.4 离线 yum 源包,并在安装 Gpu Operator 时,通过 `RepoConfig.ConfigMapName` 参数来使用。 + +## 前提条件 + +1. 用户已经在平台上安装了 v0.12.0 及以上版本的 addon 离线包。 +2. 待部署 GPU Operator 的集群节点 OS 必须为 Red Hat 8.4,且内核版本完全一致。 +3. 准备一个能够和待部署 GPU Operator 的集群网络能够联通的文件服务器,如 nginx 或 minio。 +4. 准备一个能够访问互联网、待部署 GPU Operator 的集群和文件服务器的节点,且节点上已经完成 + Docker 的安装。 +5. 全局服务集群的节点必须为 Red Hat 8.4 4.18.0-305.el8.x86_64。 + +## 操作步骤 + +本文以 Red Hat 8.4 4.18.0-305.el8.x86_64 节点为例,介绍如何基于全局服务集群任意节点构建 Red Hat 8.4 离线 yum 源包, +并在安装 Gpu Operator 时,通过 `RepoConfig.ConfigMapName` 参数来使用。 + +### 下载火种节点中的 yum 源 + +以下操作在全局服务集群的 master 节点上执行。 + +1. 使用 ssh 或其它方式进入全局服务集群内任一节点执行如下命令: + + ```bash + cat /etc/yum.repos.d/extension.repo #查看 extension.repo 中的内容 + ``` + + 预期输出如下: + + ```ini + [extension-0] + baseurl = http://10.5.14.200:9000/kubean/redhat/$releasever/os/$basearch + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/kubean/redhat-iso/$releasever/os/$basearch/AppStream + gpgcheck = 0 + name = kubean extension 1 + + [extension-2] + baseurl = http://10.5.14.200:9000/kubean/redhat-iso/$releasever/os/$basearch/BaseOS + gpgcheck = 0 + name = kubean extension 2 + ``` + +2. 在 __root__ 路径下新建一个名为 __redhat-base-repo__ 的文件夹 + + ```bash + mkdir redhat-base-repo + ``` + +3. 下载 yum 源中的 rpm 包到本地: + + ```bash + yum install yum-utils + ``` + +4. 下载 extension-1 中的 rpm 包: + + ```bash + reposync -p redhat-base-repo -n --repoid=extension-1 + ``` + +5. 下载 extension-2 中的 rpm 包: + + ```bash + reposync -p redhat-base-repo -n --repoid=extension-2 + ``` + +### 下载 elfutils-libelf-devel-0.187-4.el8.x86_64.rpm 包 + +以下操作在联网节点执行操作,在操作前,您需要保证联网节点和全局服务集群 master 节点间的网络联通性。 + +1. 在联网节点执行如下命令,下载 __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ 包: + + ```bash + wget https://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/elfutils-libelf-devel-0.187-4.el8.x86_64.rpm + ``` + +2. 在当前目录下将 __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ 包传输至步骤一中的节点上: + + ```bash + scp elfutils-libelf-devel-0.187-4.el8.x86_64.rpm user@ip:~/redhat-base-repo/extension-2/Packages/ + ``` + + 例如: + + ```bash + scp elfutils-libelf-devel-0.187-4.el8.x86_64.rpm root@10.6.175.10:~/redhat-base-repo/extension-2/Packages/ + ``` + +### 生成本地 yum repo + +以下操作在步骤一中全局服务集群的 master 节点上执行。 + +1. 进入 yum repo 目录: + + ```bash + cd ~/redhat-base-repo/extension-1/Packages + cd ~/redhat-base-repo/extension-2/Packages + ``` + +2. 生成目录 repo 索引: + + ```bash + yum install createrepo -y # 若已安装 createrepo 可省略此步骤 + createrepo_c ./ + ``` + +至此,您已经生成了内核为 `4.18.0-305.el8.x86_64` 的离线的 yum 源: __redhat-base-repo__ 。 + +### 将本地生成的 yum repo 上传至文件服务器 + +本操作示例采用的是算丰 AI 算力平台火种节点内置的 Minio 作为文件服务器,用户可基于自身情况选择文件服务器。Minio 相关信息如下: + +- 访问地址: `http://10.5.14.200:9000(一般为{火种节点 IP} + {9000 端口})` +- 登录用户名:rootuser +- 登录密码:rootpass123 + +1. 在节点当前路径下,执行如下命令将节点本地 mc 命令行工具和 minio 服务器建立链接。 + + ```bash + mc config host add minio 文件服务器访问地址 用户名 密码 + ``` + + 例如: + + ```bash + mc config host add minio http://10.5.14.200:9000 rootuser rootpass123 + ``` + + 预期输出如下: + + ```console + Added `minio` successfully. + ``` + + mc 命令行工具是 Minio 文件服务器提供的客户端命令行工具,详情请参考: + [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html)。 + +2. 在节点当前路径下,新建一个名为 __redhat-base__ 的存储桶(bucket)。 + + ```bash + mc mb -p minio/redhat-base + ``` + + 预期输出如下: + + ```console + Bucket created successfully `minio/redhat-base`. + ``` + +3. 将存储桶 __redhat-base__ 的访问策略设置为允许公开下载。以便在后期安装 GPU-operator 时能够被访问。 + + ```bash + mc anonymous set download minio/redhat-base + ``` + + 预期输出如下: + + ```console + Access permission for `minio/redhat-base` is set to `download` + ``` + +4. 在节点当前路径下,将步骤二生成的离线 yum 源文件 __redhat-base-repo__ 复制到 minio 服务器的 __minio/redhat-base__ 存储桶中。 + + ```bash + mc cp redhat-base-repo minio/redhat-base --recursive + ``` + +### 在集群创建配置项用来保存 yum 源信息 + +本步骤在待部署 GPU Operator 集群的控制节点上进行操作。 + +1. 执行如下命令创建名为 __redhat.repo__ 的文件,用来指定 yum 源存储的配置信息。 + + ```bash + # 文件名称必须为 redhat.repo,否则安装 gpu-operator 时无法被识别 + cat > redhat.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/redhat-base/redhat-base-repo/Packages #步骤一中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/redhat-base/redhat-base-repo/Packages #步骤一中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. 基于创建的 __redhat.repo__ 文件,在 gpu-operator 命名空间下,创建名为 __local-repo-config__ 的配置文件: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=./redhat.repo + ``` + + 预期输出如下: + + ``` + configmap/local-repo-config created + ``` + + __local-repo-config__ 配置文件用于在安装 gpu-operator 时,提供 `RepoConfig.ConfigMapName` 参数的值,配置文件名称用户可自定义。 + +3. 查看 __local-repo-config__ 的配置文件的内容: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + +至此,您已成功为待部署 GPU Operator 的集群创建了离线 yum 源配置文件。 +通过在[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 时通过 `RepoConfig.ConfigMapName` 参数来使用。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/hami.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/hami.md new file mode 100644 index 0000000..d164395 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/hami.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 构建 vGPU 显存超配镜像 + +[Hami 项目](https://github.com/Project-HAMi/HAMi)中 vGPU 显存超配的功能已经不存在,目前使用有显存超配的 `libvgpu.so` 文件重新构建。 + +```bash title="Dockerfile" +FROM docker.m.daocloud.io/projecthami/hami:v2.3.11 +COPY libvgpu.so /k8s-vgpu/lib/nvidia/ +``` + +执行以下命令构建镜像: + +```bash +docker build -t release.daocloud.io/projecthami/hami:v2.3.11 -f Dockerfile . +``` + +然后把镜像 push 到 `release.daocloud.io` 中。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/vgpu_addon.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/vgpu_addon.md new file mode 100644 index 0000000..72706e8 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/vgpu_addon.md @@ -0,0 +1,42 @@ +# 安装 NVIDIA vGPU Addon + +如需将一张 NVIDIA 虚拟化成多个虚拟 GPU,并将其分配给不同的云主机或用户,您可以使用 NVIDIA 的 vGPU 能力。 +本节介绍如何在算丰 AI 算力平台中安装 vGPU 插件,这是使用 NVIDIA vGPU 能力的前提。 +## 前提条件 + +- 参考 [GPU 支持矩阵](../../gpu_matrix.md) 确认集群节点上具有对应型号的 GPU 卡。 +- 当前集群已通过 Operator 部署 NVIDIA 驱动,具体参考 [GPU Operator 离线安装](../install_nvidia_driver_of_operator.md)。 + +## 操作步骤 + +1. 功能模块路径: __容器管理__ -> __集群管理__ ,点击目标集群的名称,从左侧导航栏点击 __Helm 应用__ -> __Helm 模板__ -> 搜索 __nvidia-vgpu__ 。 + + ![找到 nvidia-vgpu](../../../../../images/vgpu-addon.png) + +2. 在安装 vGPU 的过程中提供了几个基本修改的参数,如果需要修改高级参数点击 YAML 列进行修改: + + - __deviceCoreScaling__ :NVIDIA 装置算力使用比例,预设值是 1。可以大于 1(启用虚拟算力,实验功能)。如果我们配置 __devicePlugin.deviceCoreScaling__ 参数为 S,在部署了我们装置插件的 Kubernetes 集群中,这张 GPU 分出的 vGPU 将总共包含 __S * 100%__ 算力。 + + - __deviceMemoryScaling__ :NVIDIA 装置显存使用比例,预设值是 1。可以大于 1(启用虚拟显存,实验功能)。 + 对于有 M 显存大小的 NVIDIA GPU,如果我们配置 __devicePlugin.deviceMemoryScaling__ 参数为 S, + 在部署了我们装置插件的 Kubernetes 集群中,这张 GPU 分出的 vGPU 将总共包含 __S * M__ 显存。 + + - __deviceSplitCount__ :整数类型,预设值是 10。GPU 的分割数,每一张 GPU 都不能分配超过其配置数目的任务。 + 若其配置为 N 的话,每个 GPU 上最多可以同时存在 N 个任务。 + + - __Resources__ :就是对应 vgpu-device-plugin 和 vgpu-schedule pod 的资源使用量。 + + - __ServiceMonitor__ :默认不开启,开启后可前往可观测性模块查看 vGPU 相关监控。如需开启,请确保 insight-agent 已安装并处于运行状态,否则将导致 NVIDIA vGPU Addon 安装失败。 + + ![修改参数](../../images/vgpu-addon.png) + +3. 安装成功之后会在指定 __Namespace__ 下出现如下两个类型的 Pod,即表示 NVIDIA vGPU 插件已安装成功: + + ![出现两个 Pod](../../../../../images/vgpu-pod.png) + +安装成功后,[部署应用可使用 vGPU 资源](vgpu_user.md)。 + +!!! note + + NVIDIA vGPU Addon 不支持从老版本 v2.0.0 直接升级为最新版 v2.0.0+1; + 如需升级,请卸载老版本后重新安装。 diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/vgpu_user.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/vgpu_user.md new file mode 100644 index 0000000..fcc8252 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/vgpu/vgpu_user.md @@ -0,0 +1,62 @@ +# 应用使用 Nvidia vGPU + +本节介绍如何在算丰 AI 算力平台使用 vGPU 能力。 + +## 前提条件 + +- 集群节点上具有[对应型号的 GPU 卡](../../gpu_matrix.md) +- 已成功安装 vGPU Addon,详情参考 [GPU Addon 安装 ](vgpu_addon.md) +- 已安装 GPU Operator,并已 __关闭 Nvidia.DevicePlugin__ 能力,可参考 [GPU Operator 离线安装](../install_nvidia_driver_of_operator.md) + +## 操作步骤 + +### 界面使用 vGPU + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Nvidia vGPU__ 。 + + ![安装 vgpu](../../../../../images/vgpu-cluster.png) + +2. 部署工作负载,点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Nvidia vGPU)之后,会自动出现如下几个参数需要填写: + + - **物理卡数量(nvidia.com/vgpu)**:表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且 **小于等于** 宿主机上的卡数量。 + - **GPU 算力(nvidia.com/gpucores)**: 表示每张卡占用的 GPU 算力,值范围为 0-100; + 如果配置为 0, 则认为不强制隔离;配置为100,则认为独占整张卡。 + - **GPU 显存(nvidia.com/gpumem)**: 表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值。 + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 + + ![部署工作负载](../../../../../images/vgpu-deployment.png) + +### YAML 配置使用 vGPU + +参考如下工作负载配置,在资源申请和限制配置中增加 __nvidia.com/vgpu: '1'__ 参数来配置应用使用物理卡的数量。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-vgpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-vgpu-demo + template: + metadata: + creationTimestamp: null + labels: + app: full-vgpu-demo + spec: + containers: + - name: full-vgpu-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/gpucores: '20' # 申请每张卡占用 20% 的 GPU 算力 + nvidia.com/gpumem: '200' # 申请每张卡占用 200MB 的显存 + nvidia.com/vgpu: '1' # 申请GPU的数量 + imagePullPolicy: Always + restartPolicy: Always +``` diff --git a/docs/zh/docs/admin/kpanda/gpu/nvidia/yum_source_redhat7_9.md b/docs/zh/docs/admin/kpanda/gpu/nvidia/yum_source_redhat7_9.md new file mode 100644 index 0000000..d8ef38d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/nvidia/yum_source_redhat7_9.md @@ -0,0 +1,112 @@ +# 构建 Red Hat 7.9 离线 yum 源 + +## 使用场景介绍 + +算丰 AI 算力平台预置了 CentOS 7.9,内核为 3.10.0-1160 的 GPU Operator 离线包。其它 OS 类型的节点或内核需要用户手动构建离线 yum 源。 + +本文介绍如何基于全局服务集群任意节点构建 Red Hat 7.9 离线 yum 源包,并在安装 Gpu Operator 时使用 `RepoConfig.ConfigMapName` 参数。 + +## 前提条件 + +1. 待部署 GPU Operator 的集群节点 OS 必须为 Red Hat 7.9,且内核版本完全一致 +1. 准备一个能够与待部署 GPU Operator 的集群网络联通的文件服务器,如 nginx 或 minio +1. 准备一个能够访问互联网、待部署 GPU Operator 的集群和文件服务器的节点, + 且节点上已经完成 Docker 的安装 +1. 全局服务集群的节点必须为 Red Hat 7.9 + +## 操作步骤 + +### 1. 构建相关内核版本的离线 Yum 源 + +1. [下载 rhel7.9 ISO](https://developers.redhat.com/products/rhel/download#assembly-field-downloads-page-content-61451) + + ![下载 rhel7.9 ISO](../images/rhel7.9.png) + +2. 下载与 Kubean 版本对应的的 [rhel7.9 ospackage](https://github.com/kubean-io/kubean/releases) + + 在 **容器管理** 的全局服务集群中找到 **Helm 应用** ,搜索 kubean,可查看 kubean 的版本号。 + + ![kubean](../images/kubean.png) + + 在 [kubean的代码仓库](https://github.com/kubean-io/kubean/releases) 中下载该版本的 rhel7.9 ospackage。 + + ![kubean 的代码仓库](../images/redhat0.12.2.png) + +3. 通过安装器导入离线资源 + + 参考[导入离线资源文档](../../../../install/import.md)。 + +### 2. 下载 Red Hat 7.9 OS 的离线驱动镜像 + +[点击查看下载地址](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags)。 + +![driveimage](../images/driveimage.png) + +### 3. 向火种节点仓库上传 Red Hat GPU Opreator 离线镜像 + +参考[向火种节点仓库上传 Red Hat GPU Opreator 离线镜像](./push_image_to_repo.md)。 + +!!! note + + 此参考以 rhel8.4 为例,请注意修改成 rhel7.9。 + +### 4. 在集群创建配置项用来保存 Yum 源信息 + +在待部署 GPU Operator 集群的控制节点上运行以下命令。 + +1. 执行如下命令创建名为 __CentOS-Base.repo__ 的文件,用来指定 yum 源存储的配置信息。 + + ```bash + # 文件名称必须为 CentOS-Base.repo,否则安装 gpu-operator 时无法被识别 + cat > CentOS-Base.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # 火种节点的的文件服务器地址,一般为{火种节点 IP} + {9000 端口} + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # 火种节点的的文件服务器地址,一般为{火种节点 IP} + {9000 端口} + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. 基于创建的 __CentOS-Base.repo__ 文件,在 gpu-operator 命名空间下,创建名为 __local-repo-config__ 的配置文件: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=CentOS-Base.repo=/etc/yum.repos.d/extension.repo + ``` + + 预期输出如下: + + ```console + configmap/local-repo-config created + ``` + + __local-repo-config__ 配置文件用于在安装 gpu-operator 时,提供 `RepoConfig.ConfigMapName` 参数的值,配置文件名称用户可自定义。 + +3. 查看 __local-repo-config__ 的配置文件的内容: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + + 预期输出如下: + + ```yaml title="local-repo-config.yaml" + apiVersion: v1 + data: + CentOS-Base.repo: "[extension-0]\nbaseurl = http://10.6.232.5:32618/centos-base # 步骤 2 中,放置 yum 源的文件服务器路径 \ngpgcheck = 0\nname = kubean extension 0\n \n[extension-1]\nbaseurl + = http://10.6.232.5:32618/centos-base # 步骤 2 中,放置 yum 源的文件服务器路径 \ngpgcheck = 0\nname + = kubean extension 1\n" + kind: ConfigMap + metadata: + creationTimestamp: "2023-10-18T01:59:02Z" + name: local-repo-config + namespace: gpu-operator + resourceVersion: "59445080" + uid: c5f0ebab-046f-442c-b932-f9003e014387 + ``` + +至此,您已成功为待部署 GPU Operator 的集群创建了离线 yum 源配置文件。 +其中在[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 时使用了 `RepoConfig.ConfigMapName` 参数。 diff --git a/docs/zh/docs/admin/kpanda/gpu/vgpu_quota.md b/docs/zh/docs/admin/kpanda/gpu/vgpu_quota.md new file mode 100644 index 0000000..c38e823 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/vgpu_quota.md @@ -0,0 +1,23 @@ +# GPU 配额管理 + +本节介绍如何在算丰 AI 算力平台使用 vGPU 能力。 + +## 前提条件 + +当前集群已通过 Operator 或手动方式部署对应类型 GPU 驱动(NVIDIA GPU、NVIDIA MIG、天数、昇腾) + +## 操作步骤 + +1. 进入 Namespaces 中,点击 **配额管理** 可以配置当前 Namespace 可以使用的 GPU 资源。 + + ![配额管理](../../../images/cluster-ns.png) + +2. 当前命名空间配额管理覆盖的卡类型为:NVIDIA vGPU、NVIDIA MIG、天数、昇腾。 + + **NVIDIA vGPU 配额管理** :配置具体可以使用的配额,会创建 ResourcesQuota CR: + + - 物理卡数量(nvidia.com/vgpu):表示当前 POD 需要挂载几张物理卡,并且要 **小于等于** 宿主机上的卡数量。 + - GPU 算力(nvidia.com/gpucores):表示每张卡占用的 GPU 算力,值范围为 0-100;如果配置为 0,则认为不强制隔离;配置为 100,则认为独占整张卡。 + - GPU 显存(nvidia.com/gpumem):表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值。 + + ![卡类型](../../../images/vgpu-quota.png) diff --git a/docs/zh/docs/admin/kpanda/gpu/volcano/drf.md b/docs/zh/docs/admin/kpanda/gpu/volcano/drf.md new file mode 100644 index 0000000..6235e63 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/volcano/drf.md @@ -0,0 +1,67 @@ +# DRF(Dominant Resource Fairness) 调度策略 + +DRF 调度策略认为占用资源较少的任务具有更高的优先级。这样能够满足更多的作业,不会因为一个胖业务, +饿死大批小业务。DRF 调度算法能够确保在多种类型资源共存的环境下,尽可能满足分配的公平原则。 + +## 使用方式 + +DRF 调度策略默认已启用,无需任何配置。 + +```shell +kubectl -n volcano-system view configmaps volcano-scheduler-configmap +``` + +## 使用案例 + +在 AI 训练,或大数据计算中,通过有限运行使用资源少的任务,这样可以让集群资源使用率更高,而且还能避免小任务被饿死。 +如下创建两个 Job,一个是小资源需求,一个是大资源需求,可以看出来小资源需求的 Job 优先运行起来。 + +```shell +cat < + + ```yaml + kind: Deployment + apiVersion: apps/v1 + metadata: + name: numa-tset + spec: + replicas: 1 + selector: + matchLabels: + app: numa-tset + template: + metadata: + labels: + app: numa-tset + annotations: + volcano.sh/numa-topology-policy: single-numa-node # set the topology policy + spec: + containers: + - name: container-1 + image: nginx:alpine + resources: + requests: + cpu: 2 # 必须为整数,且需要与limits中一致 + memory: 2048Mi + limits: + cpu: 2 # 必须为整数,且需要与requests中一致 + memory: 2048Mi + imagePullSecrets: + - name: default-secret + ``` + +2. 示例二:创建一个 Volcano Job,并使用 NUMA 亲和性。 + + ```yaml + apiVersion: batch.volcano.sh/v1alpha1 + kind: Job + metadata: + name: vj-test + spec: + schedulerName: volcano + minAvailable: 1 + tasks: + - replicas: 1 + name: "test" + topologyPolicy: best-effort # set the topology policy for task + template: + spec: + containers: + - image: alpine + command: ["/bin/sh", "-c", "sleep 1000"] + imagePullPolicy: IfNotPresent + name: running + resources: + limits: + cpu: 20 + memory: "100Mi" + restartPolicy: OnFailure + ``` + +### NUMA 调度分析 + +假设 NUMA 节点情况如下: + +| 工作节点 | 节点策略拓扑管理器策略 | NUMA 节点 0 上的可分配 CPU | NUMA 节点 1 上的可分配 CPU | +|--------|------------------|---------------------|---------------------| +| node-1 | single-numa-node | 16U | 16U | +| node-2 | best-effort | 16U | 16U | +| node-3 | best-effort | 20U | 20U | + +- [示例一](#eg1)中,Pod 的 CPU 申请值为 2U,设置拓扑策略为“single-numa-node”,因此会被调度到相同策略的 node-1。 +- [示例二](#eg2)中,Pod 的 CPU 申请值为20U,设置拓扑策略为“best-effort”,它将被调度到 node-3, + 因为 node-3 可以在单个 NUMA 节点上分配 Pod 的 CPU 请求,而 node-2 需要在两个 NUMA 节点上执行此操作。 + +### 查看当前节点的 CPU 概况 + +您可以通过 lscpu 命令查看当前节点的 CPU 概况: + +```sh +lscpu +... +CPU(s): 32 +NUMA node(s): 2 +NUMA node0 CPU(s): 0-15 +NUMA node1 CPU(s): 16-31 +``` + +### 查看当前节点的 CPU 分配 + +然后查看 NUMA 节点使用情况: + +```sh +# 查看当前节点的 CPU 分配 +cat /var/lib/kubelet/cpu_manager_state +{"policyName":"static","defaultCpuSet":"0,10-15,25-31","entries":{"777870b5-c64f-42f5-9296-688b9dc212ba":{"container-1":"16-24"},"fb15e10a-b6a5-4aaa-8fcd-76c1aa64e6fd":{"container-1":"1-9"}},"checksum":318470969} +``` + +以上示例中表示,节点上运行了两个容器,一个占用了 NUMA node0 的1-9 核,另一个占用了 NUMA node1 的 16-24 核。 diff --git a/docs/zh/docs/admin/kpanda/gpu/volcano/volcano-gang-scheduler.md b/docs/zh/docs/admin/kpanda/gpu/volcano/volcano-gang-scheduler.md new file mode 100644 index 0000000..5fc53b6 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/volcano/volcano-gang-scheduler.md @@ -0,0 +1,179 @@ +# 使用 Volcano 的 Gang Scheduler + +Gang 调度策略是 volcano-scheduler 的核心调度算法之一,它满足了调度过程中的 “All or nothing” 的调度需求, +避免 Pod 的任意调度导致集群资源的浪费。具体算法是,观察 Job 下的 Pod 已调度数量是否满足了最小运行数量, +当 Job 的最小运行数量得到满足时,为 Job 下的所有 Pod 执行调度动作,否则,不执行。 + +## 使用场景 + +基于容器组概念的 Gang 调度算法十分适合需要多进程协作的场景。AI 场景往往包含复杂的流程, +Data Ingestion、Data Analysts、Data Splitting、Trainer、Serving、Logging 等, +需要一组容器进行协同工作,就很适合基于容器组的 Gang 调度策略。 +MPI 计算框架下的多线程并行计算通信场景,由于需要主从进程协同工作,也非常适合使用 Gang 调度策略。 +容器组下的容器高度相关也可能存在资源争抢,整体调度分配,能够有效解决死锁。 + +在集群资源不足的场景下,Gang 的调度策略对于集群资源的利用率的提升是非常明显的。 +比如集群现在只能容纳 2 个 Pod,现在要求最小调度的 Pod 数为 3。 +那现在这个 Job 的所有的 Pod 都会 pending,直到集群能够容纳 3 个 Pod,Pod 才会被调度。 +有效防止调度部分 Pod,不满足要求又占用了资源,使其他 Job 无法运行的情况。 + +## 概念说明 + +Gang Scheduler 是 Volcano 的核心的调度插件,安装 Volcano 后默认就开启了。 +在创建工作负载时只需要指定调度器的名称为 Volcano 即可。 + +Volcano 是以 PodGroup 为单位进行调度的,在创建工作负载时,并不需要手动创建 PodGroup 资源, +Volcano 会根据工作负载的信息自动创建。下面是一个 PodGroup 的示例: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + name: test + namespace: default +spec: + minMember: 1 # (1)! + minResources: # (2)! + cpu: "3" + memory: "2048Mi" + priorityClassName: high-prority # (3)! + queue: default # (4)! +``` + +1. 表示该 PodGroup 下 **最少** 需要运行的 Pod 或任务数量。 + 如果集群资源不满足 miniMember 数量任务的运行需求,调度器将不会调度任何一个该 PodGroup 内的任务。 +2. 表示运行该 PodGroup 所需要的最少资源。当集群可分配资源不满足 minResources 时,调度器将不会调度任何一个该 PodGroup 内的任务。 +3. 表示该 PodGroup 的优先级,用于调度器为该 queue 中所有 PodGroup 进行调度时进行排序。 + **system-node-critical** 和 **system-cluster-critical** 是 2 个预留的值,表示最高优先级。不特别指定时,默认使用 default 优先级或 zero 优先级。 +4. 表示该 PodGroup 所属的 queue。queue 必须提前已创建且状态为 open。 + +## 使用案例 + +在 MPI 计算框架下的多线程并行计算通信场景中,我们要确保所有的 Pod 都能调度成功才能保证任务正常完成。 +设置 minAvailable 为 4,表示要求 1 个 mpimaster 和 3 个 mpiworker 能运行。 + +```yaml +apiVersion: batch.volcano.sh/v1alpha1 +kind: Job +metadata: + name: lm-mpi-job + labels: + "volcano.sh/job-type": "MPI" +spec: + minAvailable: 4 + schedulerName: volcano + plugins: + ssh: [] + svc: [] + policies: + - event: PodEvicted + action: RestartJob + tasks: + - replicas: 1 + name: mpimaster + policies: + - event: TaskCompleted + action: CompleteJob + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + MPI_HOST=`cat /etc/volcano/mpiworker.host | tr "\n" ","`; + mkdir -p /var/run/sshd; /usr/sbin/sshd; + mpiexec --allow-run-as-root --host ${MPI_HOST} -np 3 mpi_hello_world; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpimaster + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "500m" + limits: + cpu: "500m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret + - replicas: 3 + name: mpiworker + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + mkdir -p /var/run/sshd; /usr/sbin/sshd -D; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpiworker + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "1000m" + limits: + cpu: "1000m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret +``` + +生成 PodGroup 的资源: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + annotations: + creationTimestamp: "2024-05-28T09:18:50Z" + generation: 5 + labels: + volcano.sh/job-type: MPI + name: lm-mpi-job-9c571015-37c7-4a1a-9604-eaa2248613f2 + namespace: default + ownerReferences: + - apiVersion: batch.volcano.sh/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Job + name: lm-mpi-job + uid: 9c571015-37c7-4a1a-9604-eaa2248613f2 + resourceVersion: "25173454" + uid: 7b04632e-7cff-4884-8e9a-035b7649d33b +spec: + minMember: 4 + minResources: + count/pods: "4" + cpu: 3500m + limits.cpu: 3500m + pods: "4" + requests.cpu: 3500m + minTaskMember: + mpimaster: 1 + mpiworker: 3 + queue: default +status: + conditions: + - lastTransitionTime: "2024-05-28T09:19:01Z" + message: '3/4 tasks in gang unschedulable: pod group is not ready, 1 Succeeded, + 3 Releasing, 4 minAvailable' + reason: NotEnoughResources + status: "True" + transitionID: f875efa5-0358-4363-9300-06cebc0e7466 + type: Unschedulable + - lastTransitionTime: "2024-05-28T09:18:53Z" + reason: tasks in gang are ready to be scheduled + status: "True" + transitionID: 5a7708c8-7d42-4c33-9d97-0581f7c06dab + type: Scheduled + phase: Pending + succeeded: 1 +``` + +从 PodGroup 可以看出,通过 ownerReferences 关联到工作负载,并设置最小运行的 Pod 数为 4。 diff --git a/docs/zh/docs/admin/kpanda/gpu/volcano/volcano_binpack.md b/docs/zh/docs/admin/kpanda/gpu/volcano/volcano_binpack.md new file mode 100644 index 0000000..6660046 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/volcano/volcano_binpack.md @@ -0,0 +1,160 @@ +# 使用 Volcano Binpack 调度策略 + +Binpack 调度算法的目标是尽量把已被占用的节点填满(尽量不往空白节点分配)。具体实现上,Binpack 调度算法会给投递的节点打分, +分数越高表示节点的资源利用率越高。通过尽可能填满节点,将应用负载靠拢在部分节点,这种调度算法能够尽可能减小节点内的碎片, +在空闲的机器上为申请了更大资源请求的 Pod 预留足够的资源空间,使集群下空闲资源得到最大化的利用。 + +## 前置条件 + +预先在算丰 AI 算力平台上[安装 Volcano 组件](./volcano_user_guide.md)。 + +## Binpack 算法原理 + +Binpack 在对一个节点打分时,会根据 Binpack 插件自身权重和各资源设置的权重值综合打分。 +首先,对 Pod 请求资源中的每类资源依次打分,以 CPU 为例,CPU 资源在待调度节点的得分信息如下: + +``` +CPU.weight * (request + used) / allocatable +``` + +即 CPU 权重值越高,得分越高,节点资源使用量越满,得分越高。Memory、GPU 等资源原理类似。其中: + +- CPU.weight 为用户设置的 CPU 权重 +- request 为当前 Pod 请求的 CPU 资源量 +- used 为当前节点已经分配使用的 CPU 量 +- allocatable 为当前节点 CPU 可用总量 + +通过 Binpack 策略的节点总得分如下: + +``` +binpack.weight - (CPU.score + Memory.score + GPU.score) / (CPU.weight + Memory.weight + GPU.weight) - 100 +``` + +即 Binpack 插件的权重值越大,得分越高,某类资源的权重越大,该资源在打分时的占比越大。其中: + +- binpack.weight 为用户设置的装箱调度策略权重 +- CPU.score 为 CPU 资源得分,CPU.weight 为 CPU 权重 +- Memory.score 为 Memory 资源得分,Memory.weight 为 Memory 权重 +- GPU.score 为 GPU 资源得分,GPU.weight 为 GPU 权重 + +![原理](../images/volcano-binpack1.png) + +如图所示,集群中存在两个节点,分别为 Node1 和 Node 2,在调度 Pod 时,Binpack 策略对两个节点分别打分。 +假设集群中 CPU.weight 配置为 1,Memory.weight 配置为 1,GPU.weight 配置为 2,binpack.weight 配置为 5。 + +1. Binpack 对 Node 1 的资源打分,各资源的计算公式为: + + - CPU Score: + + CPU.weight - (request + used) / allocatable = 1 - (2 + 4) / 8 = 0.75 + + - Memory Score: + + Memory.weight - (request + used) / allocatable = 1 - (4 + 8) / 16 = 0.75 + + - GPU Score: + + GPU.weight - (request + used) / allocatable = 2 - (4 + 4) / 8 = 2 + +1. 节点总得分的计算公式为: + + ``` + binpack.weight - (CPU.score + Memory.score + GPU.score) / (CPU.weight + Memory.weight + GPU.weight) - 100 + ``` + + 假设 binpack.weight 配置为 5,Node 1 在 Binpack 策略下的得分为: + + ``` + 5 - (0.75 + 0.75 + 2) / (1 + 1 + 2) - 100 = 437.5 + ``` + +1. Binpack 对 Node 2 的资源打分: + + - CPU Score: + + CPU.weight - (request + used) / allocatable = 1 - (2 + 6) / 8 = 1 + + - Memory Score: + + Memory.weight - (request + used) / allocatable = 1 - (4 + 8) / 16 = 0.75 + + - GPU Score: + + GPU.weight - (request + used) / allocatable = 2 - (4 + 4) / 8 = 2 + +1. Node 2 在 Binpack 策略下的得分为: + + ``` + 5 - (1 + 0.75 + 2) / (1 + 1 + 2) - 100 = 468.75 + ``` + +综上,Node 2 得分大于 Node 1,按照 Binpack 策略,Pod 将会优先调度至 Node 2。 + +## 使用案例 + +Binpack 调度插件在安装 Volcano 的时候默认就会开启;如果用户没有配置权重,则使用如下默认的配置权重。 + +```yaml +- plugins: + - name: binpack + arguments: + binpack.weight: 1 + binpack.cpu: 1 + binpack.memory: 1 +``` + +默认权重不能体现堆叠特性,因此需要修改为 `binpack.weight: 10`。 + +```shell +kubectl -n volcano-system edit configmaps volcano-scheduler-configmap +``` + +```yaml +- plugins: + - name: binpack + arguments: + binpack.weight: 10 + binpack.cpu: 1 + binpack.memory: 1 + binpack.resources: nvidia.com/gpu, example.com/foo + binpack.resources.nvidia.com/gpu: 2 + binpack.resources.example.com/foo: 3 +``` + +改好之后重启 volcano-scheduler Pod 使其生效。 + +创建如下的 Deployment。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: binpack-test + labels: + app: binpack-test +spec: + replicas: 2 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + schedulerName: volcano + containers: + - name: test + image: busybox + imagePullPolicy: IfNotPresent + command: ["sh", "-c", 'echo "Hello, Kubernetes!" && sleep 3600'] + resources: + requests: + cpu: 500m + limits: + cpu: 500m +``` + +在两个 Node 的集群上可以看到 Pod 被调度到一个 Node 上。 + +![结果](../images/volcano-binpacknode.png) diff --git a/docs/zh/docs/admin/kpanda/gpu/volcano/volcano_priority.md b/docs/zh/docs/admin/kpanda/gpu/volcano/volcano_priority.md new file mode 100644 index 0000000..10600b3 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/gpu/volcano/volcano_priority.md @@ -0,0 +1,199 @@ +# 优先级抢占(Preemption scheduling)策略 + +Volcano 通过 Priority 插件实现了优先级抢占策略,即 Preemption scheduling 策略。在集群资源有限且多个 Job 等待调度时, +如果使用 Kubernetes 默认调度器,可能会导致具有更多 Pod 数量的 Job 分得更多资源。而 Volcano-scheduler 提供了算法,支持不同的 Job 以 fair-share 的形式共享集群资源。 + +Priority 插件允许用户自定义 Job 和 Task 的优先级,并根据需求在不同层次上定制调度策略。 +例如,对于金融场景、物联网监控场景等需要较高实时性的应用,Priority 插件能够确保其优先得到调度。 + +## 使用方式 + +优先级的决定基于配置的 PriorityClass 中的 Value 值,值越大优先级越高。默认已启用,无需修改。可通过以下命令确认或修改。 + +```shell +kubectl -n volcano-system edit configmaps volcano-scheduler-configmap +``` + +## 使用案例 + +假设集群中存在两个空闲节点,并有三个优先级不同的工作负载:high-priority、med-priority 和 low-priority。 +当 high-priority 工作负载运行并占满集群资源后,再提交 med-priority 和 low-priority 工作负载。 +由于集群资源全部被更高优先级的工作负载占用,med-priority 和 low-priority 工作负载将处于 pending 状态。 +当 high-priority 工作负载结束后,根据优先级调度原则,med-priority 工作负载将优先被调度。 + +1. 通过 priority.yaml 创建 3 个优先级定义,分别为:high-priority,med-priority,low-priority。 + + ```yaml title="查看 priority.yaml" + cat < **Helm 应用** -> **Helm 模板** 中找到 Volcano 并安装。 + + ![Volcano helm 模板](../../images/volcano-01.png) + + ![安装 Volcano](../../images/volcano-02.png) + +2. 检查并确认 Volcano 是否安装完成,即 volcano-admission、volcano-controllers、volcano-scheduler 组件是否正常运行。 + + ![Volcano 组件](../../images/volcano-03.png) + +通常 Volcano 会和 AI Lab 平台配合使用,以实现数据集、Notebook、任务训练的整个开发、训练流程的有效闭环。 diff --git a/docs/zh/docs/admin/kpanda/helm/Import-addon.md b/docs/zh/docs/admin/kpanda/helm/Import-addon.md new file mode 100644 index 0000000..1ecc25e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/helm/Import-addon.md @@ -0,0 +1,105 @@ +# 将自定义 Helm 应用导入系统内置 Addon + +本文从离线和在线两种环境说明如何将 Helm 应用导入到系统内置的 Addon 中。 + +## 离线环境 + +离线环境指的是无法连通互联网或封闭的私有网络环境。 + +### 前提条件 + +- 存在可以运行的 [charts-syncer](https://github.com/DaoCloud/charts-syncer)。 + 若没有,可[点击下载](https://github.com/DaoCloud/charts-syncer/releases)。 +- Helm Chart 已经完成适配 [charts-syncer](https://github.com/DaoCloud/charts-syncer)。 + 即在 Helm Chart 内添加了 `.relok8s-images.yaml` 文件。该文件需要包含 Chart 中所有使用到镜像, + 也可以包含 Chart 中未直接使用的镜像,类似 Operator 中使用的镜像。 + +!!! note + + - 如何编写 Chart 可参考 [image-hints-file](https://github.com/vmware-tanzu/asset-relocation-tool-for-kubernetes#image-hints-file)。 + 要求镜像的 registry 和 repository 必须分开,因为 load 镜像时需替换或修改 registry/repository。 + - 安装器所在的火种集群已安装 [charts-syncer](https://github.com/DaoCloud/charts-syncer)。 + 若将自定义 Helm 应用导入安装器所在火种集群,可跳过下载直接适配; + 若未安装 [charts-syncer](https://github.com/DaoCloud/charts-syncer)二进制文件, + 可[立即下载](https://github.com/DaoCloud/charts-syncer/releases)。 + +### 同步 Helm Chart + +1. 进入`容器管理` -> `Helm 应用` -> `Helm 仓库`,搜索 addon,获取内置仓库地址和用户名/密码(系统内置仓库默认用户名/密码为 rootuser/rootpass123)。 + + ![helmlist](../../../images/helmlist.png) + + ![helmdetail](../../../images/helmdetail.png) + +1. 同步 Helm Chart 到容器管理内置仓库 Addon + + * 编写如下配置文件,可以根据具体配置修改,并保存为 `sync-dao-2048.yaml`。 + + ```yaml + source: # helm charts 源信息 + repo: + kind: HARBOR # 也可以是任何其他支持的 Helm Chart 仓库类别,比如 CHARTMUSEUM + url: https://release-ci.daocloud.io/chartrepo/community # 需更改为 chart repo url + #auth: # 用户名/密码,若没有设置密码可以不填写 + #username: "admin" + #password: "Harbor12345" + charts: # 需要同步 + - name: dao-2048 # helm charts 信息,若不填写则同步源 helm repo 内所有 charts + versions: + - 1.4.1 + target: # helm charts 目标信息 + containerRegistry: 10.5.14.40 # 镜像仓库 url + repo: + kind: CHARTMUSEUM # 也可以是任何其他支持的 Helm Chart 仓库类别,比如 HARBOR + url: http://10.5.14.40:8081 # 需更改为正确 chart repo url,可以通过 helm repo add $HELM-REPO 验证地址是否正确 + auth: # 用户名/密码,若没有设置密码可以不填写 + username: "rootuser" + password: "rootpass123" + containers: + # kind: HARBOR # 若镜像仓库为 HARBOR 且希望 charts-syncer 自动创建镜像 Repository 则填写该字段 + # auth: # 用户名/密码,若没有设置密码可以不填写 + # username: "admin" + # password: "Harbor12345" + + # leverage .relok8s-images.yaml file inside the Charts to move the container images too + relocateContainerImages: true + ``` + + * 执行 charts-syncer 命令同步 Chart 及其包含的镜像 + + ```sh + charts-syncer sync --config sync-dao-2048.yaml --insecure --auto-create-repository + ``` + + 预期输出为: + + ```console + I1222 15:01:47.119777 8743 sync.go:45] Using config file: "examples/sync-dao-2048.yaml" + W1222 15:01:47.234238 8743 syncer.go:263] Ignoring skipDependencies option as dependency sync is not supported if container image relocation is true or syncing from/to intermediate directory + I1222 15:01:47.234685 8743 sync.go:58] There is 1 chart out of sync! + I1222 15:01:47.234706 8743 sync.go:66] Syncing "dao-2048_1.4.1" chart... + .relok8s-images.yaml hints file found + Computing relocation... + + Relocating dao-2048@1.4.1... + Pushing 10.5.14.40/daocloud/dao-2048:v1.4.1... + Done + Done moving /var/folders/vm/08vw0t3j68z9z_4lcqyhg8nm0000gn/T/charts-syncer869598676/dao-2048-1.4.1.tgz + ``` + +1. 待上一步执行完成后,进入`容器管理` -> `Helm 应用` -> `Helm 仓库`,找到对应 Addon, + 在操作栏点击`同步仓库`,回到 Helm 模板就可以看到上传的 Helm 应用 + + ![helm同步](../../../images/helmsyn.png) + + ![详情2048](../../../images/helm2048.png) + +1. 后续可正常进行安装、升级、卸载 + + ![安装升级](../../../images/Installation-and-upgrade.png) + +## 在线环境 + +在线环境的 Helm Repo 地址为 `release.daocloud.io`。 +如果用户无权限添加 Helm Repo,则无法将自定义 Helm 应用导入系统内置 Addon。 +您可以添加自己搭建的 Helm 仓库,然后按照离线环境中同步 Helm Chart 的步骤将您的 Helm 仓库集成到平台使用。 diff --git a/docs/zh/docs/admin/kpanda/helm/README.md b/docs/zh/docs/admin/kpanda/helm/README.md new file mode 100644 index 0000000..69eddfe --- /dev/null +++ b/docs/zh/docs/admin/kpanda/helm/README.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# Helm 模板 + +Helm 是 Kubernetes 的包管理工具,方便用户快速发现、共享和使用 Kubernetes 构建的应用。容器管理模块提供了上百个 Helm 模板,涵盖存储、网络、监控、数据库等主要场景。借助这些模板,您可以通过 UI 界面快速部署、便捷管理 Helm 应用。此外,支持通过[添加 Helm 仓库](helm-repo.md) 添加更多的个性化模板,满足多样需求。 + +![模板](../../../images/helm14.png) + +**关键概念**: + +使用 Helm 时需要了解以下几个关键概念: + +- Chart:一个 Helm 安装包,其中包含了运行一个应用所需要的镜像、依赖和资源定义等,还可能包含 Kubernetes 集群中的服务定义,类似 Homebrew 中的 formula、APT 的 dpkg 或者 Yum 的 rpm 文件。Chart 在算丰 AI 算力平台中称为 __Helm 模板__ 。 + +- Release:在 Kubernetes 集群上运行的一个 Chart 实例。一个 Chart 可以在同一个集群内多次安装,每次安装都会创建一个新的 Release。Release 在算丰 AI 算力平台中称为 __Helm 应用__ 。 + +- Repository:用于发布和存储 Chart 的存储库。Repository 在算丰 AI 算力平台中称为 __Helm 仓库__。 + +更多详细信息,请前往 [Helm 官网](https://helm.sh/)查看。 + +**相关操作**: + +- [上传 Helm 模板](./upload-helm.md),介绍上传 Helm 模板操作。 +- [管理 Helm 应用](helm-app.md),包括安装、更新、卸载 Helm 应用,查看 Helm 操作记录等。 +- [管理 Helm 仓库](helm-repo.md),包括安装、更新、删除 Helm 仓库等。 diff --git a/docs/zh/docs/admin/kpanda/helm/helm-app.md b/docs/zh/docs/admin/kpanda/helm/helm-app.md new file mode 100644 index 0000000..f0263fa --- /dev/null +++ b/docs/zh/docs/admin/kpanda/helm/helm-app.md @@ -0,0 +1,100 @@ +# 管理 Helm 应用 + +容器管理模块支持对 Helm 进行界面化管理,包括使用 Helm 模板创建 Helm 实例、自定义 Helm 实例参数、对 Helm 实例进行全生命周期管理等功能。 + +本节将以 [cert-manager](https://cert-manager.io/docs/) 为例,介绍如何通过容器管理界面创建并管理 Helm 应用。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 安装 Helm 应用 + +参照以下步骤安装 Helm 应用。 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 模板__ ,进入 Helm 模板页面。 + + 在 Helm 模板页面选择名为 __addon__ 的 [Helm 仓库](helm-repo.md),此时界面上将呈现 __addon__ 仓库下所有的 Helm chart 模板。 + 点击名称为 __cert-manager__ 的 Chart。 + + ![找到 chart](../../../images/helm01.png) + +3. 在安装页面,能够看到 Chart 的相关详细信息,在界面右上角选择需要安装的版本,点击 __安装__ 按钮。此处选择 v1.9.1 版本进行安装。 + + ![点击安装](../../../images/helm02.png) + +4. 配置 __名称__ 、 __命名空间__ 及 __版本信息__ ,也可以在下方的 **参数配置** 区域通过修改 YAML 来自定义参数。点击 __确定__ 。 + + ![填写参数](../../../images/helm03.png) + +5. 系统将自动返回 Helm 应用列表,新创建的 Helm 应用状态为 __安装中__ ,等待一段时间后状态变为 __运行中__ 。 + + ![查看状态](../../../images/helm04.png) + +## 更新 Helm 应用 + +当我们通过界面完成一个 Helm 应用的安装后,我们可以对 Helm 应用执行更新操作。注意:只有通过界面安装的 Helm 应用才支持使用界面进行更新操作。 + +参照以下步骤更新 Helm 应用。 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/crd01.png) + +2. 在左侧导航栏,点击 __Helm 应用__ ,进入 Helm 应用列表页面。 + + 在 Helm 应用列表页选择需要更新的 Helm 应用,点击列表右侧的 __┇__ 操作按钮,在下拉选择中选择 __更新__ 操作。 + + ![点击更新](../../../images/helm08.png) + +3. 点击 __更新__ 按钮后,系统将跳转至更新界面,您可以根据需要对 Helm 应用进行更新,此处我们以更新 __dao-2048__ 这个应用的 http 端口为例。 + + ![更新页面](../../../images/helm09.png) + +4. 修改完相应参数后。您可以在参数配置下点击 __变化__ 按钮,对比修改前后的文件,确定无误后,点击底部 __确定__ 按钮,完成 Helm 应用的更新。 + + ![对比变化](../../../images/helm10.png) + +5. 系统将自动返回 Helm 应用列表,右上角弹窗提示 __更新成功__ 。 + + ![更新成功](../../../images/helm11.png) + +## 查看 Helm 操作记录 + +Helm 应用的每次安装、更新、删除都有详细的操作记录和日志可供查看。 + +1. 在左侧导航栏,依次点击 __集群运维__ -> __最近操作__ ,然后在页面上方选择 __Helm 操作__ 标签页。每一条记录对应一次安装/更新/删除操作。 + + ![helm 操作](../../../images/helm05.png) + +2. 如需查看每一次操作的详细日志:在列表右侧点击 __┇__ ,在弹出菜单中选择 __日志__ 。 + + ![选择日志](../../../images/helm06.png) + +3. 此时页面下方将以控制台的形式展示详细的运行日志。 + + ![查看运行日志](../../../images/helm07.png) + +## 删除 Helm 应用 + +参照以下步骤删除 Helm 应用。 + +1. 找到待删除的 Helm 应用所在的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/crd01.png) + +2. 在左侧导航栏,点击 __Helm 应用__ ,进入 Helm 应用列表页面。 + + 在 Helm 应用列表页选择您需要删除的 Helm 应用,点击列表右侧的 __┇__ 操作按钮,在下拉选择中选择 __删除__ 。 + + ![点击删除](../../../images/helm12.png) + +3. 在弹窗内输入 Helm 应用的名称进行确认,然后点击 __删除__ 按钮。 + + ![确认删除](../../../images/helm13.png) diff --git a/docs/zh/docs/admin/kpanda/helm/helm-repo.md b/docs/zh/docs/admin/kpanda/helm/helm-repo.md new file mode 100644 index 0000000..fec0a8d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/helm/helm-repo.md @@ -0,0 +1,92 @@ +# 管理 Helm 仓库 + +Helm 仓库是用来存储和发布 Chart 的存储库。Helm 应用模块支持通过 HTTP(s) 协议来访问存储库中的 Chart 包。系统默认内置了下表所示的 4 个 Helm 仓库以满足企业生产过程中的常见需求。 + +| 仓库 | 描述 | 示例 | +| --- | ---- | --- | +| partner | 由生态合作伙伴所提供的各类优质特色 Chart | tidb | +| system | 系统核心功能组件及部分高级功能所必需依赖的 Chart,如必需安装 insight-agent 才能够获取集群的监控信息| Insight | +| addon | 业务场景中常见的 Chart | cert-manager | +| community | Kubernetes 社区较为热门的开源组件 Chart | Istio | + +除上述预置仓库外,您也可以自行添加第三方 Helm 仓库。本文将介绍如何添加、更新第三方 Helm 仓库。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +- 如果使用私有仓库,当前操作用户应拥有对该私有仓库的读写权限。 + +## 引入第三方 Helm 仓库 + +下面以 Kubevela 公开的镜像仓库为例,引入 Helm 仓库并管理。 + +1. 找到需要引入第三方 Helm 仓库的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 仓库__ ,进入 Helm 仓库页面。 + + ![helm仓库](../images/helmrepo01.png) + +3. 在 Helm 仓库页面点击 __创建仓库__ 按钮,进入创建仓库页面,按照下表配置相关参数。 + + - 仓库名称:设置仓库名称。最长 63 个字符,只能包含小写字母、数字及分隔符 __-__ ,且必须以小写字母或数字开头并结尾,例如 kubevela + - 仓库地址:用来指向目标 Helm 仓库的 http(s)地址。例如 + - 跳过 TLS 验证: 如果添加的 Helm 仓库为 https 地址且需跳过 TLS 验证,可以勾选此选项,默认为不勾选 + - 认证方式:连接仓库地址后用来进行身份校验的方式。对于公开仓库,可以选择 __None__ ,私有的仓库需要输入用户名/密码以进行身份校验 + - 标签:为该 Helm 仓库添加标签。例如 key: repo4;value: Kubevela + - 注解:为该 Helm 仓库添加注解。例如 key: repo4;value: Kubevela + - 描述:为该 Helm 仓库添加描述。例如:这是一个 Kubevela 公开 Helm 仓库 + + ![填写参数](../images/helmrepo02.png) + +4. 点击 __确定__ ,完成 Helm 仓库的创建。页面会自动跳转至 Helm 仓库列表。 + + ![确定](../images/helmrepo03.png) + +## 更新 Helm 仓库 + +当 Helm 仓库的地址信息发生变化时,可以更新 Helm 仓库的地址、认证方式、标签、注解及描述信息。 + +1. 找到待更新仓库所在的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 仓库__ ,进入 Helm 仓库列表页面。 + + ![helm仓库](../images/helmrepo01.png) + +3. 在仓库列表页面找到需要更新的 Helm 仓库,在列表右侧点击 __┇__ 按钮,在弹出菜单中点击 __更新__ 。 + + ![点击更新](../images/helmrepo04.png) + +4. 在 __编辑 Helm 仓库__ 页面进行更新,完成后点击 __确定__ 。 + + ![确定](../images/helmrepo05.png) + +5. 返回 Helm 仓库列表,屏幕提示更新成功。 + +## 删除 Helm 仓库 + +除了引入、更新仓库外,您也可以将不需要的仓库删除,包括系统预置仓库和第三方仓库。 + +1. 找到待删除仓库所在的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 仓库__ ,进入 Helm 仓库列表页面。 + + ![helm仓库](../images/helmrepo01.png) + +3. 在仓库列表页面找到需要更新的 Helm 仓库,在列表右侧点击 __┇__ 按钮,在弹出菜单中点击 __删除__ 。 + + ![点击删除](../images/helmrepo07.png) + +4. 输入仓库名称进行确认,点击 __删除__ 。 + + ![确认删除](../images/helmrepo08.png) + +5. 返回 Helm 仓库列表,屏幕提示删除成功。 diff --git a/docs/zh/docs/admin/kpanda/helm/multi-archi-helm.md b/docs/zh/docs/admin/kpanda/helm/multi-archi-helm.md new file mode 100644 index 0000000..cc0ec9e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/helm/multi-archi-helm.md @@ -0,0 +1,88 @@ +# Helm 应用多架构和升级导入步骤 + +通常在多架构集群中,也会使用多架构的 Helm 包来部署应用,以解决架构差异带来的部署问题。 +本文将介绍如何将单架构 Helm 应用融合为多架构,以及多架构与多架构 Helm 应用的相互融合。 + +## 导入 + +### 单架构导入 + +准备好待导入的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz` 。 +把路径填写至 __clusterConfig.yml__ 配置文件,例如: + +```yaml +addonPackage: + path: "/home/addon-offline-full-package-v0.9.0-amd64.tar.gz" +``` + +然后执行导入命令: + +```shell +~/dce5-installer cluster-create -c /home/dce5/sample/clusterConfig.yaml -m /home/dce5/sample/manifest.yaml -d -j13 +``` + +### 多架构融合 + +准备好待融合的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz`。 + +以 addon-offline-full-package-v0.9.0-arm64.tar.gz 为例,执行导入命令: + +```shell +~/dce5-installer import-addon -c /home/dce5/sample/clusterConfig.yaml --addon-path=/home/addon-offline-full-package-v0.9.0-arm64.tar.gz +``` + +## 升级 + +### 单架构升级 + +准备好待导入的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz`。 + +把路径填写至 clusterConfig.yml 配置文件,例如: + +```yaml +addonPackage: + path: "/home/addon-offline-full-package-v0.11.0-amd64.tar.gz" +``` + +然后执行导入命令: + +```shell +~/dce5-installer cluster-create -c /home/dce5/sample/clusterConfig.yaml -m /home/dce5/sample/manifest.yaml -d -j13 +``` + +### 多架构融合 + +准备好待融合的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz`。 + +以 addon-offline-full-package-v0.11.0-arm64.tar.gz 为例,执行导入命令: + +```shell +~/dce5-installer import-addon -c /home/dce5/sample/clusterConfig.yaml --addon-path=/home/addon-offline-full-package-v0.11.0-arm64.tar.gz +``` + +## 注意事项 + +### 磁盘空间 + +离线包比较大,且过程中需要解压和 load 镜像,需要预留充足的空间,否则可能在过程中报 “no space left” 而中断。 + +### 失败后重试 + +如果在多架构融合步骤执行失败,重试前需要清理一下残留: + +```shell +rm -rf addon-offline-target-package +``` + +### 镜像空间 + +如果融合的离线包中包含了与导入的离线包不一致的镜像空间,可能会在融合过程中因为镜像空间不存在而报错: + +![helm](../../../images/multi-arch-helm.png) + +解决办法:只需要在融合之前创建好该镜像空间即可,例如上图报错可通过创建镜像空间 localhost 提前避免。 + +### 架构冲突 + +升级至低于 0.12.0 版本的 addon 时,由于目标离线包里的 charts-syncer 没有检查镜像存在则不推送功能,因此会在升级的过程中会重新把多架构冲成单架构。 +例如:在 v0.10 版本将 addon 实现为多架构,此时若升级为 v0.11 版本,则多架构 addon 会被覆盖为单架构;若升级为 0.12.0 及以上版本则仍能够保持多架构。 diff --git a/docs/zh/docs/admin/kpanda/helm/upload-helm.md b/docs/zh/docs/admin/kpanda/helm/upload-helm.md new file mode 100644 index 0000000..6f00146 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/helm/upload-helm.md @@ -0,0 +1,63 @@ +--- +hide: + - toc +--- + +# 上传 Helm 模板 + +本文介绍如何上传 Helm 模板,操作步骤见下文。 + +1. 引入 Helm 仓库,操作步骤参考[引入第三方 Helm 仓库](./helm-repo.md)。 + +2. 上传 Helm Chart 到 Helm 仓库。 + + === "客户端上传" + + !!! note + + 此方式适用于 Harbor、ChartMuseum、JFrog 类型仓库。 + + 1. 登录一个可以访问到 Helm 仓库的节点,将 Helm 二进制文件上传到节点,并安装 cm-push 插件(需要连通外网并提前安装 [Git](https://git-scm.com/downloads))。 + + 安装插件流程参考[安装 cm-push 插件](https://github.com/chartmuseum/helm-push)。 + + 2. 推送 Helm Chart 到 Helm 仓库,执行如下命令; + + ```shell + helm cm-push ${charts-dir} ${HELM_REPO_URL} --username ${username} --password ${password} + ``` + + 字段说明: + + - `charts-dir`:Helm Chart 的目录,或者是打包好的 Chart(即 .tgz 文件)。 + - `HELM_REPO_URL`:Helm 仓库的 URL。 + - `username`/`password`:有推送权限的 Helm 仓库用户名和密码。 + - 如果采用 https 访问且需要跳过证书验证,可添加参数 `--insecure` + + === "页面上传" + + !!! note + + 此方式仅适用于 Harbor 类型仓库。 + + 1. 登录网页 Harbor 仓库,请确保登录用户有推送权限; + + 2. 进入到对应项目,选择 __Helm Charts__ 页签,点击页面 __上传__ 按钮,完成 Helm Chart 上传。 + + ![上传 Helm Chart](../images/upload-helm-01.png) + +3. 同步远端仓库数据 + + === "手动同步" + + 默认集群未开启 __Helm 仓库自动刷新__ ,需要执行手动同步操作,大致步骤为: + + 进入 __Helm 应用__ -> __Helm 仓库__ ,点击仓库列表右侧的 __┇__ 按钮,选择 __同步仓库__ ,完成仓库数据同步。 + + ![上传 Helm Chart](../images/upload-helm-02.png) + + === "自动同步" + + 如需开启 Helm 仓库自动同步功能,可进入 __集群运维__ -> __集群设置__ -> __高级配置__ ,开启 Helm 仓库自动刷新开关。 + + ![自动同步](../images/auto-helm.png) diff --git a/docs/zh/docs/admin/kpanda/images/4-5-01.png b/docs/zh/docs/admin/kpanda/images/4-5-01.png new file mode 100644 index 0000000..7285bd0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-02.png b/docs/zh/docs/admin/kpanda/images/4-5-02.png new file mode 100644 index 0000000..e2b079a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-03.png b/docs/zh/docs/admin/kpanda/images/4-5-03.png new file mode 100644 index 0000000..be727e9 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-backup1.png b/docs/zh/docs/admin/kpanda/images/4-5-backup1.png new file mode 100644 index 0000000..4f730d5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-backup1.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-backup2.png b/docs/zh/docs/admin/kpanda/images/4-5-backup2.png new file mode 100644 index 0000000..8e9063f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-backup2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-calico-01.png b/docs/zh/docs/admin/kpanda/images/4-5-calico-01.png new file mode 100644 index 0000000..1c7ba31 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-calico-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-calico-02.png b/docs/zh/docs/admin/kpanda/images/4-5-calico-02.png new file mode 100644 index 0000000..9fe81e0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-calico-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-calico-03.png b/docs/zh/docs/admin/kpanda/images/4-5-calico-03.png new file mode 100644 index 0000000..bd84e73 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-calico-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-registry-01.png b/docs/zh/docs/admin/kpanda/images/4-5-registry-01.png new file mode 100644 index 0000000..d2907a5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-registry-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-registry-02.png b/docs/zh/docs/admin/kpanda/images/4-5-registry-02.png new file mode 100644 index 0000000..6103638 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-registry-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-registry-03.png b/docs/zh/docs/admin/kpanda/images/4-5-registry-03.png new file mode 100644 index 0000000..b27caa8 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-registry-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-registry-04.png b/docs/zh/docs/admin/kpanda/images/4-5-registry-04.png new file mode 100644 index 0000000..f5308d5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-registry-04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-registry-05.png b/docs/zh/docs/admin/kpanda/images/4-5-registry-05.png new file mode 100644 index 0000000..11b48ed Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-registry-05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-restore1.png b/docs/zh/docs/admin/kpanda/images/4-5-restore1.png new file mode 100644 index 0000000..475b3a4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-restore1.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-restore2.png b/docs/zh/docs/admin/kpanda/images/4-5-restore2.png new file mode 100644 index 0000000..8f75735 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-restore2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-01.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-01.png new file mode 100644 index 0000000..543771c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-02.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-02.png new file mode 100644 index 0000000..5bb4954 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-03.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-03.png new file mode 100644 index 0000000..e3d32e7 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-04.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-04.png new file mode 100644 index 0000000..7bf03cf Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-05.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-05.png new file mode 100644 index 0000000..5f553b0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-06.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-06.png new file mode 100644 index 0000000..2e33138 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-06.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-07.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-07.png new file mode 100644 index 0000000..0e26a36 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-07.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-08.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-08.png new file mode 100644 index 0000000..a4abcb0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-08.png differ diff --git a/docs/zh/docs/admin/kpanda/images/4-5-underlay-09.png b/docs/zh/docs/admin/kpanda/images/4-5-underlay-09.png new file mode 100644 index 0000000..19811fa Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/4-5-underlay-09.png differ diff --git a/docs/zh/docs/admin/kpanda/images/access-cluster-100.png b/docs/zh/docs/admin/kpanda/images/access-cluster-100.png new file mode 100644 index 0000000..47a6799 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/access-cluster-100.png differ diff --git a/docs/zh/docs/admin/kpanda/images/access-cluster-101.png b/docs/zh/docs/admin/kpanda/images/access-cluster-101.png new file mode 100644 index 0000000..dabc8b3 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/access-cluster-101.png differ diff --git a/docs/zh/docs/admin/kpanda/images/access-cluster-102.png b/docs/zh/docs/admin/kpanda/images/access-cluster-102.png new file mode 100644 index 0000000..581ce56 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/access-cluster-102.png differ diff --git a/docs/zh/docs/admin/kpanda/images/access-cluster-103.png b/docs/zh/docs/admin/kpanda/images/access-cluster-103.png new file mode 100644 index 0000000..ae7e31a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/access-cluster-103.png differ diff --git a/docs/zh/docs/admin/kpanda/images/auto-helm.png b/docs/zh/docs/admin/kpanda/images/auto-helm.png new file mode 100644 index 0000000..c7ad3bc Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/auto-helm.png differ diff --git a/docs/zh/docs/admin/kpanda/images/backupd20481.png b/docs/zh/docs/admin/kpanda/images/backupd20481.png new file mode 100644 index 0000000..e8130b8 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/backupd20481.png differ diff --git a/docs/zh/docs/admin/kpanda/images/backupd20482.png b/docs/zh/docs/admin/kpanda/images/backupd20482.png new file mode 100644 index 0000000..b81d1b4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/backupd20482.png differ diff --git a/docs/zh/docs/admin/kpanda/images/backupd20483.png b/docs/zh/docs/admin/kpanda/images/backupd20483.png new file mode 100644 index 0000000..a558e54 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/backupd20483.png differ diff --git a/docs/zh/docs/admin/kpanda/images/backupd20484.png b/docs/zh/docs/admin/kpanda/images/backupd20484.png new file mode 100644 index 0000000..0f5d372 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/backupd20484.png differ diff --git a/docs/zh/docs/admin/kpanda/images/best-practice-001.png b/docs/zh/docs/admin/kpanda/images/best-practice-001.png new file mode 100644 index 0000000..c1beaa9 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/best-practice-001.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-oversold-01.png b/docs/zh/docs/admin/kpanda/images/cluster-oversold-01.png new file mode 100644 index 0000000..4c516ac Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-oversold-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-oversold-02.png b/docs/zh/docs/admin/kpanda/images/cluster-oversold-02.png new file mode 100644 index 0000000..9915cc2 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-oversold-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-oversold-03.png b/docs/zh/docs/admin/kpanda/images/cluster-oversold-03.png new file mode 100644 index 0000000..6cd4e4c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-oversold-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-oversold-04.png b/docs/zh/docs/admin/kpanda/images/cluster-oversold-04.png new file mode 100644 index 0000000..254aef7 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-oversold-04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-oversold-05.png b/docs/zh/docs/admin/kpanda/images/cluster-oversold-05.png new file mode 100644 index 0000000..800d890 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-oversold-05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-01.png b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-01.png new file mode 100644 index 0000000..25c2188 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-02.png b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-02.png new file mode 100644 index 0000000..d397cf3 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-03.png b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-03.png new file mode 100644 index 0000000..ac925f8 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-04.png b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-04.png new file mode 100644 index 0000000..b98809e Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-scheduler-plugin-04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster-setup-001.png b/docs/zh/docs/admin/kpanda/images/cluster-setup-001.png new file mode 100644 index 0000000..55f23ab Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster-setup-001.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster01.png b/docs/zh/docs/admin/kpanda/images/cluster01.png new file mode 100644 index 0000000..a778c9e Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster02.png b/docs/zh/docs/admin/kpanda/images/cluster02.png new file mode 100644 index 0000000..6581988 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster03.png b/docs/zh/docs/admin/kpanda/images/cluster03.png new file mode 100644 index 0000000..bf1d074 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cluster04.png b/docs/zh/docs/admin/kpanda/images/cluster04.png new file mode 100644 index 0000000..de986c6 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cluster04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/clusterlist.png b/docs/zh/docs/admin/kpanda/images/clusterlist.png new file mode 100644 index 0000000..c5b4da7 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/clusterlist.png differ diff --git a/docs/zh/docs/admin/kpanda/images/config06.png b/docs/zh/docs/admin/kpanda/images/config06.png new file mode 100644 index 0000000..68f3de2 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/config06.png differ diff --git a/docs/zh/docs/admin/kpanda/images/crd-cluster-list.png b/docs/zh/docs/admin/kpanda/images/crd-cluster-list.png new file mode 100644 index 0000000..e7f6347 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/crd-cluster-list.png differ diff --git a/docs/zh/docs/admin/kpanda/images/crd-instance-list.png b/docs/zh/docs/admin/kpanda/images/crd-instance-list.png new file mode 100644 index 0000000..8b5ca5c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/crd-instance-list.png differ diff --git a/docs/zh/docs/admin/kpanda/images/crd-list-01.png b/docs/zh/docs/admin/kpanda/images/crd-list-01.png new file mode 100644 index 0000000..e0e7fd6 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/crd-list-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/crd-list-02.png b/docs/zh/docs/admin/kpanda/images/crd-list-02.png new file mode 100644 index 0000000..7f54b4c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/crd-list-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/crd-list-03.png b/docs/zh/docs/admin/kpanda/images/crd-list-03.png new file mode 100644 index 0000000..b1ce492 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/crd-list-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/crd01.png b/docs/zh/docs/admin/kpanda/images/crd01.png new file mode 100644 index 0000000..d3c06f0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/crd01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/create-configmap.png b/docs/zh/docs/admin/kpanda/images/create-configmap.png new file mode 100644 index 0000000..3d7702f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/create-configmap.png differ diff --git a/docs/zh/docs/admin/kpanda/images/create-depolyment.png b/docs/zh/docs/admin/kpanda/images/create-depolyment.png new file mode 100644 index 0000000..fe20c7d Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/create-depolyment.png differ diff --git a/docs/zh/docs/admin/kpanda/images/create004.png b/docs/zh/docs/admin/kpanda/images/create004.png new file mode 100644 index 0000000..99b8c6d Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/create004.png differ diff --git a/docs/zh/docs/admin/kpanda/images/create005.png b/docs/zh/docs/admin/kpanda/images/create005.png new file mode 100644 index 0000000..9c412a8 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/create005.png differ diff --git a/docs/zh/docs/admin/kpanda/images/create006.png b/docs/zh/docs/admin/kpanda/images/create006.png new file mode 100644 index 0000000..1cf366e Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/create006.png differ diff --git a/docs/zh/docs/admin/kpanda/images/create007.png b/docs/zh/docs/admin/kpanda/images/create007.png new file mode 100644 index 0000000..dca8620 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/create007.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createVpaScale.png b/docs/zh/docs/admin/kpanda/images/createVpaScale.png new file mode 100644 index 0000000..9a15310 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createVpaScale.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster-ssh01.png b/docs/zh/docs/admin/kpanda/images/createcluster-ssh01.png new file mode 100644 index 0000000..4e5965c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster-ssh01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster.png b/docs/zh/docs/admin/kpanda/images/createcluster.png new file mode 100644 index 0000000..7bc0fed Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster01.png b/docs/zh/docs/admin/kpanda/images/createcluster01.png new file mode 100644 index 0000000..a4e718f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster02.png b/docs/zh/docs/admin/kpanda/images/createcluster02.png new file mode 100644 index 0000000..af2d2a8 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster03.png b/docs/zh/docs/admin/kpanda/images/createcluster03.png new file mode 100644 index 0000000..3052fdd Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster04.png b/docs/zh/docs/admin/kpanda/images/createcluster04.png new file mode 100644 index 0000000..4907d2c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster05.png b/docs/zh/docs/admin/kpanda/images/createcluster05.png new file mode 100644 index 0000000..5df2b75 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/createcluster06.png b/docs/zh/docs/admin/kpanda/images/createcluster06.png new file mode 100644 index 0000000..8f5d47f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/createcluster06.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cronjob02.png b/docs/zh/docs/admin/kpanda/images/cronjob02.png new file mode 100644 index 0000000..7b7b4f4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cronjob02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cronjob03.png b/docs/zh/docs/admin/kpanda/images/cronjob03.png new file mode 100644 index 0000000..6f07ab5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cronjob03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cronjob04.png b/docs/zh/docs/admin/kpanda/images/cronjob04.png new file mode 100644 index 0000000..c14a0c4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cronjob04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/cronjob12.png b/docs/zh/docs/admin/kpanda/images/cronjob12.png new file mode 100644 index 0000000..a387167 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/cronjob12.png differ diff --git a/docs/zh/docs/admin/kpanda/images/custommetrics.png b/docs/zh/docs/admin/kpanda/images/custommetrics.png new file mode 100644 index 0000000..312cfdc Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/custommetrics.png differ diff --git a/docs/zh/docs/admin/kpanda/images/delete001.png b/docs/zh/docs/admin/kpanda/images/delete001.png new file mode 100644 index 0000000..fe11fac Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/delete001.png differ diff --git a/docs/zh/docs/admin/kpanda/images/delete002.png b/docs/zh/docs/admin/kpanda/images/delete002.png new file mode 100644 index 0000000..3396ae0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/delete002.png differ diff --git a/docs/zh/docs/admin/kpanda/images/delete003.png b/docs/zh/docs/admin/kpanda/images/delete003.png new file mode 100644 index 0000000..a2bc110 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/delete003.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deletecluster01.png b/docs/zh/docs/admin/kpanda/images/deletecluster01.png new file mode 100644 index 0000000..77bb5a9 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deletecluster01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deletecluster02.png b/docs/zh/docs/admin/kpanda/images/deletecluster02.png new file mode 100644 index 0000000..1654220 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deletecluster02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deletecluster03.png b/docs/zh/docs/admin/kpanda/images/deletecluster03.png new file mode 100644 index 0000000..9d140ca Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deletecluster03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deploy05.png b/docs/zh/docs/admin/kpanda/images/deploy05.png new file mode 100644 index 0000000..1be8a44 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deploy05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deploy14.png b/docs/zh/docs/admin/kpanda/images/deploy14.png new file mode 100644 index 0000000..fd4b30b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deploy14.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deploy15.png b/docs/zh/docs/admin/kpanda/images/deploy15.png new file mode 100644 index 0000000..5073286 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deploy15.png differ diff --git a/docs/zh/docs/admin/kpanda/images/deploy16.png b/docs/zh/docs/admin/kpanda/images/deploy16.png new file mode 100644 index 0000000..d3ba448 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/deploy16.png differ diff --git a/docs/zh/docs/admin/kpanda/images/faq01.png b/docs/zh/docs/admin/kpanda/images/faq01.png new file mode 100644 index 0000000..225d370 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/faq01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/faq02.png b/docs/zh/docs/admin/kpanda/images/faq02.png new file mode 100644 index 0000000..f261535 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/faq02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/faq204.png b/docs/zh/docs/admin/kpanda/images/faq204.png new file mode 100644 index 0000000..a771fbd Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/faq204.png differ diff --git a/docs/zh/docs/admin/kpanda/images/gpu_mig04.png b/docs/zh/docs/admin/kpanda/images/gpu_mig04.png new file mode 100644 index 0000000..a01cdab Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/gpu_mig04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo01.png b/docs/zh/docs/admin/kpanda/images/helmrepo01.png new file mode 100644 index 0000000..8e11f54 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo02.png b/docs/zh/docs/admin/kpanda/images/helmrepo02.png new file mode 100644 index 0000000..72df4f5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo03.png b/docs/zh/docs/admin/kpanda/images/helmrepo03.png new file mode 100644 index 0000000..d822eac Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo04.png b/docs/zh/docs/admin/kpanda/images/helmrepo04.png new file mode 100644 index 0000000..85046be Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo05.png b/docs/zh/docs/admin/kpanda/images/helmrepo05.png new file mode 100644 index 0000000..8ba82ef Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo07.png b/docs/zh/docs/admin/kpanda/images/helmrepo07.png new file mode 100644 index 0000000..cf7c1cc Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo07.png differ diff --git a/docs/zh/docs/admin/kpanda/images/helmrepo08.png b/docs/zh/docs/admin/kpanda/images/helmrepo08.png new file mode 100644 index 0000000..047dadd Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/helmrepo08.png differ diff --git a/docs/zh/docs/admin/kpanda/images/hpa-cronhpa-capability-rule-01.png b/docs/zh/docs/admin/kpanda/images/hpa-cronhpa-capability-rule-01.png new file mode 100644 index 0000000..30ee0e4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/hpa-cronhpa-capability-rule-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/imagequest.png b/docs/zh/docs/admin/kpanda/images/imagequest.png new file mode 100644 index 0000000..8a9ccc8 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/imagequest.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-home.png b/docs/zh/docs/admin/kpanda/images/inspection-home.png new file mode 100644 index 0000000..603832a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-home.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-list-more.png b/docs/zh/docs/admin/kpanda/images/inspection-list-more.png new file mode 100644 index 0000000..bb22184 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-list-more.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-report-01.png b/docs/zh/docs/admin/kpanda/images/inspection-report-01.png new file mode 100644 index 0000000..1d88404 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-report-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-report-02.png b/docs/zh/docs/admin/kpanda/images/inspection-report-02.png new file mode 100644 index 0000000..927d7c2 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-report-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-report-03.png b/docs/zh/docs/admin/kpanda/images/inspection-report-03.png new file mode 100644 index 0000000..11d621a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-report-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-start-alone.png b/docs/zh/docs/admin/kpanda/images/inspection-start-alone.png new file mode 100644 index 0000000..35a27f6 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-start-alone.png differ diff --git a/docs/zh/docs/admin/kpanda/images/inspection-start.png b/docs/zh/docs/admin/kpanda/images/inspection-start.png new file mode 100644 index 0000000..fb550d1 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/inspection-start.png differ diff --git a/docs/zh/docs/admin/kpanda/images/join-cluster01.png b/docs/zh/docs/admin/kpanda/images/join-cluster01.png new file mode 100644 index 0000000..b07542a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/join-cluster01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/join-cluster02.png b/docs/zh/docs/admin/kpanda/images/join-cluster02.png new file mode 100644 index 0000000..3631364 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/join-cluster02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/knative-install-1.png b/docs/zh/docs/admin/kpanda/images/knative-install-1.png new file mode 100644 index 0000000..0925c12 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/knative-install-1.png differ diff --git a/docs/zh/docs/admin/kpanda/images/knative-install-2.png b/docs/zh/docs/admin/kpanda/images/knative-install-2.png new file mode 100644 index 0000000..c2fa119 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/knative-install-2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/knative-install-3.png b/docs/zh/docs/admin/kpanda/images/knative-install-3.png new file mode 100644 index 0000000..1e84211 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/knative-install-3.png differ diff --git a/docs/zh/docs/admin/kpanda/images/knative-request-flow.png b/docs/zh/docs/admin/kpanda/images/knative-request-flow.png new file mode 100644 index 0000000..dfa6eb4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/knative-request-flow.png differ diff --git a/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-01.png b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-01.png new file mode 100644 index 0000000..a2dc078 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-02.png b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-02.png new file mode 100644 index 0000000..bb4d28f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-03.png b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-03.png new file mode 100644 index 0000000..c7685a4 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-04.png b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-04.png new file mode 100644 index 0000000..968cbbb Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/limit-disk-usage-docker-04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/note.svg b/docs/zh/docs/admin/kpanda/images/note.svg new file mode 100644 index 0000000..5e473ae --- /dev/null +++ b/docs/zh/docs/admin/kpanda/images/note.svg @@ -0,0 +1,18 @@ + + + + Icon/16/Prompt备份@0.5x + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/images/ns00.png b/docs/zh/docs/admin/kpanda/images/ns00.png new file mode 100644 index 0000000..7300a9c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/ns00.png differ diff --git a/docs/zh/docs/admin/kpanda/images/ns01.png b/docs/zh/docs/admin/kpanda/images/ns01.png new file mode 100644 index 0000000..c199640 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/ns01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/ns02.png b/docs/zh/docs/admin/kpanda/images/ns02.png new file mode 100644 index 0000000..dad110c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/ns02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/ns03.png b/docs/zh/docs/admin/kpanda/images/ns03.png new file mode 100644 index 0000000..058390a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/ns03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/ns04.png b/docs/zh/docs/admin/kpanda/images/ns04.png new file mode 100644 index 0000000..8b8863c Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/ns04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/operator-framework.svg b/docs/zh/docs/admin/kpanda/images/operator-framework.svg new file mode 100644 index 0000000..d3dc0fa --- /dev/null +++ b/docs/zh/docs/admin/kpanda/images/operator-framework.svg @@ -0,0 +1 @@ +Operator Framework logo \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/images/permisson02.png b/docs/zh/docs/admin/kpanda/images/permisson02.png new file mode 100644 index 0000000..4c69bdc Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/permisson02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/remove001.png b/docs/zh/docs/admin/kpanda/images/remove001.png new file mode 100644 index 0000000..e20f17d Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/remove001.png differ diff --git a/docs/zh/docs/admin/kpanda/images/rules.png b/docs/zh/docs/admin/kpanda/images/rules.png new file mode 100644 index 0000000..9cbefbb Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/rules.png differ diff --git a/docs/zh/docs/admin/kpanda/images/sc01.png b/docs/zh/docs/admin/kpanda/images/sc01.png new file mode 100644 index 0000000..62d05e0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/sc01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/sc03.png b/docs/zh/docs/admin/kpanda/images/sc03.png new file mode 100644 index 0000000..0bff950 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/sc03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/sc04 2.png b/docs/zh/docs/admin/kpanda/images/sc04 2.png new file mode 100644 index 0000000..b96215a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/sc04 2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/sc04.png b/docs/zh/docs/admin/kpanda/images/sc04.png new file mode 100644 index 0000000..0919834 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/sc04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/sc05.png b/docs/zh/docs/admin/kpanda/images/sc05.png new file mode 100644 index 0000000..35352a2 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/sc05.png differ diff --git a/docs/zh/docs/admin/kpanda/images/sc06.png b/docs/zh/docs/admin/kpanda/images/sc06.png new file mode 100644 index 0000000..1f7dea5 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/sc06.png differ diff --git a/docs/zh/docs/admin/kpanda/images/secret04.png b/docs/zh/docs/admin/kpanda/images/secret04.png new file mode 100644 index 0000000..40868ff Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/secret04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/secret08.png b/docs/zh/docs/admin/kpanda/images/secret08.png new file mode 100644 index 0000000..a986531 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/secret08.png differ diff --git a/docs/zh/docs/admin/kpanda/images/security08.png b/docs/zh/docs/admin/kpanda/images/security08.png new file mode 100644 index 0000000..4a1c8ab Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/security08.png differ diff --git a/docs/zh/docs/admin/kpanda/images/service03.png b/docs/zh/docs/admin/kpanda/images/service03.png new file mode 100644 index 0000000..338c365 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/service03.png differ diff --git a/docs/zh/docs/admin/kpanda/images/service04.png b/docs/zh/docs/admin/kpanda/images/service04.png new file mode 100644 index 0000000..fbd972e Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/service04.png differ diff --git a/docs/zh/docs/admin/kpanda/images/servicemonitor.png b/docs/zh/docs/admin/kpanda/images/servicemonitor.png new file mode 100644 index 0000000..fc0f82f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/servicemonitor.png differ diff --git a/docs/zh/docs/admin/kpanda/images/settings02.png b/docs/zh/docs/admin/kpanda/images/settings02.png new file mode 100644 index 0000000..e8f301f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/settings02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/success.png b/docs/zh/docs/admin/kpanda/images/success.png new file mode 100644 index 0000000..79d2a69 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/success.png differ diff --git a/docs/zh/docs/admin/kpanda/images/update-kpanda.png b/docs/zh/docs/admin/kpanda/images/update-kpanda.png new file mode 100644 index 0000000..44a204a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/update-kpanda.png differ diff --git a/docs/zh/docs/admin/kpanda/images/upgrade.png b/docs/zh/docs/admin/kpanda/images/upgrade.png new file mode 100644 index 0000000..a7566e3 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/upgrade.png differ diff --git a/docs/zh/docs/admin/kpanda/images/upload-helm-01.png b/docs/zh/docs/admin/kpanda/images/upload-helm-01.png new file mode 100644 index 0000000..9da7ed6 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/upload-helm-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/upload-helm-02.png b/docs/zh/docs/admin/kpanda/images/upload-helm-02.png new file mode 100644 index 0000000..9c22ba1 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/upload-helm-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/volcano-01 2.png b/docs/zh/docs/admin/kpanda/images/volcano-01 2.png new file mode 100644 index 0000000..c176723 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/volcano-01 2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/volcano-01.png b/docs/zh/docs/admin/kpanda/images/volcano-01.png new file mode 100644 index 0000000..0b03312 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/volcano-01.png differ diff --git a/docs/zh/docs/admin/kpanda/images/volcano-02 2.png b/docs/zh/docs/admin/kpanda/images/volcano-02 2.png new file mode 100644 index 0000000..d79735b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/volcano-02 2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/volcano-02.png b/docs/zh/docs/admin/kpanda/images/volcano-02.png new file mode 100644 index 0000000..fbcbf4b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/volcano-02.png differ diff --git a/docs/zh/docs/admin/kpanda/images/volcano-03 2.png b/docs/zh/docs/admin/kpanda/images/volcano-03 2.png new file mode 100644 index 0000000..5112532 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/volcano-03 2.png differ diff --git a/docs/zh/docs/admin/kpanda/images/volcano-03.png b/docs/zh/docs/admin/kpanda/images/volcano-03.png new file mode 100644 index 0000000..97afd08 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/images/volcano-03.png differ diff --git a/docs/zh/docs/admin/kpanda/inspect/config.md b/docs/zh/docs/admin/kpanda/inspect/config.md new file mode 100644 index 0000000..0685684 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/inspect/config.md @@ -0,0 +1,52 @@ +--- +hide: + - toc +--- + +# 创建巡检配置 + +算丰 AI 算力平台容器管理模块提供集群巡检功能,支持从集群维度、节点维度、容器组维度进行巡检。 + +- 集群维度:检查集群中系统组件的运行情况,包括集群状态、资源使用情况,以及控制节点特有的巡检项等,例如 __kube-apiserver__ 和 __etcd__ 的状态。 +- 节点维度:包括控制节点和工作节点通用的检查项,例如节点资源使用情况、句柄数、PID 状态、网络状态。 +- 容器组维度:检查 Pod 的 CPU 和内存使用情况、运行状态、PV 和 PVC 的状态等。 + +下面介绍如何创建巡检配置。 + +## 前提条件 + +- 在容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建集群](../clusters/create-cluster.md) +- 所选集群处于 __运行中__ 状态且已经在集群中[安装了 insight 组件](../../../admin/insight/quickstart/install/install-agent.md) + +## 操作步骤 + +1. 在左侧导航栏点击 __集群巡检__ 。 + + ![nav](../../../images/inspect01.png) + +2. 在页面右侧点击 __巡检配置__ 。 + + ![create](../images/inspection-home.png) + +3. 参考以下说明填写巡检配置,然后在页面底部点击 __确定__ 即可。 + + - 集群:下拉选择要对哪些集群进行巡检。**如果选择多个集群,则自动生成多个巡检配置(仅巡检的集群不一致,其他配置都完全一致)** + - 定时巡检:启用后可根据事先设置的巡检频率定期自动执行集群巡检 + - 巡检频率:设置自动巡检的周期,例如每周二上午十点。支持自定义 CronExpression,可参考 [Cron 时间表语法](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax) + - 巡检记录保留条数:累计最多保留多少条巡检记录,包括所有集群的巡检记录 + - 参数配置:参数配置分为集群维度、节点维度、容器组维度三部分,可以根据场景需求启用或禁用某些巡检项。 + + ![basic](../../../images/inspect03.png) + +巡检配置创建完成后,会自动显示在巡检配置列表中。在配置右侧点击更多操作按钮可以立即执行巡检、修改巡检配置、删除巡检配置和巡检记录。 + +- 点击 __巡检__ 可以根据该配置立即执行一次巡检。 +- 点击 __巡检配置__ 可以修改巡检配置。 +- 点击 __删除__ 可以删除该巡检配置和历史的巡检记录 + + ![basic](../images/inspection-list-more.png) + +!!! note + + - 巡检配置创建完成后,如果启用了 __定时巡检__ 配置,则会在指定时间自动执行巡检。 + - 如未启用 __定时巡检__ 配置,则需要手动[触发巡检](inspect.md)。 diff --git a/docs/zh/docs/admin/kpanda/inspect/index.md b/docs/zh/docs/admin/kpanda/inspect/index.md new file mode 100644 index 0000000..3dd6e97 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/inspect/index.md @@ -0,0 +1,17 @@ +--- +hide: + - toc +--- + +# 集群巡检 + +集群巡检可以通过自动或手动方式,定期或随时检查集群的整体健康状态,让管理员获得保障集群安全的主动权。 +基于合理的巡检计划,这种主动自发的集群检查可以让管理员随时掌握集群状态,摆脱之前出现故障时只能被动排查问题的困境,做到事先监控、提前防范。 + +算丰 AI 算力平台容器管理模块提供的集群巡检功能,支持从集群、节点、容器组(Pod)三个维度进行自定义巡检项,巡检结束后会自动生成可视化的巡检报告。 + +- 集群维度:检查集群中系统组件的运行情况,包括集群状态、资源使用情况以及控制节点特有的巡检项等,例如 __kube-apiserver__ 和 __etcd__ 的状态。 +- 节点维度:包括控制节点和工作节点通用的检查项,例如节点资源使用情况、句柄数、PID 状态、网络状态。 +- 容器组维度:检查 Pod 的 CPU 和内存使用情况、运行状态、PV 和 PVC 的状态等。 + +如需了解或执行安全方面的巡检,可参考算丰 AI 算力平台支持的[安全扫描类型](../security/index.md)。 diff --git a/docs/zh/docs/admin/kpanda/inspect/inspect.md b/docs/zh/docs/admin/kpanda/inspect/inspect.md new file mode 100644 index 0000000..d84c9d5 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/inspect/inspect.md @@ -0,0 +1,40 @@ +--- +hide: + - toc +--- + +# 执行集群巡检 + +巡检配置创建完成后,如果启用了 __定时巡检__ 配置,则会在指定时间自动执行巡检。如未启用 __定时巡检__ 配置,则需要手动触发巡检。 + +此页介绍如何手动执行集群巡检。 + +## 前提条件 + +- 在容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建集群](../clusters/create-cluster.md) +- 已[创建巡检配置](config.md) +- 所选集群处于 __运行中__ 状态且已经在集群中[安装了 insight 组件](../../../admin/insight/quickstart/install/install-agent.md) + +## 操作步骤 + +执行巡检时,支持勾选多个集群进行批量巡检,或者仅对某一个集群进行单独巡检。 + +=== "批量巡检" + + 1. 在容器管理模块的一级导航栏点击 __集群巡检__ ,然后在页面右侧点击 __巡检__ 。 + + ![start](../images/inspection-start.png) + + 2. 勾选需要巡检的集群,然后在页面底部点击 __确定__ 即可。 + + - 若选择多个集群进行同时巡检,系统将根据不同集群的巡检配置进行巡检。 + - 如未设置集群巡检配置,将使用系统默认配置。 + + ![start](../../../images/inspect05.png) + +=== "单独巡检" + + 1. 进入集群巡检页面。 + 2. 在对应巡检配置的右侧点击 __┇__ 更多操作按钮,然后在弹出的菜单中选择 __巡检__ 即可。 + + ![basic](../images/inspection-start-alone.png) diff --git a/docs/zh/docs/admin/kpanda/inspect/report.md b/docs/zh/docs/admin/kpanda/inspect/report.md new file mode 100644 index 0000000..7799cb1 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/inspect/report.md @@ -0,0 +1,32 @@ +--- +hide: + - toc +--- + +# 查看巡检报告 + +[巡检执行](inspect.md)完成后,可以查看巡检记录和详细的巡检报告。 + +## 前提条件 + +- 已经[创建了巡检配置](config.md) +- 已经[执行过至少一次巡检](inspect.md) + +## 操作步骤 + +1. 进入集群巡检页面,点击目标巡检集群的名称。 + + ![start](../images/inspection-report-01.png) + +2. 点击想要查看的巡检记录名称。 + + - 每执行一次巡检,就会生成一条巡检记录。 + - 当巡检记录超过[巡检配置](config.md)中设置的最大保留条数时,从执行时间最早的记录开始删除。 + + ![start](../images/inspection-report-02.png) + +3. 查看巡检的详细信息,根据巡检配置可能包括集群资源概览、系统组件的运行情况等。 + + 在页面右上角可以下载巡检报告或删除该项巡检报告。 + + ![start](../images/inspection-report-03.png) diff --git a/docs/zh/docs/admin/kpanda/namespaces/createns.md b/docs/zh/docs/admin/kpanda/namespaces/createns.md new file mode 100644 index 0000000..215b467 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/namespaces/createns.md @@ -0,0 +1,56 @@ +# 命名空间 + +命名空间是 Kubernetes 中用来进行资源隔离的一种抽象。一个集群下可以包含多个不重名的命名空间,每个命名空间中的资源相互隔离。有关命名空间的详细介绍,可参考[命名空间](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/namespaces/)。 + +本文将介绍命名空间的相关操作。 + +## 创建命名空间 + +支持通过表单轻松创建命名空间,也支持通过编写或导入 YAML 文件快速创建命名空间。 + +!!! note + + - 在创建命名空间之前,需要在容器管理模块[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md)。 + - 集群初始化后通常会自动生成默认的命名空间 __default__ 。但对于生产集群而言,为便于管理,建议创建其他的命名空间,而非直接使用 __default__ 命名空间。 + +### 表单创建 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏点击 __命名空间__ ,然后点击页面右侧的 __创建__ 按钮。 + + ![点击创建](../images/ns01.png) + +3. 填写命名空间的名称,配置工作空间和标签(可选设置),然后点击 __确定__ 。 + + !!! info + + - 命名空间绑定工作空间之后,该命名空间的资源就会共享给所绑定的工作空间。有关工作空间的详细说明,可参考[工作空间与层级](../../ghippo/workspace/workspace.md)。 + + - 命名空间创建完成后,仍然可以绑定/解绑工作空间。 + + ![填写表单](../images/ns02.png) + +4. 点击 __确定__ ,完成命名空间的创建。在命名空间列表右侧,点击 __┇__ ,可以从弹出菜单中选择查看 YAML、修改标签、绑定/解绑工作空间、配额管理、删除等更多操作。 + + ![更多操作](../images/ns03.png) + +### YAML 创建 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏点击 __命名空间__ ,然后点击页面右侧的 __YAML 创建__ 按钮。 + + ![点击创建](../images/ns00.png) + +3. 输入或粘贴事先准备好的 YAML 内容,或者从本地直接导入已有的 YAML 文件。 + + > 输入 YAML 内容后,点击 __下载__ 可以将该 YAML 文件保存到本地。 + + ![点击创建](../images/ns04.png) + +4. 最后在弹框右下角点击 __确定__ 即可。 \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/namespaces/exclusive.md b/docs/zh/docs/admin/kpanda/namespaces/exclusive.md new file mode 100644 index 0000000..a246a8f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/namespaces/exclusive.md @@ -0,0 +1,203 @@ +# 启用命名空间独享节点 + +命名空间独享节点指在 kubernetes 集群中,通过污点和污点容忍的方式实现特定命名空间对一个或多个节点 CPU、内存等资源的独享。为特定命名空间配置独享节点后,其它非此命名空间的应用和服务均不能运行在被独享的节点上。使用独享节点可以让重要应用独享一部分计算资源,从而和其他应用实现物理隔离。 + +!!! note + + 在节点被设置为独享节点前已经运行在此节点上的应用和服务将不会受影响,依然会正常运行在该节点上,仅当这些 Pod 被删除或重建时,才会调度到其它非独享节点上。 + +## 准备工作 + +检查当前集群的 kube-apiserver 是否启用了 __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器。 + +使用命名空间独享节点功能需要用户启用 kube-apiserver 上的 __PodNodeSelector__ 和 __PodTolerationRestriction__ 两个特性准入控制器(Admission Controllers),关于准入控制器更多说明请参阅 [kubernetes Admission Controllers Reference](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)。 + +您可以前往当前集群下任意一个 Master 节点上检查 __kube-apiserver.yaml__ 文件内是否启用了这两个特性,也可以在 Master 节点上执行执行如下命令进行快速检查: + + ```bash + [root@g-master1 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep enable-admission-plugins + + # 预期输出如下: + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +## 在全局服务集群上启用命名空间独享节点 + +由于全局服务集群上运行着 kpanda、ghippo、insight 等平台基础组件,在 Global 启用命名空间独享节点将可能导致当系统组件重启后,系统组件无法调度到被独享的节点上,影响系统的整体高可用能力。因此,**通常情况下,我们不推荐用户在全局服务集群上启用命名空间独享节点特性**。 + +如果您确实需要在全局服务集群上启用命名空间独享节点,请参考以下步骤进行开启: + +1. 为全局服务集群的 kube-apiserver 启用了 __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器 + + !!! note + + 如果集群已启用了上述的两个准入控制器,请跳过此步,直接前往配置系统组件容忍。 + + 前往当前集群下任意一个 Master 节点上修改 __kube-apiserver.yaml__ 配置文件,也可以在 Master 节点上执行执行如下命令进行配置: + + ```bash + [root@g-master1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml + + # 预期输出如下: + apiVersion: v1 + kind: Pod + metadata: + ...... + spec: + containers: + - command: + - kube-apiserver + ...... + - --default-not-ready-toleration-seconds=300 + - --default-unreachable-toleration-seconds=300 + - --enable-admission-plugins=NodeRestriction #启用的准入控制器列表 + - --enable-aggregator-routing=False + - --enable-bootstrap-token-auth=true + - --endpoint-reconciler-type=lease + - --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.crt + ...... + ``` + + 找到 __--enable-admission-plugins__ 参数,加入(以英文逗号分隔的) __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器。参考如下: + + ```bash + # 加入 __ ,PodNodeSelector,PodTolerationRestriction__ + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +2. 为平台组件所在的命名空间添加容忍注解 + + 完成准入控制器的开启后,您需要为平台组件所在的命名空间添加容忍注解,以保证平台组件的高可用。 + + 目前算丰 AI 算力平台的系统组件命名空间如下表: + + | 命名空间 | 所包含的系统组件 | + | ------------------- | ------------------------------------------------------------ | + | kpanda-system | kpanda | + | hwameiStor-system | hwameiStor | + | istio-system | istio | + | metallb-system | metallb | + | cert-manager-system | cert-manager | + | contour-system | contour | + | kubean-system | kubean | + | ghippo-system | ghippo | + | kcoral-system | kcoral | + | kcollie-system | kcollie | + | insight-system | insight、insight-agent: | + | ipavo-system | ipavo | + | kairship-system | kairship | + | karmada-system | karmada | + | amamba-system | amamba、jenkins | + | skoala-system | skoala | + | mspider-system | mspider | + | mcamel-system | mcamel-rabbitmq、mcamel-elasticsearch、mcamel-mysql、mcamel-redis、mcamel-kafka、mcamel-minio、mcamel-postgresql | + | spidernet-system | spidernet | + | kangaroo-system | kangaroo | + | gmagpie-system | gmagpie | + | dowl-system | dowl | + + 检查当前集群中所有命名空间是否存在上述的命名空间,执行如下命令,分别为每个命名空间添加注解: `scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": "NoSchedule", "key": "ExclusiveNamespace"}]'` 。 + + ```bash + kubectl annotate ns scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]' + ``` + 请确保将 `` 替换为要添加注解的平台命名空间名称。 + +3. 使用界面为命名空间设置独享节点 + + 当您确认集群 API 服务器上的 __PodNodeSelector__ 和 __PodTolerationRestriction__ 两个特性准入控制器已经开启后,请参考如下步骤使用算丰 AI 算力平台的 UI 管理界面为命名空间设置独享节点了。 + + 1. 在集群列表页面点击集群名称,然后在左侧导航栏点击 __命名空间__ 。 + + ![命名空间](../../../images/exclusive01.png) + + 2. 点击命名空间名称,然后点击 __独享节点__ 页签,在下方右侧点击 __添加节点__ 。 + + ![添加节点](../../../images/exclusive02.png) + + 3. 在页面左侧选择让该命名空间独享哪些节点,在右侧可以清空或删除某个已选节点,最后在底部点击 __确定__ 。 + + ![确定](../../../images/exclusive03.png) + + 4. 可以在列表中查看此命名空间的已有的独享节点,在节点右侧可以选择 __取消独享__ 。 + + > 取消独享之后,其他命名空间下的 Pod 也可以被调度到该节点上。 + + ![取消独享](../../../images/exclusive04.png) + +## 在 非全局服务集群上启用命名空间独享节点 + +在 非全局服务集群上启用命名空间独享节点,请参考以下步骤进行开启: + +1. 为当前集群的 kube-apiserver 启用了 __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器 + + !!! note + + 如果集群已启用了上述的两个准入控制器,请跳过此步,直接前往界面为命名空间设置独享节点 + + 前往当前集群下任意一个 Master 节点上修改 __kube-apiserver.yaml__ 配置文件,也可以在 Master 节点上执行执行如下命令进行配置: + + ```bash + [root@g-master1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml + + # 预期输出如下: + apiVersion: v1 + kind: Pod + metadata: + ...... + spec: + containers: + - command: + - kube-apiserver + ...... + - --default-not-ready-toleration-seconds=300 + - --default-unreachable-toleration-seconds=300 + - --enable-admission-plugins=NodeRestriction #启用的准入控制器列表 + - --enable-aggregator-routing=False + - --enable-bootstrap-token-auth=true + - --endpoint-reconciler-type=lease + - --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.crt + ...... + ``` + + 找到 __--enable-admission-plugins__ 参数,加入(以英文逗号分隔的) __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器。参考如下: + + ```bash + # 加入 __ ,PodNodeSelector,PodTolerationRestriction__ + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +2. 使用界面为命名空间设置独享节点 + + 当您确认集群 API 服务器上的 __PodNodeSelector__ 和 __PodTolerationRestriction__ 两个特性准入控制器已经开启后,请参考如下步骤使用算丰 AI 算力平台的 UI 管理界面为命名空间设置独享节点了。 + + 1. 在集群列表页面点击集群名称,然后在左侧导航栏点击 __命名空间__ 。 + + ![命名空间](../../../images/exclusive01.png) + + 2. 点击命名空间名称,然后点击 __独享节点__ 页签,在下方右侧点击 __添加节点__ 。 + + ![添加节点](../../../images/exclusive02.png) + + 3. 在页面左侧选择让该命名空间独享哪些节点,在右侧可以清空或删除某个已选节点,最后在底部点击 __确定__ 。 + + ![确定](../../../images/exclusive03.png) + + 4. 可以在列表中查看此命名空间的已有的独享节点,在节点右侧可以选择 __取消独享__ 。 + + > 取消独享之后,其他命名空间下的 Pod 也可以被调度到该节点上。 + + ![取消独享](../../../images/exclusive04.png) + +3. 为需要高可用的组件所在的命名空间添加容忍注解(可选) + + 执行如下命令,需要高可用的组件所在的命名空间添加注解:`scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]'`。 + + ```bash + kubectl annotate ns scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]' + ``` + + 请确保将 `` 替换为要添加注解的平台命名空间名称。 diff --git a/docs/zh/docs/admin/kpanda/namespaces/podsecurity.md b/docs/zh/docs/admin/kpanda/namespaces/podsecurity.md new file mode 100644 index 0000000..680a84d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/namespaces/podsecurity.md @@ -0,0 +1,51 @@ +# 容器组安全策略 + +容器组安全策略指在 kubernetes 集群中,通过为指定命名空间配置不同的等级和模式,实现在安全的各个方面控制 Pod 的行为,只有满足一定的条件的 Pod 才会被系统接受。它设置三个等级和三种模式,用户可以根据自己的需求选择更加合适的方案来设置限制策略。 + +!!! note + + 一条安全模式仅能配置一条安全策略。同时请谨慎为命名空间配置 enforce 的安全模式,违反后将会导致 Pod 无法创建。 + +本节将介绍如何通过容器管理界面为命名空间配置容器组安全策略。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),集群的版本需要在 v1.22 以上,且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 为命名空间配置容器组安全策略 + +1. 选择需要配置容器组安全策略的命名空间,进入详情页。在 __容器组安全策略__ 页面点击 __配置策略__ ,进入配置页。 + + ![配置策略列表](../../../images/ps01.png) + +2. 在配置页点击 __添加策略__ ,则会出现一条策略,包括安全级别和安全模式,以下是对安全级别和安全策略的详细介绍。 + + | 安全级别 | 描述 | + | ---------- | ------------------------------------------------------------ | + | Privileged | 不受限制的策略,提供最大可能范围的权限许可。此策略允许已知的特权提升。 | + | Baseline | 限制性最弱的策略,禁止已知的策略提升。允许使用默认的(规定最少)Pod 配置。 | + | Restricted | 限制性非常强的策略,遵循当前的保护 Pod 的最佳实践。 | + + | 安全模式 | 描述 | + | -------- | ------------------------------------------------------------ | + | Audit | 违反指定策略会在审计日志中添加新的审计事件,Pod 可以被创建。 | + | Warn | 违反指定策略会返回用户可见的告警信息,Pod 可以被创建。 | + | Enforce | 违反指定策略会导致 Pod 无法创建。 | + + ![添加策略](../../../images/ps02.png) + +3. 不同的安全级别对应不同的检查项,若您不知道该如何为您的命名空间配置,可以点击页面右上角的 __策略配置项说明__ 查看详细信息。 + + ![配置项说明01](../../../images/ps03.png) + + ![配置项说明01](../../../images/ps04.png) + +4. 点击确定,若创建成功,则页面上将出现您配置的安全策略。 + + ![创建成功](../../../images/ps05.png) + +5. 点击 __┇__ 还可以编辑或者删除您配置的安全策略。 + + ![操作](../../../images/ps06.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/network/create-ingress.md b/docs/zh/docs/admin/kpanda/network/create-ingress.md new file mode 100644 index 0000000..61ab628 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/network/create-ingress.md @@ -0,0 +1,90 @@ +# 创建路由(Ingress) + +在 Kubernetes 集群中,[Ingress](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ingress-v1beta1-networking-k8s-io) 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 +流量路由由 Ingress 资源上定义的规则控制。下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例: + +![ingress-diagram](../../../images/ingress.svg) + +Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 +- 已经完成 Ingress 实例的创建,已[部署应用工作负载](../workloads/create-deployment.md),并且已[创建对应 Service](create-services.md) +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 创建路由 + +1. 以 __NS Editor__ 用户成功登录后,点击左上角的 __集群列表__ 进入 __集群列表__ 页面。在集群列表中,点击一个集群名称。 + + ![集群列表](../../../images/ingress01.png) + +2. 在左侧导航栏中,点击 __容器网络__ -> __路由__ 进入服务列表,点击右上角 __创建路由__ 按钮。 + + ![服务与路由](../../../images/ingress02.png) + + !!! note + + 也可以通过 __YAML 创建__ 一个路由。 + +3. 打开 __创建路由__ 页面,进行配置。可选择两种协议类型,参考以下两个参数表进行配置。 + +### 创建 HTTP 协议路由 + +输入如下参数: + +![创建路由](../../../images/ingress03.png) + +- __路由名称__ :必填,输入新建路由的名称。 +- __命名空间__ :必填,选择新建服务所在的命名空间。关于命名空间更多信息请参考命名空间概述。 +- __设置路由规则__ : + - __域名__ :必填,使用域名对外提供访问服务。默认为集群的域名。 + - __协议__ :必填,指授权入站到达集群服务的协议,支持 HTTP (不需要身份认证)或 HTTPS(需需要配置身份认证) 协议。 + 这里选择 HTTP 协议的路由。 + - __转发策略__ :选填,指定 Ingress 的访问策略 + - __路径__ :指定服务访问的URL路径,默认为根路径 + - __目标服务__ :进行路由的服务名称 + - __目标服务端口__ :服务对外暴露的端口 +- __负载均衡器类型__ :必填,Ingress 实例的使用范围 + - __平台级负载均衡器__ :同一个集群内,共享同一个 Ingress 实例,其中 Pod 都可以接收到由该负载均衡分发的请求 + - __租户级负载均衡器__ :租户负载均衡器,Ingress 实例独属于当前命名空,或者独属于某一工作空间, + 并且设置的工作空间中包含当前命名空间,其中 Pod 都可以接收到由该负载均衡分发的请求 +- __Ingress Class__ :选填,选择对应的 Ingress 实例,选择后将流量导入到指定的 Ingress 实例。 + - 为 None 时使用默认的 DefaultClass,请在创建 Ingress 实例时设置 DefaultClass, + 更多信息请参考 Ingress Class + - 若选择其他实例(如 __ngnix__ ),则会出现高级配置,可设置 __会话保持__ 、 __路径重写__ 、 __重定向__ 和 __流量分发__ 。 +- __会话保持__ :选填,会话保持分为 三种类型: __L4 源地址哈希__ 、 __Cookie Key__ 、 __L7 Header Name__ ,开启后根据对应规则进行会话保持。 + - __L4 源地址哈希__ :开启后默认在 Annotation 中加入如下标签: + `nginx.ingress.kubernetes.io/upstream-hash-by: "$binary_remote_addr"` + - __Cookie Key__ :开启后来自特定客户端的连接将传递至相同 Pod,开启后 默认在 Annotation 中增加如下参数: + `nginx.ingress.kubernetes.io/affinity: "cookie"。nginx.ingress.kubernetes.io/affinity-mode: persistent` + - __L7 Header Name__ :开启后默认在 Annotation 中加入如下标签: + `nginx.ingress.kubernetes.io/upstream-hash-by: "$http_x_forwarded_for"` +- __路径重写__ :选填, __rewrite-target__ ,某些场景中后端服务暴露的URL与Ingress规则中指定的路径不同,如果不进行URL重写配置,访问会出现错误。 +- __重定向__ :选填, __permanent-redirect__ ,永久重定向,输入重写路径后,访问路径重定向至设置的地址。 +- __流量分发__ :选填,开启后并设置后,根据设定条件进行流量分发。 + - __基于权重__ :设定权重后,在创建的 Ingress 添加如下 Annotation: + __nginx.ingress.kubernetes.io/canary-weight: "10"__ + - __基于 Cookie__ :设定 Cookie 规则后,流量根据设定的 Cookie 条件进行流量分发 + - __基于 Header__ : 设定 Header 规则后,流量根据设定的 Header 条件进行流量分发 +- __标签__ :选填,为路由添加标签 +- __注解__ :选填,为路由添加注解 + +### 创建 HTTPS 协议路由 + +输入如下参数: +![创建路由](../../../images/ingress04.png) + +!!! note + + 注意:与 HTTP 协议 __设置路由规则__ 不同,增加密钥选择证书,其他基本一致。 + +- __协议__ :必填指授权入站到达集群服务的协议,支持 HTTP (不需要身份认证)或 HTTPS(需需要配置身份认证) 协议。这里选择 HTTPS 协议的路由。 +- __密钥__ :必填,Https TLS 证书,[创建秘钥](../configmaps-secrets/create-secret.md)。 + +### 完成路由创建 + +配置完所有参数后,点击 __确定__ 按钮,自动返回路由列表。在列表右侧,点击 __┇__ ,可以修改或删除所选路由。 + +![路由列表](../../../images/ingress05.png) diff --git a/docs/zh/docs/admin/kpanda/network/create-services.md b/docs/zh/docs/admin/kpanda/network/create-services.md new file mode 100644 index 0000000..2bb7763 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/network/create-services.md @@ -0,0 +1,95 @@ +# 创建服务(Service) + +在 Kubernetes 集群中,每个 Pod 都有一个内部独立的 IP 地址,但是工作负载中的 Pod 可能会被随时创建和删除,直接使用 Pod IP 地址并不能对外提供服务。 + +这就需要创建服务,通过服务您会获得一个固定的 IP 地址,从而实现工作负载前端和后端的解耦,让外部用户能够访问服务。同时,服务还提供了负载均衡(LoadBalancer)功能,使用户能从公网访问到工作负载。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 创建服务 + +1. 以 __NS Editor__ 用户成功登录后,点击左上角的 __集群列表__ 进入 __集群列表__ 页面。在集群列表中,点击一个集群名称。 + + ![集群列表](../../../images/service01.png) + +2. 在左侧导航栏中,点击 __容器网络__ -> __服务__ 进入服务列表,点击右上角 __创建服务__ 按钮。 + + ![服务与路由](../../../images/service02.png) + + !!! tip + + 也可以通过 YAML 创建 一个服务。 + +3. 打开 __创建服务__ 页面,选择一种访问类型,参考以下几个参数表进行配置。 + + ![创建服务](../images/service03.png) + +### 创建 ClusterIP 服务 + +点选 __集群内访问(ClusterIP)__ ,这是指通过集群的内部 IP 暴露服务,选择此项的服务只能在集群内部访问。这是默认的服务类型。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | +| ---------------- | :----------------------------------------------------------- | :-------- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择集群内访问(ClusterIP)。 | ClusterIP | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | +| 标签选择器 | 【类型】必填
【含义】添加标签,Service 根据标签选择 Pod,填写后点击“添加”。也可以引用已有工作负载的标签,点击 __引用负载标签__ ,在弹出的窗口中选择负载,系统会默认将所选的负载标签作为选择器。 | app:job01 | +| 端口配置 | 【类型】必填
【含义】为服务添加协议端口,需要先选择端口协议类型,目前支持 TCP、UDP 两种传输协议。
**端口名称**:输入自定义的端口的名称。
**服务端口(port)**:Pod 对外提供服务的访问端口。
**容器端口(targetport)**:工作负载实际监听的容器端口,用来对集群内暴露服务。 | | +| 会话保持 | 【类型】选填
【含义】开启后,相同客户端的请求将转发至同一 Pod | 开启 | +| 会话保持最大时长 | 【类型】选填
【含义】开启会话保持后,保持的最大时长,默认为 30 秒 | 30 秒 | +| 注解 | 【类型】选填
【含义】为服务添加注解
| | + +### 创建 NodePort 服务 + +点选 __节点访问(NodePort)__ ,这是指通过每个节点上的 IP 和静态端口( __NodePort__ )暴露服务。 __NodePort__ 服务会路由到自动创建的 __ClusterIP__ 服务。通过请求 __<节点 IP>:<节点端口>__ ,您可以从集群的外部访问一个 __NodePort__ 服务。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | +| ---------------- | :----------------------------------------------------------- | :------- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择节点访问(NodePort)。 | NodePort | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | +| 标签选择器 | 【类型】必填
【含义】添加标签,Service 根据标签选择 Pod,填写后点击“添加”。也可以引用已有工作负载的标签,点击 __引用负载标签__ ,在弹出的窗口中选择负载,系统会默认将所选的负载标签作为选择器。 | | +| 端口配置 | 【类型】必填
【含义】为服务添加协议端口,需要先选择端口协议类型,目前支持 TCP、UDP 两种传输协议。
**端口名称**:输入自定义的端口的名称。
**服务端口(port)**:Pod 对外提供服务的访问端口。*默认情况下,为了方便起见,服务端口被设置为与容器端口字段相同的值。*
**容器端口(targetport)**:工作负载实际监听的容器端口。
**节点端口(nodeport)**:节点的端口,接收来自 ClusterIP 传输的流量。用来做外部流量访问的入口。 | | +| 会话保持 | 【类型】选填
【含义】开启后,相同客户端的请求将转发至同一 Pod
开启后 Service 的 `.spec.sessionAffinity` 为 __ClientIP__ ,详情请参考:[Service 的会话亲和性](https://kubernetes.io/zh-cn/docs/reference/networking/virtual-ips/#session-affinity) | 开启 | +| 会话保持最大时长 | 【类型】选填
【含义】开启会话保持后,保持的最大时长,默认超时时长为 30 秒
.spec.sessionAffinityConfig.clientIP.timeoutSeconds 默认设置为 30 秒 | 30 秒 | +| 注解 | 【类型】选填
【含义】为服务添加注解
| | + +### 创建 LoadBalancer 服务 + +点选 __负载均衡(LoadBalancer)__ ,这是指使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 __NodePort__ 服务和 __ClusterIP__ 服务上。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | | +| ------------- | :----------------------------------------------------------- | :------- | ---- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择负载均衡(LoadBalancer)。 | LoadBalancer | | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | | +| 外部流量策略 | 【类型】必填
【含义】设置外部流量策略。
**Cluster**:流量可以转发到集群中所有节点上的 Pod。
**Local**:流量只发给本节点上的 Pod。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | | | +| 标签选择器 | 【类型】必填
【含义】添加标签,Service 根据标签选择 Pod,填写后点击“添加”。也可以引用已有工作负载的标签,点击 __引用负载标签__ ,在弹出的窗口中选择负载,系统会默认将所选的负载标签作为选择器。 | | | +| 负载均衡类型 | 【类型】必填
【含义】使用的负载均衡类型,当前支持 MetalLB 和其他。 | | | +| MetalLB IP 池 | 【类型】必填
【含义】选择的 负载均衡类型为 MetalLB 时,LoadBalancer Service默认会从这个池中分配 IP 地址, 并且通过 APR 宣告这个池中的所有 IP 地址 | | | +| 负载均衡地址 | 【类型】必填
【含义】
1.如使用的是公有云 CloudProvider,此处填写的为云厂商提供的负载均衡地址;
2.如果上述负载均衡类型选择为 MetalLB ,默认从上述 IP 池中获取 IP ,如果不填则自动获取。 | | | +| 端口配置 | 【类型】必填
【含义】为服务添加协议端口,需要先选择端口协议类型,目前支持 TCP、UDP 两种传输协议。
**端口名称**:输入自定义的端口的名称。
**服务端口(port)**:Pod 对外提供服务的访问端口。默认情况下,为了方便起见,服务端口被设置为与容器端口字段相同的值。
**容器端口(targetport)**:工作负载实际监听的容器端口。
**节点端口(nodeport)**:节点的端口,接收来自 ClusterIP 传输的流量。用来做外部流量访问的入口。 | | | +| 注解 | 【类型】选填
【含义】为服务添加注解
| | | + +### 创建 ExternalName 服务 + +点选 __外部服务(ExternalName)__ ,这是指通过将服务映射到外部域名来暴露服务。选择此项的服务不会创建典型的 ClusterIP 或 NodePort,而是通过 DNS 名称解析将请求重定向到外部的服务地址。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | | +| ------------- | :----------------------------------------------------------- | :------- | ---- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择外部服务(ExternalName)。 | ExternalName | | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | | +| 域名 | 【类型】必填
| | | + +### 完成服务创建 + +配置完所有参数后,点击 __确定__ 按钮,自动返回服务列表。在列表右侧,点击 __┇__ ,可以修改或删除所选服务。 + +![服务列表](../images/service04.png) diff --git a/docs/zh/docs/admin/kpanda/network/network-policy.md b/docs/zh/docs/admin/kpanda/network/network-policy.md new file mode 100644 index 0000000..7eb40a4 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/network/network-policy.md @@ -0,0 +1,87 @@ +# 网络策略 + +网络策略(NetworkPolicy)可以在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量。容器管理模块目前支持创建基于 Pod 或命名空间的网络策略,支持通过标签选择器来设定哪些流量可以进入或离开带有特定标签的 Pod。 + +有关网络策略的更多详情,可参考 Kubernetes 官方文档[网络策略](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/)。 + +## 创建网络策略 + +目前支持通过 YAML 和表单两种方式创建网络策略,这两种方式各有优劣,可以满足不同用户的使用需求。 + +通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉网络策略的 YAML 文件配置。 + +通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器网络__ -> __网络策略__ -> __YAML 创建__ 。 + + ![路径](../../../images/networkpolicy01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + ![yaml](../../../images/networkpolicy02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器网络__ -> __网络策略__ -> __创建策略__ 。 + + ![路径](../../../images/networkpolicy03.png) + +2. 填写基本信息。 + + 名称和命名空间在创建之后不可更改。 + + ![基本信息](../../../images/networkpolicy04.png) + +3. 填写策略配置。 + + 策略配置分为入流量策略和出流量策略。如果源 Pod 想要成功连接到目标 Pod,源 Pod 的出流量策略和目标 Pod 的入流量策略都需要允许连接。如果任何一方不允许连接,都会导致连接失败。 + + - 入流量策略:点击 __➕__ 开始配置策略,支持配置多条策略。多条网络策略的效果相互叠加,只有同时满足所有网络策略,才能成功建立连接。 + + ![ingress](../../../images/networkpolicy05.png) + + - 出流量策略 + + ![egress](../../../images/networkpolicy06.png) + +## 查看网络策略 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器网络__ -> __网络策略__ ,点击网络策略的名称。 + + ![路径](../../../images/networkpolicy07.png) + +2. 查看该策略的基本配置、关联实例信息、入流量策略、出流量策略。 + + ![详情](../../../images/networkpolicy08.png) + +!!! info + + 在关联实例页签下,支持查看实例监控、日志、容器列表、YAML 文件、事件等。 + + ![查看实例信息](../../../images/networkpolicy09.png) + +## 更新网络策略 + +有两种途径可以更新网络策略。支持通过表单或 YAML 文件更新网络策略。 + +- 在网络策略列表页面,找到需要更新的策略,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/networkpolicy10.png) + +- 点击网络策略的名称,进入网络策略的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/networkpolicy11.png) + +## 删除网络策略 + +有两种途径可以删除网络策略。支持通过表单或 YAML 文件更新网络策略。 + +- 在网络策略列表页面,找到需要更新的策略,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 删除。 + + ![删除](../../../images/networkpolicy12.png) + +- 点击网络策略的名称,进入网络策略的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 删除。 + + ![删除](../../../images/networkpolicy13.png) diff --git a/docs/zh/docs/admin/kpanda/nodes/add-node.md b/docs/zh/docs/admin/kpanda/nodes/add-node.md new file mode 100644 index 0000000..d490f8d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/add-node.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# 集群节点扩容 + +随着业务应用不断增长,集群资源日趋紧张,这时可以基于 kubean 对集群节点进行扩容。扩容后,应用可以运行在新增的节点上,缓解资源压力。 + +只有通过容器管理模块[创建的集群](../clusters/create-cluster.md)才支持节点扩缩容,从外部接入的集群不支持此操作。本文主要介绍同种架构下工作集群的 **工作节点** 扩容。 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + 若 __集群角色__ 中带有 __接入集群__ 的标签,则说明该集群不支持节点扩缩容。 + + ![进入集群列表页面](../../../images/addnode01_1.png) + +2. 在左侧导航栏点击 __节点管理__ ,然后在页面右上角点击 __接入节点__ 。 + + ![节点管理](../../../images/addnode02.png) + +3. 输入主机名称和节点 IP 并点击 __确定__ 。 + + 点击 __➕ 添加工作节点__ 可以继续接入更多节点。 + + ![节点管理](../../../images/addnode03.png) + +!!! note + + 接入节点大约需要 20 分钟,请您耐心等待。 + +## 参考文档 + +- [对工作集群的控制节点扩容](../../best-practice/add-master-node.md) +- [为工作集群添加异构节点](../../best-practice/multi-arch.md) +- [为全局服务集群的工作节点扩容](../../best-practice/add-worker-node-on-global.md) +- [替换工作集群的首个控制节点](../../best-practice/replace-first-master-node.md) diff --git a/docs/zh/docs/admin/kpanda/nodes/delete-node.md b/docs/zh/docs/admin/kpanda/nodes/delete-node.md new file mode 100644 index 0000000..03d6bd1 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/delete-node.md @@ -0,0 +1,34 @@ +# 集群节点缩容 + +当业务高峰期结束之后,为了节省资源成本,可以缩小集群规模,卸载冗余的节点,即节点缩容。节点卸载后,应用无法继续运行在该节点上。 + +## 前提条件 + +- 当前操作用户具有 [Cluster Admin](../permissions/permission-brief.md) 角色授权 。 +- 只有通过容器管理模块[创建的集群](../clusters/create-cluster.md)才支持节点扩缩容,从外部接入的集群不支持此操作。 +- 卸载节点之前,需要[暂停调度该节点](schedule.md),并且将该节点上的应用都驱逐至其他节点。 +- 驱逐方式:登录控制器节点,通过 kubectl drain 命令驱逐节点上所有 Pod。安全驱逐的方式可以允许容器组里面的容器优雅地中止。 + +## 注意事项 + +1. 集群节点缩容时,只能逐个进行卸载,无法批量卸载。 + +2. 如需卸载集群控制器节点,需要确保最终控制器节点数为 **奇数**。 + +3. 集群节点缩容时不可下线 **第一个控制器** 节点。如果必须执行此操作,请联系售后工程师。 + +## 操作步骤 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + 若 __集群角色__ 中带有 __接入集群__ 的标签,则说明该集群不支持节点扩缩容。 + + ![进入集群列表页面](../../../images/addnode01.png) + +2. 在左侧导航栏点击 __节点管理__ ,找到需要卸载的节点,点击 __┇__ 选择 __移除节点__ 。 + + ![移除节点](../../../images/deletenode01.png) + +3. 输入节点名称,并点击 __删除__ 进行确认。 + + ![移除节点](../../../images/deletenode02.png) diff --git a/docs/zh/docs/admin/kpanda/nodes/labels-annotations.md b/docs/zh/docs/admin/kpanda/nodes/labels-annotations.md new file mode 100644 index 0000000..2233929 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/labels-annotations.md @@ -0,0 +1,29 @@ +--- +hide: + - toc +--- + +# 标签与注解 + +标签(Labels)是为 Pod、节点、集群等 Kubernetes 对象添加的标识性键值对,可结合标签选择器查找并筛选满足某些条件的 Kubernetes 对象。每个键对于给定对象必须是唯一的。 + +注解(Annotations)和标签一样,也是键/值对,但不具备标识或筛选功能。 +使用注解可以为节点添加任意的元数据。 +注解的键通常使用的格式为 __前缀(可选)/名称(必填)__ ,例如 __nfd.node.kubernetes.io/extended-resources__ 。 +如果省略前缀,表示该注解键是用户私有的。 + +有关标签和注解的更多信息,可参考 Kubernetes 的官方文档[标签和选择算符](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/)或[注解](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/annotations/)。 + +添加/删除标签与注解的步骤如下: + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![进入集群列表页面](../../../images/schedule01.png) + +2. 在左侧导航栏点击 __节点管理__ ,在节点右侧点击 __┇__ 操作图标,点击 __修改标签__ 或 __修改注解__ 。 + + ![暂停调度](../../../images/labels01.png) + +3. 点击 __➕ 添加__ 可以添加标签或注解,点击 __X__ 可以删除标签或注解,最后点击 __确定__ 。 + + ![节点管理](../../../images/labels02.png) diff --git a/docs/zh/docs/admin/kpanda/nodes/node-authentication.md b/docs/zh/docs/admin/kpanda/nodes/node-authentication.md new file mode 100644 index 0000000..b0a0c04 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/node-authentication.md @@ -0,0 +1,70 @@ +# 节点认证 + +## 使用 SSH 密钥认证节点 + +如果您选择使用 SSH 密钥作为待创建集群的节点认证方式,您需要按照如下说明配置公私钥。 + +1. 执行如下命令,在 **待建集群的管理集群中的任意节点** 上生成公私钥。 + + ```shell + cd /root/.ssh + ssh-keygen -t rsa + ``` + +2. 执行 __ls__ 命令查看管理集群上的密钥是否创建成功,正确反馈如下: + + ```shell + ls + id_rsa id_rsa.pub known_hosts + ``` + + 其中名为 __id_rsa__ 的文件是私钥,名为 __id_rsa.pub__ 的文件是公钥。 + +3. 执行如下命令,分别将公钥文件 __id_rsa.pub__ 加载到待创建集群的所有节点上。 + + ```shell + ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.0.0 + ``` + + 将上面命令中的 __root@10.0.0.0__ 用户账号和节点 IP 替换为待创建集群的节点用户名和 IP。** 需要在待创建集群的每台节点都执行相同的操作 **。 + +4. 执行如下命令,查看步骤 1 所创建的私钥文件 __id_rsa__ 。 + + ```shell + cat /root/.ssh/id_rsa + ``` + + 输出如下内容: + + ```bash + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEA3UvyKINzY5BFuemQ+uJ6q+GqgfvnWwNC8HzZhpcMSjJy26MM + UtBEBJxy8fMi57XcjYxPibXW/wnd+32ICCycqCwByUmuXeCC1cjlCQDqjcAvXae7 + Y54IXGF7wm2IsMNwf0kjFEXjuS48FLDA0mGRaN3BG+Up5geXcHckg3K5LD8kXFFx + dEmSIjdyw55NaUitmEdHzN7cIdfi6Z56jcV8dcFBgWKUx+ebiyPmZBkXToz6GnMF + rswzzZCl+G6Jb2xTGy7g7ozb4BoZd1IpSD5EhDanRrESVE0C5YuJ5zUAC0CvVd1l + v67AK8Ko6MXToHp01/bcsvlM6cqgwUFXZKVeOwIDAQABAoIBAQCO36GQlo3BEjxy + M2HvGJmqrx+unDxafliRe4nVY2AD515Qf4xNSzke4QM1QoyenMOwf446krQkJPK0 + k+9nl6Xszby5gGCbK4BNFk8I6RaGPjZWeRx6zGUJf8avWJiPxx6yjz2esSC9RiR0 + F0nmiiefVMyAfgv2/5++dK2WUFNNRKLgSRRpP5bRaD5wMzzxtSSXrUon6217HO8p + 3RoWsI51MbVzhdVgpHUNABcoa0rpr9svT6XLKZxY8mxpKFYjM0Wv2JIDABg3kBvh + QbJ7kStCO3naZjKMU9UuSqVJs06cflGYw7Or8/tABR3LErNQKPjkhAQqt0DXw7Iw + 3tKdTAJBAoGBAP687U7JAOqQkcphek2E/A/sbO/d37ix7Z3vNOy065STrA+ZWMZn + pZ6Ui1B/oJpoZssnfvIoz9sn559X0j67TljFALFd2ZGS0Fqh9KVCqDvfk+Vst1dq + +3r/yZdTOyswoccxkJiC/GDwZGK0amJWqvob39JCZhDAKIGLbGMmjdAHAoGBAN5k + m1WGnni1nZ+3dryIwgB6z1hWcnLTamzSET6KhSuo946ET0IRG9xtlheCx6dqICbr + Vk1Y4NtRZjK/p/YGx59rDWf7E3I8ZMgR7mjieOcUZ4lUlA4l7ZIlW/2WZHW+nUXO + Ti20fqJ8qSp4BUvOvuth1pz2GLUHe2/Fxjf7HIstAoGBAPHpPr9r+TfIlPsJeRj2 + 6lzA3G8qWFRQfGRYjv0fjv0pA+RIb1rzgP/I90g5+63G6Z+R4WdcxI/OJJNY1iuG + uw9n/pFxm7U4JC990BPE6nj5iLz+clpNGYckNDBF9VG9vFSrSDLdaYkxoVNvG/xJ + a9Na90H4lm7f3VewrPy310KvAoGAZr+mwNoEh5Kpc6xo8Gxi7aPP/mlaUVD6X7Ki + gvmu02AqmC7rC4QqEiqTaONkaSXwGusqIWxJ3yp5hELmUBYLzszAEeV/s4zRp1oZ + g133LBRSTbHFAdBmNdqK6Nu+KGRb92980UMOKvZbliKDl+W6cbfvVu+gtKrzTc3b + aevb4TUCgYEAnJAxyVYDP1nJf7bjBSHXQu1E/DMwbtrqw7dylRJ8cAzI7IxfSCez + 7BYWq41PqVd9/zrb3Pbh2phiVzKe783igAIMqummcjo/kZyCwFsYBzK77max1jF5 + aPQsLbRS2aDz8kIH6jHPZ/R+15EROmdtLmA7vIJZGerWWQR0dUU+XXA= + ``` + + 将私钥内容复制后填至界面密钥输入框。 + + ![SSH 认证](../../../images/createcluster-ssh01.png) diff --git a/docs/zh/docs/admin/kpanda/nodes/node-check.md b/docs/zh/docs/admin/kpanda/nodes/node-check.md new file mode 100644 index 0000000..9b6312c --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/node-check.md @@ -0,0 +1,38 @@ +# 创建集群节点可用性检查 + +在创建集群或为已有集群添加节点时,请参阅下表,检查节点配置,以避免因节点配置错误导致集群创建或扩容失败。 + +| 检查项 | 描述 | +| -------------- | -------------------------------------- | +| 操作系统 | 参考[支持的架构及操作系统](#_2) | +| SELinux | 关闭 | +| 防火墙 | 关闭 | +| 架构一致性 | 节点间 CPU 架构一致(如均为 ARM 或 x86) | +| 主机时间 | 所有主机间同步误差小于 10 秒。 | +| 网络联通性 | 节点及其 SSH 端口能够正常被平台访问。 | +| CPU | 可用 CPU 资源大于 4 Core | +| 内存 | 可用内存资源大于 8 GB | + +## 支持的架构及操作系统 + +| 架构 | 操作系统 | 备注 | +| ---- | ---------------------------------------------------------- | ---- | +| ARM | Kylin Linux Advanced Server release V10 (Sword) SP2 | 推荐 | +| ARM | UOS Linux | | +| ARM | openEuler | | +| x86 | CentOS 7.x | 推荐 | +| x86 | Redhat 7.x | 推荐 | +| x86 | Redhat 8.x | 推荐 | +| x86 | Flatcar Container Linux by Kinvolk | | +| x86 | Debian Bullseye, Buster, Jessie, Stretch | | +| x86 | Ubuntu 16.04, 18.04, 20.04, 22.04 | | +| x86 | Fedora 35, 36 | | +| x86 | Fedora CoreOS | | +| x86 | openSUSE Leap 15.x/Tumbleweed | | +| x86 | Oracle Linux 7, 8, 9 | | +| x86 | Alma Linux 8, 9 | | +| x86 | Rocky Linux 8, 9 | | +| x86 | Amazon Linux 2 | | +| x86 | Kylin Linux Advanced Server release V10 (Sword) - SP2 海光 | | +| x86 | UOS Linux | | +| x86 | openEuler | | diff --git a/docs/zh/docs/admin/kpanda/nodes/node-details.md b/docs/zh/docs/admin/kpanda/nodes/node-details.md new file mode 100644 index 0000000..437ec32 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/node-details.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 节点详情 + +接入或创建集群之后,可以查看集群中各个节点的信息,包括节点状态、标签、资源用量、Pod、监控信息等。 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![进入集群列表页面](../../../images/schedule01_2.png) + +2. 在左侧导航栏点击 __节点管理__ ,可以查看节点状态、角色、标签、CPU/内存使用情况、IP 地址、创建时间。 + + ![暂停调度](../../../images/node-details01.png) + +3. 点击节点名称,可以进入节点详情页面查看更多信息,包括概览信息、容器组信息、标签注解信息、事件列表、状态等。 + + ![节点管理](../../../images/node-details02.png) + + 此外,还可以查看节点的 YAML 文件、监控信息、标签和注解等。 + + ![节点管理](../../../images/node-details03.png) diff --git a/docs/zh/docs/admin/kpanda/nodes/schedule.md b/docs/zh/docs/admin/kpanda/nodes/schedule.md new file mode 100644 index 0000000..ccc54a0 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/schedule.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 节点调度 + +支持将节点暂停调度或恢复调度。暂停调度指,停止将 Pod 调度到该节点。恢复调度指,可以将 Pod 调度到该节点。 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![进入集群列表页面](../../../images/schedule01_1.png) + +2. 在左侧导航栏点击 __节点管理__ ,在节点右侧点击 __┇__ 操作图标,点击 __暂停调度__ 按钮即可暂停调度该节点。 + + ![暂停调度](../../../images/schedule02.png) + +3. 在节点右侧点击 __┇__ 操作图标,点击 __恢复调度__ 按钮即可恢复调度该节点。 + + ![节点管理](../../../images/schedule03.png) + +节点调度状态可能因网络情况有所延迟,点击搜索框右侧的刷新图标可以刷新节点调度状态。 + +![节点管理](../../../images/schedule04.png) diff --git a/docs/zh/docs/admin/kpanda/nodes/taints.md b/docs/zh/docs/admin/kpanda/nodes/taints.md new file mode 100644 index 0000000..7b2708b --- /dev/null +++ b/docs/zh/docs/admin/kpanda/nodes/taints.md @@ -0,0 +1,36 @@ +# 节点污点管理 + +污点 (Taint) 能够使节点排斥某一类 Pod,避免 Pod 被调度到该节点上。 +每个节点上可以应用一个或多个污点,不能容忍这些污点的 Pod 则不会被调度该节点上。 + +## 注意事项 + +1. 当前操作用户应具备 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色授权或其他更高权限。 +2. 为节点添加污点之后,只有能容忍该污点的 Pod 才能被调度到该节点。 + +## 操作步骤 + +1. 在 __集群列表__ 页找到目标集群,点击集群名称,进入 __集群概览__ 页面。 + + ![点击集群名称](../../../images/taint-click--cluster-name.png) + +2. 在左侧导航栏,点击 __节点管理__ ,找到需要修改污点的节点,点击右侧的 __┇__ 操作图标并点击 __修改污点__ 按钮。 + + ![修改污点](../../../images/taint-change.png) + +3. 在弹框内输入污点的键值信息,选择污点效果,点击 __确定__ 。 + + 点击 __➕ 添加__ 可以为节点添加多个污点,点击污点效果右侧的 __X__ 可以删除污点。 + + 目前支持三种污点效果: + + - `NoSchedule`:新的 Pod 不会被调度到带有此污点的节点上,除非新的 Pod 具有相匹配的容忍度。当前正在节点上运行的 Pod **不会** 被驱逐。 + - `NoExecute`:这会影响已在节点上运行的 Pod: + - 如果 Pod 不能容忍此污点,会马上被驱逐。 + - 如果 Pod 能够容忍此污点,但是在容忍度定义中没有指定 `tolerationSeconds`,则 Pod 还会一直在这个节点上运行。 + - 如果 Pod 能够容忍此污点而且指定了 `tolerationSeconds`,则 Pod 还能在这个节点上继续运行指定的时长。这段时间过去后,再从节点上驱除这些 Pod。 + - `PreferNoSchedule`:这是“软性”的 `NoSchedule`。控制平面将**尝试**避免将不容忍此污点的 Pod 调度到节点上,但不能保证完全避免。所以要尽量避免使用此污点。 + + ![修改污点](../../../images/taint-add-remove.png) + +有关污点的更多详情,请参阅 Kubernetes 官方文档:[污点和容忍度](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)。 diff --git a/docs/zh/docs/admin/kpanda/olm/import-miniooperator.md b/docs/zh/docs/admin/kpanda/olm/import-miniooperator.md new file mode 100644 index 0000000..6c40d7a --- /dev/null +++ b/docs/zh/docs/admin/kpanda/olm/import-miniooperator.md @@ -0,0 +1,167 @@ +--- +hide: + - toc +--- + + +# 导入离线 MinIo Operator + +本文将介绍在离线环境下如何导入 MinIo Operator。 + +## 前提条件 + +- 当前集群已接入容器管理且全局服务集群已经安装 __kolm__ 组件(helm 模板搜索 kolm) +- 当前集群已经安装 __olm__ 组件且版本 >= 0.2.4 (helm 模板搜索 olm) +- 支持执行 Docker 命令 +- 准备一个镜像仓库 + +## 操作步骤 + +1. 在执行环境中设置环境变量并在后续步骤使用,执行命令: + + ```bash + export OPM_IMG=10.5.14.200/quay.m.daocloud.io/operator-framework/opm:v1.29.0 + export BUNDLE_IMG=10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3 + ``` + + 如何获取上述镜像地址: + + 前往 __容器管理__ -> 选择当前集群 -> __helm 应用__ -> 查看 __olm__ 组件 -> __插件设置__ ,找到后续步骤所需 opm,minio,minio bundle,minio operator 的镜像。 + + ![olm](../../../images/olm.png) + + ```bash + 以上诉截图为例,则四个镜像地址如下 + + # opm 镜像 + 10.5.14.200/quay.m.daocloud.io/operator-framework/opm:v1.29.0 + + # minio 镜像 + 10.5.14.200/quay.m.daocloud.io/minio/minio:RELEASE.2023-03-24T21-41-23Z + + # minio bundle 镜像 + 10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3 + + # minio operator 镜像 + 10.5.14.200/quay.m.daocloud.io/minio/operator:v5.0.3 + ``` + +2. 执行 opm 命令获取离线 bundle 镜像包含的 operator。 + + ```bash + # 创建 operator 存放目录 + $ mkdir minio-operator && cd minio-operator + + # 获取 operator yaml + $ docker run --user root -v $PWD/minio-operator:/minio-operator ${OPM_IMG} alpha bundle unpack --skip-tls-verify -v -d ${BUNDLE_IMG} -o ./minio-operator + + # 预期结果 + . + └── minio-operator + ├── manifests + │   ├── console-env_v1_configmap.yaml + │   ├── console-sa-secret_v1_secret.yaml + │   ├── console_v1_service.yaml + │   ├── minio-operator.clusterserviceversion.yaml + │   ├── minio.min.io_tenants.yaml + │   ├── operator_v1_service.yaml + │   ├── sts.min.io_policybindings.yaml + │   └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 3 directories, 9 files + ``` + +3. 替换  minio-operator/manifests/minio-operator.clusterserviceversion.yaml  文件中的所有镜像地址为离线镜像仓库地址镜像。 + + 替换前: + + ![image1](../../../images/csv1.png) + + 替换后: + + ![image2](../../../images/csv2.png) + +4. 生成构建 bundle 镜像的 Dockerfile + + ```bash + $ docker run --user root -v $PWD:/minio-operator -w /minio-operator ${OPM_IMG} alpha bundle generate --channels stable,beta -d /minio-operator/minio-operator/manifests -e stable -p minio-operator   + + # 预期结果 + . + ├── bundle.Dockerfile + └── minio-operator + ├── manifests + │   ├── console-env_v1_configmap.yaml + │   ├── console-sa-secret_v1_secret.yaml + │   ├── console_v1_service.yaml + │   ├── minio-operator.clusterserviceversion.yaml + │   ├── minio.min.io_tenants.yaml + │   ├── operator_v1_service.yaml + │   ├── sts.min.io_policybindings.yaml + │   └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 3 directories, 10 files + ``` + +5. 执行构建命令,构建 bundle 镜像且推送到离线 registry。 + + ```bash + # 设置新的 bundle image + export OFFLINE_BUNDLE_IMG=10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3-offline + + $ docker build . -f bundle.Dockerfile -t ${OFFLINE_BUNDLE_IMG}   + + $ docker push ${OFFLINE_BUNDLE_IMG} + ``` + +6. 生成构建 catalog 镜像的 Dockerfile。 + + ```bash + $ docker run --user root -v $PWD:/minio-operator -w /minio-operator ${OPM_IMG} index add --bundles ${OFFLINE_BUNDLE_IMG} --generate --binary-image ${OPM_IMG} --skip-tls-verify + + # 预期结果 + . + ├── bundle.Dockerfile + ├── database + │   └── index.db + ├── index.Dockerfile + └── minio-operator + ├── manifests + │   ├── console-env_v1_configmap.yaml + │   ├── console-sa-secret_v1_secret.yaml + │   ├── console_v1_service.yaml + │   ├── minio.min.io_tenants.yaml + │   ├── minio-operator.clusterserviceversion.yaml + │   ├── operator_v1_service.yaml + │   ├── sts.min.io_policybindings.yaml + │   └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 4 directories, 12 files + ``` + +7. 构建 catalog 镜像 + + ```bash + # 设置新的 catalog image + export OFFLINE_CATALOG_IMG=10.5.14.200/release.daocloud.io/operator-framework/system-operator-index:v0.1.0-offline + + $ docker build . -f index.Dockerfile -t ${OFFLINE_CATALOG_IMG} + + $ docker push ${OFFLINE_CATALOG_IMG} + ``` + +8. 前往容器管理,更新 helm 应用 olm 的内置 catsrc 镜像(填写构建 catalog 镜像指定的 ${catalog-image} 即可) + + ![olm1](../../../images/olm1.png) + + ![olm2](../../../images/olm2.png) + +9. 更新成功后,Operator Hub 中会出现 __minio-operator__ 组件 + + ![olm3](../../../images/olm3.png) diff --git a/docs/zh/docs/admin/kpanda/permissions/cluster-ns-auth.md b/docs/zh/docs/admin/kpanda/permissions/cluster-ns-auth.md new file mode 100644 index 0000000..3fd57ff --- /dev/null +++ b/docs/zh/docs/admin/kpanda/permissions/cluster-ns-auth.md @@ -0,0 +1,55 @@ +# 集群和命名空间授权 + +容器管理基于全局权限管理及全局用户/用户组管理实现授权,如需为用户授予容器管理的最高权限(可以创建、管理、删除所有集群),请参见[什么是用户与访问控制](../../ghippo/access-control/iam.md)。 + +## 前提条件 + +给用户/用户组授权之前,请完成如下准备: + +- 已在全局管理中创建了待授权的用户/用户组,请参考[用户](../../ghippo/access-control/user.md)。 + +- 仅 [Kpanda Owner](../../ghippo/access-control/global.md) 及当前集群的 [Cluster Admin](permission-brief.md) 具备集群授权能力。详情可参考[权限说明](permission-brief.md)。 + +- 仅 [Kpanda Owner](../../ghippo/access-control/global.md)、当前集群的 [Cluster Admin](permission-brief.md),当前命名空间的 [NS Admin](permission-brief.md) 具备命名空间授权能力。 + +## 集群授权 + +1. 用户登录平台后,点击左侧菜单栏 __容器管理__ 下的 __权限管理__ ,默认位于 __集群权限__ 页签。 + + ![集群权限](../../../images/perm01.png) + +2. 点击 __添加授权__ 按钮。 + + ![添加授权](../../../images/perm02.png) + +3. 在 __添加集群权限__ 页面中,选择目标集群、待授权的用户/用户组后,点击 __确定__ 。 + + 目前仅支持的集群角色为 __Cluster Admin__ ,详情权限可参考[权限说明](permission-brief.md)。如需要给多个用户/用户组同时进行授权, 可点击 __添加用户权限__ 进行多次添加。 + + ![添加集群权限](../../../images/perm03.png) + +4. 返回集群权限管理页面,屏幕出现消息: __添加集群权限成功__ 。 + + ![添加成功](../../../images/perm04.png) + +## 命名空间授权 + +1. 用户登录平台后,点击左侧菜单栏 __容器管理__ 下的 __权限管理__ ,点击 __命名空间权限__ 页签。 + + ![命名空间权限](../../../images/perm05.png) + +2. 点击 __添加授权__ 按钮。在 __添加命名空间权限__ 页面中,选择目标集群、目标命名空间,以及待授权的用户/用户组后,点击 __确定__ 。 + + 目前支持的命名空间角色为 NS Admin、NS Editor、NS Viewer,详情权限可参考[权限说明](permission-brief.md)。如需给多个用户/用户组同时进行授权,可点击 __添加用户权限__ 进行多次添加。点击 __确定__ 完成权限授权。 + + ![添加命名空间权限](../../../images/perm06.png) + +3. 返回命名空间权限管理页面,屏幕出现消息: __添加集群权限成功__ 。 + + ![添加成功](../../../images/perm07.png) + + !!! tip + + 后续如需删除或编辑权限,可点击列表右侧的 __┇__ ,选择 __编辑__ 或 __删除__ 。 + + ![编辑或删除](../../../images/perm08.png) diff --git a/docs/zh/docs/admin/kpanda/permissions/custom-kpanda-role.md b/docs/zh/docs/admin/kpanda/permissions/custom-kpanda-role.md new file mode 100644 index 0000000..17a0748 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/permissions/custom-kpanda-role.md @@ -0,0 +1,84 @@ +# 增加 Kpanda 内置角色权限点 + +*[Kpanda]: 容器管理的开发代号 + +过去 Kpanda 内置角色的权限点(rbac rules)都是提前预定义好的且用户无法修改,因为以前修改内置角色的权限点之后也会被 Kpanda 控制器还原成预定义的权限点。 +为了支持更加灵活的权限配置,满足对系统角色的自定义需求,目前 Kpanda 支持为内置系统角色(cluster admin、ns admin、ns editor、ns viewer)修改权限点。 +以下示例演示如何新增 ns-viewer 权限点,尝试增加可以删除 Deployment 的权限。其他权限点操作类似。 + +## 前提条件 + +- 适用于容器管理 v0.27.0 及以上版本。 +- [已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../ghippo/access-control/user.md),并为用户授予 [NS Viewer](./permission-brief.md#ns-viewer) ,详情可参考[命名空间授权](./cluster-ns-auth.md)。 + +!!! note + + - 只需在 Global Cluster 增加权限点,Kpanda 控制器会把 Global Cluster 增加的权限点同步到所有接入子集群中,同步需一段时间才能完成 + - 只能在 Global Cluster 增加权限点,在子集群新增的权限点会被 Global Cluster 内置角色权限点覆盖 + - 只支持使用固定 Label 的 ClusterRole 追加权限,不支持替换或者删除权限,也不能使用 role 追加权限,内置角色跟用户创建的 ClusterRole Label 对应关系如下 + + ```output + cluster-admin: rbac.kpanda.io/role-template-cluster-admin: "true" + cluster-edit: rbac.kpanda.io/role-template-cluster-edit: "true" + cluster-view: rbac.kpanda.io/role-template-cluster-view: "true" + ns-admin: rbac.kpanda.io/role-template-ns-admin: "true" + ns-edit: rbac.kpanda.io/role-template-ns-edit: "true" + ns-view: rbac.kpanda.io/role-template-ns-view: "true" + ``` + +## 操作步骤 + +1. 使用 admin 或者 cluster admin 权限的用户[创建无状态负载](../workloads/create-deployment.md) + + ![image-20240514112742395](../images/create-depolyment.png) + +1. 授权 ns-viewer,用户有该 namespace ns-view 权限 + + ![image-20240514113009311](../images/permisson02.png) + +1. 切换登录用户为 ns-viewer,打开控制台获取 ns-viewer 用户对应的 token,使用 curl 请求删除上述的 deployment nginx,发现无删除权限 + + ```bash + [root@master-01 ~]# curl -k -X DELETE 'https://${URL}/apis/kpanda.io/v1alpha1/clusters/cluster-member/namespaces/default/deployments/nginx' -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJOU044MG9BclBRMzUwZ2VVU2ZyNy1xMEREVWY4MmEtZmJqR05uRE1sd1lFIn0.eyJleHAiOjE3MTU3NjY1NzksImlhdCI6MTcxNTY4MDE3OSwiYXV0aF90aW1lIjoxNzE1NjgwMTc3LCJqdGkiOiIxZjI3MzJlNC1jYjFhLTQ4OTktYjBiZC1iN2IxZWY1MzAxNDEiLCJpc3MiOiJodHRwczovLzEwLjYuMjAxLjIwMTozMDE0Ny9hdXRoL3JlYWxtcy9naGlwcG8iLCJhdWQiOiJfX2ludGVybmFsLWdoaXBwbyIsInN1YiI6ImMxZmMxM2ViLTAwZGUtNDFiYS05ZTllLWE5OGU2OGM0MmVmMCIsInR5cCI6IklEIiwiYXpwIjoiX19pbnRlcm5hbC1naGlwcG8iLCJzZXNzaW9uX3N0YXRlIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiYXRfaGFzaCI6IlJhTHoyQjlKQ2FNc1RrbGVMR3V6blEiLCJhY3IiOiIwIiwic2lkIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJucy12aWV3ZXIiLCJsb2NhbGUiOiIifQ.As2ipMjfvzvgONAGlc9RnqOd3zMwAj82VXlcqcR74ZK9tAq3Q4ruQ1a6WuIfqiq8Kq4F77ljwwzYUuunfBli2zhU2II8zyxVhLoCEBu4pBVBd_oJyUycXuNa6HfQGnl36E1M7-_QG8b-_T51wFxxVb5b7SEDE1AvIf54NAlAr-rhDmGRdOK1c9CohQcS00ab52MD3IPiFFZ8_Iljnii-RpXKZoTjdcULJVn_uZNk_SzSUK-7MVWmPBK15m6sNktOMSf0pCObKWRqHd15JSe-2aA2PKBo1jBH3tHbOgZyMPdsLI0QdmEnKB5FiiOeMpwn_oHnT6IjT-BZlB18VkW8rA' + {"code":7,"message":"[RBAC] delete resources(deployments: nginx) is forbidden for user(ns-viewer) in cluster(cluster-member)","details":[]}[root@master-01 ~]# + [root@master-01 ~]# + ``` + +1. 在全局服务集群上创建如下 ClusterRole: + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: append-ns-view # (1)! + labels: + rbac.kpanda.io/role-template-ns-view: "true" # (2)! + rules: + - apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "delete" ] + ``` + + 1. 此字段值可任意指定,只需不重复且符合 Kubernetes 资源名称规则要求 + 2. 注意给不同的角色添加权限时应打上不同的 label + +1. 等待 Kpanda 控制器添加用户创建权限到内置角色 ns-viewer 中,可查看对应内置角色如是否有上一步新增的权限点 + + ```bash + [root@master-01 ~]# kubectl get clusterrole role-template-ns-view -oyaml|grep deployments -C 10|tail -n 6 + ``` + ```yaml + - apiGroups: + - apps + resources: + - deployments + verbs: + - delete + ``` + +1. 再次使用 curl 请求删除上述的 deployment nginx,这次成功删除了。也就是说,ns-viewer 成功新增了删除 Deployment 的权限。 + + ```bash + [root@master-01 ~]# curl -k -X DELETE 'https://${URL}/apis/kpanda.io/v1alpha1/clusters/cluster-member/namespaces/default/deployments/nginx' -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJOU044MG9BclBRMzUwZ2VVU2ZyNy1xMEREVWY4MmEtZmJqR05uRE1sd1lFIn0.eyJleHAiOjE3MTU3NjY1NzksImlhdCI6MTcxNTY4MDE3OSwiYXV0aF90aW1lIjoxNzE1NjgwMTc3LCJqdGkiOiIxZjI3MzJlNC1jYjFhLTQ4OTktYjBiZC1iN2IxZWY1MzAxNDEiLCJpc3MiOiJodHRwczovLzEwLjYuMjAxLjIwMTozMDE0Ny9hdXRoL3JlYWxtcy9naGlwcG8iLCJhdWQiOiJfX2ludGVybmFsLWdoaXBwbyIsInN1YiI6ImMxZmMxM2ViLTAwZGUtNDFiYS05ZTllLWE5OGU2OGM0MmVmMCIsInR5cCI6IklEIiwiYXpwIjoiX19pbnRlcm5hbC1naGlwcG8iLCJzZXNzaW9uX3N0YXRlIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiYXRfaGFzaCI6IlJhTHoyQjlKQ2FNc1RrbGVMR3V6blEiLCJhY3IiOiIwIiwic2lkIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJucy12aWV3ZXIiLCJsb2NhbGUiOiIifQ.As2ipMjfvzvgONAGlc9RnqOd3zMwAj82VXlcqcR74ZK9tAq3Q4ruQ1a6WuIfqiq8Kq4F77ljwwzYUuunfBli2zhU2II8zyxVhLoCEBu4pBVBd_oJyUycXuNa6HfQGnl36E1M7-_QG8b-_T51wFxxVb5b7SEDE1AvIf54NAlAr-rhDmGRdOK1c9CohQcS00ab52MD3IPiFFZ8_Iljnii-RpXKZoTjdcULJVn_uZNk_SzSUK-7MVWmPBK15m6sNktOMSf0pCObKWRqHd15JSe-2aA2PKBo1jBH3tHbOgZyMPdsLI0QdmEnKB5FiiOeMpwn_oHnT6IjT-BZlB18VkW8rA' + ``` diff --git a/docs/zh/docs/admin/kpanda/permissions/permission-brief.md b/docs/zh/docs/admin/kpanda/permissions/permission-brief.md new file mode 100644 index 0000000..a5c182e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/permissions/permission-brief.md @@ -0,0 +1,362 @@ +# 容器管理权限说明 + +容器管理权限基于全局权限管理以及 Kubernetes RBAC 权限管理打造的多维度权限管理体系。 +支持集群级、命名空间级的权限控制,帮助用户便捷灵活地对租户下的 IAM 用户、用户组(用户的集合)设定不同的操作权限。 + +## 集群权限 + +集群权限基于 Kubernetes RBAC 的 ClusterRolebinding 授权,集群权限设置可让用户/用户组具备集群相关权限。 +目前的默认集群角色为 __Cluster Admin__ (不具备集群的创建、删除权限)。 + +### __Cluster Admin__ + +__Cluster Admin__ 具有以下权限: + +- 可管理、编辑、查看对应集群 + +- 管理、编辑、查看 命名空间下的所有工作负载及集群内所有资源 + +- 可授权用户为集群内角色 (Cluster Admin、NS Admin、NS Editor、NS Viewer) + +该集群角色的 YAML 示例如下: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:49Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-cluster-admin + resourceVersion: "15168" + uid: f8f86d42-d5ef-47aa-b284-097615795076 +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +``` + +## 命名空间权限 + +命名空间权限是基于 Kubernetes RBAC 能力的授权,可以实现不同的用户/用户组对命名空间下的资源具有不同的操作权限(包括 Kubernetes API 权限),详情可参考:[Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)。目前容器管理的默认角色为:NS Admin、NS Editor、NS Viewer。 + +### __NS Admin__ + +__NS Admin__ 具有以下权限: + +- 可查看对应命名空间 +- 管理、编辑、查看 命名空间下的所有工作负载,及自定义资源 +- 可授权用户为对应命名空间角色 (NS Editor、NS Viewer) + +该集群角色的 YAML 示例如下: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:49Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-admin + resourceVersion: "15173" + uid: 69f64c7e-70e7-4c7c-a3e0-053f507f2bc3 +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +``` + +### __NS Editor__ + +__NS Editor__ 具有以下权限: + +- 可查看对应有权限的命名空间 +- 管理、编辑、查看 命名空间下的所有工作负载 + +??? note "点击查看集群角色的 YAML 示例" + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:50Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-edit + resourceVersion: "15175" + uid: ca9e690e-96c0-4978-8915-6e4c00c748fe + rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - persistentvolumeclaims/status + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - services/status + verbs: + - '*' + - apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - '*' + - apiGroups: + - "" + resources: + - namespaces + verbs: + - '*' + - apiGroups: + - apps + resources: + - controllerrevisions + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - replicasets + - replicasets/scale + - replicasets/status + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - horizontalpodautoscalers/status + verbs: + - '*' + - apiGroups: + - batch + resources: + - cronjobs + - cronjobs/status + - jobs + - jobs/status + verbs: + - '*' + - apiGroups: + - extensions + resources: + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - ingresses + - ingresses/status + - networkpolicies + - replicasets + - replicasets/scale + - replicasets/status + - replicationcontrollers/scale + verbs: + - '*' + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - poddisruptionbudgets/status + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: + - '*' + ``` + +### __NS Viewer__ + +__NS Viewer__ 具有以下权限: + +- 可查看对应命名空间 +- 可查看对应命名空间下的所有工作负载,及自定义资源 + +??? note "点击查看集群角色的 YAML 示例" + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:50Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-view + resourceVersion: "15183" + uid: 853888fd-6ee8-42ac-b91e-63923918baf8 + rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - persistentvolumeclaims/status + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - services/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - controllerrevisions + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - replicasets + - replicasets/scale + - replicasets/status + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - horizontalpodautoscalers/status + verbs: + - get + - list + - watch + - apiGroups: + - batch + resources: + - cronjobs + - cronjobs/status + - jobs + - jobs/status + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - ingresses + - ingresses/status + - networkpolicies + - replicasets + - replicasets/scale + - replicasets/status + - replicationcontrollers/scale + verbs: + - get + - list + - watch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - poddisruptionbudgets/status + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: + - get + - list + - watch + ``` + +## 权限 FAQ + +1. 全局权限和容器管理权限管理的关系? + + 答:全局权限仅授权为粗粒度权限,可管理所有集群的创建、编辑、删除;而对于细粒度的权限,如单个集群的管理权限,单个命名空间的管理、编辑、删除权限,需要基于 Kubernetes RBAC 的容器管理权限进行实现。 + 一般权限的用户仅需要在容器管理中进行授权即可。 + +2. 目前仅支持四个默认角色,后台自定义角色的 __RoleBinding__ 以及 __ClusterRoleBinding__ (Kubernetes 细粒度的 RBAC)是否也能生效? + + 答:目前自定义权限暂时无法通过图形界面进行管理,但是通过 kubectl 创建的权限规则同样能生效。 diff --git a/docs/zh/docs/admin/kpanda/scale/create-hpa.md b/docs/zh/docs/admin/kpanda/scale/create-hpa.md new file mode 100644 index 0000000..b235ade --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/create-hpa.md @@ -0,0 +1,64 @@ +# 基于内置指标创建 HPA + +算丰 AI 算力平台支持 Pod 资源基于指标进行弹性伸缩(Horizontal Pod Autoscaling, HPA)。 +用户可以通过设置 CPU 利用率、内存用量及自定义指标指标来动态调整 Pod 资源的副本数量。 +例如,为工作负载设置基于 CPU 利用率指标弹性伸缩策略后,当 Pod 的 CPU 利用率超过/低于您设置的指标阀值,工作负载控制器将会自动增加/较少 Pod 副本数。 + +本文将介绍如何为工作负载配置基于内置指标的弹性伸缩。 + +!!! note + + 1. HPA 仅适用于 Deployment 和 StatefulSet,每个工作负载只能创建一个 HPA。 + 2. 如果基于 CPU 利用率创建 HPA 策略,必须预先为工作负载设置配置限制(Limit),否则无法计算 CPU 利用率。 + 3. 如果同时使用内置指标和多种自定义指,HPA 会根据多项指标分别计算所需伸缩副本数,取较大值(但不会超过设置 HPA 策略时配置的最大副本数)进行弹性伸缩。 + +## 内置指标弹性伸缩策略 + +系统内置了 CPU 和内存两种弹性伸缩指标以满足用户的基础业务使用场景。 + +### 前提条件 + +在为工作负载配置内置指标弹性伸缩策略之前,需要满足以下前提条件: + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[无状态工作负载的创建](../workloads/create-deployment.md)或[有状态工作负载的创建](../workloads/create-statefulset.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 已完成[ __metrics-server 插件安装__ ](install-metrics-server.md)。 + +### 操作步骤 + +参考以下步骤,为工作负载配置内置指标弹性伸缩策略。 + +1. 点击左侧导航栏上的 __集群列表__ 进入集群列表页面。点击一个集群名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_14.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ 进入工作负载列表后,点击一个负载名称,进入 __工作负载详情__ 页面。 + + ![工作负载](../../../images/createScale.png) + +3. 点击 __弹性伸缩__ 页签,查看当前集群的弹性伸缩配置情况。 + + ![弹性伸缩](../../../images/createScale02.png) + +4. 确认集群已[安装了 __metrics-server__ 插件](install-metrics-server.md),且插件运行状态为正常后,即可点击 __新建伸缩__ 按钮。 + + ![新建伸缩](../../../images/createScale07.png) + +5. 创建自定义指标弹性伸缩策略参数。 + + ![工作负载](../../../images/createScale08.png) + + - 策略名称:输入弹性伸缩策略的名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 hpa-my-dep。 + - 命名空间:负载所在的命名空间。 + - 工作负载:执行弹性伸缩的工作负载对象。 + - 目标 CPU 利用率:工作负载资源下 Pod 的 CPU 使用率。计算方式为:工作负载下所有的 Pod 资源 / 工作负载的请求(request)值。当实际 CPU 用量大于/小于目标值时,系统自动减少/增加 Pod 副本数量。 + - 目标内存用量:工作负载资源下的 Pod 的内存用量。当实际内存用量大于/小于目标值时,系统自动减少/增加 Pod 副本数量。 + - 副本范围:Pod 副本数的弹性伸缩范围。默认区间为为 1 - 10。 + +6. 完成参数配置后,点击 __确定__ 按钮,自动返回弹性伸缩详情页面。点击列表右侧的 __┇__ ,可以执行编辑、删除操作,还可以查看相关事件。 + + ![工作负载](../../../images/createScale09.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/scale/create-vpa.md b/docs/zh/docs/admin/kpanda/scale/create-vpa.md new file mode 100644 index 0000000..a166be4 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/create-vpa.md @@ -0,0 +1,67 @@ +# 创建 VPA + +容器垂直扩缩容策略(Vertical Pod Autoscaler, VPA)通过监控 Pod 在一段时间内的资源申请和用量, +计算出对该 Pod 而言最适合的 CPU 和内存请求值。使用 VPA 可以更加合理地为集群下每个 Pod 分配资源,提高集群的整体资源利用率,避免集群资源浪费。 + +算丰 AI 算力平台支持通过容器垂直扩缩容策略(Vertical Pod Autoscaler, VPA),基于此功能可以根据容器资源的使用情况动态调整 Pod 请求值。 +算丰 AI 算力平台支持通过手动和自动两种方式来修改资源请求值,您可以根据实际需要进行配置。 + +本文将介绍如何为工作负载配置 Pod 垂直伸缩。 + +!!! warning + + 使用 VPA 修改 Pod 资源请求会触发 Pod 重启。由于 Kubernetes 本身的限制, Pod 重启后可能会被调度到其它节点上。 + +## 前提条件 + +为工作负载配置垂直伸缩策略之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)、[用户](../../ghippo/access-control/user.md)、[无状态工作负载](../workloads/create-deployment.md)或[有状态工作负载](../workloads/create-statefulset.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 当前集群已经安装 [metrics-server](install-metrics-server.md) 和 [VPA](install-vpa.md) 插件。 + +## 操作步骤 + +参考以下步骤,为工作负载配置内置指标弹性伸缩策略。 + +1. 在 __集群列表__ 中找到目前集群,点击目标集群的名称。 + + ![集群详情](images/create-vpa-01.png) + +2. 在左侧导航栏点击 __工作负载__ ,找到需要创建 VPA 的负载,点击该负载的名称。 + + ![工作负载](images/create-vpa-02.png) +3. 点击 __弹性伸缩__ 页签,查看当前集群的弹性伸缩配置,确认已经安装了相关插件并且插件是否运行正常。 + + ![垂直伸缩](images/create-vpa-03.png) + +4. 点击 __新建伸缩__ 按钮,并配置 VPA 垂直伸缩策略参数。 + + ![新建伸缩](images/create-vpa-04.png) + + - 策略名称:输入垂直伸缩策略的名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 vpa-my-dep。 + - 伸缩模式:执行修改 CPU 和内存请求值的方式,目前垂直伸缩支持手动和自动两种伸缩模式。 + - 手动伸缩:垂直伸缩策略计算出推荐的资源配置值后,需用户手动修改应用的资源配额。 + - 自动伸缩:垂直伸缩策略自动计算和修改应用的资源配额。 + - 目标容器:选择需要进行垂直伸缩的容器。 + +5. 完成参数配置后,点击 __确定__ 按钮,自动返回弹性伸缩详情页面。点击列表右侧的 __┇__ ,可以执行编辑、删除操作。 + + ![工作负载](images/create-vpa-05.png) + +!!! note + + 默认情况下,--min-replicas 的值为 2。表示当副本数大于 1 时,VPA 才会生效, + 可以通过修改 updater 的 --min-replicas 参数值来改变这一默认行为。 + + ```yaml + spec: + containers: + - name: updater + args: + - "--min-replicas=2" + ``` diff --git a/docs/zh/docs/admin/kpanda/scale/custom-hpa.md b/docs/zh/docs/admin/kpanda/scale/custom-hpa.md new file mode 100644 index 0000000..cf01341 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/custom-hpa.md @@ -0,0 +1,166 @@ +# 基于自定义指标创建 HPA + +当系统内置的 CPU 和内存两种指标不能满足您业务的实际需求时,您可以通过配置 ServiceMonitoring 来添加自定义指标, +并基于自定义指标实现弹性伸缩。本文将介绍如何为工作负载配置基于自定义指标进行弹性伸缩。 + +!!! note + + 1. HPA 仅适用于 Deployment 和 StatefulSet,每个工作负载只能创建一个 HPA。 + 2. 如果同时使用内置指标和多种自定义指,HPA 会根据多项指标分别计算所需伸缩副本数,取较大值(但不会超过设置 HPA 策略时配置的最大副本数)进行弹性伸缩。 + +## 前提条件 + +在为工作负载配置自定义指标弹性伸缩策略之前,需要满足以下前提条件: + +- [已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md), + 且能够访问集群的 UI 界面 +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[无状态工作负载的创建](../workloads/create-deployment.md)或[有状态工作负载的创建](../workloads/create-statefulset.md) +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限, + 详情可参考[命名空间授权](../namespaces/createns.md) +- 已安装 [metrics-server 插件](install-metrics-server.md) +- 已安装 [insight-agent 插件](../../../admin/insight/quickstart/install/install-agent.md) +- 已安装 Prometheus-adapter 插件 + +## 操作步骤 + +参考以下步骤,为工作负载配置指标弹性伸缩策略。 + +1. 点击左侧导航栏上的 __集群列表__ 进入集群列表页面。点击一个集群名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_15.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ 进入工作负载列表后,点击一个负载名称,进入 __工作负载详情__ 页面。 + + ![工作负载](../../../images/createScale_1.png) + +3. 点击 __弹性伸缩__ 页签,查看当前集群的弹性伸缩配置情况。 + + ![弹性伸缩配置](../../../images/createScale02_1.png) + +4. 确认集群已[安装了 __metrics-server__ ](install-metrics-server.md)、Insight、Prometheus-adapter 插件且插件运行状态为正常后,即可点击 __新建伸缩__ 按钮。 + + !!! note + + 如果相关插件未安装或插件处于异常状态,您在页面上将无法看见创建自定义指标弹性伸缩入口。 + + ![新建伸缩](../../../images/createScale07_1.png) + +5. 创建自定义指标弹性伸缩策略参数。 + + ![伸缩策略参数](../../../images/createScale10.png) + + - 策略名称:输入弹性伸缩策略的名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 hpa-my-dep。 + - 命名空间:负载所在的命名空间。 + - 工作负载:执行弹性伸缩的工作负载对象。 + - 资源类型:进行监控的自定义指标类型,包含 Pod 和 Service 两种类型。 + - 指标:使用 ServiceMonitoring 创建的自定义指标名称或系统内置的自定义指标名称。 + - 数据类型:用于计算指标值的方法,包含目标值和目标平均值两种类型,当资源类型为 Pod 时,只支持使用目标平均值。 + +## 操作示例 + +本案例以 Golang 业务程序为例,该示例程序暴露了 `httpserver_requests_total` 指标,并记录 HTTP 的请求,通过该指标可以计算出业务程序的 QPS 值。 + +### 部署业务程序 + +使用 Deployment 部署业务程序: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: httpserver + namespace: httpserver +spec: + replicas: 1 + selector: + matchLabels: + app: httpserver + template: + metadata: + labels: + app: httpserver + spec: + containers: + - name: httpserver + image: registry.imroc.cc/test/httpserver:custom-metrics + imagePullPolicy: Always +--- + +apiVersion: v1 +kind: Service +metadata: + name: httpserver + namespace: httpserver + labels: + app: httpserver + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + prometheus.io/port: "http" +spec: + type: ClusterIP + ports: + - port: 80 + protocol: TCP + name: http + selector: + app: httpserver +``` + +### Prometheus 采集业务监控 + +若已安装 insight-agent,可以通过创建 ServiceMonitor 的 CRD 对象配置 Prometheus。 + +操作步骤:在 **集群详情** -> **自定义资源** 搜索“servicemonitors.monitoring.coreos.com",点击名称进入详情。 +通过创建 YAML,在命名空间 **httpserver** 下创建如下示例的 CRD: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: httpserver + namespace: httpserver + labels: + operator.insight.io/managed-by: insight +spec: + endpoints: + - port: http + interval: 5s + namespaceSelector: + matchNames: + - httpserver + selector: + matchLabels: + app: httpserver +``` + +![servicemonitor](../images/servicemonitor.png) + +!!! note + + 若通过 insight 安装 Prometheus,则 serviceMonitor 上必须打上 `operator.insight.io/managed-by: insight` + 这个 label,通过其他方式安装则无需此 label。 + +### 在 prometheus-adapter 中配置指标规则 + +操作步骤:在 **集群详情** -> **Helm 应用** 搜索 “prometheus-adapter",通过操作栏进入更新页面,在 YAML 中配置自定义指标,示例如下: + +```yaml +rules: + custom: + - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) + name: + as: httpserver_requests_qps + matches: httpserver_requests_total + resources: + template: <<.Resource>> + seriesQuery: httpserver_requests_total +``` + +![rules](../images/rules.png) + +### 创建自定义指标弹性伸缩策略参数 + +按照上述步骤在 Deployment 中找到应用程序 httpserver 并通过自定义指标创建弹性伸缩。 + +![custommetrics](../images/custommetrics.png) diff --git a/docs/zh/docs/admin/kpanda/scale/hpa-cronhpa-compatibility-rules.md b/docs/zh/docs/admin/kpanda/scale/hpa-cronhpa-compatibility-rules.md new file mode 100644 index 0000000..488b06f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/hpa-cronhpa-compatibility-rules.md @@ -0,0 +1,37 @@ +# HPA 和 CronHPA 兼容规则 + +HPA 全称为 HorizontalPodAutoscaler,即 Pod 水平自动伸缩。 + +CronHPA 全称为 Cron HorizontalPodAutoscaler,即 Pod 定时的水平自动伸缩。 + +## CronHPA 和 HPA 兼容冲突 + +定时伸缩 CronHPA 通过设置定时的方式触发容器的水平副本伸缩。为了防止突发的流量冲击等状况, +您可能已经配置 HPA 保障应用的正常运行。如果同时检测到了 HPA 和 CronHPA 的存在, +由于 CronHPA 和 HPA 相互独立无法感知,就会出现两个控制器各自工作,后执行的操作会覆盖先执行的操作。 + +对比 CronHPA 和 HPA 的定义模板,可以观察到以下几点: + +- CronHPA 和 HPA 都是通过 scaleTargetRef 字段来获取伸缩对象。 +- CronHPA 通过 jobs 的 crontab 规则定时伸缩副本数。 +- HPA 通过资源利用率判断伸缩情况。 + +!!! note + + 如果同时设置 CronHPA 和 HPA,会出现 CronHPA 和 HPA 同时操作一个 scaleTargetRef 的场景。 + +## CronHPA 和 HPA 兼容方案 + +从上文可知,CronHPA 和 HPA 同时使用会导致后执行的操作覆盖先执行操作的本质原因是两个控制器无法相互感知, +那么只需要让 CronHPA 感知 HPA 的当前状态就能解决冲突问题。 + +系统会将 HPA 作为定时伸缩 CronHPA 的扩缩容对象,从而实现对该 HPA 定义的 Deployment 对象的定时扩缩容。 + +HPA 的定义将 Deployment 配置在 scaleTargetRef 字段下,然后 Deployment 通过自身定义查找 ReplicaSet,最后通过 ReplicaSet 调整真实的副本数目。 + +算丰 AI 算力平台将 CronHPA 中的 scaleTargetRef 设置为 HPA 对象,然后通过 HPA 对象来寻找真实的 scaleTargetRef,从而让 CronHPA 感知 HPA 的当前状态。 + +![CronHPA 和 HPA 兼容方案](../images/hpa-cronhpa-capability-rule-01.png) + +CronHPA 会通过调整 HPA 的方式感知 HPA。CronHPA 通过识别要达到的副本数与当前副本数两者间的较大值, +判断是否需要扩缩容及修改 HPA 的上限;CronHPA 通过识别 CronHPA 要达到的副本数与 HPA 的配置间的较小值,判断是否需要修改 HPA 的下限。 diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-01.png b/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-01.png new file mode 100644 index 0000000..4c359e3 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-01.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-02.png b/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-02.png new file mode 100644 index 0000000..4335320 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-02.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-03.png b/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-03.png new file mode 100644 index 0000000..c57019a Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-metrics-server-03.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-vpa-01.png b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-01.png new file mode 100644 index 0000000..c509dc0 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-01.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-vpa-02.png b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-02.png new file mode 100644 index 0000000..446df49 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-02.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-vpa-03.png b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-03.png new file mode 100644 index 0000000..a76fe33 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-03.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-vpa-04.png b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-04.png new file mode 100644 index 0000000..c6c1c8f Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-04.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/create-vpa-05.png b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-05.png new file mode 100644 index 0000000..27c7f4b Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/create-vpa-05.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/install-vpa-01.png b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-01.png new file mode 100644 index 0000000..9f0b0e9 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-01.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/install-vpa-02.png b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-02.png new file mode 100644 index 0000000..2853242 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-02.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/install-vpa-03.png b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-03.png new file mode 100644 index 0000000..6e6ed16 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-03.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/images/install-vpa-04.png b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-04.png new file mode 100644 index 0000000..e7a5584 Binary files /dev/null and b/docs/zh/docs/admin/kpanda/scale/images/install-vpa-04.png differ diff --git a/docs/zh/docs/admin/kpanda/scale/install-cronhpa.md b/docs/zh/docs/admin/kpanda/scale/install-cronhpa.md new file mode 100644 index 0000000..b63b342 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/install-cronhpa.md @@ -0,0 +1,60 @@ +# 安装 kubernetes-cronhpa-controller 插件 + +容器副本定时水平扩缩容策略(CronHPA)能够为周期性高并发应用提供稳定的计算资源保障, __kubernetes-cronhpa-controller__ 则是实现 CronHPA 的关键组件。 + +本节介绍如何安装 __kubernetes-cronhpa-controller__ 插件。 + +!!! note + + 为了使用 CornHPA,不仅需要安装 __kubernetes-cronhpa-controller__ 插件,还要[安装 __metrics-server__ 插件](install-metrics-server.md)。 + +## 前提条件 + +安装 __kubernetes-cronhpa-controller__ 插件之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +参考如下步骤为集群安装 __kubernetes-cronhpa-controller__ 插件。 + +1. 在 __集群列表__ 页面找到需要安装此插件的目标集群,点击该集群的名称,然后在左侧点击 __工作负载__ -> __无状态工作负载__ ,点击目标工作负载的名称。 + +2. 在工作负载详情页面,点击 __弹性伸缩__ 页签,在 __CronHPA__ 右侧点击 __安装__ 。 + + ![工作负载](../../../images/installcronhpa.png) + +3. 阅读该插件的相关介绍,选择版本后点击 __安装__ 按钮。推荐安装 __1.3.0__ 或更高版本。 + + ![工作负载](../../../images/installcronhpa1.png) + +4. 参考以下说明配置参数。 + + ![工作负载](../../../images/installcronhpa2.png) + + - 名称:输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 kubernetes-cronhpa-controller。 + - 命名空间:选择将插件安装在哪个命名空间,此处以 __default__ 为例。 + - 版本:插件的版本,此处以 __1.3.0__ 版本为例。 + - 就绪等待:启用后,将等待应用下的所有关联资源都处于就绪状态,才会标记应用安装成功。 + - 失败删除:如果插件安装失败,则删除已经安装的关联资源。开启后,将默认同步开启 __就绪等待__ 。 + - 详情日志:开启后,将记录安装过程的详细日志。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要较长时间才会被标记为“运行中”状态。 + +5. 在页面右下角点击 __确定__ ,系统将自动跳转至 __Helm 应用__ 列表页面。稍等几分钟后刷新页面作,即可看到刚刚安装的应用。 + + !!! warning + + 如需删除 __kubernetes-cronhpa-controller__ 插件,应在 __Helm 应用__ 列表页面才能将其彻底删除。 + + 如果在工作负载的 __弹性伸缩__ 页签下删除插件,这只是删除了该插件的工作负载副本,插件本身仍未删除,后续重新安装该插件时也会提示错误。 + +6. 回到工作负载详情页面下的 __弹性伸缩__ 页签,可以看到界面显示 __插件已安装__ 。现在可以开始创建 CronHPA 策略了。 + + ![工作负载](../../../images/installcronhpa3.png) diff --git a/docs/zh/docs/admin/kpanda/scale/install-metrics-server.md b/docs/zh/docs/admin/kpanda/scale/install-metrics-server.md new file mode 100644 index 0000000..de0480a --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/install-metrics-server.md @@ -0,0 +1,142 @@ +--- +hide: + - toc +--- + +# 安装 metrics-server 插件 + +__metrics-server__ 是 Kubernetes 内置的资源使用指标采集组件。 +您可以通过配置弹性伸缩(HPA)策略来实现工作负载资源自动水平伸缩 Pod 副本。 + +本节介绍如何安装 __metrics-server__ 。 + +## 前提条件 + +安装 __metrics-server__ 插件前,需要满足以下前提条件: + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +请执行如下步骤为集群安装 __metrics-server__ 插件。 + +1. 在工作负载详情下的弹性伸缩页面,点击 __去安装__ ,进入 __metrics-server__ 插件安装界面。 + + ![工作负载](images/create-metrics-server-02.png) + +2. 阅读 __metrics-server__ 插件相关介绍,选择版本后点击 __安装__ 按钮。本文将以 __3.8.2__ 版本为例进行安装,推荐您安装 __3.8.2__ 及更高版本。 + + ![工作负载](images/create-metrics-server-01.png) + +3. 在安装配置界面配置基本参数。 + + ![工作负载](images/create-metrics-server-03.png) + + - 名称:输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 metrics-server-01。 + - 命名空间:选择插件安装的命名空间,此处以 __default__ 为例。 + - 版本:插件的版本,此处以 __3.8.2__ 版本为例。 + - 就绪等待:启用后,将等待应用下所有关联资源处于就绪状态,才会标记应用安装成功。 + - 失败删除:开启后,将默认同步开启就绪等待。如果安装失败,将删除安装相关资源。 + - 详情日志:开启安装过程日志的详细输出。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要经过较长时间才会被标记为 __运行中__ 状态。 + +4. 高级参数配置 + + - 如果集群网络无法访问 `k8s.gcr.io` 仓库,请尝试修改 `repositort` 参数为 `repository: k8s.m.daocloud.io/metrics-server/metrics-server` + + - 安装 __metrics-server__ 插件还需提供 SSL 证书。如需绕过证书校验,需要在 `defaultArgs:` 处添加 `- --kubelet-insecure-tls` 参数。 + + ??? note "点击查看推荐的 YAML 参数" + + ```yaml + image: + repository: k8s.m.daocloud.io/metrics-server/metrics-server # 将仓库源地址修改为 k8s.m.daocloud.io + tag: '' + pullPolicy: IfNotPresent + imagePullSecrets: [] + nameOverride: '' + fullnameOverride: '' + serviceAccount: + create: true + annotations: {} + name: '' + rbac: + create: true + pspEnabled: false + apiService: + create: true + podLabels: {} + podAnnotations: {} + podSecurityContext: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + priorityClassName: system-cluster-critical + containerPort: 4443 + hostNetwork: + enabled: false + replicas: 1 + updateStrategy: {} + podDisruptionBudget: + enabled: false + minAvailable: null + maxUnavailable: null + defaultArgs: + - '--cert-dir=/tmp' + - '--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname' + - '--kubelet-use-node-status-port' + - '--metric-resolution=15s' + - --kubelet-insecure-tls # 绕过证书校验 + args: [] + livenessProbe: + httpGet: + path: /livez + port: https + scheme: HTTPS + initialDelaySeconds: 0 + periodSeconds: 10 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /readyz + port: https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 10 + failureThreshold: 3 + service: + type: ClusterIP + port: 443 + annotations: {} + labels: {} + metrics: + enabled: false + serviceMonitor: + enabled: false + additionalLabels: {} + interval: 1m + scrapeTimeout: 10s + resources: {} + extraVolumeMounts: [] + extraVolumes: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ``` + +5. 点击 __确定__ 按钮,完成 __metrics-server__ 插件的安装,之后系统将自动跳转至 __Helm 应用__ 列表页面, + 稍等几分钟后,为页面执行刷新操作,即可看到刚刚安装的应用。 + +!!! note + + 删除 __metrics-server__ 插件时,在 __Helm 应用__ 列表页面才能彻底删除该插件。如果仅在工作负载页面删除 __metrics-server__ , + 这只是删除了该应用的工作负载副本,应用本身仍未删除,后续重新安装该插件时也会提示错误。 diff --git a/docs/zh/docs/admin/kpanda/scale/install-vpa.md b/docs/zh/docs/admin/kpanda/scale/install-vpa.md new file mode 100644 index 0000000..b521c23 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/install-vpa.md @@ -0,0 +1,55 @@ +# 安装 vpa 插件 + +容器垂直扩缩容策略(Vertical Pod Autoscaler, VPA)能够让集群的资源配置更加合理,避免集群资源浪费。 __vpa__ 则是实现容器垂直扩缩容的关键组件。 + +本节介绍如何安装 __vpa__ 插件。 + + 为了使用 VPA 策略,不仅需要安装 __vpa__ 插件,还要[安装 __metrics-server__ 插件](install-metrics-server.md)。 + +## 前提条件 + +安装 __vpa__ 插件之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +参考如下步骤为集群安装 __vpa__ 插件。 + +1. 在 __集群列表__ 页面找到需要安装此插件的目标集群,点击该集群的名称,然后在左侧点击 __工作负载__ -> __无状态工作负载__ ,点击目标工作负载的名称。 + +2. 在工作负载详情页面,点击 __弹性伸缩__ 页签,在 __VPA__ 右侧点击 __安装__ 。 + + ![工作负载](images/install-vpa-01.png) +3. 阅读该插件的相关介绍,选择版本后点击 __安装__ 按钮。推荐安装 __1.5.0__ 或更高版本。 + + ![工作负载](images/install-vpa-02.png) +4. 查看以下说明配置参数。 + + ![工作负载](images/install-vpa-04.png) + - 名称:输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 kubernetes-cronhpa-controller。 + - 命名空间:选择将插件安装在哪个命名空间,此处以 __default__ 为例。 + - 版本:插件的版本,此处以 __4.5.0__ 版本为例。 + - 就绪等待:启用后,将等待应用下的所有关联资源都处于就绪状态,才会标记应用安装成功。 + - 失败删除:如果插件安装失败,则删除已经安装的关联资源。开启后,将默认同步开启 __就绪等待__ 。 + - 详情日志:开启后,将记录安装过程的详细日志。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要经过较长时间才会被标记为“运行中”状态。 + +5. 在页面右下角点击 __确定__ ,系统将自动跳转至 __Helm 应用__ 列表页面。稍等几分钟后刷新页面作,即可看到刚刚安装的应用。 + + !!! warning + + 如需删除 __vpa__ 插件,应在 __Helm 应用__ 列表页面才能将其彻底删除。 + + 如果在工作负载的 __弹性伸缩__ 页签下删除插件,这只是删除了该插件的工作负载副本,插件本身仍未删除,后续重新安装该插件时也会提示错误。 + +6. 回到工作负载详情页面下的 __弹性伸缩__ 页签,可以看到界面显示 __插件已安装__ 。现在可以开始[创建 VPA](create-vpa.md) 策略了。 + + ![工作负载.png](images/install-vpa-03.png) diff --git a/docs/zh/docs/admin/kpanda/scale/knative/install.md b/docs/zh/docs/admin/kpanda/scale/knative/install.md new file mode 100644 index 0000000..4d8ec4e --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/knative/install.md @@ -0,0 +1,19 @@ +# 安装 + +Knative 是一个面向无服务器部署的跨平台解决方案。 + +1. 登录集群,点击侧边栏 __Helm 应用__ -> __Helm 模板__ ,在右侧上方搜索框输入 __knative__ ,然后按回车键搜索。 + + ![Install-1](../../images/knative-install-1.png) + +2. 点击搜索出的 __knative-operator__ ,进入安装配置界面。你可以在该界面查看可用版本以及 Helm values 的 Parameters 可选项。 + + ![Install-2](../../images/knative-install-2.png) + +3. 点击安装按钮后,进入安装配置界面。 + + ![Install-3](../../images/knative-install-3.png) + +4. 输入名称,安装租户,建议勾选 __就绪等待__ 和 __详细日志__ 。 + +5. 在下方设置,可以勾选 __Serving__ ,并输入 Knative Serving 组件的安装租户,会在安装后部署 Knative Serving 组件,该组件由 Knative Operator 管理。 diff --git a/docs/zh/docs/admin/kpanda/scale/knative/knative.md b/docs/zh/docs/admin/kpanda/scale/knative/knative.md new file mode 100644 index 0000000..d7a4a72 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/knative/knative.md @@ -0,0 +1,57 @@ +# Kantive 介绍 + +Knative 提供了一种更高层次的抽象,简化并加速了在 Kubernetes 上构建、部署和管理应用的过程。它使得开发人员能够更专注于业务逻辑的实现,而将大部分基础设施和运维工作交给 Knative 去处理,从而显著提高生产力。 + +## 组件 + +knative-operator 运行组件如下。 + +```shell +knative-operator knative-operator-58f7d7db5c-7f6r5 1/1 Running 0 6m55s +knative-operator operator-webhook-667dc67bc-qvrv4 1/1 Running 0 6m55s +``` + +knative-serving 组件如下。 + +```shell +knative-serving 3scale-kourier-gateway-d69fbfbd-bd8d8 1/1 Running 0 7m13s +knative-serving activator-7c6fddd698-wdlng 1/1 Running 0 7m3s +knative-serving autoscaler-8f4b876bb-kd25p 1/1 Running 0 7m17s +knative-serving autoscaler-hpa-5f7f74679c-vkc7p 1/1 Running 0 7m15s +knative-serving controller-789c896c46-tfvsv 1/1 Running 0 7m17s +knative-serving net-kourier-controller-7db578c889-7gd5l 1/1 Running 0 7m14s +knative-serving webhook-5c88b94c5-78x7m 1/1 Running 0 7m1s +knative-serving storage-version-migration-serving-serving-1.12.2-t7zvd 0/1 Completed 0 7m15s +``` + +| 组件 | 作用 | +|----------|-------------| +| Activator | 对请求排队(如果一个 Knative Service 已经缩减到零)。调用 autoscaler,将缩减到 0 的服务恢复并转发排队的请求。Activator 还可以充当请求缓冲器,处理突发流量。 | +| Autoscaler | Autoscaler 负责根据配置、指标和进入的请求来缩放 Knative 服务。 | +| Controller | 管理 Knative CR 的状态。它会监视多个对象,管理依赖资源的生命周期,并更新资源状态。 | +| Queue-Proxy | Sidecar 容器,每个 Knative Service 都会注入一个。负责收集流量数据并报告给 Autoscaler,Autoscaler 根据这些数据和预设的规则来发起扩容或缩容请求。 | +| Webhooks | Knative Serving 有几个 Webhooks 负责验证和变更 Knative 资源。 | + +## Ingress 流量入口方案 + +| 方案 | 适用场景 | +|----------|-------------| +| Istio | 如果已经用了 Istio,可以选择 Istio 作为流量入口方案。 | +| Contour | 如果集群中已经启用了 Contour,可以选择 Contour 作为流量入口方案。 | +| Kourier | 如果在没有上述 2 种 Ingress 组件时,可以使用 Knative 基于 Envoy 实现的 Kourier Ingress 作为流量入口。 | + +## Autoscaler 方案对比 + +| Autoscaler 类型 | 是否为 Knative Serving 核心部分 | 默认启用 | Scale to Zero 支持 | 基于 CPU 的 Autoscaling 支持 | +| -------------- | -------------------------- | ------------ | ------------------ | -------------- | +| Knative Pod Autoscaler (KPA) | 是 | 是 | 是 | 否 | +| Horizontal Pod Autoscaler (HPA) | 否 | 需安装 Knative Serving 后启用 | 否 | 是 | + +## CRD + +| 资源类型 | API 名称 | 描述 | +| ------------ | ----------- | --- | +| Services | service.serving.knative.dev | 自动管理 Workload 的整个生命周期,控制其他对象的创建,确保应用具有 Routes、Configurations 以及每次更新时的新 revision。 | +| Routes | route.serving.knative.dev | 将网络端点映射到一个或多个修订版本,支持流量分配和版本路由。 | +| Configurations | configuration.serving.knative.dev | 维护部署的期望状态,提供代码和配置之间的分离,遵循 Twelve-Factor 应用程序方法论,修改配置会创建新的 revision。 | +| Revisions | revision.serving.knative.dev | 每次对工作负载修改的时间点快照,是不可变对象,可根据流量自动扩容和缩容。 | diff --git a/docs/zh/docs/admin/kpanda/scale/knative/playground.md b/docs/zh/docs/admin/kpanda/scale/knative/playground.md new file mode 100644 index 0000000..64df7d1 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/knative/playground.md @@ -0,0 +1,145 @@ +# Knative 使用实践 + +在本节中,我们将通过几个实践来深入了解学习 Knative。 + +## case 1 - Hello World + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +可以使用 kubectl 已部署的应用的状态,这个应用由 knative 自动配置了 ingress 和伸缩器。 + +```shell +~ kubectl get service.serving.knative.dev/hello +NAME URL LATESTCREATED LATESTREADY READY REASON +hello http://hello.knative-serving.knative.loulan.me hello-00001 hello-00001 True +``` + +部署出的 Pod YAML 如下,由 2 个 Pod 组成:user-container 和 queue-proxy。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: hello-00003-deployment-5fcb8ccbf-7qjfk +spec: + containers: + - name: user-container + - name: queue-proxy +``` + +![knative-request-flow](../../images/knative-request-flow.png) + +请求流: + +1. case1 在低流量或零流量时,流量将路由到 activator +2. case2 流量大时,流量大于 target-burst-capacity 时才直接路由到 Pod + 1. 配置为 0,只有从 0 扩容存在 + 2. 配置为 -1,activator 会一直存在请求路径 + 3. 配置为 >0,触发扩缩容之前,系统能够额外处理的并发请求数量。 +3. case3 流量再变小时,流量低于 current_demand + target-burst-capacity > (pods * concurrency-target) 时将再次路由到 activator + + 待处理的请求总数 + 能接受的超过目标并发数的请求数量 > 每个 Pod 的目标并发数 * Pod 数量 + +## case 2 - 基于并发弹性伸缩 + +我们首先在集群应用下面 YAML 定义。 + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "1" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +执行下面命令测试,并可以通过 `kubectl get pods -A -w` 来观察扩容的 Pod。 + +```shell +wrk -t2 -c4 -d6s http://hello.knative-serving.knative.daocloud.io/ +``` + +## case 3 - 基于并发弹性伸缩,达到特定比例提前扩容 + +我们可以很轻松的实现,例如限制每个容器并发为 10,可以通过 `autoscaling.knative.dev/target-utilization-percentage: 70` 来实现,达到 70% 就开始扩容 Pod。 + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "10" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" +        autoscaling.knative.dev/target-utilization-percentage: "70" +        autoscaling.knative.dev/metric: "concurrency" +     spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +## case 4 - 灰度发布/流量百分比 + +我们可以通过 `spec.traffic` 实现到每个版本流量的控制。 + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "1" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" + traffic: + - latestRevision: true + percent: 50 + - latestRevision: false + percent: 50 + revisionName: hello-00001 +``` diff --git a/docs/zh/docs/admin/kpanda/scale/knative/scene.md b/docs/zh/docs/admin/kpanda/scale/knative/scene.md new file mode 100644 index 0000000..f9666d4 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/scale/knative/scene.md @@ -0,0 +1,19 @@ +# 使用场景 + +## 适合的场景 + +* 短连接高并发业务 +* 需要弹性伸缩的业务 +* 大量应用需要缩容到 0 提高资源利用率 +* AI Serving 服务,基于特定指标进行扩容 + +!!! tip + + 短连接高并发业务以及需要弹性伸缩的业务,推荐使用 HPA 和 VPA 能力。 + +## 不适合的场景 + +* 长连接业务 +* 延时敏感业务 +* 基于 cookie 的流量分流 +* 基于 header 的流量分流 diff --git a/docs/zh/docs/admin/kpanda/security/audit.md b/docs/zh/docs/admin/kpanda/security/audit.md new file mode 100644 index 0000000..52dd57b --- /dev/null +++ b/docs/zh/docs/admin/kpanda/security/audit.md @@ -0,0 +1,61 @@ +# 权限扫描 + +为了使用[权限扫描](index.md)功能,需要先创建扫描策略,执行该策略之后会自动生成扫描报告以供查看。 + +## 创建扫描策略 + +1. 在容器管理模块的首页左侧导航栏点击 __安全管理__ 。 + + ![安全管理](../../../images/security01_2.png) + +2. 在左侧导航栏点击 __权限扫描__ ,点击 __扫描策略__ 页签,在右侧点击 __创建扫描策略__ 。 + + ![安全管理](../../../images/security11.png) + +3. 参考下列说明填写配置,最后点击 __确定__ 即可。 + + - 集群:选择需要扫描哪个集群。可选的集群列表来自容器管理模块中接入或创建的集群。如果没有想选的集群,可以去容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建](../clusters/create-cluster.md)集群。 + - 扫描类型: + + - 立即扫描:在扫描策略创建好之后立即执行一次扫描,后续不可以自动/手动再次执行扫描。 + - 定时扫描:通过设置扫描周期,自动按时重复执行扫描。 + + - 扫描报告保留数量:设置最多保留多少扫描报告。超过指定的保留数量时,从最早的报告开始删除。 + + ![安全管理](../../../images/security12.png) + +## 更新/删除扫描策略 + +创建扫描策略之后,可以根据需要更新或删除扫描策略。 + +在 __扫描策略__ 页签下,点击配置右侧的 __┇__ 操作按钮: + +- 对于周期性的扫描策略: + + - 选择 __立即执行__ 意味着,在周期计划之外立即再扫描一次集群 + - 选择 __禁用__ 会中断扫描计划,直到点击 __启用__ 才可以继续根据周期计划执行该扫描策略。 + - 选择 __编辑__ 可以更新配置,支持更新扫描配置、类型、扫描周期、报告保留数量,不可更改配置名称和需要扫描的目标集群。 + - 选择 __删除__ 可以删除该配置 + +- 对于一次性的扫描策略:仅支持 __删除__ 操作。 + + ![创建扫描配置](../../../images/security13.png) + +## 查看扫描报告 + +1. 在 __安全管理__ -> __权限扫描__ -> __扫描报告__ 页签下,点击报告名称 + + > 在报告右侧点击 __删除__ 可以手动删除报告。 + + ![创建扫描配置](../../../images/security14.png) + +2. 查看扫描报告内容,包括: + + - 扫描的目标集群 + - 使用的扫描策略 + - 扫描项总数、警告数、错误数 + - 在周期性扫描策略生成的扫描报告中,还可以查看扫描频率 + - 扫描开始的时间 + - 检查详情,例如被检查的资源、资源类型、扫描结果、错误类型、错误详情 + + ![创建扫描配置](../../../images/security15.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/kpanda/security/cis/config.md b/docs/zh/docs/admin/kpanda/security/cis/config.md new file mode 100644 index 0000000..5602891 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/security/cis/config.md @@ -0,0 +1,39 @@ +# 扫描配置 + +使用[合规性扫描](../index.md)的第一步,就是先创建扫描配置。基于扫描配置再创建扫描策略、执行扫描策略,最后查看扫描结果。 + +## 创建扫描配置 + +创建扫描配置的步骤如下: + +1. 在容器管理模块的首页左侧导航栏点击 __安全管理__ 。 + + ![安全管理](../../../../images/security01_3.png) + +2. 默认进入 __合规性扫描__ 页面,点击 __扫描配置__ 页签,然后在右上角点击 __创建扫描配置__ 。 + + ![安全管理](../../../../images/security02.png) + +3. 填写配置名称、选择配置模板、按需勾选扫描项,最后点击 __确定__ 。 + + 扫描模板:目前提供了两个模板。 __kubeadm__ 模板适用于一般情况下的 Kubernetes 集群。 + 我们在 __kubeadm__ 模板基础上,结合算丰 AI 算力平台的平台设计忽略了不适用于算丰 AI 算力平台的扫描项。 + + ![安全管理](../../../../images/security03.png) + +## 查看扫描配置 + +在扫描配置页签下,点击扫描配置的名称,可以查看该配置的类型、扫描项数量、创建时间、配置模板,以及该配置启用的具体扫描项。 + +![安全管理](../../../../images/security04.png) + +## 更新/删除扫描配置 + +扫描配置创建成功之后,可以根据需求更新配置或删除该配置。 + +在扫描配置页签下,点击配置右侧的 __┇__ 操作按钮: + +- 选择 __编辑__ 可以更新配置,支持更新描述、模板和扫描项。不可更改配置名称。 +- 选择 __删除__ 可以删除该配置。 + + ![安全管理](../../../../images/security04.png) diff --git a/docs/zh/docs/admin/kpanda/security/cis/policy.md b/docs/zh/docs/admin/kpanda/security/cis/policy.md new file mode 100644 index 0000000..5afed68 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/security/cis/policy.md @@ -0,0 +1,39 @@ +# 扫描策略 + +## 创建扫描策略 + +[创建扫描配置](config.md)之后,可以基于配置创建扫描策略。 + +1. 在 __安全管理__ -> __合规性扫描__ 页面的 __扫描策略__ 页签下,在右侧点击创建扫描策略。 + + ![创建扫描配置](../../../../images/security05.png) + +2. 参考下列说明填写配置后,点击 __确定__ 。 + + - 集群:选择需要扫描哪个集群。可选的集群列表来自容器管理模块中接入或创建的集群。如果没有想选的集群,可以去容器管理模块中[接入](../../clusters/integrate-cluster.md)或[创建](../../clusters/create-cluster.md)集群。 + - 扫描配置:选择事先创建好的扫描配置。扫描配置规定了需要执行哪些具体的扫描项。 + - 扫描类型: + + - 立即扫描:在扫描策略创建好之后立即执行一次扫描,后续不可以自动/手动再次执行扫描。 + - 定时扫描:通过设置扫描周期,自动按时重复执行扫描。 + + - 扫描报告保留数量:设置最多保留多少扫描报告。超过指定的保留数量时,从最早的报告开始删除。 + + ![创建扫描配置](../../../../images/security06.png) + +## 更新/删除扫描策略 + +创建扫描策略之后,可以根据需要更新或删除扫描策略。 + +在 __扫描策略__ 页签下,点击配置右侧的 __┇__ 操作按钮: + +- 对于周期性的扫描策略: + + - 选择 __立即执行__ 意味着,在周期计划之外立即再扫描一次集群 + - 选择 __禁用__ 会中断扫描计划,直到点击 __启用__ 才可以继续根据周期计划执行该扫描策略。 + - 选择 __编辑__ 可以更新配置,支持更新扫描配置、类型、扫描周期、报告保留数量,不可更改配置名称和需要扫描的目标集群。 + - 选择 __删除__ 可以删除该配置 + +- 对于一次性的扫描策略:仅支持 __删除__ 操作。 + + ![创建扫描配置](../../../../images/security07.png) diff --git a/docs/zh/docs/admin/kpanda/security/cis/report.md b/docs/zh/docs/admin/kpanda/security/cis/report.md new file mode 100644 index 0000000..6024862 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/security/cis/report.md @@ -0,0 +1,27 @@ +--- +hide: + - toc +--- + +# 扫描报告 + +执行扫描策略之后会自动生成扫描报告。您可以在线查看扫描报告或将其下载到本地查看。 + +- 下载查看扫描报告 + + __安全管理__ -> __合规性扫描__ 页面的 __扫描报告__ 页签点击报告右侧的 __┇__ 操作按钮选择 __下载__ 。 + + ![报告列表截图](../../../../images/security09.png) + +- 在线查看扫描报告 + + 点击某个报告的名称,您可以在线查看 CIS 合规性扫描的报告内容。具体包括: + + - 扫描的目标集群 + - 使用的扫描策略和扫描配置 + - 扫描开始时间 + - 扫描项总数、通过数与未通过数 + - 对于未通过的扫描项给出对应的修复建议 + - 对于通过的扫描项给出更安全的操作建议 + + ![报告列表截图](../../../../images/security10.png) diff --git a/docs/zh/docs/admin/kpanda/security/hunter.md b/docs/zh/docs/admin/kpanda/security/hunter.md new file mode 100644 index 0000000..d741eb8 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/security/hunter.md @@ -0,0 +1,61 @@ +# 漏洞扫描 + +为了使用[漏洞扫描](index.md)功能,需要先创建扫描策略,执行该策略之后会自动生成扫描报告以供查看。 + +## 创建扫描策略 + +1. 在容器管理模块的首页左侧导航栏点击 __安全管理__ 。 + + ![安全管理](../../../images/security01_1.png) + +2. 在左侧导航栏点击 __漏洞扫描__ ,点击 __扫描策略__ 页签,在右侧点击 __创建扫描策略__ 。 + + ![安全管理](../../../images/security16.png) + +3. 参考下列说明填写配置,最后点击 __确定__ 即可。 + + - 集群:选择需要扫描哪个集群。可选的集群列表来自容器管理模块中接入或创建的集群。如果没有想选的集群,可以去容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建](../clusters/create-cluster.md)集群。 + - 扫描类型: + + - 立即扫描:在扫描策略创建好之后立即执行一次扫描,后续不可以自动/手动再次执行扫描。 + - 定时扫描:通过设置扫描周期,自动按时重复执行扫描。 + + - 扫描报告保留数量:设置最多保留多少扫描报告。超过指定的保留数量时,从最早的报告开始删除。 + + ![安全管理](../../../images/security17.png) + +## 更新/删除扫描策略 + +创建扫描策略之后,可以根据需要更新或删除扫描策略。 + +在 __扫描策略__ 页签下,点击配置右侧的 __┇__ 操作按钮: + +- 对于周期性的扫描策略: + + - 选择 __立即执行__ 意味着,在周期计划之外立即再扫描一次集群 + - 选择 __禁用__ 会中断扫描计划,直到点击 __启用__ 才可以继续根据周期计划执行该扫描策略。 + - 选择 __编辑__ 可以更新配置,支持更新扫描配置、类型、扫描周期、报告保留数量,不可更改配置名称和需要扫描的目标集群。 + - 选择 __删除__ 可以删除该配置 + +- 对于一次性的扫描策略:仅支持 __删除__ 操作。 + + ![创建扫描配置](../../../images/security18.png) + +## 查看扫描报告 + +1. 在 __安全管理__ -> __权限扫描__ -> __扫描报告__ 页签下,点击报告名称 + + > 在报告右侧点击 __删除__ 可以手动删除报告。 + + ![创建扫描配置](../../../images/security19.png) + +2. 查看扫描报告内容,包括: + + - 扫描的目标集群 + - 使用的扫描策略 + - 扫描频率 + - 风险总数、高风险数、中风险数、低风险数 + - 扫描时间 + - 检查详情,例如漏洞 ID、漏洞类型、漏洞名称、漏洞描述等 + + ![创建扫描配置](../../../images/security20.png) diff --git a/docs/zh/docs/admin/kpanda/security/index.md b/docs/zh/docs/admin/kpanda/security/index.md new file mode 100644 index 0000000..76a6c7d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/security/index.md @@ -0,0 +1,63 @@ +# 安全扫描类型 + +在Kubernetes(简称K8s)环境中,安全扫描是确保集群安全性的关键措施之一。其中,合规性扫描(基于CIS Benchmark)、权限扫描(基于kube-audit审计功能)、漏洞扫描(基于 kube-hunter)是三种常见且重要的安全扫描手段: + +- 合规性扫描:基于 [CIS Benchmark](https://github.com/aquasecurity/kube-bench/tree/main/cfg) 对集群节点进行安全扫描。CIS Benchmark 是一套全球公认的最佳实践标准,为 Kubernetes 集群提供了详细的安全配置指南和自动化检查工具(如Kube-Bench),帮助组织确保其K8s集群符合安全基线要求,保护系统和数据免受威胁。 + +- 权限扫描:基于kube-audit审计功能。权限扫描主要解决集群访问控制和操作透明度的问题。通过审计日志,集群管理员能够追溯集群资源的访问历史,识别异常行为,如未经授权的访问、敏感数据的泄露、有安全漏洞的操作记录等。这对于故障排查、安全事件响应以及满足合规性要求至关重要。此外,权限扫描还可以帮助组织发现潜在的权限滥用问题,及时采取措施防止安全事件的发生。 + +- 漏洞扫描:基于 kube-hunter,主要解决 Kubernetes 集群中存在的已知漏洞和配置错误问题。kube-hunter 通过模拟攻击行为,能够识别集群中可被恶意利用的漏洞,如未授权访问、暴露的服务和API端点、配置错误的角色和绑定策略等。特别地,kube-hunter能够识别并报告 CVE 漏洞,这些漏洞如果被恶意利用,可能导致数据泄露、服务中断等严重后果。[CVE 漏洞](https://www.mitre.org/)是由国际知名的安全组织如MITRE所定义和维护的,CVE数据库为软件和固件中的已知漏洞提供了唯一标识符,成为全球安全社区共同遵循的标准。kube-hunter 通过利用 CVE 数据库中的信息,能够帮助用户快速识别并响应Kubernetes集群中的安全威胁。 + +## 合规性扫描 + +合规性扫描的对象是集群节点。扫描结果中会列出扫描项以及扫描结果,并针对未通过的扫描项给出修复建议。有关扫描时用到的具体安全规则,可参考 [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes) + +检查不同类型的节点时,扫描的侧重点有所不同。 + +- 扫描控制平面节点(Controller) + + - 关注 __API Server__ 、 __controller-manager__ 、 __scheduler__ 、 __kubelet__ 等系统组件的安全性 + - 检查 Etcd 数据库的安全配置 + - 检查集群身份验证机制、授权策略和网络安全配置是否符合安全标准 + +- 扫描工作节点(Worker) + + - 检查 kubelet、Docker等容器运行时的配置否符合安全标准 + - 检查容器镜像是否经过信任验证 + - 检查节点的网络安全配置否符合安全标准 + +!!! tip + + 使用合规性扫描时,需要先创建[扫描配置](cis/config.md),然后基于该配置创建[扫描策略](cis/policy.md)。执行扫描策略之后,可以[查看扫描报告](cis/report.md)。 + +## 权限扫描 + +权限扫描侧重于权限问题引发的安全漏洞。权限扫描可以帮助用户识别 Kubernetes 集群中的安全威胁,标识哪些资源需要进行进一步的审查和保护措施。通过执行这些检查项,用户可以更清楚、更全面地了解自己的 Kubernetes 环境,确保集群环境符合 Kubernetes 的最佳实践和安全标准。 + +具体而言,权限扫描支持以下操作: + +- 扫描集群中的所有节点的健康状态。 + +- 扫描集群组件的运行状况,如 __kube-apiserver__ 、 __kube-controller-manager__ 、 __kube-scheduler__ 等。 + +- 扫描安全配置:检查 Kubernetes 的安全配置 + + - API 安全:启用了不安全的 API 版本,是否设置了适当的 RBAC 角色和权限限制等 + - 容器安全:是否使用了不安全的 Image、是否开放了特权模式,是否设置了合适的安全上下文等 + - 网络安全:是否启用了合适的网络策略来限制流量,是否使用了 TLS 加密等 + - 存储安全:是否启用了适当的加密、访问控制等。 + - 应用程序安全:是否设置了必要的安全措施,例如密码管理、跨站脚本攻击防御等。 + +- 提供警告和建议:建议集群管理员执行的安全最佳实践,例如定期轮换证书、使用强密码、限制网络访问等。 + +!!! tip + + 使用合规性扫描时,需要先创建扫描策略。执行扫描策略之后,可以查看扫描报告。详情可参考[安全扫描](audit.md)。 + +## 漏洞扫描 + +漏洞扫描侧重于扫描潜在的恶意攻击和安全漏洞,例如远程代码执行、SQL 注入、XSS 攻击等,以及一些针对 Kubernetes 特定的攻击。最终的扫描报告会列出集群中存在的安全漏洞,并提出修复建议。 + +!!! tip + + 使用合规性扫描时,需要先创建扫描策略。执行扫描策略之后,可以查看扫描报告。详情可参考[漏洞扫描](hunter.md)。 diff --git a/docs/zh/docs/admin/kpanda/storage/pv.md b/docs/zh/docs/admin/kpanda/storage/pv.md new file mode 100644 index 0000000..9be2a5f --- /dev/null +++ b/docs/zh/docs/admin/kpanda/storage/pv.md @@ -0,0 +1,112 @@ +# 数据卷(PV) + +数据卷(PersistentVolume,PV)是集群中的一块存储,可由管理员事先制备,或使用存储类(Storage Class)来动态制备。PV 是集群资源,但拥有独立的生命周期,不会随着 Pod 进程结束而被删除。将 PV 挂载到工作负载可以实现工作负载的数据持久化。PV 中保存了可被 Pod 中容器访问的数据目录。 + +## 创建数据卷 + +目前支持通过 YAML 和表单两种方式创建数据卷,这两种方式各有优劣,可以满足不同用户的使用需求。 + +- 通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉数据卷的 YAML 文件配置。 + +- 通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷(PV)__ -> __YAML 创建__ 。 + + ![路径](../../../images/pv01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![yaml](../../../images/pv02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷(PV)__ -> __创建数据卷(PV)__ 。 + + ![路径](../../../images/pv03.png) + +2. 填写基本信息。 + + - 数据卷名称、数据卷类型、挂载路径、卷模式、节点亲和性在创建之后不可更改。 + - 数据卷类型:有关卷类型的详细介绍,可参考 Kubernetes 官方文档[卷](https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/)。 + + - Local:将 Node 节点的本地存储包装成 PVC 接口,容器直接使用 PVC 而无需关注底层的存储类型。Local 卷不支持动态配置数据卷,但支持配置节点亲和性,可以限制能从哪些节点上访问该数据卷。 + - HostPath:使用 Node 节点的文件系统上的文件或目录作为数据卷,不支持基于节点亲和性的 Pod 调度。 + + - 挂载路径:将数据卷挂载到容器中的某个具体目录下。 + - 访问模式: + + - ReadWriteOnce:数据卷可以被一个节点以读写方式挂载。 + - ReadWriteMany:数据卷可以被多个节点以读写方式挂载。 + - ReadOnlyMany:数据卷可以被多个节点以只读方式挂载。 + - ReadWriteOncePod:数据卷可以被单个 Pod 以读写方式挂载。 + + - 回收策略: + + - Retain:不删除 PV,仅将其状态变为 __released__ ,需要用户手动回收。有关如何手动回收,可参考[持久卷](https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#retain)。 + - Recycle:保留 PV 但清空其中的数据,执行基本的擦除操作( __rm -rf /thevolume/*__ )。 + - Delete:删除 PV 时及其中的数据。 + + - 卷模式: + + - 文件系统:数据卷将被 Pod 挂载到某个目录。如果数据卷的存储来自某块设备而该设备目前为空,第一次挂载卷之前会在设备上创建文件系统。 + - 块:将数据卷作为原始块设备来使用。这类卷以块设备的方式交给 Pod 使用,其上没有任何文件系统,可以让 Pod 更快地访问数据卷。 + + - 节点亲和性: + + ![基本信息](../../../images/pv04.png) + +## 查看数据卷 + +在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷(PV)__ 。 + +- 该页面可以查看当前集群中的所有数据卷,以及各个数据卷的状态、容量、命名空间等信息。 + +- 支持按照数据卷的名称、状态、命名空间、创建时间进行顺序或逆序排序。 + + ![详情](../../../images/pv06.png) + +- 点击数据卷的名称,可以查看该数据卷的基本配置、存储池信息、标签、注解等信息。 + + ![详情](../../../images/pv05.png) + +## 克隆数据卷 + +通过克隆数据卷,可以基于被克隆数据卷的配置,重新创建一个新的数据卷。 + +1. 进入克隆页面 + + - 在数据卷列表页面,找到需要克隆的数据卷,在右侧的操作栏下选择 __克隆__ 。 + + > 也可以点击数据卷的名称,在详情页面的右上角点击操作按钮选择 __克隆__ 。 + + ![克隆](../../../images/pv11.png) + +2. 直接使用原配置,或者按需进行修改,然后在页面底部点击 __确定__ 。 + +## 更新数据卷 + +有两种途径可以更新数据卷。支持通过表单或 YAML 文件更新数据卷。 + +!!! note + + 仅支持更新数据卷的别名、容量、访问模式、回收策略、标签和注解。 + +- 在数据卷列表页面,找到需要更新的数据卷,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pv07.png) + +- 点击数据卷的名称,进入数据卷的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pv08.png) + +## 删除数据卷 + +在数据卷列表页面,找到需要删除的数据,在右侧的操作栏下选择 __删除__ 。 + +> 也可以点击数据卷的名称,在详情页面的右上角点击操作按钮选择 __删除__ 。 + +![删除](../../../images/pv09.png) diff --git a/docs/zh/docs/admin/kpanda/storage/pvc.md b/docs/zh/docs/admin/kpanda/storage/pvc.md new file mode 100644 index 0000000..e723647 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/storage/pvc.md @@ -0,0 +1,127 @@ +# 数据卷声明(PVC) + +持久卷声明(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。PVC 消耗 PV 资源,申领使用特定大小、特定访问模式的数据卷,例如要求 PV 卷以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 等模式来挂载。 + +## 创建数据卷声明 + +目前支持通过 YAML 和表单两种方式创建数据卷声明,这两种方式各有优劣,可以满足不同用户的使用需求。 + +- 通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉数据卷声明的 YAML 文件配置。 + +- 通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷声明 (PVC)__ -> __YAML 创建__ 。 + + ![路径](../../../images/pvc01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![yaml](../../../images/pvc02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷声明 (PVC)__ -> __创建数据卷声明 (PVC)__ 。 + + ![路径](../../../images/pvc03.png) + +2. 填写基本信息。 + + - 数据卷声明的名称、命名空间、创建方式、数据卷、容量、访问模式在创建之后不可更改。 + - 创建方式:在已有的存储池或者数据卷中动态创建新的数据卷声明,或者基于数据卷声明的快照创建新的数据卷声明。 + + > 基于快照创建时无法修改数据卷声明的容量,可以在创建完成后再进行修改。 + + - 选择创建方式之后,在下拉列表中选择想要使用的存储池/数据卷/快照。 + - 访问模式: + + - ReadWriteOnce,数据卷声明可以被一个节点以读写方式挂载。 + - ReadWriteMany,数据卷声明可以被多个节点以读写方式挂载。 + - ReadOnlyMany,数据卷声明可以被多个节点以只读方式挂载。 + - ReadWriteOncePod,数据卷声明可以被单个 Pod 以读写方式挂载。 + + ![基本信息](../../../images/pvc04.png) + +## 查看数据卷声明 + +在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷声明(PVC)__ 。 + +- 该页面可以查看当前集群中的所有数据卷声明,以及各个数据卷声明的状态、容量、命名空间等信息。 + +- 支持按照数据卷声明的名称、状态、命名空间、创建时间进行顺序或逆序排序。 + + ![详情](../../../images/pvc06.png) + +- 点击数据卷声明的名称,可以查看该数据卷声明的基本配置、存储池信息、标签、注解等信息。 + + ![详情](../../../images/pvc05.png) + +## 扩容数据卷声明 + +1. 在左侧导航栏点击 __容器存储__ -> __数据卷声明(PVC)__ ,找到想要调整容量的数据卷声明。 + + ![扩容](../../../images/pvc14.png) + +2. 点击数据卷声明的名称,然后在页面右上角点击操作按钮选择 __扩容__ 。 + + ![扩容](../../../images/pvc15.png) + +3. 输入目标容量,然后点击 __确定__ 。 + + ![克隆](../../../images/pvc16.png) + +## 克隆数据卷声明 + +通过克隆数据卷声明,可以基于被克隆数据卷声明的配置,重新创建一个新的数据卷声明。 + +1. 进入克隆页面 + + - 在数据卷声明列表页面,找到需要克隆的数据卷声明,在右侧的操作栏下选择 __克隆__ 。 + + > 也可以点击数据卷声明的名称,在详情页面的右上角点击操作按钮选择 __克隆__ 。 + + ![克隆](../../../images/pvc11.png) + +2. 直接使用原配置,或者按需进行修改,然后在页面底部点击 __确定__ 。 + + ![克隆](../../../images/pvc12.png) + +## 更新数据卷声明 + +有两种途径可以更新数据卷声明。支持通过表单或 YAML 文件更新数据卷声明。 + +!!! note + + 仅支持更新数据卷声明的别名、标签和注解。 + +- 在数据卷列表页面,找到需要更新的数据卷声明,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pvc07.png) + +- 点击数据卷声明的名称,进入数据卷声明的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pvc08.png) + +## 删除数据卷声明 + +在数据卷声明列表页面,找到需要删除的数据,在右侧的操作栏下选择 __删除__ 。 + +> 也可以点击数据卷声明的名称,在详情页面的右上角点击操作按钮选择 __删除__ 。 + +![删除](../../../images/pvc09.png) + +## 常见问题 + +1. 如果列表中没有可选的存储池或数据卷,可以[创建存储池](sc.md)或[创建数据卷](pv.md)。 + +2. 如果列表中没有可选的快照,可以进入数据卷声明的详情页,在右上角制作快照。 + + ![制作快照](../../../images/pvc17.png) + +3. 如果数据卷声明所使用的存储池 (SC) 没有启用快照,则无法制作快照,页面不会显示“制作快照”选项。 +4. 如果数据卷声明所使用的存储池 (SC) 没有开启扩容功能,则该数据卷不支持扩容,页面不会显示扩容选项。 + + ![开启快照](../../../images/pvc18.png) diff --git a/docs/zh/docs/admin/kpanda/storage/sc-share.md b/docs/zh/docs/admin/kpanda/storage/sc-share.md new file mode 100644 index 0000000..ff881e4 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/storage/sc-share.md @@ -0,0 +1,14 @@ +# 共享存储池 + +算丰 AI 算力平台容器管理模块支持将一个存储池共享给多个命名空间使用,以便提高资源利用效率。 + +1. 在存储池列表中找到需要共享的存储池,在右侧操作栏下点击 __授权命名空间__ 。 + + ![授权](../../../images/sc-share01.png) + +2. 点击 __自定义命名空间__ 可以逐一选择需要将此存储池共享到哪些命名空间。 + + - 点击 __授权所有命名空间__ 可以一次性将此存储池共享到当前集群下的所有命名空间。 + - 在列表右侧的操作栏下方点击 __移除授权__ ,可以解除授权,停止将此存储池共享到该命名空间。 + + ![授权](../../../images/sc-share02.png) diff --git a/docs/zh/docs/admin/kpanda/storage/sc.md b/docs/zh/docs/admin/kpanda/storage/sc.md new file mode 100644 index 0000000..53f0c5d --- /dev/null +++ b/docs/zh/docs/admin/kpanda/storage/sc.md @@ -0,0 +1,73 @@ +# 存储池(SC) + +存储池指将许多物理磁盘组成一个大型存储资源池,本平台支持接入各类存储厂商后创建块存储池、本地存储池、自定义存储池,然后为工作负载动态配置数据卷。 + +## 创建存储池(SC) + +目前支持通过 YAML 和表单两种方式创建存储池,这两种方式各有优劣,可以满足不同用户的使用需求。 + +- 通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉存储池的 YAML 文件配置。 + +- 通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __存储池(SC)__ -> __YAML 创建__ 。 + + ![路径](../images/sc01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![yaml](../../../images/sc02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __存储池(SC)__ -> __创建存储池(SC)__ 。 + + ![路径](../images/sc03.png) + +2. 填写基本信息,然后在底部点击 __确定__ 。 + + **自定义存储系统** + + - 存储池名称、驱动、回收策略在创建后不可修改。 + - CSI 存储驱动:基于标准 Kubernetes 的容器存储接口插件,需遵守存储厂商规定的格式,例如 __rancher.io/local-path__ 。 + + - 有关如何填写不同厂商提供的 CSI 驱动,可参考 Kubernetes 官方文档[存储类](https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#provisioner)。 + - 回收策略:删除数据卷时,保留数据卷中的数据或者删除其中的数据。 + - 快照/扩容:开启后,基于该存储池的数据卷/数据卷声明才能支持扩容和快照功能,但 **前提是底层使用的存储驱动支持快照和扩容功能**。 + + **HwameiStor 存储系统** + + - 存储池名称、驱动、回收策略在创建后不可修改。 + - 存储系统:HwameiStor 存储系统。 + - 存储类型:支持 LVM,裸磁盘类型 + - __LVM 类型__ :HwameiStor 推荐使用此方式,可使用高可用数据卷,对应的的 CSI 存储驱动为 `lvm.hwameistor.io`。 + - __裸磁盘数据卷__ : 适用于非高可用场景,无高可用能力,对应的 CSI 驱动为 `hdd.hwameistor.io` + - 高可用模式:使用高可用能力之前请确认 __DRBD 组件__ 已安装。开启高可用模式后,可将数据卷副本数设置为 1 和 2。 如需要可将数据卷副本从 1 Convert 成 1 + - 回收策略:删除数据卷时,保留数据卷中的数据或者删除其中的数据。 + - 快照/扩容:开启后,基于该存储池的数据卷/数据卷声明才能支持扩容和快照功能,但 **前提是底层使用的存储驱动支持快照和扩容功能**。 + + !!! note + + 目前 HwameiStor xfs、ext4 两种文件系统,其中默认使用的是 xfs 文件系统,如果想要替换为 ext4,可以在自定义参数添加 __csi.storage.k8s.io/fstype: ext4__ + + ![基本信息](../images/sc04.png) + +## 更新存储池(SC) + +在存储池列表页面,找到需要更新的存储池,在右侧的操作栏下选择 __编辑__ 即可通过更新存储池。 + +![更新](../images/sc05.png) + +!!! info + + 选择 __查看 YAML__ 可以查看该存储池的 YAML 文件,但不支持编辑。 + +## 删除存储池(SC) + +在存储池列表页面,找到需要删除的存储池,在右侧的操作栏下选择 __删除__ 。 + +![删除](../images/sc06.png) diff --git a/docs/zh/docs/admin/kpanda/workloads/create-cronjob.md b/docs/zh/docs/admin/kpanda/workloads/create-cronjob.md new file mode 100644 index 0000000..f7f7bac --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/create-cronjob.md @@ -0,0 +1,223 @@ +# 创建定时任务(CronJob) + +本文介绍如何通过镜像和 YAML 文件两种方式创建定时任务(CronJob)。 + +定时任务(CronJob)适用于于执行周期性的操作,例如备份、报告生成等。这些任务可以配置为周期性重复的(例如:每天/每周/每月一次),可以定义任务开始执行的时间间隔。 + +## 前提条件 + +创建定时任务(CronJob)之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个定时任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_6.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __定时任务__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/cronjob01.png) + +3. 依次填写[基本信息](create-cronjob.md#_3)、[容器配置](create-cronjob.md#_4)、[定时任务配置](create-cronjob.md#_5)、[高级配置](create-cronjob.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __定时任务__ 列表。点击列表右侧的 __┇__ ,可以对定时任务执行执行更新、删除、重启等操作。 + + ![操作菜单](../../../images/cronjob06.png) + +### 基本信息 + +在 __创建定时任务__ 页面中,根据下表输入信息后,点击 __下一步__ 。 + +![基本信息](../images/cronjob02.png) + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的定时任务部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 描述:输入工作负载的描述信息,内容自定义。字符数量应不超过 512 个。 + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../images/cronjob03.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_3.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_3.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_3.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_3.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_3.png) + +### 定时任务配置 + +![定时任务配置](../images/cronjob04.png) + +- 并发策略:是否允许多个 Job 任务并行执行。 + + - __Allow__ :可以在前一个任务未完成时就创建新的定时任务,而且多个任务可以并行。任务太多可能抢占集群资源。 + - __Forbid__ :在前一个任务完成之前,不能创建新任务,如果新任务的执行时间到了而之前的任务仍未执行完,CronJob 会忽略新任务的执行。 + - __Replace__ :如果新任务的执行时间到了,但前一个任务还未完成,新的任务会取代前一个任务。 + + > 上述规则仅适用于同一个 CronJob 创建的多个任务。多个 CronJob 创建的多个任务总是允许并发执行。 + +- 定时规则:基于分钟、小时、天、周、月设置任务执行的时间周期。支持用数字和 `*` 自定义 Cron 表达式,**输入表达式后下方会提示当前表达式的含义**。有关详细的表达式语法规则,可参考 [Cron 时间表语法](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax)。 +- 任务记录:设定保留多少条任务执行成功或失败的记录。 __0__ 表示不保留。 +- 超时时间:超出该时间时,任务就会被标识为执行失败,任务下的所有 Pod 都会被删除。为空时表示不设置超时时间。默认值为 360 s。 +- 重试次数:任务可重试次数,默认值为 6。 +- 重启策略:设置任务失败时是否重启 Pod。 + +### 服务配置 + +为有状态负载配置[服务(Service)](../network/create-services.md),使有状态负载能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../images/cronjob12.png) + +2. 参考[创建服务](../network/create-services.md),配置服务参数。 + + ![创建服务](../../../images/deploy13_2.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +定时任务的高级配置主要涉及标签与注解。 + +可以点击 __添加__ 按钮为工作负载实例 Pod 添加标签和注解。 + +![定时任务配置](../../../images/cronjob05.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建定时任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_6.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __定时任务__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/cronjob07.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/cronjob08_1.png) + +??? note "点击查看创建定时任务的 YAML 示例" + + ```yaml + apiVersion: batch/v1 + kind: CronJob + metadata: + creationTimestamp: '2022-12-26T09:45:47Z' + generation: 1 + name: demo + namespace: default + resourceVersion: '92726617' + uid: d030d8d7-a405-4dcd-b09a-176942ef36c9 + spec: + concurrencyPolicy: Allow + failedJobsHistoryLimit: 1 + jobTemplate: + metadata: + creationTimestamp: null + spec: + activeDeadlineSeconds: 360 + backoffLimit: 6 + template: + metadata: + creationTimestamp: null + spec: + containers: + - image: nginx + imagePullPolicy: IfNotPresent + lifecycle: {} + name: container-3 + resources: + limits: + cpu: 250m + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + securityContext: + privileged: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + schedule: 0 0 13 * 5 + successfulJobsHistoryLimit: 3 + suspend: false + status: {} + ``` diff --git a/docs/zh/docs/admin/kpanda/workloads/create-daemonset.md b/docs/zh/docs/admin/kpanda/workloads/create-daemonset.md new file mode 100644 index 0000000..fc9884a --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/create-daemonset.md @@ -0,0 +1,391 @@ +# 创建守护进程(DaemonSet) + +本文介绍如何通过镜像和 YAML 文件两种方式创建守护进程(DaemonSet)。 + +守护进程(DaemonSet)通过[节点亲和性](https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)与[污点](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)功能确保在全部或部分节点上运行一个 Pod 的副本。对于新加入集群的节点,DaemonSet 自动在新节点上部署相应的 Pod,并跟踪 Pod 的运行状态。当节点被移除时,DaemonSet 则删除其创建的所有 Pod。 + +守护进程的常见用例包括: + +- 在每个节点上运行集群守护进程。 + +- 在每个节点上运行日志收集守护进程。 + +- 在每个节点上运行监控守护进程。 + +简单起见,可以在每个节点上为每种类型的守护进程都启动一个 DaemonSet。如需更精细、更高级地管理守护进程,也可以为同一种守护进程部署多个 DaemonSet。每个 DaemonSet 具有不同的标志,并且对不同硬件类型具有不同的内存、CPU 要求。 + +## 前提条件 + +创建 DaemonSet 之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个守护进程。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_2.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __守护进程__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/daemon01.png) + +3. 依次填写[基本信息](create-daemonset.md#_3)、[容器配置](create-daemonset.md#_4)、[服务配置](create-daemonset.md#_5)、[高级配置](create-daemonset.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __守护进程__ 列表。点击列表右侧的 __┇__ ,可以对守护进程执行执行更新、删除、重启等操作。 + + ![操作菜单](../../../images/daemon05.png) + +### 基本信息 + +在 __创建守护进程__ 页面中,根据下表输入信息后,点击 __下一步__ 。 + +![基本信息](../../../images/daemon02.png) + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的守护进程部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 描述:输入工作负载的描述信息,内容自定义。字符数量应不超过 512 个。 + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../../../images/daemon06.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_1.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_1.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_1.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_1.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_1.png) + +### 服务配置 + +为守护进程创建[服务(Service)](../network/create-services.md),使守护进程能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../../../images/daemon03.png) + +2. 配置服务参数,详情请参考[创建服务](../network/create-services.md)。 + + ![创建服务](../../../images/deploy13.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +高级配置包括负载的网络配置、升级策略、调度策略、标签与注解四部分,可点击下方的页签查看各部分的配置要求。 + +=== "网络配置" + + 应用在某些场景下会出现冗余的 DNS 查询。Kubernetes 为应用提供了与 DNS 相关的配置选项,能够在某些场景下有效地减少冗余的 DNS 查询,提升业务并发量。 + + ![DNS 配置](../../../images/deploy17.png) + + - DNS 策略 + + - Default:使容器使用 kubelet 的 __--resolv-conf__ 参数指向的域名解析文件。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的 DNS 查询。 + - ClusterFirstWithHostNet:应用对接主机的域名文件。 + - ClusterFirst:应用对接 Kube-DNS/CoreDNS。 + - None:Kubernetes v1.9(Beta in v1.10)中引入的新选项值。设置为 None 之后,必须设置 dnsConfig,此时容器的域名解析文件将完全通过 dnsConfig 的配置来生成。 + + - 域名服务器:填写域名服务器的地址,例如 __10.6.175.20__ 。 + - 搜索域:域名查询时的 DNS 搜索域列表。指定后,提供的搜索域列表将合并到基于 dnsPolicy 生成的域名解析文件的 search 字段中,并删除重复的域名。Kubernetes 最多允许 6 个搜索域。 + - Options:DNS 的配置选项,其中每个对象可以具有 name 属性(必需)和 value 属性(可选)。该字段中的内容将合并到基于 dnsPolicy 生成的域名解析文件的 options 字段中,dnsConfig 的 options 的某些选项如果与基于 dnsPolicy 生成的域名解析文件的选项冲突,则会被 dnsConfig 所覆盖。 + - 主机别名:为主机设置的别名。 + +=== "升级策略" + + ![升级策略](../../../images/deploy14.png) + + - 升级方式: __滚动升级__ 指逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。 __重建升级__ 指先删除老版本的负载实例,再安装指定的新版本,升级过程中业务会中断。 + - 最大无效 Pod 数:指定负载更新过程中不可用 Pod 的最大值或比率,默认 25%。如果等于实例数有服务中断的风险。 + - 最大浪涌:更新 Pod 的过程中 Pod 总数超过 Pod 期望副本数部分的最大值或比率。默认 25%。 + - 最大保留版本数:设置版本回滚时保留的旧版本数量。默认 10。 + - Pod 可用最短时间:Pod 就绪的最短时间,只有超出这个时间 Pod 才被认为可用,默认 0 秒。 + - 升级最大持续时间:如果超过所设置的时间仍未部署成功,则将该负载标记为失败。默认 600 秒。 + - 缩容时间窗:负载停止前命令的执行时间窗(0-9,999秒),默认 30 秒。 + +=== "调度策略" + + ![调度策略](../../../images/deploy15.png) + + - 容忍时间:负载实例所在的节点不可用时,将负载实例重新调度到其它可用节点的时间,默认为 300 秒。 + - 节点亲和性:根据节点上的标签来约束 Pod 可以调度到哪些节点上。 + - 工作负载亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到哪些节点。 + - 工作负载反亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 不可以调度到哪些节点。 + - 拓扑域:即 topologyKey,用于指定可以调度的一组节点。例如, __kubernetes.io/os__ 表示只要某个操作系统的节点满足 labelSelector 的条件就可以调度到该节点。 + + > 具体详情请参考[调度策略](pod-config/scheduling-policy.md)。 + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载和容器组添加标签和注解。 + + ![标签与注解](../../../images/deploy16.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建守护进程。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_2.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __守护进程__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/daemon07.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/daemon08.png) + +??? note "点击查看创建守护进程的 YAML 示例" + + ```yaml + kind: DaemonSet + apiVersion: apps/v1 + metadata: + name: hwameistor-local-disk-manager + namespace: hwameistor + uid: ccbdc098-7de3-4a8a-96dd-d1cee159c92b + resourceVersion: '90999552' + generation: 1 + creationTimestamp: '2022-12-15T09:03:44Z' + labels: + app.kubernetes.io/managed-by: Helm + annotations: + deprecated.daemonset.template.generation: '1' + meta.helm.sh/release-name: hwameistor + meta.helm.sh/release-namespace: hwameistor + spec: + selector: + matchLabels: + app: hwameistor-local-disk-manager + template: + metadata: + creationTimestamp: null + labels: + app: hwameistor-local-disk-manager + spec: + volumes: + - name: udev + hostPath: + path: /run/udev + type: Directory + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + hostPath: + path: /dev + type: Directory + - name: socket-dir + hostPath: + path: /var/lib/kubelet/plugins/disk.hwameistor.io + type: DirectoryOrCreate + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: /var/lib/kubelet/pods + type: DirectoryOrCreate + containers: + - name: registrar + image: k8s-gcr.m.daocloud.io/sig-storage/csi-node-driver-registrar:v2.5.0 + args: + - '--v=5' + - '--csi-address=/csi/csi.sock' + - >- + --kubelet-registration-path=/var/lib/kubelet/plugins/disk.hwameistor.io/csi.sock + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + resources: {} + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + lifecycle: + preStop: + exec: + command: + - /bin/sh + - '-c' + - >- + rm -rf /registration/disk.hwameistor.io + /registration/disk.hwameistor.io-reg.sock + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: manager + image: ghcr.m.daocloud.io/hwameistor/local-disk-manager:v0.6.1 + command: + - /local-disk-manager + args: + - '--endpoint=$(CSI_ENDPOINT)' + - '--nodeid=$(NODENAME)' + - '--csi-enable=true' + env: + - name: CSI_ENDPOINT + value: unix://var/lib/kubelet/plugins/disk.hwameistor.io/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: NODENAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OPERATOR_NAME + value: local-disk-manager + resources: {} + volumeMounts: + - name: udev + mountPath: /run/udev + - name: procmount + readOnly: true + mountPath: /host/proc + - name: devmount + mountPath: /dev + - name: registration-dir + mountPath: /var/lib/kubelet/plugins_registry + - name: plugin-dir + mountPath: /var/lib/kubelet/plugins + mountPropagation: Bidirectional + - name: pods-mount-dir + mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + privileged: true + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: hwameistor-admin + serviceAccount: hwameistor-admin + hostNetwork: true + hostPID: true + securityContext: {} + schedulerName: default-scheduler + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + - key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + effect: NoSchedule + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + revisionHistoryLimit: 10 + status: + currentNumberScheduled: 4 + numberMisscheduled: 0 + desiredNumberScheduled: 4 + numberReady: 4 + observedGeneration: 1 + updatedNumberScheduled: 4 + numberAvailable: 4 + ``` diff --git a/docs/zh/docs/admin/kpanda/workloads/create-deployment.md b/docs/zh/docs/admin/kpanda/workloads/create-deployment.md new file mode 100644 index 0000000..17a5089 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/create-deployment.md @@ -0,0 +1,223 @@ +# 创建无状态负载(Deployment) + +本文介绍如何通过镜像和 YAML 文件两种方式创建无状态负载。 + +[无状态负载(Deployment)](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/)是 Kubernetes 中的一种常见资源,主要为 [Pod](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/) 和 [ReplicaSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/) 提供声明式更新,支持弹性伸缩、滚动升级、版本回退等功能。在 Deployment 中声明期望的 Pod 状态,Deployment Controller 会通过 ReplicaSet 修改当前状态,使其达到预先声明的期望状态。Deployment 是无状态的,不支持数据持久化,适用于部署无状态的、不需要保存数据、随时可以重启回滚的应用。 + +通过算丰 AI 算力平台的容器管理模块,可以基于相应的角色权限轻松管理多云多集群上的工作负载,包括对无状态负载的创建、更新、删除、弹性扩缩、重启、版本回退等全生命周期管理。 + +## 前提条件 + +在使用镜像创建无状态负载之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个无状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_4.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __无状态负载__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/deploy02.png) + +3. 依次填写[基本信息](create-deployment.md#_3)、[容器配置](create-deployment.md#_4)、[服务配置](create-deployment.md#_5)、[高级配置](create-deployment.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __无状态负载__ 列表。点击列表右侧的 __┇__ ,可以对负载执行执行更新、删除、弹性扩缩、重启、版本回退等操作。如果负载状态出现异常,请查看具体异常信息,可参考[工作负载状态](../workloads/pod-config/workload-status.md)。 + + ![操作菜单](../../../images/deploy18.png) + +### 基本信息 + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 deployment-01。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的负载部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 实例数:输入负载的 Pod 实例数量,默认创建 1 个 Pod 实例。 +- 描述:输入负载的描述信息,内容自定义。字符数不超过 512。 + + ![基本信息](../../../images/deploy04.png) + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../images/deploy05.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 安装算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_2.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_2.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_2.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_2.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_2.png) + +### 服务配置 + +为无状态负载配置[服务(Service)](../network/create-services.md),使无状态负载能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../../../images/deploy12.png) + +2. 参考[创建服务](../network/create-services.md),配置服务参数。 + + ![创建服务](../../../images/deploy13_1.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +高级配置包括负载的网络配置、升级策略、调度策略、标签与注解四部分,可点击下方的页签查看各部分的配置要求。 + +=== "网络配置" + + - 如在集群中部署了 SpiderPool 和 Multus 组件,则可以在网络配置中配置容器网卡。 + + - DNS 配置:应用在某些场景下会出现冗余的 DNS 查询。Kubernetes 为应用提供了与 DNS 相关的配置选项,能够在某些场景下有效地减少冗余的 DNS 查询,提升业务并发量。 + + - DNS 策略 + + - Default:使容器使用 kubelet 的 __--resolv-conf__ 参数指向的域名解析文件。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的 DNS 查询。 + - ClusterFirstWithHostNet:应用对接主机的域名文件。 + - ClusterFirst:应用对接 Kube-DNS/CoreDNS。 + - None:Kubernetes v1.9(Beta in v1.10)中引入的新选项值。设置为 None 之后,必须设置 dnsConfig,此时容器的域名解析文件将完全通过 dnsConfig 的配置来生成。 + + - 域名服务器:填写域名服务器的地址,例如 __10.6.175.20__ 。 + - 搜索域:域名查询时的 DNS 搜索域列表。指定后,提供的搜索域列表将合并到基于 dnsPolicy 生成的域名解析文件的 search 字段中,并删除重复的域名。Kubernetes 最多允许 6 个搜索域。 + - Options:DNS 的配置选项,其中每个对象可以具有 name 属性(必需)和 value 属性(可选)。该字段中的内容将合并到基于 dnsPolicy 生成的域名解析文件的 options 字段中,dnsConfig 的 options 的某些选项如果与基于 dnsPolicy 生成的域名解析文件的选项冲突,则会被 dnsConfig 所覆盖。 + - 主机别名:为主机设置的别名。 + + ![DNS 配置](../../../images/deploy17_1.png) + +=== "升级策略" + + - 升级方式: __滚动升级__ 指逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。 __重建升级__ 指先删除老版本的负载实例,再安装指定的新版本,升级过程中业务会中断。 + - 最大不可用:指定负载更新过程中不可用 Pod 的最大值或比率,默认 25%。如果等于实例数有服务中断的风险。 + - 最大峰值:更新 Pod 的过程中 Pod 总数超过 Pod 期望副本数部分的最大值或比率。默认 25%。 + - 最大保留版本数:设置版本回滚时保留的旧版本数量。默认 10。 + - Pod 可用最短时间:Pod 就绪的最短时间,只有超出这个时间 Pod 才被认为可用,默认 0 秒。 + - 升级最大持续时间:如果超过所设置的时间仍未部署成功,则将该负载标记为失败。默认 600 秒。 + - 缩容时间窗:负载停止前命令的执行时间窗(0-9,999秒),默认 30 秒。 + + ![升级策略](../images/deploy14.png) + +=== "调度策略" + + - 容忍时间:负载实例所在的节点不可用时,将负载实例重新调度到其它可用节点的时间,默认为 300 秒。 + - 节点亲和性:根据节点上的标签来约束 Pod 可以调度到哪些节点上。 + - 工作负载亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到哪些节点。 + - 工作负载反亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 不可以调度到哪些节点。 + + > 具体详情请参考[调度策略](pod-config/scheduling-policy.md)。 + + ![调度策略](../images/deploy15.png) + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载和容器组添加标签和注解。 + + ![标签与注解](../images/deploy16.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建无状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_4.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __无状态负载__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/deploy02Yaml.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/deploy03yaml.png) + +??? note "点击查看创建无状态负载的 YAML 示例" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-deployment + spec: + selector: + matchLabels: + app: nginx + replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + ``` diff --git a/docs/zh/docs/admin/kpanda/workloads/create-job.md b/docs/zh/docs/admin/kpanda/workloads/create-job.md new file mode 100644 index 0000000..8a67b06 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/create-job.md @@ -0,0 +1,209 @@ +# 创建任务(Job) + +本文介绍如何通过镜像和 YAML 文件两种方式创建任务(Job)。 + +任务(Job)适用于执行一次性任务。Job 会创建一个或多个 Pod,Job 会一直重新尝试执行 Pod,直到成功终止的 Pod 达到一定数量。成功终止的 Pod 达到指定的数量后,Job 也随之结束。删除 Job 时会一同清除该 Job 创建的所有 Pod。暂停 Job 时删除该 Job 中的所有活跃 Pod,直到 Job 被继续执行。有关任务(Job)的更多介绍,可参考[Job](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/job/)。 + +## 前提条件 + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __任务__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/job01.png) + +3. 依次填写[基本信息](create-job.md#_3)、[容器配置](create-job.md#_4)、服务配置、[高级配置](create-job.md#_5)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __任务__ 列表。点击列表右侧的 __┇__ ,可以对任务执行执行更新、删除、重启等操作。 + + ![操作菜单](../../../images/job08.png) + +### 基本信息 + +在 __创建任务__ 页面中,根据下表输入基本信息后,点击 __下一步__ 。 + +![创建任务](../../../images/job02.png) + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的任务部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 实例数:输入工作负载的 Pod 实例数量。默认创建 1 个 Pod 实例。 +- 描述:输入工作负载的描述信息,内容自定义。字符数量应不超过 512 个。 + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../../../images/job02-1.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10.png) + +### 高级配置 + +高级配置包括任务设置、标签与注解两部分。 + +=== "任务设置" + + ![任务设置](../../../images/job03.png) + + - 并行数:任务执行过程中允许同时创建的最大 Pod 数,并行数应不大于 Pod 总数。默认为 1。 + - 超时时间:超出该时间时,任务会被标识为执行失败,任务下的所有 Pod 都会被删除。为空时表示不设置超时时间。 + - 重启策略:设置失败时是否重启 Pod。 + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载实例 Pod 添加标签和注解。 + + ![标签与注解](../../../images/job04.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __任务__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/job09.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/cronjob08.png) + +??? note "点击查看创建任务的 YAML 示例" + + ```yaml + kind: Job + apiVersion: batch/v1 + metadata: + name: demo + namespace: default + uid: a9708239-0358-4aa1-87d3-a092c080836e + resourceVersion: '92751876' + generation: 1 + creationTimestamp: '2022-12-26T10:52:22Z' + labels: + app: demo + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + job-name: demo + annotations: + revisions: >- + {"1":{"status":"running","uid":"a9708239-0358-4aa1-87d3-a092c080836e","start-time":"2022-12-26T10:52:22Z","completion-time":"0001-01-01T00:00:00Z"}} + spec: + parallelism: 1 + backoffLimit: 6 + selector: + matchLabels: + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + template: + metadata: + creationTimestamp: null + labels: + app: demo + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + job-name: demo + spec: + containers: + - name: container-4 + image: nginx + resources: + limits: + cpu: 250m + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + lifecycle: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + privileged: false + restartPolicy: Never + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: {} + schedulerName: default-scheduler + completionMode: NonIndexed + suspend: false + status: + startTime: '2022-12-26T10:52:22Z' + active: 1 + ``` diff --git a/docs/zh/docs/admin/kpanda/workloads/create-statefulset.md b/docs/zh/docs/admin/kpanda/workloads/create-statefulset.md new file mode 100644 index 0000000..c954b67 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/create-statefulset.md @@ -0,0 +1,670 @@ +# 创建有状态负载(StatefulSet) + +本文介绍如何通过镜像和 YAML 文件两种方式创建有状态负载(StatefulSet)。 + +[有状态负载(StatefulSet)](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/)是 Kubernetes 中的一种常见资源,和[无状态负载(Deployment)](create-deployment.md)类似,主要用于管理 Pod 集合的部署和伸缩。二者的主要区别在于,Deployment 是无状态的,不保存数据,而 StatefulSet 是有状态的,主要用于管理有状态应用。此外,StatefulSet 中的 Pod 具有永久不变的 ID,便于在匹配存储卷时识别对应的 Pod。 + +通过算丰 AI 算力平台的容器管理模块,可以基于相应的角色权限轻松管理多云多集群上的工作负载,包括对有状态工作负载的创建、更新、删除、弹性扩缩、重启、版本回退等全生命周期管理。 + +## 前提条件 + +在使用镜像创建有状态负载之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../ghippo/access-control/user.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个有状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_8.png) + +2. 点击左侧导航栏的 __工作负载__ -> __有状态负载__ ,然后点击右上角 __镜像创建__ 按钮。 + + ![工作负载](../../../images/state02.png) + +3. 依次填写[基本信息](create-statefulset.md#_3)、[容器配置](create-statefulset.md#_4)、[服务配置](create-statefulset.md#_5)、[高级配置](create-statefulset.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __有状态工作负载__ 列表,等待工作负载状态变为 __运行中__ 。如果工作负载状态出现异常,请查看具体异常信息,可参考[工作负载状态](../workloads/pod-config/workload-status.md)。 + + 点击新建工作负载列右侧的 __┇__ ,可以对工作负载执行执行更新、删除、弹性扩缩、重启、版本回退等操作。 + + ![操作菜单](../../../images/state10.png) + +### 基本信息 + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 deployment-01。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的负载部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 实例数:输入负载的 Pod 实例数量,默认创建 1 个 Pod 实例。 +- 描述:输入负载的描述信息,内容自定义。字符数不超过 512。 + + ![基本信息](../../../images/state01.png) + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../../../images/state11.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_4.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态。有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_4.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_4.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_4.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_4.png) + +### 服务配置 + +为有状态负载配置[服务(Service)](../network/create-services.md),使有状态负载能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../../../images/state12.png) + +2. 参考[创建服务](../network/create-services.md),配置服务参数。 + + ![创建服务](../../../images/deploy13_3.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +高级配置包括负载的网络配置、升级策略、调度策略、标签与注解四部分,可点击下方的页签查看各部分的配置要求。 + +=== "网络配置" + + - 如在集群中部署了 SpiderPool 和 Multus 组件,则可以在网络配置中配置容器网卡。 + + - DNS 配置:应用在某些场景下会出现冗余的 DNS 查询。Kubernetes 为应用提供了与 DNS 相关的配置选项,能够在某些场景下有效地减少冗余的 DNS 查询,提升业务并发量。 + + - DNS 策略 + + - Default:使容器使用 kubelet 的 __--resolv-conf__ 参数指向的域名解析文件。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的 DNS 查询。 + - ClusterFirstWithHostNet:应用对接主机的域名文件。 + - ClusterFirst:应用对接 Kube-DNS/CoreDNS。 + - None:Kubernetes v1.9(Beta in v1.10)中引入的新选项值。设置为 None 之后,必须设置 dnsConfig,此时容器的域名解析文件将完全通过 dnsConfig 的配置来生成。 + + - 域名服务器:填写域名服务器的地址,例如 __10.6.175.20__ 。 + - 搜索域:域名查询时的 DNS 搜索域列表。指定后,提供的搜索域列表将合并到基于 dnsPolicy 生成的域名解析文件的 search 字段中,并删除重复的域名。Kubernetes 最多允许 6 个搜索域。 + - Options:DNS 的配置选项,其中每个对象可以具有 name 属性(必需)和 value 属性(可选)。该字段中的内容将合并到基于 dnsPolicy 生成的域名解析文件的 options 字段中,dnsConfig 的 options 的某些选项如果与基于 dnsPolicy 生成的域名解析文件的选项冲突,则会被 dnsConfig 所覆盖。 + - 主机别名:为主机设置的别名。 + + ![DNS 配置](../../../images/deploy17_2.png) + +=== "升级策略" + + - 升级方式: __滚动升级__ 指逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。 __重建升级__ 指先删除老版本的负载实例,再安装指定的新版本,升级过程中业务会中断。 + - 最大保留版本数:设置版本回滚时保留的旧版本数量。默认 10。 + - 缩容时间窗:负载停止前命令的执行时间窗(0-9,999秒),默认 30 秒。 + + ![升级策略](../../../images/deploy14_1.png) + +=== "容器管理策略" + + Kubernetes v1.7 及其之后的版本可以通过 __.spec.podManagementPolicy__ 设置 Pod 的管理策略,支持以下两种方式: + + - __按序策略(OrderedReady)__ :默认的 Pod 管理策略,表示按顺序部署 Pod,只有前一个 Pod 部署 成功完成后,有状态负载才会开始部署下一个 Pod。删除 Pod 时则采用逆序,最后创建的最先被删除。 + + - __并行策略(Parallel)__ :并行创建或删除容器,和 Deployment 类型的 Pod 一样。StatefulSet 控制器并行地启动或终止所有的容器。启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 ready 或者完全停止状态。 这个选项只会影响扩缩操作的行为,不影响更新时的顺序。 + + ![容器管理策略](../../../images/state05.png) + +=== "调度策略" + + - 容忍时间:负载实例所在的节点不可用时,将负载实例重新调度到其它可用节点的时间,默认为 300 秒。 + - 节点亲和性:根据节点上的标签来约束 Pod 可以调度到哪些节点上。 + - 工作负载亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到哪些节点。 + - 工作负载反亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 不可以调度到哪些节点。 + - 拓扑域:即 topologyKey,用于指定可以调度的一组节点。例如, __kubernetes.io/os__ 表示只要某个操作系统的节点满足 labelSelector 的条件就可以调度到该节点。 + + > 具体详情请参考[调度策略](pod-config/scheduling-policy.md)。 + + ![调度策略](../../../images/deploy15_1.png) + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载和容器组添加标签和注解。 + + ![标签与注解](../../../images/deploy16_1.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建有状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_8.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __有状态负载__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/deploy02Yaml_1.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/state03yaml.png) + +??? note "点击查看创建有状态负载的 YAML 示例" + + ```yaml + kind: StatefulSet + apiVersion: apps/v1 + metadata: + name: test-mysql-123-mysql + namespace: default + uid: d3f45527-a0ab-4b22-9013-5842a06f4e0e + resourceVersion: '20504385' + generation: 1 + creationTimestamp: '2022-09-22T09:34:10Z' + ownerReferences: + - apiVersion: mysql.presslabs.org/v1alpha1 + kind: MysqlCluster + name: test-mysql-123 + uid: 5e877cc3-5167-49da-904e-820940cf1a6d + controller: true + blockOwnerDeletion: true + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + mysql.presslabs.org/cluster: test-mysql-123 + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: test-mysql-123 + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + app.kubernetes.io/version: 5.7.31 + mysql.presslabs.org/cluster: test-mysql-123 + annotations: + config_rev: '13941099' + prometheus.io/port: '9125' + prometheus.io/scrape: 'true' + secret_rev: '13941101' + spec: + volumes: + - name: conf + emptyDir: {} + - name: init-scripts + emptyDir: {} + - name: config-map + configMap: + name: test-mysql-123-mysql + defaultMode: 420 + - name: data + persistentVolumeClaim: + claimName: data + initContainers: + - name: init + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - clone-and-init + envFrom: + - secretRef: + name: test-mysql-123-mysql-operated + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: BACKUP_USER + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: BACKUP_USER + optional: true + - name: BACKUP_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: BACKUP_PASSWORD + optional: true + resources: {} + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: config-map + mountPath: /mnt/conf + - name: data + mountPath: /var/lib/mysql + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + containers: + - name: mysql + image: docker.m.daocloud.io/mysql:5.7.31 + ports: + - name: mysql + containerPort: 3306 + protocol: TCP + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: ORCH_CLUSTER_ALIAS + value: test-mysql-123.default + - name: ORCH_HTTP_API + value: http://mysql-operator.mcamel-system/api + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: ROOT_PASSWORD + optional: false + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: USER + optional: true + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: PASSWORD + optional: true + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: DATABASE + optional: true + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 100m + memory: 512Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: data + mountPath: /var/lib/mysql + livenessProbe: + exec: + command: + - mysqladmin + - '--defaults-file=/etc/mysql/client.conf' + - ping + initialDelaySeconds: 60 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + test $(mysql --defaults-file=/etc/mysql/client.conf -NB -e + 'SELECT COUNT(*) FROM sys_operator.status WHERE + name="configured" AND value="1"') -eq 1 + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 2 + successThreshold: 1 + failureThreshold: 3 + lifecycle: + preStop: + exec: + command: + - bash + - /etc/mysql/pre-shutdown-ha.sh + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: sidecar + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - config-and-serve + ports: + - name: sidecar-http + containerPort: 8080 + protocol: TCP + envFrom: + - secretRef: + name: test-mysql-123-mysql-operated + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: XTRABACKUP_TARGET_DIR + value: /tmp/xtrabackup_backupfiles/ + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 10m + memory: 64Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: data + mountPath: /var/lib/mysql + readinessProbe: + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: metrics-exporter + image: prom/mysqld-exporter:v0.13.0 + args: + - '--web.listen-address=0.0.0.0:9125' + - '--web.telemetry-path=/metrics' + - '--collect.heartbeat' + - '--collect.heartbeat.database=sys_operator' + ports: + - name: prometheus + containerPort: 9125 + protocol: TCP + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: USER + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: METRICS_EXPORTER_USER + optional: false + - name: PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: METRICS_EXPORTER_PASSWORD + optional: false + - name: DATA_SOURCE_NAME + value: $(USER):$(PASSWORD)@(127.0.0.1:3306)/ + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 32Mi + livenessProbe: + httpGet: + path: /metrics + port: 9125 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 30 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: pt-heartbeat + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - pt-heartbeat + - '--update' + - '--replace' + - '--check-read-only' + - '--create-table' + - '--database' + - sys_operator + - '--table' + - heartbeat + - '--utc' + - '--defaults-file' + - /etc/mysql/heartbeat.conf + - '--fail-successive-errors=20' + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 10m + memory: 32Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: + runAsUser: 999 + fsGroup: 999 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: test-mysql-123 + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + app.kubernetes.io/version: 5.7.31 + mysql.presslabs.org/cluster: test-mysql-123 + topologyKey: kubernetes.io/hostname + schedulerName: default-scheduler + volumeClaimTemplates: + - kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: data + creationTimestamp: null + ownerReferences: + - apiVersion: mysql.presslabs.org/v1alpha1 + kind: MysqlCluster + name: test-mysql-123 + uid: 5e877cc3-5167-49da-904e-820940cf1a6d + controller: true + spec: + accessModes: + - ReadWriteOnce + resources: + limits: + storage: 1Gi + requests: + storage: 1Gi + storageClassName: local-path + volumeMode: Filesystem + status: + phase: Pending + serviceName: mysql + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: 0 + revisionHistoryLimit: 10 + status: + observedGeneration: 1 + replicas: 1 + readyReplicas: 1 + currentReplicas: 1 + updatedReplicas: 1 + currentRevision: test-mysql-123-mysql-6b8f5577c7 + updateRevision: test-mysql-123-mysql-6b8f5577c7 + collisionCount: 0 + availableReplicas: 1 + ``` diff --git a/docs/zh/docs/admin/kpanda/workloads/pod-config/env-variables.md b/docs/zh/docs/admin/kpanda/workloads/pod-config/env-variables.md new file mode 100644 index 0000000..2dfd005 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/pod-config/env-variables.md @@ -0,0 +1,13 @@ +# 配置环境变量 + +环境变量是指容器运行环境中设定的一个变量,用于给 Pod 添加环境标志或传递配置等,支持通过键值对的形式为 Pod 配置环境变量。 + +算丰 AI 算力平台容器管理在原生 Kubernetes 的基础上增加了图形化界面为 Pod 配置环境变量,支持以下几种配置方式: + +- **键值对**(Key/Value Pair):将自定义的键值对作为容器的环境变量 +- **资源引用**(Resource):将 Container 定义的字段作为环境变量的值,例如容器的内存限制、副本数等 +- **变量/变量引用**(Pod Field):将 Pod 字段作为环境变量的值,例如 Pod 的名称 +- **配置项键值导入**(ConfigMap key):导入配置项中某个键的值作为某个环境变量的值 +- **密钥键值导入**(Secret Key):使用来自 Secret 中的数据定义环境变量的值 +- **密钥导入**(Secret):将 Secret 中的所有键值都导入为环境变量 +- **配置项导入**(ConfigMap):将配置项中所有键值都导入为环境变量 diff --git a/docs/zh/docs/admin/kpanda/workloads/pod-config/health-check.md b/docs/zh/docs/admin/kpanda/workloads/pod-config/health-check.md new file mode 100644 index 0000000..05cae25 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/pod-config/health-check.md @@ -0,0 +1,159 @@ +# 容器的健康检查 + +容器健康检查根据用户需求,检查容器的健康状况。配置后,容器内的应用程序入如果异常,容器会自动进行重启恢复。Kubernetes 提供了存活(Liveness)检查、就绪(Readiness)检查和启动(Startup)检查。 + +- **存活检查(LivenessProbe)** 可探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。 + +- **就绪检查(ReadinessProbe)** 可探知容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。 + +- **启动检查(StartupProbe)** 可以了解应用容器何时启动,配置后,可控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探测器不会影响应用的启动。 启动探测可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。 + +## 存活和就绪检查 + +存活检查(LivenessProbe)的配置和就绪检查(ReadinessProbe)的配置参数相似, 唯一区别是要使用 __readinessProbe__ 字段,而不是 __livenessProbe__ 字段。 + +**HTTP GET 参数说明:** + +| 参数 | 参数说明 | +| -------------------------------- | ------------------------------------------------------------ | +| 路径( Path) | 访问的请求路径。如: 示例中的 /healthz 路径 | +| 端口(Port) | 服务监听端口。 如: 示例中的 8080 端口 | +| 协议 | 访问协议,Http 或者Https | +| 延迟时间(initialDelaySeconds) | 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。 | +| 超时时间(timeoutSeconds) | 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 | +| 超时时间(timeoutSeconds) | 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 | +| 成功阈值(successThreshold) | 探测失败后,被视为成功的最小连续成功数。默认值是 1,最小值是 1。存活和启动探测的这个值必须是 1。 | +| 最大失败次数(failureThreshold) | 当探测失败时重试的次数。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。 | + +### 使用 HTTP GET 请求检查 + +**YAML 示例:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-http +spec: + containers: + - name: liveness + image: k8s.gcr.io/liveness + args: + - /server + livenessProbe: + httpGet: + path: /healthz # 访问的请求路径 + port: 8080 # 服务监听端口 + httpHeaders: + - name: Custom-Header + value: Awesome + initialDelaySeconds: 3 # kubelet 在执行第一次探测前应该等待 3 秒 + periodSeconds: 3 # kubelet 每隔 3 秒执行一次存活探测 +``` + +按照设定的规则,kubelet 向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 __/healthz__ 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。 容器存活期间的最开始 10 秒中, __/healthz__ 处理程序返回 200 的状态码。 之后处理程序返回 500 的状态码。 + +### 使用 TCP 端口检查 + +**TCP 端口参数说明:** + +| 参数 | 参数说明 | +| ------------------------------- | ------------------------------------------------------------ | +| 端口(Port) | 服务监听端口。 如: 示例中的 8080 端口 | +| 延迟时间(initialDelaySeconds) | 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。 | +| 超时时间(timeoutSeconds) | 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 | + +对于提供TCP通信服务的容器,基于此配置,按照设定规则集群对该容器建立TCP连接,如果连接成功,则证明探测成功,否则探测失败。选择TCP端口探测方式,必须指定容器监听的端口。 + +**YAML 示例:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: goproxy + labels: + app: goproxy +spec: + containers: + - name: goproxy + image: k8s.gcr.io/goproxy:0.1 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 + +``` + +此示例同时使用就绪和存活探针。kubelet 在容器启动 5 秒后发送第一个就绪探测。 尝试连接 __goproxy__ 容器的 8080 端口, 如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。 + +除了就绪探测,这个配置包括了一个存活探测。 kubelet 会在容器启动 15 秒后进行第一次存活探测。 就绪探测会尝试连接 __goproxy__ 容器的 8080 端口。 如果存活探测失败,容器会被重新启动。 + +### 执行命令检查 + +**YAML 示例:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-exec +spec: + containers: + - name: liveness + image: k8s.gcr.io/busybox + args: + - /bin/sh + - -c + - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600 + livenessProbe: + exec: + command: + - cat + - /tmp/healthy + initialDelaySeconds: 5 # kubelet 在执行第一次探测前等待 5 秒 + periodSeconds: 5 #kubelet 每 5 秒执行一次存活探测 +``` + + __periodSeconds__ 字段指定了 kubelet 每 5 秒执行一次存活探测, __initialDelaySeconds__ 字段指定 kubelet 在执行第一次探测前等待 5 秒。按照设定规则,集群周期性的通过 kubelet 在容器内执行命令 __cat /tmp/healthy__ 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。 + +### 使用启动前检查保护慢启动容器 + +有些应用在启动时需要较长的初始化时间,需要使用相同的命令来设置启动探测,针对 HTTP 或 TCP 检测,可以通过将 __failureThreshold * periodSeconds__ 参数设置为足够长的时间来应对启动需要较长时间的场景。 + +**YAML 示例:** + +```yaml +ports: +- name: liveness-port + containerPort: 8080 + hostPort: 8080 + +livenessProbe: + httpGet: + path: /healthz + port: liveness-port + failureThreshold: 1 + periodSeconds: 10 + +startupProbe: + httpGet: + path: /healthz + port: liveness-port + failureThreshold: 30 + periodSeconds: 10 +``` + +如上设置,应用将有最多 5 分钟(30 * 10 = 300s)的时间来完成启动过程, 一旦启动探测成功,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应。 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 __restartPolicy__ 来 执行进一步处置。 diff --git a/docs/zh/docs/admin/kpanda/workloads/pod-config/job-parameters.md b/docs/zh/docs/admin/kpanda/workloads/pod-config/job-parameters.md new file mode 100644 index 0000000..253b0e8 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/pod-config/job-parameters.md @@ -0,0 +1,46 @@ +# 任务参数说明 + +根据 __.spec.completions__ 和 __.spec.Parallelism__ 的设置,可以将任务(Job)划分为以下几种类型: + +| Job 类型 | 说明 | +| -------------------------- | ------------------------------------------------------------ | +| 非并行 Job | 创建一个 Pod 直至其 Job 成功结束 | +| 具有确定完成计数的并行 Job | 当成功的 Pod 个数达到 __.spec.completions__ 时,Job 被视为完成 | +| 并行 Job | 创建一个或多个 Pod 直至有一个成功结束 | + +**参数说明** + +| RestartPolicy | 创建一个 Pod 直至其成功结束 | +| --------------------------- | ------------------------------------------------------------ | +| .spec.completions | 表示 Job 结束需要成功运行的 Pod 个数,默认为 1 | +| .spec.parallelism | 表示并行运行的 Pod 的个数,默认为 1 | +| spec.backoffLimit | 表示失败 Pod 的重试最大次数,超过这个次数不会继续重试。 | +| .spec.activeDeadlineSeconds | 表示 Pod 运行时间,一旦达到这个时间,Job 即其所有的 Pod 都会停止。且activeDeadlineSeconds 优先级高于 backoffLimit,即到达 activeDeadlineSeconds 的 Job 会忽略backoffLimit 的设置。 | + +以下是一个 Job 配置示例,保存在 myjob.yaml 中,其计算 π 到 2000 位并打印输出。 + +```yaml +apiVersion: batch/v1 +kind: Job #当前资源的类型 +metadata: + name: myjob +spec: + completions: 50 # Job结束需要运行50个Pod,这个示例中就是打印π 50次 + parallelism: 5 # 并行5个Pod + backoffLimit: 5 # 最多重试5次 + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never #重启策略 +``` + +**相关命令** + +```bash +kubectl apply -f myjob.yaml #启动 job +kubectl get job #查看这个job +kubectl logs myjob-1122dswzs 查看Job Pod 的日志 +``` diff --git a/docs/zh/docs/admin/kpanda/workloads/pod-config/lifecycle.md b/docs/zh/docs/admin/kpanda/workloads/pod-config/lifecycle.md new file mode 100644 index 0000000..6553fa5 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/pod-config/lifecycle.md @@ -0,0 +1,55 @@ +# 配置容器生命周期 + +Pod 遵循一个预定义的生命周期,起始于 __Pending__ 阶段,如果 Pod 内至少有一个容器正常启动,则进入 __Running__ 状态。如果 Pod 中有容器以失败状态结束,则状态变为 __Failed__ 。以下 __phase__ 字段值表明了一个 Pod 处于生命周期的哪个阶段。 + +值 | 描述 +:-----|:----------- +__Pending__
(悬决)| Pod 已被系统接受,但有一个或者多个容器尚未创建亦未运行。这个阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 +__Running__
(运行中) | Pod 已经绑定到了某个节点,Pod 中的所有容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 +__Succeeded__
(成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 +__Failed__
(失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败而终止。也就是说,容器以非 0 状态退出或者被系统终止。 +__Unknown__
(未知) | 因为某些原因无法取得 Pod 的状态,这种情况通常是因为与 Pod 所在主机通信失败所致。 + +在算丰 AI 算力平台容器管理中创建一个工作负载时,通常使用镜像来指定容器中的运行环境。默认情况下,在构建镜像时,可以通过 __Entrypoint__ 和 __CMD__ 两个字段来定义容器运行时执行的命令和参数。如果需要更改容器镜像启动前、启动后、停止前的命令和参数,可以通过设置容器的生命周期事件命令和参数,来覆盖镜像中默认的命令和参数。 + +## 生命周期配置 + +根据业务需要对容器的启动命令、启动后命令、停止前命令进行配置。 + +| 参数 | 说明 | 举例值 | +| :-------- | :----------------------------------------------------------- | :------------------------------------------------ | +| 启动命令 | 【类型】选填
【含义】容器将按照启动命令进行启动。 | | +| 启动后命令 | 【类型】选填
【含义】容器启动后出发的命令
| | +| 停止前命令 | 【类型】选填
【含义】容器在收到停止命令后执行的命令。确保升级或实例删除时可提前将实例中运行的业务排水。 | -- | + +### 启动命令 + +根据下表对启动命令进行配置。 + +| 参数 | 说明 | 举例值 | +| :------- | :----------------------------------------------------------- | :---------- | +| 运行命令 | 【类型】必填
【含义】输入可执行的命令,多个命令之间用空格进行分割,如命令本身带空格,则需要加(“”)。
【含义】多命令时,运行命令建议用/bin/sh或其他的shell,其他全部命令作为参数来传入。 | /run/server | +| 运行参数 | 【类型】选填
【含义】输入控制容器运行命令参数。
| port=8080 | + +### 启动后命令 + +算丰 AI 算力平台提供命令行脚本和 HTTP 请求两种处理类型对启动后命令进行配置。您可以根据下表选择适合您的配置方式。 + +**命令行脚本配置** + +| 参数 | 说明 | 举例值 | +| :------- | :----------------------------------------------------------- | :---------- | +| 运行命令 | 【类型】选填
【含义】输入可执行的命令,多个命令之间用空格进行分割,如命令本身带空格,则需要加(“”)。
【含义】多命令时,运行命令建议用/bin/sh或其他的shell,其他全部命令作为参数来传入。 | /run/server | +| 运行参数 | 【类型】选填
【含义】输入控制容器运行命令参数。
| port=8080 | + +### 停止前命令 + +算丰 AI 算力平台提供命令行脚本和 HTTP 请求两种处理类型对停止前命令进行配置。您可以根据下表选择适合您的配置方式。 + +**HTTP 请求配置** + +| 参数 | 说明 | 举例值 | +| :------- | :----------------------------------------------------------- | :---------- | +| URL 路径 | 【类型】选填
【含义】请求的URL路径。
【含义】多命令时,运行命令建议用/bin/sh或其他的shell,其他全部命令作为参数来传入。 | /run/server | +| 端口 | 【类型】必填
【含义】请求的端口。
| port=8080 | +| 节点地址 | 【类型】选填
【含义】请求的 IP 地址,默认是容器所在的节点 IP。
| -- | diff --git a/docs/zh/docs/admin/kpanda/workloads/pod-config/scheduling-policy.md b/docs/zh/docs/admin/kpanda/workloads/pod-config/scheduling-policy.md new file mode 100644 index 0000000..7c6af3b --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/pod-config/scheduling-policy.md @@ -0,0 +1,98 @@ +# 调度策略 + +在 Kubernetes 集群中,节点也有[标签](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/)。您可以[手动添加标签](https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-pods-nodes/#add-a-label-to-a-node)。 Kubernetes 也会为集群中所有节点添加一些标准的标签。参见[常用的标签、注解和污点](https://kubernetes.io/zh-cn/docs/reference/labels-annotations-taints/)以了解常见的节点标签。通过为节点添加标签,您可以让 Pod 调度到特定节点或节点组上。您可以使用这个功能来确保特定的 Pod 只能运行在具有一定隔离性,安全性或监管属性的节点上。 + + __nodeSelector__ 是节点选择约束的最简单推荐形式。您可以将 __nodeSelector__ 字段添加到 Pod 的规约中设置您希望目标节点所具有的[节点标签](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#built-in-node-labels)。Kubernetes 只会将 Pod 调度到拥有指定每个标签的节点上。 __nodeSelector__ 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。亲和性和反亲和性扩展了您可以定义的约束类型。使用亲和性与反亲和性的一些好处有: + +- 亲和性、反亲和性语言的表达能力更强。 __nodeSelector__ 只能选择拥有所有指定标签的节点。亲和性、反亲和性为您提供对选择逻辑的更强控制能力。 + +- 您可以标明某规则是“软需求”或者“偏好”,这样调度器在无法找到匹配节点时,会忽略亲和性/反亲和性规则,确保 Pod 调度成功。 + +- 您可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束,而不是只能使用节点本身的标签。这个能力让您能够定义规则允许哪些 Pod 可以被放置在一起。 + +您可以通过设置亲和(affinity)与反亲和(anti-affinity)来选择 Pod 要部署的节点。 + +## 容忍时间 + +当工作负载实例所在的节点不可用时,系统将实例重新调度到其它可用节点的时间窗。默认为 300 秒。 + +## 节点亲和性(nodeAffinity) + +节点亲和性概念上类似于 __nodeSelector__ , 它使您可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种: + +- **必须满足:( __requiredDuringSchedulingIgnoredDuringExecution__ )** 调度器只有在规则被满足的时候才能执行调度。此功能类似于 __nodeSelector__ , 但其语法表达能力更强。您可以定义多条硬约束规则,但只需满足其中一条。 + +- **尽量满足:( __preferredDuringSchedulingIgnoredDuringExecution__ )** 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。同时您还可以定义多条硬约束规则,但只需满足其中一条。 + +#### 标签名 + +对应节点的标签,可以使用默认的标签也可以用户自定义标签。 + +#### 操作符 + +- In:标签值需要在 values 的列表中 +- NotIn:标签的值不在某个列表中 +- Exists:判断某个标签是存在,无需设置标签值 +- DoesNotExist:判断某个标签是不存在,无需设置标签值 +- Gt:标签的值大于某个值(字符串比较) +- Lt:标签的值小于某个值(字符串比较) + +#### 权重 + +仅支持在“尽量满足”策略中添加,可以理解为调度的优先级,权重大的会被优先调度。取值范围是 1 到 100。 + +## 工作负载亲和性 + +与节点亲和性类似,工作负载的亲和性也有两种类型: + +- **必须满足:( __requiredDuringSchedulingIgnoredDuringExecution__ )** 调度器只有在规则被满足的时候才能执行调度。此功能类似于 __nodeSelector__ , 但其语法表达能力更强。您可以定义多条硬约束规则,但只需满足其中一条。 +- **尽量满足:( __preferredDuringSchedulingIgnoredDuringExecution__ )** 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。同时您还可以定义多条硬约束规则,但只需满足其中一条。 + +工作负载的亲和性主要用来决定工作负载的 Pod 可以和哪些 Pod部 署在同一拓扑域。例如,对于相互通信的服务,可通过应用亲和性调度,将其部署到同一拓扑域(如同一可用区)中,减少它们之间的网络延迟。 + +#### 标签名 + +对应节点的标签,可以使用默认的标签也可以用户自定义标签。 + +#### 命名空间 + +指定调度策略生效的命名空间。 + +#### 操作符 + +- In:标签值需要在 values 的列表中 +- NotIn:标签的值不在某个列表中 +- Exists:判断某个标签是存在,无需设置标签值 +- DoesNotExist:判断某个标签是不存在,无需设置标签值 + +#### 拓扑域 + +指定调度时的影响范围。例如,如果指定为 __kubernetes.io/Clustername__ 表示以 Node 节点为区分范围。 + +## 工作负载反亲和性 + +与节点亲和性类似,工作负载的反亲和性也有两种类型: + +- **必须满足:( __requiredDuringSchedulingIgnoredDuringExecution__ )** 调度器只有在规则被满足的时候才能执行调度。此功能类似于 __nodeSelector__ , 但其语法表达能力更强。您可以定义多条硬约束规则,但只需满足其中一条。 +- **尽量满足:( __preferredDuringSchedulingIgnoredDuringExecution__ )** 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。同时您还可以定义多条硬约束规则,但只需满足其中一条。 + +工作负载的反亲和性主要用来决定工作负载的 Pod 不可以和哪些 Pod 部署在同一拓扑域。例如,将一个负载的相同 Pod 分散部署到不同的拓扑域(例如不同主机)中,提高负载本身的稳定性。 + +#### 标签名 + +对应节点的标签,可以使用默认的标签也可以用户自定义标签。 + +#### 命名空间 + +指定调度策略生效的命名空间。 + +#### 操作符 + +- In:标签值需要在 values 的列表中 +- NotIn:标签的值不在某个列表中 +- Exists:判断某个标签是存在,无需设置标签值 +- DoesNotExist:判断某个标签是不存在,无需设置标签值 + +#### 拓扑域 + +指定调度时的影响范围。例如,如果指定为 __kubernetes.io/Clustername__ 表示以 Node 节点为区分范围。 diff --git a/docs/zh/docs/admin/kpanda/workloads/pod-config/workload-status.md b/docs/zh/docs/admin/kpanda/workloads/pod-config/workload-status.md new file mode 100644 index 0000000..d56eab3 --- /dev/null +++ b/docs/zh/docs/admin/kpanda/workloads/pod-config/workload-status.md @@ -0,0 +1,53 @@ +# 工作负载状态 + +工作负载是运行在 Kubernetes 上的一个应用程序,在 Kubernetes 中,无论您的应用程序是由单个同一组件或是由多个不同的组件构成,都可以使用一组 Pod 来运行它。Kubernetes 提供了五种内置的工作负载资源来管理 Pod: + +- [无状态工作负载](../create-deployment.md) +- [有状态工作负载](../create-statefulset.md) +- [守护进程](../create-daemonset.md) +- [任务](../create-job.md) +- [定时任务](../create-cronjob.md) + +您也可以通过设置[自定义资源 CRD](../../custom-resources/create.md) 来实现对工作负载资源的扩展。在第五代容器管理中,支持对工作负载进行创建、更新、扩容、监控、日志、删除、版本管理等全生命周期管理。 + +## Pod 状态 + +Pod 是 Kuberneters 中创建和管理的、最小的计算单元,即一组容器的集合。这些容器共享存储、网络以及管理控制容器运行方式的策略。 +Pod 通常不由用户直接创建,而是通过工作负载资源来创建。 +Pod 遵循一个预定义的生命周期,起始于 __Pending__ [阶段](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase),如果至少其中有一个主要容器正常启动,则进入 __Running__ ,之后取决于 Pod 中是否有容器以失败状态结束而进入 __Succeeded__ 或者 __Failed__ 阶段。 + +## 工作负载状态 + +第五代容器管理模块依据 Pod 的状态、副本数等因素,设计了一种内置的工作负载生命周期的状态集,以让用户能够更加真实的感知工作负载运行情况。 +由于不同的工作负载类型(比如无状态工作负载和任务)对 Pod 的管理机制不一致,因此,不同的工作负载在运行过程中会呈现不同的生命周期状态,具体如下表: + +### 无状态负载、有状态负载、守护进程状态 + +| 状态 | 描述 | +| :---------------------- | :----------------------------------------------------------- | +| 等待中 | 1. 工作负载创建正在进行中,工作负载处于此状态。
2. 触发升级或者回滚动作后,工作负载处于此状态。
3. 触发暂停/扩缩容等操作,工作负载处在此状态。 | +| 运行中 | 负载下的所有实例都在运行中且副本数与用户预定义的数量一致时处于此状态。 | +| 删除中 | 执行删除操作时,负载处于此状态,直到删除完成。 | +| 异常 | 因为某些原因无法取得工作负载的状态。这种情况通常是因为与 Pod 所在主机通信失败。 | +| 未就绪 | 容器处于异常,pending 状态时,因未知错误导致负载无法启动时显示此状态 | + +### 任务状态 + +| 状态 | 描述 | +| :------- | :----------------------------------------------------------- | +| 等待中 | 任务创建正在进行中,工作负载处于此状态。 | +| 执行中 | 任务正在执行中,工作负载处于此状态。 | +| 执行完成 | 任务执行完成,工作负载处于此状态。 | +| 删除中 | 触发删除操作,工作负载处在此状态。 | +| 异常 | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 | + +### 定时任务状态 + +| 状态 | 描述 | +| :----- | :----------------------------------------------------------- | +| 等待中 | 定时任务创建正在进行中,定时任务处于此状态。 | +| 已启动 | 创建定时任务成功后,正常运行或将已暂停的任务启动时定时任务处于此状态。 | +| 已停止 | 执行停止任务操作时,定时任务处于此状态。 | +| 删除中 | 触发删除操作,定时任务处在此状态。 | + +当工作负载处于异常或未就绪状态时,您可以通过将鼠标移动到负载的状态值上,系统将通过提示框展示更加详细的错误信息。您也可以通过查看[日志](../../../../insight/data-query/log.mdlog.md)或事件来获取工作负载的相关运行信息。 diff --git a/docs/zh/docs/admin/register/bindws.md b/docs/zh/docs/admin/register/bindws.md new file mode 100644 index 0000000..d71a168 --- /dev/null +++ b/docs/zh/docs/admin/register/bindws.md @@ -0,0 +1,38 @@ +# 为用户绑定工作空间 + +用户成功注册之后,需要为其绑定一个工作空间。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](index.md) +- 有一个可用的管理员账号 + +## 操作步骤 + +1. 以管理员身份登录 AI 算力平台 +1. 导航切换至 **全局管理** -> **工作空间与层级** ,点击 **创建工作空间** + + ![workspace](../images/bindws01.png) + +1. 输入名称,选择文件夹后点击 **确定** ,创建一个工作空间 + + ![create ws](../images/bindws02.png) + +1. 给工作空间绑定资源 + + ![bind resource](../images/bindws07.png) + + 可以在这个界面上点击 **创建集群-命名空间** 来创建一个命名空间。 + +1. 添加授权:将用户分配至工作空间 + + ![授权1](../images/bindws08.png) + ![授权2](../images/bindws09.png) + +1. 用户登录 AI 算力平台,查看是否具有工作空间及命名空间的权限。 + 管理员可以通过右侧的 **┇** 执行更多操作。 + + ![确认](../images/bindws11.png) + +下一步:[为工作空间分配资源](./wsres.md) diff --git a/docs/zh/docs/admin/register/index.md b/docs/zh/docs/admin/register/index.md new file mode 100644 index 0000000..09f9816 --- /dev/null +++ b/docs/zh/docs/admin/register/index.md @@ -0,0 +1,33 @@ +# 用户注册 + +新用户首次使用 AI 算力平台需要进行注册。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 已开启邮箱注册功能 +- 有一个可用的邮箱 + +## 邮箱注册步骤 + +1. 打开 AI 算力平台首页 ,点击 **注册** + + ![home](../../images/regis01.PNG) + +1. 键入用户名、密码、邮箱后点击 **注册** + + ![to register](../../images/regis02.PNG) + +1. 系统提示发送了一封邮件到您的邮箱。 + + ![to register](../../images/regis03.PNG) + +1. 登录自己的邮箱,找到邮件,点击链接。 + + ![email](../../images/regis04.PNG) + +1. 恭喜,您成功进入了 AI 算力平台,现在可以开始您的 AI 之旅了。 + + ![verify](../../images/regis05.PNG) + +下一步:[为用户绑定工作空间](bindws.md) diff --git a/docs/zh/docs/admin/register/wsres.md b/docs/zh/docs/admin/register/wsres.md new file mode 100644 index 0000000..ac575af --- /dev/null +++ b/docs/zh/docs/admin/register/wsres.md @@ -0,0 +1,26 @@ +# 为工作空间分配资源 + +将[用户绑定到工作空间](./bindws.md)后,需要给工作空间分配合适的资源。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 有一个可用的管理员账号 +- 工作空间已创建且绑定了命名空间 + +## 操作步骤 + +1. 以管理员身份登录 AI 算力平台 +1. 导航到 **全局管理** -> **工作空间与层级**,找到要添加资源的工作空间,点击 **新增共享资源** + + ![点击按钮](../images/wsres01.png) + +1. 选择集群,设置合适的资源配额后,点击 **确定**
+ + ![配置](../images/wsres02.png) + +1. 返回共享资源页,为工作空间成功分配了资源,管理员可以通过右侧的 **┇** 随时修改。 + + ![成功](../images/wsres03.png) + +下一步:[创建云主机](../host/createhost.md) diff --git a/docs/zh/docs/admin/security/falco-exporter.md b/docs/zh/docs/admin/security/falco-exporter.md new file mode 100644 index 0000000..4cc514c --- /dev/null +++ b/docs/zh/docs/admin/security/falco-exporter.md @@ -0,0 +1,55 @@ +# Falco-exporter + +[Falco-exporter](https://github.com/falcosecurity/falco-exporter) 是一个 Falco 输出事件的 Prometheus Metrics 导出器。 + +Falco-exporter 会部署为 Kubernetes 集群上的守护进程集。如果集群中已安装并运行 Prometheus,Prometheus 将自动发现 Falco-exporter 提供的指标。 + +## 安装 Falco-exporter + +本页介绍如何安装 Falco-exporter 组件。 + +!!! note + + 在安装使用 Falco-exporter 之前,需要[安装](./falco-install.md)并运行 Falco,并启用 gRPC 输出(默认通过 Unix 套接字启用)。 + 关于启用 gRPC 输出的更多信息,可参阅[在 Falco Helm Chart 中启用 gRPC 输出](https://github.com/falcosecurity/charts/tree/master/falco#enabling-grpc)。 + +请确认您的集群已成功接入`容器管理`平台,然后执行以下步骤安装 Falco-exporter。 + +1. 从左侧导航栏点击`容器管理`—>`集群列表`,然后找到准备安装 Falco-exporter 的集群名称。 + + ![falco_cluster](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco_cluster.png) + +2. 在左侧导航栏中选择 `Helm 应用` -> `Helm 模板`,找到并点击 `falco-exporter`。 + + ![falco-exporter_helm-1](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-exporter-install-1.png) + +3. 在`版本选择`中选择希望安装的版本,点击`安装`。 + + ![falco-exporter_helm-2](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-exporter-install-2.png) + +4. 在安装界面,填写所需的安装参数。 + + ![falco-exporter_helm-3](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-exporter-install-3.png) + + 在如上界面中,填写`应用名称`、`命名空间`、`版本`等。 + + ![falco-exporter_helm-4](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-exporter-install-4.png) + + 在如上界面中,填写以下参数: + + - `Falco Prometheus Exporter` -> `Image Settings` -> `Registry`:设置 falco-exporter 镜像的仓库地址,已经默认填写可用的在线仓库。如果是私有化环境,可修改为私有仓库地址。 + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Repository`:设置 falco-exporter 镜像名。 + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Install ServiceMonitor`:安装 Prometheus Operator 服务监视器,默认开启。 + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Scrape Interval`:用户自定义的间隔;如果未指定,则使用 Prometheus 默认间隔。 + - `Falco Prometheus Exporter` -> `Prometheus ServiceMonitor Settings` -> `Scrape Timeout`:用户自定义的抓取超时时间;如果未指定,则使用 Prometheus 默认的抓取超时时间。 + + ![falco-exporter_helm-4](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-exporter-install-5.png) + + ![falco-exporter_helm-4](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-exporter-install-6.png) + + 在如上界面中,填写以下参数: + + - `Falco Prometheus Exporter` -> `Prometheus prometheusRules` -> `Install prometheusRules`:创建 PrometheusRules,对优先事件发出警报,默认开启。 + - `Falco Prometheus Exporter` -> `Prometheus prometheusRules` -> `Alerts settings`:警报设置,为不同级别的日志事件设置警报是否启用、警报的间隔时间、警报的阈值。 + +5. 点击右下角`确定`按钮即可完成安装。 diff --git a/docs/zh/docs/admin/security/falco-install.md b/docs/zh/docs/admin/security/falco-install.md new file mode 100644 index 0000000..09a92cf --- /dev/null +++ b/docs/zh/docs/admin/security/falco-install.md @@ -0,0 +1,58 @@ +# 安装 Falco + +请确认您的集群已成功接入`容器管理`平台,然后执行以下步骤安装 Falco。 + +1. 从左侧导航栏点击`容器管理`—>`集群列表`,然后找到准备安装 Falco 的集群名称。 + + ![falco_cluster](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco_cluster.png) + +2. 在左侧导航栏中选择 `Helm 应用` -> `Helm 模板`,找到并点击 `Falco`。 + + ![falco_helm-1](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-install-1.png) + +3. 在`版本选择`中选择希望安装的版本,点击`安装`。 + + ![falco-helm-2](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-install-2.png) + +4. 在安装界面,填写所需的安装参数。 + + ![falco_helm-3](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-install-3.png) + + 在如上界面中,填写`应用名称`、`命名空间`、`版本`等。 + + ![falco_helm-4](https://docs.daocloud.io/daocloud-docs-images/docs/security/images/falco-install-4.png) + + 在如上界面中,填写以下参数: + + - `Falco` -> `Image Settings` -> `Registry`:设置 Falco 镜像的仓库地址,已经默认填写可用的在线仓库。如果是私有化环境,可修改为私有仓库地址。 + + - `Falco` -> `Image Settings` -> `Repository`:设置 Falco 镜像名。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Registry`:设置 Falco Driver 镜像的仓库地址,已经默认填写可用的在线仓库。如果是私有化环境,可修改为私有仓库地址。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Repository`:设置 Falco Driver 镜像名。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Driver Kind`:设置 Driver Kind,提供以下两种选择: + + 1. ebpf:使用 ebpf 来检测事件,这需要 Linux 内核支持 ebpf,并启用 CONFIG_BPF_JIT 和 sysctl net.core.bpf_jit_enable=1。 + + 2. module:使用内核模块检测,支持有限的操作系统版本,参考 module 支持[系统版本](https://download.falco.org/?prefix=driver)。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Log Level`:要包含在日志中的最小日志级别。 + + 可选择值为:`emergency`, `alert`, `critical`, `error`, `warning`, `notice`, `info`, `debug`。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Registry`:设置 Falco Driver 镜像的仓库地址,已经默认填写可用的在线仓库。如果是私有化环境,可修改为私有仓库地址。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Repository`:设置 Falco Driver 镜像名。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Driver Kind`:设置 Driver Kind,提供以下两种选择: + + 1. ebpf:使用 ebpf 来检测事件,这需要 Linux 内核支持 ebpf,并启用 CONFIG_BPF_JIT 和 sysctl net.core.bpf_jit_enable=1。 + 1. module:使用内核模块检测,支持有限的操作系统版本,参考 module 支持[系统版本](https://download.falco.org/?prefix=driver)。 + + - `Falco` -> `Falco Driver` -> `Image Settings` -> `Log Level`:要包含在日志中的最小日志级别。 + + 可选择值为:`emergency`、`alert`、`critical`、`error`、`warning`、`notice`、`info`、`debug`。 + +5. 点击右下角`确定`按钮即可完成安装。 diff --git a/docs/zh/docs/admin/security/falco.md b/docs/zh/docs/admin/security/falco.md new file mode 100644 index 0000000..8034cff --- /dev/null +++ b/docs/zh/docs/admin/security/falco.md @@ -0,0 +1,51 @@ +# 什么是 Falco + +[Falco](https://falco.org) 是一个`云原生运行时安全`工具,旨在检测应用程序中的异常活动,可用于监控 Kubernetes 应用程序和内部组件的运行时安全性。仅需为 Falco 撰写一套规则,即可持续监测并监控容器、应用、主机及网络的异常活动。 + +## Falco 能检测到什么? + +Falco 可对任何涉及 Linux 系统调用的行为进行检测和报警。Falco 的警报可以通过使用特定的系统调用、参数以及调用进程的属性来触发。例如,Falco 可以轻松检测到包括但不限于以下事件: + +- Kubernetes 中的容器或 pod 内正在运行一个 shell 。 +- 容器以特权模式运行,或从主机挂载敏感路径,如 /proc。 +- 一个服务器进程正在生成一个意外类型的子进程。 +- 意外读取一个敏感文件,如 /etc/shadow。 +- 一个非设备文件被写到 /dev。 +- 一个标准的系统二进制文件,如 ls,正在进行一个外向的网络连接。 +- 在 Kubernetes 集群中启动一个有特权的 Pod。 + +关于 Falco 附带的更多默认规则,请参考 [Rules 文档](https://github.com/falcosecurity/falco/blob/master/rules_inventory/rules_overview.md)。 + +## 什么是 Falco 规则? + +Falco 规则定义 Falco 应监视的行为及事件;可以在 Falco 规则文件或通用配置文件撰写规则。有关编写、管理和部署规则的更多信息,请参阅 Falco [Rules](https://falco.org/docs/rules/)。 + +## 什么是 Falco 警报? + +警报是可配置的下游操作,可以像记录日志一样简单,也可以像 STDOUT 向客户端传递 gRPC 调用一样复杂。有关配置、理解和开发警报的更多信息,请参阅Falco [警报](https://falco.org/docs/alerts/)。Falco 可以将警报发送至: + +- 标准输出 +- 一份文件 +- 系统日志 +- 生成的程序 +- 一个 HTTP[s] 端点 +- 通过 gRPC API 的客户端 + +## Falco 由哪些部分组成? + +Falco 由以下几个主要组件组成: + +- 用户空间程序:CLI 工具,可用于与 Falco 交互。用户空间程序处理信号,解析来自 Falco 驱动的信息,并发送警报。 + +- 配置:定义 Falco 的运行方式、要断言的规则以及如何执行警报。有关详细信息,请参阅[配置](https://falco.org/docs/configuration)。 + +- Driver:一款遵循 Falco 驱动规范并发送系统调用信息流的软件。如果不安装驱动程序,将无法运行 Falco。目前,Falco 支持以下驱动程序: + + - 基于 C++ 库构建 libscap 的内核模块 libsinsp(默认) + - 由相同模块构建的 BPF 探针 + - 用户空间检测 + + 有关详细信息,请参阅 Falco [驱动程序](https://falco.org/docs/event-sources/drivers/)。 + +- 插件:可用于扩展 falco libraries/falco 可执行文件的功能,扩展方式是通过添加新的事件源和从事件中提取信息的新字段。 + 有关详细信息,请参阅[插件](https://falco.org/docs/plugins/)。 diff --git a/docs/zh/docs/admin/security/index.md b/docs/zh/docs/admin/security/index.md new file mode 100644 index 0000000..ee4167b --- /dev/null +++ b/docs/zh/docs/admin/security/index.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 云原生安全 + +算丰 AI 算力平台针对容器、Pod、镜像、运行时、微服务提供了全面自动化的安全实现。 +下表列出了一些已实现或正在实现中的安全特性。 + +| 安全特性 | 细目 | 描述 | +| ------- | --- | ---- | +| 镜像安全 | 可信镜像分发 | 为实现镜像的安全传输,需具备密钥对和签名信息,保证传输安全。在传输镜像时具备选择密钥进行镜像签名能力。 | +| 运行时安全 | 事件关联分析 | 支持对运行时检测出的安全事件做关联与风险分析,增加攻击溯源能力,收敛告警,降低无效告警,提高事件响应效率。 | +| - | 容器诱饵仓库 | 具备容器诱饵仓库,常见诱饵包括但不限于:未授权访问漏洞、代码执行漏洞、本地文件读取漏洞、远程命令执行 RCE 漏洞等容器诱饵。 | +| - | 容器诱饵部署 | 支持自定义新增诱饵容器,可以自定义服务名称、服务位置等。 | +| - | 容器诱饵告警 | 支持对容器诱饵中可疑行为进行告警。 | +| - | 偏移检测 | 在扫描镜像同时,学习镜像中全部二进制文件信息,并形成“白名单”,容器上线后仅允许“白名单”中二进制文件运行,确保容器内不能运行不授信(如非法下载)的可执行文件。 | +| 微隔离 | 隔离策略智能推荐 | 支持记录资源历史访问流量,并在对资源进行隔离策略配置时能够智能依据历史访问流量进行策略推荐。 | +| - | 租户隔离 | 支持对 Kubernetes 集群内租户进行隔离控制,具备对不同的租户设置不同的网络安全组的能力,支持租户级别的安全策略设置功能,通过不同安全组和设置的安全策略实现租户间网络的访问与隔离。 | +| 微服务安全 | 服务及 API 安全扫描 | 对集群内的服务及 API 支持自动扫描、手动扫描及周期性扫描的安全扫描方式,支持全部的传统 web 扫描项目包括 XSS 漏洞、SQL 注入、命令/代码注入、目录枚举、路径穿越、XML 实体注入、poc、文件上传、弱口令、jsonp、ssrf、任意跳转、CRLF 注入等风险,以及容器环境特有的项,针对发现的漏洞支持漏洞类型展示、url 展示、参数展示、危险级别展示、测试方法展示等。 | diff --git a/docs/zh/docs/admin/share/infer.md b/docs/zh/docs/admin/share/infer.md new file mode 100644 index 0000000..7909df9 --- /dev/null +++ b/docs/zh/docs/admin/share/infer.md @@ -0,0 +1,2 @@ +# 创建推理服务 + diff --git a/docs/zh/docs/admin/share/job.md b/docs/zh/docs/admin/share/job.md new file mode 100644 index 0000000..c37b349 --- /dev/null +++ b/docs/zh/docs/admin/share/job.md @@ -0,0 +1 @@ +# 创建训练任务 diff --git a/docs/zh/docs/admin/share/notebook.md b/docs/zh/docs/admin/share/notebook.md new file mode 100644 index 0000000..1285232 --- /dev/null +++ b/docs/zh/docs/admin/share/notebook.md @@ -0,0 +1,85 @@ +# 使用 Notebook + +Notebook 通常指的是 Jupyter Notebook 或类似的交互式计算环境。 +这是一种非常流行的工具,广泛用于数据科学、机器学习和深度学习等领域。 +本页说明如何在算丰 AI 算力平台中使用 Notebook。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](../register/index.md) +- [管理员为用户分配了工作空间](../register/bindws.md) +- 已准备好数据集(代码、数据等) + +## 创建和使用 Notebook 实例 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. 导航至 **AI Lab** -> **运维管理** -> **队列管理** ,点击右侧的 **创建** 按钮 + + ![create queue](../images/notebook01.png) + +1. 键入名称,选择集群、工作空间和配额后,点击 **确定** + + ![ok](../images/notebook02.png) + +1. 以 **用户身份** 登录 AI 算力平台,导航至 **AI Lab** -> **Notebook** ,点击右侧的 **创建** 按钮 + + ![create notebook](../images/notebook03.png) + +1. 配置各项参数后点击 **确定** + + === "基本信息" + + 键入名称,选择集群、命名空间,选择刚创建的队列,点击 **一键初始化** + + ![basic](../images/notebook04.png) + + === "资源配置" + + 选择 Notebook 类型,配置内存、CPU,开启 GPU,创建和配置 PVC: + + ![resource](../images/notebook05.png) + + === "高级配置" + + 开启 SSH 外网访问: + + ![advanced](../images/notebook06.png) + +1. 自动跳转到 Notebook 实例列表,点击实例名称 + + ![click name](../images/notebook07.png) + +1. 进入 Notebook 实例详情页,点击右上角的 **打开** 按钮 + + ![open](../images/notebook08.png) + +1. 进入了 Notebook 开发环境,比如在 `/home/jovyan` 目录挂载了持久卷,可以通过 git 克隆代码,通过 SSH 连接后上传数据等。 + + ![notebook](../images/notebook09.png) + +## 通过 SSH 访问 Notebook 实例 + +1. 在自己的电脑上生成 SSH 密钥对 + + 在自己电脑上打开命令行,比如在 Windows 上打开 git bash,输入 `ssh-keygen.exe -t rsa`,然后一路回车。 + + ![generate](../images/ssh01.png) + +1. 通过 `cat ~/.ssh/id_rsa.pub` 等命令查看并复制公钥 + + ![copy key](../images/ssh02.png) + +1. 以用户身份登录 AI 算力平台,在右上角点击 **个人中心** -> **SSH 公钥** -> **导入 SSH 公钥** + + ![import](../images/ssh03.png) + +1. 进入 Notebook 实例的详情页,复制 SSH 的链接 + + ![copy link](../images/ssh04.png) + +1. 在客户端使用 SSH 访问 Notebook 实例 + + ![ssh](../images/ssh05.png) + +下一步:[创建训练任务](../baize/developer/jobs/create.md) diff --git a/docs/zh/docs/admin/share/quota.md b/docs/zh/docs/admin/share/quota.md new file mode 100644 index 0000000..8a020d1 --- /dev/null +++ b/docs/zh/docs/admin/share/quota.md @@ -0,0 +1,26 @@ +# 配额管理 + +用户被绑定到工作空间后,即可为工作空间分配资源,管理资源配额。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 有一个可用的管理员账号 + +## 创建和管理配额 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. [创建工作空间和命名空间,并绑定用户](../register/bindws.md) +1. [为工作空间分配资源配额](../register/wsres.md#quota) + + ![quota to ws](../images/quota01.png) + +1. 管理命名空间 `test-ns-1` 的资源配额,其数值不能超过工作空间的配额。 + + ![quota to ns](../images/quota02.png) + +1. 以 **用户身份** 登录 AI 算力平台,查看其是否被分配了 `test-ns-1` 命名空间。 + + ![check ns](../images/quota03.png) + +下一步:[创建 AI 负载使用 GPU 资源](./workload.md) diff --git a/docs/zh/docs/admin/share/workload.md b/docs/zh/docs/admin/share/workload.md new file mode 100644 index 0000000..041f5f1 --- /dev/null +++ b/docs/zh/docs/admin/share/workload.md @@ -0,0 +1,51 @@ +# 创建 AI 负载使用 GPU 资源 + +管理员为工作空间分配资源配额后,用户就可以创建 AI 工作负载来使用 GPU 算力资源。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](../register/index.md) +- [管理员为用户分配了工作空间](../register/bindws.md) +- [为工作空间设置了资源配额](./quota.md) +- [已经创建了一个集群](../k8s/create-k8s.md) + +## 创建 AI 负载步骤 + +1. 以用户身份登录 AI 算力平台 +1. 导航至 **容器管理** ,选择一个命名空间,点击 **工作负载** -> **无状态负载** , + 点击右侧的 **镜像创建** 按钮 + + ![button](../images/workload01.png) + +1. 配置各项参数后点击 **确定** + + === "基本信息" + + 选择自己的命名空间。 + + ![basic](../images/workload02.png) + + === "容器配置" + + 设置镜像,配置 CPU、内存、GPU 等资源,设置启动命令。 + + ![container](../images/workload03.png) + + === "其他" + + 服务配置和高级配置可以使用默认配置。 + +1. 自动返回无状态负载列表,点击负载名称 + + ![click name](../images/workload04.png) + +1. 进入详情页,可以看到 GPU 配额 + + ![check gpu](../images/workload05.png) + +1. 你还可以进入控制台,运行 `mx-smi` 命令查看 GPU 资源 + + ![check gpu](../images/workload06.png) + +下一步:[使用 Notebook](./notebook.md) diff --git a/docs/zh/docs/admin/virtnest/best-practice/import-ubuntu.md b/docs/zh/docs/admin/virtnest/best-practice/import-ubuntu.md new file mode 100644 index 0000000..4ab02b7 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/best-practice/import-ubuntu.md @@ -0,0 +1,229 @@ +# 如何从 VMWare 导入传统 Linux 云主机到云原生云主机平台 + +本文将详细介绍如何通过命令行将外部平台 VMware 上的 Linux 云主机导入到 AI 算力中心的云主机中。 + +!!! info + + 本文档外部虚拟平台是 VMware vSphere Client,后续简写为 vSphere。 + 技术上是依靠 kubevirt cdi 来实现的。操作前,vSphere 上被导入的云主机需要关机。 + 以 Ubuntu 操作系统的云主机为例。 + +## 获取 vSphere 的云主机基础信息 + +- vSphere URL:目标平台的 URL 地址信息 + +- vSphere SSL 证书指纹 thumbprint:需要通过 openssl 获取 + + ```sh + openssl s_client -connect 10.64.56.11:443 __标头__ 找到如下图所示的 URL。 + + ![找到 URL](../images/uuid01.png) + + - 点击 __响应__ ,定位到 __vmConfigContext__ —> __config__ ,最终找到目标值 __uuid__ 。 + + ![找到 uuid](../images/uuid02.png) + +- 需要导入云主机的 vmdk 文件 path + +## 网络配置 + +需要根据网络模式的不同配置不同的信息,若有固定 IP 的需求,需要选择 Bridge 网络模式 + +- 创建 ovs 类型的 Multus CR,可参考[创建 Multus CR](https://spidernet-io.github.io/spiderpool/v0.9/usage/install/underlay/get-started-ovs-zh_CN/) +- 创建子网及 IP 池,参考[创建子网和 IP 池](../../network/config/ippool/createpool.md) + + ```yaml + apiVersion: spiderpool.spidernet.io/v2beta1 + kind: SpiderIPPool + metadata: + name: test2 + spec: + ips: + - 10.20.3.90 + subnet: 10.20.0.0/16 + gateway: 10.20.0.1 + + --- + apiVersion: spiderpool.spidernet.io/v2beta1 + kind: SpiderIPPool + metadata: + name: test3 + spec: + ips: + - 10.20.240.1 + subnet: 10.20.0.0/16 + gateway: 10.20.0.1 + + --- + apiVersion: spiderpool.spidernet.io/v2beta1 + kind: SpiderMultusConfig + metadata: + name: test1 + namespace: kube-system + spec: + cniType: ovs + coordinator: + detectGateway: false + detectIPConflict: false + mode: auto + tunePodRoutes: true + disableIPAM: false + enableCoordinator: true + ovs: + bridge: br-1 + ippools: + ipv4: + - test1 + - test2 + ``` + +## 获取 vSphere 的账号密码 secret + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: vsphere # 可更改 + labels: + app: containerized-data-importer # 请勿更改 +type: Opaque +data: + accessKeyId: "username-base64" + secretKey: "password-base64" +``` + +## 编写 kubevirt vm yaml 创建 vm + +!!! tip + + 若有固定IP需求,则该 yaml 与使用默认网络的 yaml 有一些区别,已标注。 + +```yaml +apiVersion: kubevirt.io/v1 +kind: VirtualMachine +metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + virtnest.io/alias-name: "" + virtnest.io/image-secret: "" + creationTimestamp: "2024-05-23T06:46:28Z" + finalizers: + - kubevirt.io/virtualMachineControllerFinalize + generation: 1 + labels: + virtnest.io/os-family: Ubuntu + virtnest.io/os-version: "22.04" + name: export-ubuntu + namespace: default +spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: export-ubuntu-rootdisk + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: local-path + source: + vddk: + backingFile: "[A05-09-ShangPu-Local-DataStore] virtnest-export-ubuntu/virtnest-export-ubuntu.vmdk" + url: "https://10.64.56.21" + uuid: "421d6135-4edb-df80-ee54-8c5b10cc4e78" + thumbprint: "D7:C4:22:E3:6F:69:DA:72:50:81:12:FA:42:18:3F:29:5C:7F:41:CA" + secretRef: "vsphere" + initImageURL: "release.daocloud.io/virtnest/vddk:v8" + runStrategy: Manual + template: + metadata: + annotations: + ipam.spidernet.io/ippools: '[{"cleangateway":false,"ipv4":["test2"]}]' // 这里添加 spiderpool 网络 + creationTimestamp: null + spec: + architecture: amd64 + domain: + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: rootdisk + interfaces: // 修改这里的网络配置 + - bridge: {} + name: ovs-bridge0 + machine: + type: q35 + resources: + requests: + memory: 4Gi + networks: // 修改这里的网络配置 + - multus: + default: true + networkName: kube-system/test1 + name: ovs-bridge0 + volumes: + - dataVolume: + name: export-ubuntu-rootdisk + name: rootdisk +``` + +## 进入 VNC 检查是否成功运行 + +1. 修改云主机的网络配置 + +1. 查看当前网络 + + 在实际导入完成时,如下图所示的配置已经完成。然而,需要注意的是,enp1s0接口并没有包含inet字段,因此无法连接到外部网络。 + + ![查看网络配置](../images/import-ubuntu04.png) + +1. 配置 netplan + + 在上图所示的配置中,将 ethernets 中的对象更改为 enp1s0,并使用 DHCP 获得 IP 地址。 + + ![配置 netplan](../images/import-ubuntu05.png) + +1. 将 netplan 配置应用到系统网络配置中 + + ```sh + sudo netplan apply + ``` + +1. 对外部网络进行 ping 测试 + + ![ping网络](../images/import-ubuntu06.png) + +1. 通过 SSH 在节点上访问云主机。 + + ![访问云主机](../images/import-ubuntu07.png) diff --git a/docs/zh/docs/admin/virtnest/best-practice/import-windows.md b/docs/zh/docs/admin/virtnest/best-practice/import-windows.md new file mode 100644 index 0000000..5715784 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/best-practice/import-windows.md @@ -0,0 +1,323 @@ +# 如何从 VMWare 导入传统 Windows 云主机到云原生云主机平台 + +本文将详细介绍如何通过命令行将外部平台 VMware 上的云主机导入到 AI 算力中心的云主机中。 + +!!! info + + 本文档外部虚拟平台是 VMware vSphere Client,后续简写为 vSphere。 + 技术上是依靠 kubevirt cdi 来实现的。操作前,vSphere 上被导入的云主机需要关机。 + 以 Windows 操作系统的云主机为例。 + +## 环境准备 + +导入前,需要参考[网络配置](../vm/vm-network.md)准备环境。 + +### 获取 Windows 云主机的信息 + +与导入 Linux 操作系统的云主机类似,可参考[如何从 VMWare 导入传统 Linuxs 云主机到云原生云主机平台](import-ubuntu.md)获取以下信息: + +- 获取 vSphere 账号密码 +- 获取 vSphere 云主机信息 + +### 检查 Windows 的引导类型 + +将外部平台的云主机导入到 AI 算力中心的虚拟化平台中时,需要根据云主机的启动类型(BIOS 或 UEFI)进行相应的配置,以确保云主机能够正确启动和运行。 + +可以通过"系统信息"检查 Windows 是 BIOS 还是 UEFI 引导。如果是 UEFI 则需要在 YAML 文件中添加相关信息。 + +![系统信息](../images/window-uefi.png) + +## 导入过程 + +准备 `window.yaml` 文件,注意以下配置项 + +- 引导 Virtio 驱动的 PVC +- 磁盘总线类型,根据引导类型设置为 sata 或 virtio +- 如果使用 UEFI,需要添加 UEFI 配置 + +
+点击查看 window.yaml 示例 + +```yaml title="window.yaml" +apiVersion: kubevirt.io/v1 +kind: VirtualMachine +metadata: + labels: + virtnest.io/os-family: windows + virtnest.io/os-version: "server2019" + name: export-window-21 + namespace: default +spec: + dataVolumeTemplates: + - metadata: + name: export-window-21-rootdisk + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 22Gi + storageClassName: local-path + source: + vddk: + backingFile: "[A05-09-ShangPu-Local-DataStore] virtnest-export-window/virtnest-export-window.vmdk" + url: "https://10.64.56.21" + uuid: "421d40f2-21a2-cfeb-d5c9-e7f8abfc2faa" + thumbprint: "D7:C4:22:E3:6F:69:DA:72:50:81:12:FA:42:18:3F:29:5C:7F:41:CA" + secretRef: "vsphere21" + initImageURL: "release.daocloud.io/virtnest/vddk:v8" + - metadata: + name: export-window-21-datadisk + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: local-path + source: + vddk: + backingFile: "[A05-09-ShangPu-Local-DataStore] virtnest-export-window/virtnest-export-window_1.vmdk" + url: "https://10.64.56.21" + uuid: "421d40f2-21a2-cfeb-d5c9-e7f8abfc2faa" + thumbprint: "D7:C4:22:E3:6F:69:DA:72:50:81:12:FA:42:18:3F:29:5C:7F:41:CA" + secretRef: "vsphere21" + initImageURL: "release.daocloud.io/virtnest/vddk:v8" + # <1>. 引导 virtio 驱动的 pvc + # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ + - metadata: + name: virtio-disk + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi + storageClassName: local-path + source: + blank: {} + # ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ + running: true + template: + metadata: + annotations: + ipam.spidernet.io/ippools: '[{"cleangateway":false,"ipv4":["test86"]}]' + spec: + dnsConfig: + nameservers: + - 223.5.5.5 + domain: + cpu: + cores: 2 + memory: + guest: 4Gi + devices: + disks: + - bootOrder: 1 + disk: + bus: sata # <2> 磁盘总线类型,根据引导类型设置为 sata 或 virtio + name: rootdisk + - bootOrder: 2 + disk: + bus: sata # <2> 磁盘总线类型,根据引导类型设置为 sata 或 virtio + name: datadisk + # <1>. 引导 virtio 驱动的 disk + # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ + - bootOrder: 3 + disk: + bus: virtio + name: virtdisk + - bootOrder: 4 + cdrom: + bus: sata + name: virtiocontainerdisk + # ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ + interfaces: + - bridge: {} + name: ovs-bridge0 + # <3> 在上文“查看 window 引导是 BIOS 还是 UEFI” + # 如果使用了 UEFI 需要添加的信息 + # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ + features: + smm: + enabled: true + firmware: + bootloader: + efi: + secureBoot: false + # ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ + machine: + type: q35 + resources: + requests: + memory: 4Gi + networks: + - multus: + default: true + networkName: kube-system/test1 + name: ovs-bridge0 + volumes: + - dataVolume: + name: export-window-21-rootdisk + name: rootdisk + - dataVolume: + name: export-window-21-datadisk + name: datadisk + # <1> 引导 virtio 驱动的 volumes + # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ + - dataVolume: + name: virtio-disk + name: virtdisk + - containerDisk: + image: release-ci.daocloud.io/virtnest/kubevirt/virtio-win:v4.12.12-5 + name: virtiocontainerdisk + # ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ +``` + +
+ +### 通过 VNC 安装 VirtIO 驱动 + +1. 通过 VNC 访问和连接到云主机。 +2. 根据 Windows 版本下载并安装相应的 VirtIO 驱动程序。 +3. 可以开启远程桌面(Remote Desktop),方便在后续通过远程桌面协议(RDP)连接到云主机。 +4. 安装完成后,重启云主机后更新 YAML。 + +![下载 VirtIO 1](../images/install01.png) + +![下载 VirtIO 2](../images/install02.png) + +![开启远程桌面Remote Desktop](../images/turn-on.png) + +### 重启后更新 YAML + +
+点击查看修改后的 window.yaml 示例 + +```yaml title="window.yaml" +# 删除 标号 <1> 相关字段,修改标号 <2> 字段:sata 改成 virtio +apiVersion: kubevirt.io/v1 +kind: VirtualMachine +metadata: + labels: + virtnest.io/os-family: windows + virtnest.io/os-version: "server2019" + name: export-window-21 + namespace: default +spec: + dataVolumeTemplates: + - metadata: + name: export-window-21-rootdisk + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 22Gi + storageClassName: local-path + source: + vddk: + backingFile: "[A05-09-ShangPu-Local-DataStore] virtnest-export-window/virtnest-export-window.vmdk" + url: "https://10.64.56.21" + uuid: "421d40f2-21a2-cfeb-d5c9-e7f8abfc2faa" + thumbprint: "D7:C4:22:E3:6F:69:DA:72:50:81:12:FA:42:18:3F:29:5C:7F:41:CA" + secretRef: "vsphere21" + initImageURL: "release.daocloud.io/virtnest/vddk:v8" + - metadata: + name: export-window-21-datadisk + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + storageClassName: local-path + source: + vddk: + backingFile: "[A05-09-ShangPu-Local-DataStore] virtnest-export-window/virtnest-export-window_1.vmdk" + url: "https://10.64.56.21" + uuid: "421d40f2-21a2-cfeb-d5c9-e7f8abfc2faa" + thumbprint: "D7:C4:22:E3:6F:69:DA:72:50:81:12:FA:42:18:3F:29:5C:7F:41:CA" + secretRef: "vsphere21" + initImageURL: "release.daocloud.io/virtnest/vddk:v8" + running: true + template: + metadata: + annotations: + ipam.spidernet.io/ippools: '[{"cleangateway":false,"ipv4":["test86"]}]' + spec: + dnsConfig: + nameservers: + - 223.5.5.5 + domain: + cpu: + cores: 2 + memory: + guest: 4Gi + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio # <2> + name: rootdisk + - bootOrder: 2 + disk: + bus: virtio # <2> + name: datadisk + interfaces: + - bridge: {} + name: ovs-bridge0 + # <3> 在上文“查看 window 引导是 BIOS 还是 UEFI” + # 如果使用了 UEFI 需要添加的信息 + # ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ + features: + smm: + enabled: true + firmware: + bootloader: + efi: + secureBoot: false + # ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ + machine: + type: q35 + resources: + requests: + memory: 4Gi + networks: + - multus: + default: true + networkName: kube-system/test1 + name: ovs-bridge0 + volumes: + - dataVolume: + name: export-window-21-rootdisk + name: rootdisk + - dataVolume: + name: export-window-21-datadisk + name: datadisk +``` + +
+ +### RDP 访问和验证 + +- 使用 RDP 客户端连接到云主机。输入默认账号 `admin` 和密码 `dangerous!123` 进行登录。 + + ![访问云主机](../images/pc.png) + +- 验证网络访问和数据盘数据 + + ![验证网络](../images/windows-network.png) + + ![查看数据盘数据](../images/disk.png) + +## 对比导入 Linux 和 Windows 云主机的差异 + +- Windows 可能需要 UEFI 配置。 +- Windows 通常需要安装 VirtIO 驱动。 +- Windows 多磁盘导入通常不需要重新挂载磁盘。 diff --git a/docs/zh/docs/admin/virtnest/best-practice/vm-windows.md b/docs/zh/docs/admin/virtnest/best-practice/vm-windows.md new file mode 100644 index 0000000..618d7ab --- /dev/null +++ b/docs/zh/docs/admin/virtnest/best-practice/vm-windows.md @@ -0,0 +1,365 @@ +# 创建 Windows 云主机 + +本文将介绍如何通过命令行创建 Windows 云主机。 + +## 前提条件 + +1. 创建 Windows 云主机之前,需要先参考[安装云主机模块的依赖和前提](../install/install-dependency.md)确定您的环境已经准备就绪。 +2. 创建过程建议参考官方文档:[安装 windows 的文档](https://kubevirt.io/2022/KubeVirt-installing_Microsoft_Windows_11_from_an_iso.html)、 + [安装 Windows 相关驱动程序](https://kubevirt.io/virtual_machines/windows_virtio_drivers/#how-to-install-during-windows-install)。 +3. Windows 云主机建议使用 VNC 的访问方式。 + +## 导入 ISO 镜像 + +​创建 Windows 云主机需要导入 ISO 镜像的主要原因是为了安装 Windows 操作系统。 +与 Linux 操作系统不同,Windows 操作系统安装过程通常需要从安装光盘或 ISO 镜像文件中引导。 +因此,在创建 Windows 云主机时,需要先导入 Windows 操作系统的安装 ISO 镜像文件,以便云主机能够正常安装。 + +以下介绍两个导入 ISO 镜像的办法: + +1. (推荐)制作 Docker 镜像,建议参考 [构建镜像](../vm-image/index.md) + +2. (不推荐)使用 virtctl 将镜像导入到 PVC 中 + + 可参考如下命令 + + ```sh + virtctl image-upload -n <命名空间> pvc \ + --image-path= \ + --access-mode=ReadWriteOnce \ + --size=6G \ --uploadproxy-url= \ + --force-bind \ + --insecure \ + --wait-secs=240 \ + --storage-class= + ``` + + 例如: + + ```sh + virtctl image-upload -n <命名空间> pvc \ + --image-path= \ + --access-mode=ReadWriteOnce \ + --size=6G \ --uploadproxy-url= \ + --force-bind \ + --insecure \ + --wait-secs=240 \ + --storage-class= + ``` + +## YAML 创建 Windows 云主机 + +使用 yaml 创建 Windows 云主机,更加灵活并且更易编写喝维护。以下介绍三种参考的 yaml: + +1. 推荐使用 Virtio 驱动 + Docker 镜像的方式 + + - 如果你需要使用存储能力-挂载磁盘,请安装 [viostor 驱动程序](https://kubevirt.io/virtual_machines/windows_virtio_drivers/#how-to-install-during-windows-install) + - 如果你需要使用网络能力,请安装 [NetKVM 驱动程序](https://kubevirt.io/virtual_machines/windows_virtio_drivers/#how-to-install-after-windows-install) + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + labels: + virtnest.io/os-family: Windows + virtnest.io/os-version: '10' + name: windows10-virtio + namespace: default + spec: + dataVolumeTemplates: + - metadata: + name: win10-system-virtio + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 32Gi + storageClassName: local-path + source: + blank: {} + running: true + template: + metadata: + labels: + app: windows10-virtio + version: v1 + kubevirt.io/domain: windows10-virtio + spec: + architecture: amd64 + domain: + cpu: + cores: 8 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio # 使用 virtio + name: win10-system-virtio + - bootOrder: 2 + cdrom: + bus: sata # 对于 ISO 镜像,使用 sata + name: iso-win10 + - bootOrder: 3 + cdrom: + bus: sata # 对于 containerdisk,使用 sata + name: virtiocontainerdisk + interfaces: + - name: default + masquerade: {} + machine: + type: q35 + resources: + requests: + memory: 8G + networks: + - name: default + pod: {} + volumes: + - name: iso-win10 + persistentVolumeClaim: + claimName: iso-win10 + - name: win10-system-virtio + persistentVolumeClaim: + claimName: win10-system-virtio + - containerDisk: + image: kubevirt/virtio-container-disk + name: virtiocontainerdisk + ``` + +2. (不推荐)使用 Virtio 驱动和 virtctl 工具的组合方式,将镜像导入到 Persistent Volume Claim(PVC)中。 + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + labels: + virtnest.io/os-family: Windows + virtnest.io/os-version: '10' + name: windows10-virtio + namespace: default + spec: + dataVolumeTemplates: + - metadata: + name: win10-system-virtio + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 32Gi + storageClassName: local-path + source: + blank: {} + running: true + template: + metadata: + labels: + app: windows10-virtio + version: v1 + kubevirt.io/domain: windows10-virtio + spec: + architecture: amd64 + domain: + cpu: + cores: 8 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + # 请使用 virtio + disk: + bus: virtio + name: win10-system-virtio + # ISO 镜像请使用 sata + - bootOrder: 2 + cdrom: + bus: sata + name: iso-win10 +               # containerdisk 请使用 sata + - bootOrder: 3 + cdrom: + bus: sata + name: virtiocontainerdisk + interfaces: + - name: default + masquerade: {} + machine: + type: q35 + resources: + requests: + memory: 8G + networks: + - name: default + pod: {} + volumes: + - name: iso-win10 + persistentVolumeClaim: + claimName: iso-win10 + - name: win10-system-virtio + persistentVolumeClaim: + claimName: win10-system-virtio + - containerDisk: + image: kubevirt/virtio-container-disk + name: virtiocontainerdisk + ``` + +3. (不推荐)不使用 Virtio 驱动的情况下,使用 virtctl 工具将镜像导入到 Persistent Volume Claim(PVC)中。云主机可能使用其他类型的驱动或默认驱动来操作磁盘和网络设备。 + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + labels: + virtnest.io/os-family: Windows + virtnest.io/os-version: '10' + name: windows10 + namespace: default + spec: + dataVolumeTemplates: + # 创建系统盘,你创建多个 PVC(磁盘) + - metadata: + name: win10-system + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 32Gi + storageClassName: local-path + source: + blank: {} + running: true + template: + metadata: + labels: + app: windows10 + version: v1 + kubevirt.io/domain: windows10 + spec: + architecture: amd64 + domain: + cpu: + cores: 8 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + # 无 virtio 驱动,请使用 sata +              cdrom: + bus: sata + name: win10-system + # ISO 镜像,请使用 sata + - bootOrder: 2 + cdrom: + bus: sata + name: iso-win10 + interfaces: + - name: default + masquerade: {} + machine: + type: q35 + resources: + requests: + memory: 8G + networks: + - name: default + pod: {} + volumes: + - name: iso-win10 + persistentVolumeClaim: + claimName: iso-win10 + - name: win10-system + persistentVolumeClaim: + claimName: win10-system + ``` + +## 云桌面 + +Windows 版本的云主机大多数情况是需要远程桌面控制访问的,建议使用 [Microsoft 远程桌面](https://learn.microsoft.com/zh-cn/windows-server/remote/remote-desktop-services/clients/remote-desktop-mac#get-the-remote-desktop-client)控制您的云主机。 + +!!! note + + - 你的 Windows 版本需支持远程桌面控制,才能使用 + [Microsoft 远程桌面](https://learn.microsoft.com/zh-cn/windows-server/remote/remote-desktop-services/clients/remote-desktop-mac#get-the-remote-desktop-client)。 + - 需要关闭 Windows 的防火墙。 + +## 增加数据盘 + +Windows 云主机添加数据盘的方式和 Linux 云主机一致。你可以参考下面的 YAML 示例: + +```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + <...> + spec: + dataVolumeTemplates: + # 添加一块数据盘 + - metadata: + name: win10-disk + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 16Gi + storageClassName: hwameistor-storage-lvm-hdd + source: + blank: {} + template: + spec: + domain: + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: win10-system + # 添加一块数据盘 + - bootOrder: 2 + disk: + bus: virtio + name: win10-disk + <....> + volumes: + <....> + # 添加一块数据盘 + - name: win10-disk + persistentVolumeClaim: + claimName: win10-disk +``` + +## 快照、克隆、实时迁移 + +这些能力和 Linux 云主机一致,可直接参考配置 Linux 云主机的方式。 + +## 访问 Windows 云主机 + +1. 创建成功后,进入云主机列表页面,发现云主机正常运行。 + + ![运行成功](../images/window01.png) + +2. 点击控制台访问(VNC),可以正常访问。 + + ![访问](../images/windows-vnc.png) diff --git a/docs/zh/docs/admin/virtnest/gpu/vm-gpu.md b/docs/zh/docs/admin/virtnest/gpu/vm-gpu.md new file mode 100644 index 0000000..cb1b541 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/gpu/vm-gpu.md @@ -0,0 +1,271 @@ +# 云主机配置 GPU(直通模式) + +本文将介绍如何在创建云主机时,配置 GPU 的前提条件。 + +配置云主机的 GPU 的重点是对 GPU Operator 进行配置,以便在工作节点上部署不同的软件组件, +具体取决于这些节点上配置运行的 GPU 工作负载。以下三个节点为例: + +- controller-node-1 节点配置为运行容器。 +- work-node-1 节点配置为运行具有直通 GPU 的云主机。 +- work-node-2 节点配置为运行具有虚拟 vGPU 的云主机。 + +## 假设、限制和依赖性 + +工作节点可以运行 GPU 加速容器,也可以运行具有 GPU 直通的 GPU 加速 VM,或者具有 vGPU 的 GPU 加速 VM,但不能运行其中任何一个的组合。 + +1. 集群管理员或开发人员需要提前了解集群情况,并正确标记节点以指示它们将运行的 GPU 工作负载类型。 +2. 运行具有 GPU 直通或 vGPU 的 GPU 加速 VM 的工作节点被假定为裸机,如果工作节点是云主机, + 则需要在云主机平台上启用 GPU 直通功能,请向云主机平台提供商咨询。 +3. 不支持 Nvidia MIG 的 vGPU。 +4. GPU Operator 不会自动在 VM 中安装 GPU 驱动程序。 + +## 启用 IOMMU + +为了启用GPU直通功能,集群节点需要开启IOMMU。请参考[如何开启 IOMMU](https://www.server-world.info/en/note?os=CentOS_7&p=kvm&f=10)。 +如果您的集群是在云主机上运行,请咨询您的云主机平台提供商。 + +## 标记集群节点 + +进入 __容器管理__ ,选取您的工作集群,点击 __节点管理__ 的操作栏 __修改标签__ ,为节点添加标签,每个节点只能有一种标签。 + +您可以为标签分配以下值:container、vm-passthrough 和 vm-vgpu。 + +![标记标签](../images/gpu-02.png) + +## 安装 Nvidia Operator + +1. 进入 __容器管理__ ,选取您的工作集群,点击 __Helm 应用__ -> __Helm 模板__ ,选择并安装 gpu-operator。 + 需要修改一些 yaml 中的相关字段。 + + ```yaml + gpu-operator.sandboxWorkloads.enabled=true + gpu-operator.vfioManager.enabled=true + gpu-operator.sandboxDevicePlugin.enabled=true + gpu-operator.sandboxDevicePlugin.version=v1.2.4 # (1)! + gpu-operator.toolkit.version=v1.14.3-ubuntu20.04 + ``` + + 1. version 需要 >= v1.2.4 + +2. 等待安装成功,如下图所示: + + ![安装成功](../images/gpu-03.png) + +## 安装 virtnest-agent 并配置 CR + +1. 安装 virtnest-agent,参考[安装 virtnest-agent](../install/virtnest-agent.md)。 + +2. 将 vGPU 和 GPU 直通加入 Virtnest Kubevirt CR,以下示例是添加 vGPU 和 GPU 直通后的 部分关键 yaml: + + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com /GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com /GP104GL_TESLA_P4 + ``` + + 1. 下面是需要填写的信息 + 2. vGPU + 3. GPU 直通 + +3. 在 kubevirt CR yaml 中,`permittedHostDevices` 用于导入 VM 设备,vGPU 需在其中添加 mediatedDevices,具体结构如下: + + ```yaml + mediatedDevices: + - mdevNameSelector: GRID P4-1Q # (1)! + resourceName: nvidia.com/GRID_P4-1Q # (2)! + ``` + + 1. 设备名称 + 2. GPU Operator 注册到节点的 vGPU 信息 + +4. GPU 直通需要在 `permittedHostDevices` 下添加 pciHostDevices,具体结构如下: + + ```yaml + pciHostDevices: + - externalResourceProvider: true # (1)! + pciVendorSelector: 10DE:1BB3 # (2)! + resourceName: nvidia.com/GP104GL_TESLA_P4 # (3)! + ``` + + 1. 默认不要更改 + 2. 当前 pci 设备的 vednor id + 3. GPU Operator 注册到节点的 GPU 信息 + +5. 获取 vGPU 信息示例(仅适用于 vGPU):在标记为 `nvidia.com/gpu.workload.config=vm-gpu` 的节点(例如 `work-node-2`)上查看节点信息, + Capacity 中的 `nvidia.com/GRID_P4-1Q: 8` 表示可用 vGPU: + + ```bash + kubectl describe node work-node-2 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GRID_P4-1Q : 8 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GRID_P4-1Q: 8 + pods: 110 + ``` + + 那么 mdevNameSelector 应该是 “GRID P4-1Q”,resourceName 应该是 “GRID_P4-1Q” + +6. 获取 GPU 直通信息:在标记 `nvidia.com/gpu.workload.config=vm-passthrough` 的 node 上(本文档示例 node 为 work-node-1), + 查看 node 信息,Capacity 中 `nvidia.com/GP104GL_TESLA_P4: 2` 就是可用 vGPU: + + ```bash + kubectl describe node work-node-1 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + ``` + + 那么 resourceName 应该是 “GRID_P4-1Q”, 如何获取 pciVendorSelector 呢?通过 ssh 登录到 work-node-1 目标节点, + 通过 `lspci -nnk -d 10de:` 命令获取 Nvidia GPU PCI 信息,如下所示:红框所示即是 pciVendorSelector 信息。 + + ![获取 pciVendorSelector](../images/gpu-04.png) + +7. 编辑 kubevirt CR 提示:如果同一型号 GPU 有多个,只需在 CR 中写入一个即可,无需列出每个 GPU。 + + ```bash + kubectl -n virtnest-system edit kubevirt kubevirt + ``` + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com/GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com/GP104GL_TESLA_P4 + ``` + + 1. 下面是需要填写的信息 + 2. vGPU + 3. GPU 直通,上面的示例中 TEESLA P4 有两个 GPU,这里只需要注册一个即可 + +## 通过 YAML 创建 VM 并使用 GPU 加速 + +与普通云主机唯一的区别是在 devices 中添加 GPU 相关信息。 + +??? note "点击查看完整 YAML" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: testvm-gpu1 + namespace: default + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: systemdisk-testvm-gpu1 + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: www + source: + registry: + url: docker://release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 + runStrategy: Manual + template: + metadata: + creationTimestamp: null + spec: + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: systemdisk-testvm-gpu1 + - disk: + bus: virtio + name: cloudinitdisk + gpus: + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-0 + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-1 + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-testvm-gpu1 + name: systemdisk-testvm-gpu1 + - cloudInitNoCloud: + userDataBase64: I2Nsb3VkLWNvbmZpZwpzc2hfcHdhdXRoOiB0cnVlCmRpc2FibGVfcm9vdDogZmFsc2UKY2hwYXNzd2Q6IHsibGlzdCI6ICJyb290OmRhbmdlcm91cyIsIGV4cGlyZTogRmFsc2V9CgoKcnVuY21kOgogIC0gc2VkIC1pICIvI1w/UGVybWl0Um9vdExvZ2luL3MvXi4qJC9QZXJtaXRSb290TG9naW4geWVzL2ciIC9ldGMvc3NoL3NzaGRfY29uZmlnCiAgLSBzeXN0ZW1jdGwgcmVzdGFydCBzc2guc2VydmljZQ== + name: cloudinitdisk + ``` diff --git a/docs/zh/docs/admin/virtnest/gpu/vm-vgpu.md b/docs/zh/docs/admin/virtnest/gpu/vm-vgpu.md new file mode 100644 index 0000000..a78379f --- /dev/null +++ b/docs/zh/docs/admin/virtnest/gpu/vm-vgpu.md @@ -0,0 +1,331 @@ +# 云主机配置 GPU(vGPU) + +本文将介绍如何在创建云主机时,配置 GPU 的前提条件。 + +配置云主机的 GPU 的重点是对 GPU Operator 进行配置,以便在工作节点上部署不同的软件组件, +具体取决于这些节点上配置运行的 GPU 工作负载。以下三个节点为例: + +- controller-node-1 节点配置为运行容器。 +- work-node-1 节点配置为运行具有直通 GPU 的云主机。 +- work-node-2 节点配置为运行具有虚拟 vGPU 的云主机。 + +## 假设、限制和依赖性 + +工作节点可以运行 GPU 加速容器,也可以运行具有 GPU 直通的 GPU 加速 VM,或者具有 vGPU 的 GPU 加速 VM,但不能运行其中任何一个的组合。 + +1. 工作节点可以单独运行 GPU 加速容器、具有 GPU 直通的 GPU 加速 VM,或者具有 vGPU 的 GPU 加速 VM,不支持任何组合形式。 +2. 集群管理员或开发人员需要提前了解集群情况,并正确标记节点以指示它们将运行的 GPU 工作负载类型。 +3. 运行具有 GPU 直通或vGPU的 GPU 加速 VM的工作节点被假定为裸机,如果工作节点是云主机,则需要在云主机平台上启用GPU直通功能,请向云主机平台提供商咨询。 +4. 不支持 Nvidia MIG 的 vGPU。 +5. GPU Operator 不会自动在 VM 中安装 GPU 驱动程序。 + +## 启用 IOMMU + +为了启用GPU直通功能,集群节点需要开启IOMMU。请参考[如何开启IOMMU](https://www.server-world.info/en/note?os=CentOS_7&p=kvm&f=10)。 +如果您的集群是在云主机上运行,请咨询您的云主机平台提供商。 + +## 构建 vGPU Manager 镜像 + +注意:仅当使用 NVIDIA vGPU 时才需要构建 vGPU Manager 镜像。如果您计划仅使用 GPU 直通,请跳过此部分。 + +以下是构建 vGPU Manager 镜像并将其推送到镜像仓库中的步骤: + +1. 从 NVIDIA Licensing Portal 下载 vGPU 软件。 + + - 登录 NVIDIA Licensing Portal,转到 **Software Downloads** 页面。 + - NVIDIA vGPU 软件位于 **Software Downloads** 页面的 **Driver downloads** 选项卡中。 + - 在筛选条件中选择 **VGPU + Linux** ,点击 **下载** 以获取 Linux KVM 的软件包。 + 请解压下载的文件(`NVIDIA-Linux-x86_64--vgpu-kvm.run`)。 + + ![下载vGPU软件](../images/gpu-01.png) + +2. 打开终端克隆 container-images/driver 仓库 + + ```bash + git clone https://gitlab.com/nvidia/container-images/driver cd driver + ``` + +3. 切换到您的操作系统对应 vgpu-manager 目录 + + ```bash + cd vgpu-manager/ + ``` + +4. 将步骤 1 中提取的 .run 文件 copy 到当前目录 + + ```bash + cp /*-vgpu-kvm.run ./ + ``` + +5. 设置环境变量 + + - PRIVATE_REGISTRY:专用注册表的名称,用于存储驱动程序映像。 + - VERSION:NVIDIA vGPU管理器的版本,从NVIDIA软件门户下载。 + - OS_TAG:必须与集群节点操作系统版本匹配。 + - CUDA_VERSION:用于构建驱动程序映像的CUDA基本映像版本。 + + ```bash + export PRIVATE_REGISTRY=my/private/registry VERSION=510.73.06 OS_TAG=ubuntu22.04 CUDA_VERSION=12.2.0 + ``` + +6. 构建 NVIDIA vGPU Manager Image + + ```bash + docker build \ + --build-arg DRIVER_VERSION=${VERSION} \ + --build-arg CUDA_VERSION=${CUDA_VERSION} \ + -t ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} . + ``` + +7. 将 NVIDIA vGPU Manager 映像推送到您的镜像仓库 + + ```bash + docker push ${PRIVATE_REGISTRY}/vgpu-manager:${VERSION}-${OS_TAG} + ``` + +## 标记集群节点 + +进入 __容器管理__ ,选取您的工作集群,然后点击 __节点管理__ , 进入列表页面。点击列表右侧的 __┇__ ,选择 __修改标签__ ,为节点添加标签,每个节点只能有一种标签。 + +您可以为标签分配以下值:container、vm-passthrough 和 vm-vgpu。 + +![标记标签](../images/gpu-02.png) + +## 安装 Nvidia Operator + +1. 进入 __容器管理__ ,选取您的工作集群,点击 __Helm 应用__ -> __Helm 模板__ ,选择并安装 gpu-operator。需要修改一些 yaml 中的相关字段。 + + ```yaml + gpu-operator.sandboxWorkloads.enabled=true + gpu-operator.vgpuManager.enabled=true + gpu-operator.vgpuManager.repository= # (1)! + gpu-operator.vgpuManager.image=vgpu-manager + gpu-operator.vgpuManager.version= # (2)! + gpu-operator.vgpuDeviceManager.enabled=true + ``` + + 1. “构建 vGPU Manager 镜像” 步骤中的镜像仓库地址 + 2. “构建 vGPU Manager 镜像” 步骤中的 VERSION + +2. 等待安装成功,如下图所示: + + ![安装成功](../images/gpu-03.png) + +## 安装 virtnest-agent 并配置 CR + +1. 安装 virtnest-agent,参考[安装 virtnest-agent](../install/virtnest-agent.md)。 + +2. 将 vGPU 和 GPU 直通加入 Virtnest Kubevirt CR,以下示例是添加 vGPU 和 GPU 直通后的 部分关键 yaml: + + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com /GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com /GP104GL_TESLA_P4 + ``` + + 1. 下面是需要填写的信息 + 2. vGPU + 3. GPU 直通 + +3. 在 kubevirt CR yaml 中,`permittedHostDevices` 用于导入 VM 设备,vGPU 需在其中添加 mediatedDevices,具体结构如下: + + ```yaml + mediatedDevices: + - mdevNameSelector: GRID P4-1Q # (1)! + resourceName: nvidia.com/GRID_P4-1Q # (2)! + ``` + + 1. 设备名称 + 2. GPU Operator 注册到节点的 vGPU 信息 + +4. GPU 直通需要在 `permittedHostDevices` 下添加 pciHostDevices,具体结构如下: + + ```yaml + pciHostDevices: + - externalResourceProvider: true # (1)! + pciVendorSelector: 10DE:1BB3 # (2)! + resourceName: nvidia.com/GP104GL_TESLA_P4 # (3)! + ``` + + 1. 默认不要更改 + 2. 当前 pci 设备的 vednor id + 3. GPU Operator 注册到节点的 GPU 信息 + +5. 获取 vGPU 信息示例(仅适用于 vGPU):在标记为 `nvidia.com/gpu.workload.config=vm-gpu` 的节点(例如 work-node-2)上查看节点信息, + Capacity 中的 `nvidia.com/GRID_P4-1Q: 8` 表示可用 vGPU: + + ```bash + kubectl describe node work-node-2 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GRID_P4-1Q : 8 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GRID_P4-1Q: 8 + pods: 110 + ``` + + 那么 mdevNameSelector 应该是 “GRID P4-1Q”,resourceName 应该是 “GRID_P4-1Q” + +6. 获取 GPU 直通信息:在标记 `nvidia.com/gpu.workload.config=vm-passthrough` 的 node 上(本文档示例 node 为 work-node-1), + 查看 node 信息,Capacity 中 `nvidia.com/GP104GL_TESLA_P4: 2` 就是可用 vGPU: + + ```bash + kubectl describe node work-node-1 + ``` + ```output + Capacity: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 102626232Ki + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 264010840Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + Allocatable: + cpu: 64 + devices.kubevirt.io/kvm: 1k + devices.kubevirt.io/tun: 1k + devices.kubevirt.io/vhost-net: 1k + ephemeral-storage: 94580335255 + hugepages-1Gi: 0 + hugepages-2Mi: 0 + memory: 263908440Ki + nvidia.com/GP104GL_TESLA_P4: 2 + pods: 110 + ``` + + 那么 resourceName 应该是 “GRID_P4-1Q”, 如何获取 pciVendorSelector 呢?通过 ssh 登录到 work-node-1 目标节点, + 通过 `lspci -nnk -d 10de:` 命令获取 Nvidia GPU PCI 信息,如下所示:红框所示即是 pciVendorSelector 信息。 + + ![获取 pciVendorSelector](../images/gpu-04.png) + +7. 编辑 kubevirt CR 提示:如果同一型号 GPU 有多个,只需在 CR 中写入一个即可,无需列出每个 GPU。 + + ```bash + kubectl -n virtnest-system edit kubevirt kubevirt + ``` + ```yaml + spec: + configuration: + developerConfiguration: + featureGates: + - GPU + - DisableMDEVConfiguration + permittedHostDevices: # (1)! + mediatedDevices: # (2)! + - mdevNameSelector: GRID P4-1Q + resourceName: nvidia.com/GRID_P4-1Q + pciHostDevices: # (3)! + - externalResourceProvider: true + pciVendorSelector: 10DE:1BB3 + resourceName: nvidia.com/GP104GL_TESLA_P4 + ``` + + 1. 下面是需要填写的信息 + 2. vGPU + 3. GPU 直通,上面的示例中 TEESLA P4 有两个 GPU,这里只需要注册一个即可 + +## 通过 YAML 创建 VM 并使用 GPU 加速 + +与普通云主机唯一的区别是在 devices 中添加 gpu 相关信息。 + +??? note "点击查看完整 YAML" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: testvm-gpu1 + namespace: default + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: systemdisk-testvm-gpu1 + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: www + source: + registry: + url: docker://release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 + runStrategy: Manual + template: + metadata: + creationTimestamp: null + spec: + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: systemdisk-testvm-gpu1 + - disk: + bus: virtio + name: cloudinitdisk + gpus: + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-0 + - deviceName: nvidia.com/GP104GL_TESLA_P4 + name: gpu-0-1 + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-testvm-gpu1 + name: systemdisk-testvm-gpu1 + - cloudInitNoCloud: + userDataBase64: I2Nsb3VkLWNvbmZpZwpzc2hfcHdhdXRoOiB0cnVlCmRpc2FibGVfcm9vdDogZmFsc2UKY2hwYXNzd2Q6IHsibGlzdCI6ICJyb290OmRhbmdlcm91cyIsIGV4cGlyZTogRmFsc2V9CgoKcnVuY21kOgogIC0gc2VkIC1pICIvI1w/UGVybWl0Um9vdExvZ2luL3MvXi4qJC9QZXJtaXRSb290TG9naW4geWVzL2ciIC9ldGMvc3NoL3NzaGRfY29uZmlnCiAgLSBzeXN0ZW1jdGwgcmVzdGFydCBzc2guc2VydmljZQ== + name: cloudinitdisk + ``` diff --git a/docs/zh/docs/admin/virtnest/images/clone01.png b/docs/zh/docs/admin/virtnest/images/clone01.png new file mode 100644 index 0000000..7266194 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/clone01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/clone02.png b/docs/zh/docs/admin/virtnest/images/clone02.png new file mode 100644 index 0000000..c10c611 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/clone02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/clone03.png b/docs/zh/docs/admin/virtnest/images/clone03.png new file mode 100644 index 0000000..ef4b91b Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/clone03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/cold01.png b/docs/zh/docs/admin/virtnest/images/cold01.png new file mode 100644 index 0000000..30babf6 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/cold01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/cold02.png b/docs/zh/docs/admin/virtnest/images/cold02.png new file mode 100644 index 0000000..54c325a Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/cold02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/cold03.png b/docs/zh/docs/admin/virtnest/images/cold03.png new file mode 100644 index 0000000..36b9416 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/cold03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/cold04.png b/docs/zh/docs/admin/virtnest/images/cold04.png new file mode 100644 index 0000000..41cafee Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/cold04.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm-error01.png b/docs/zh/docs/admin/virtnest/images/createvm-error01.png new file mode 100644 index 0000000..a718621 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm-error01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm-error02.png b/docs/zh/docs/admin/virtnest/images/createvm-error02.png new file mode 100644 index 0000000..6a588e8 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm-error02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm-net01.png b/docs/zh/docs/admin/virtnest/images/createvm-net01.png new file mode 100644 index 0000000..b564338 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm-net01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm-net02.png b/docs/zh/docs/admin/virtnest/images/createvm-net02.png new file mode 100644 index 0000000..ad26822 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm-net02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm-net03.png b/docs/zh/docs/admin/virtnest/images/createvm-net03.png new file mode 100644 index 0000000..5f38320 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm-net03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm01.png b/docs/zh/docs/admin/virtnest/images/createvm01.png new file mode 100644 index 0000000..b0720c6 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm03.png b/docs/zh/docs/admin/virtnest/images/createvm03.png new file mode 100644 index 0000000..976500b Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm04.png b/docs/zh/docs/admin/virtnest/images/createvm04.png new file mode 100644 index 0000000..4eaea5d Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm04.png differ diff --git a/docs/zh/docs/admin/virtnest/images/createvm06.png b/docs/zh/docs/admin/virtnest/images/createvm06.png new file mode 100644 index 0000000..7b5e70d Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/createvm06.png differ diff --git a/docs/zh/docs/admin/virtnest/images/cronjob.jpg b/docs/zh/docs/admin/virtnest/images/cronjob.jpg new file mode 100644 index 0000000..c7185d9 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/cronjob.jpg differ diff --git a/docs/zh/docs/admin/virtnest/images/detail-event.png b/docs/zh/docs/admin/virtnest/images/detail-event.png new file mode 100644 index 0000000..267d904 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/detail-event.png differ diff --git a/docs/zh/docs/admin/virtnest/images/detail-network.png b/docs/zh/docs/admin/virtnest/images/detail-network.png new file mode 100644 index 0000000..94155dc Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/detail-network.png differ diff --git a/docs/zh/docs/admin/virtnest/images/detail-sc.png b/docs/zh/docs/admin/virtnest/images/detail-sc.png new file mode 100644 index 0000000..7c88c79 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/detail-sc.png differ diff --git a/docs/zh/docs/admin/virtnest/images/detail-snapshot.png b/docs/zh/docs/admin/virtnest/images/detail-snapshot.png new file mode 100644 index 0000000..6ee4ea8 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/detail-snapshot.png differ diff --git a/docs/zh/docs/admin/virtnest/images/detail01.png b/docs/zh/docs/admin/virtnest/images/detail01.png new file mode 100644 index 0000000..99a6335 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/detail01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/disk.png b/docs/zh/docs/admin/virtnest/images/disk.png new file mode 100644 index 0000000..351b499 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/disk.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit01.png b/docs/zh/docs/admin/virtnest/images/edit01.png new file mode 100644 index 0000000..137945f Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit02.png b/docs/zh/docs/admin/virtnest/images/edit02.png new file mode 100644 index 0000000..de23d45 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit03.png b/docs/zh/docs/admin/virtnest/images/edit03.png new file mode 100644 index 0000000..eb9a6c0 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit04.png b/docs/zh/docs/admin/virtnest/images/edit04.png new file mode 100644 index 0000000..b3eae45 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit04.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit05.png b/docs/zh/docs/admin/virtnest/images/edit05.png new file mode 100644 index 0000000..cf67e73 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit05.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit06.png b/docs/zh/docs/admin/virtnest/images/edit06.png new file mode 100644 index 0000000..7e17d94 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit06.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit07.png b/docs/zh/docs/admin/virtnest/images/edit07.png new file mode 100644 index 0000000..806ef3e Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit07.png differ diff --git a/docs/zh/docs/admin/virtnest/images/edit08.png b/docs/zh/docs/admin/virtnest/images/edit08.png new file mode 100644 index 0000000..e416aa1 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/edit08.png differ diff --git a/docs/zh/docs/admin/virtnest/images/event.png b/docs/zh/docs/admin/virtnest/images/event.png new file mode 100644 index 0000000..db59e86 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/event.png differ diff --git a/docs/zh/docs/admin/virtnest/images/gpu-01.png b/docs/zh/docs/admin/virtnest/images/gpu-01.png new file mode 100644 index 0000000..f2c41c2 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/gpu-01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/gpu-02.png b/docs/zh/docs/admin/virtnest/images/gpu-02.png new file mode 100644 index 0000000..62d5a5c Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/gpu-02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/gpu-03.png b/docs/zh/docs/admin/virtnest/images/gpu-03.png new file mode 100644 index 0000000..880503d Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/gpu-03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/gpu-04.png b/docs/zh/docs/admin/virtnest/images/gpu-04.png new file mode 100644 index 0000000..6b0c077 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/gpu-04.png differ diff --git a/docs/zh/docs/admin/virtnest/images/gpu01.png b/docs/zh/docs/admin/virtnest/images/gpu01.png new file mode 100644 index 0000000..403b246 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/gpu01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu01.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu01.png new file mode 100644 index 0000000..b196cf2 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu02.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu02.png new file mode 100644 index 0000000..c7097db Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu03.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu03.png new file mode 100644 index 0000000..1379d8c Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu04.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu04.png new file mode 100644 index 0000000..a8da676 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu04.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu05.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu05.png new file mode 100644 index 0000000..f2a5b5d Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu05.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu06.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu06.png new file mode 100644 index 0000000..6a8f908 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu06.png differ diff --git a/docs/zh/docs/admin/virtnest/images/import-ubuntu07.png b/docs/zh/docs/admin/virtnest/images/import-ubuntu07.png new file mode 100644 index 0000000..78eefdc Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/import-ubuntu07.png differ diff --git a/docs/zh/docs/admin/virtnest/images/install01.png b/docs/zh/docs/admin/virtnest/images/install01.png new file mode 100644 index 0000000..d73bca5 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/install01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/install02.png b/docs/zh/docs/admin/virtnest/images/install02.png new file mode 100644 index 0000000..956b765 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/install02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/live01.png b/docs/zh/docs/admin/virtnest/images/live01.png new file mode 100644 index 0000000..c9e4256 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/live01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/live02.png b/docs/zh/docs/admin/virtnest/images/live02.png new file mode 100644 index 0000000..ef7464c Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/live02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/live03.png b/docs/zh/docs/admin/virtnest/images/live03.png new file mode 100644 index 0000000..f0f9190 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/live03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/monitor01.png b/docs/zh/docs/admin/virtnest/images/monitor01.png new file mode 100644 index 0000000..7e98fb1 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/monitor01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/monitor02.png b/docs/zh/docs/admin/virtnest/images/monitor02.png new file mode 100644 index 0000000..ee42045 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/monitor02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/monitor03.png b/docs/zh/docs/admin/virtnest/images/monitor03.png new file mode 100644 index 0000000..86303d2 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/monitor03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/monitor04.png b/docs/zh/docs/admin/virtnest/images/monitor04.png new file mode 100644 index 0000000..6de302e Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/monitor04.png differ diff --git a/docs/zh/docs/admin/virtnest/images/monitor05.png b/docs/zh/docs/admin/virtnest/images/monitor05.png new file mode 100644 index 0000000..c0fc9b4 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/monitor05.png differ diff --git a/docs/zh/docs/admin/virtnest/images/pc.png b/docs/zh/docs/admin/virtnest/images/pc.png new file mode 100644 index 0000000..24f44ec Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/pc.png differ diff --git a/docs/zh/docs/admin/virtnest/images/snapshot.jpg b/docs/zh/docs/admin/virtnest/images/snapshot.jpg new file mode 100644 index 0000000..b62954c Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/snapshot.jpg differ diff --git a/docs/zh/docs/admin/virtnest/images/tep-detail.png b/docs/zh/docs/admin/virtnest/images/tep-detail.png new file mode 100644 index 0000000..05ee9f2 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/tep-detail.png differ diff --git a/docs/zh/docs/admin/virtnest/images/tep-yaml.png b/docs/zh/docs/admin/virtnest/images/tep-yaml.png new file mode 100644 index 0000000..58e56de Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/tep-yaml.png differ diff --git a/docs/zh/docs/admin/virtnest/images/tep01.png b/docs/zh/docs/admin/virtnest/images/tep01.png new file mode 100644 index 0000000..ba34239 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/tep01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/tep02.png b/docs/zh/docs/admin/virtnest/images/tep02.png new file mode 100644 index 0000000..ca39d0e Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/tep02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/tep03.png b/docs/zh/docs/admin/virtnest/images/tep03.png new file mode 100644 index 0000000..cc87657 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/tep03.png differ diff --git a/docs/zh/docs/admin/virtnest/images/turn-on.png b/docs/zh/docs/admin/virtnest/images/turn-on.png new file mode 100644 index 0000000..c81b520 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/turn-on.png differ diff --git a/docs/zh/docs/admin/virtnest/images/uuid01.png b/docs/zh/docs/admin/virtnest/images/uuid01.png new file mode 100644 index 0000000..83560a8 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/uuid01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/uuid02.png b/docs/zh/docs/admin/virtnest/images/uuid02.png new file mode 100644 index 0000000..ad69f78 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/uuid02.png differ diff --git a/docs/zh/docs/admin/virtnest/images/vgpu01.png b/docs/zh/docs/admin/virtnest/images/vgpu01.png new file mode 100644 index 0000000..394c1ff Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/vgpu01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/vm-tep.png b/docs/zh/docs/admin/virtnest/images/vm-tep.png new file mode 100644 index 0000000..85d7e9e Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/vm-tep.png differ diff --git a/docs/zh/docs/admin/virtnest/images/window-uefi.png b/docs/zh/docs/admin/virtnest/images/window-uefi.png new file mode 100644 index 0000000..4a3d3e8 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/window-uefi.png differ diff --git a/docs/zh/docs/admin/virtnest/images/window01.png b/docs/zh/docs/admin/virtnest/images/window01.png new file mode 100644 index 0000000..cdbec90 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/window01.png differ diff --git a/docs/zh/docs/admin/virtnest/images/windows-network.png b/docs/zh/docs/admin/virtnest/images/windows-network.png new file mode 100644 index 0000000..6841d41 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/windows-network.png differ diff --git a/docs/zh/docs/admin/virtnest/images/windows-vnc.png b/docs/zh/docs/admin/virtnest/images/windows-vnc.png new file mode 100644 index 0000000..58f9af1 Binary files /dev/null and b/docs/zh/docs/admin/virtnest/images/windows-vnc.png differ diff --git a/docs/zh/docs/admin/virtnest/install/index.md b/docs/zh/docs/admin/virtnest/install/index.md new file mode 100644 index 0000000..3e58099 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/install/index.md @@ -0,0 +1,76 @@ +# 安装云主机模块 + +本页说明如何安装云主机模块。 + +!!! info + + 下述命令或脚本内出现的 __virtnest__ 字样是云主机模块的内部开发代号。 + +## 配置 virtnest helm 仓库 + +helm-charts 仓库地址: + +```shell +helm repo add virtnest-release https://release.daocloud.io/chartrepo/virtnest +helm repo update virtnest-release +``` + +如果您想体验最新开发版的 virtnest,那么请添加如下仓库地址(开发版本的 virtnest 极其不稳定) + +```shell +helm repo add virtnest-release-ci https://release-ci.daocloud.io/chartrepo/virtnest +helm repo update virtnest-release-ci +``` + +## 选择您想安装的 virtnest 版本 + +建议安装最新版本。 + +```shell +[root@master ~]# helm search repo virtnest-release/virtnest --versions +NAME CHART VERSION APP VERSION DESCRIPTION +virtnest-release/virtnest 0.6.0 v0.6.0 A Helm chart for virtnest +``` + +## 创建 namespace + +```shell +kubectl create namespace virtnest-system +``` + +## 执行安装步骤 + +```shell +helm install virtnest virtnest-release/virtnest -n virtnest-system --version 0.6.0 +``` + +## 升级 + +### 更新 virtnest helm 仓库 + +```shell +helm repo update virtnest-release +``` + +### 备份 --set 参数 + +> 在升级 virtnest 版本之前,我们建议您执行如下命令,备份上一个版本的 --set 参数 + +```shell +helm get values virtnest -n virtnest-system -o yaml > bak.yaml +``` + +### 执行 helm upgrade + +```shell +helm upgrade virtnest virtnest-release/virtnest \ + -n virtnest-system \ + -f ./bak.yaml \ + --version 0.6.0 +``` + +## 卸载 + +```shell +helm delete virtnest -n virtnest-system +``` diff --git a/docs/zh/docs/admin/virtnest/install/install-dependency.md b/docs/zh/docs/admin/virtnest/install/install-dependency.md new file mode 100644 index 0000000..42d5b79 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/install/install-dependency.md @@ -0,0 +1,126 @@ +# 安装依赖和前提条件 + +本页说明安装云主机模块的依赖和前提条件。 + +!!! info + + 下述命令或脚本内出现的 __virtnest__ 字样是全局管理模块的内部开发代号。 + +## 前提条件 + +### 操作系统内核版本需要在 4.11 以上 + +目标集群所有节点的操作系统内核版本需要大于 4.11(详见 [kubevirt issue](https://github.com/kubevirt/kubevirt/issues/11886))。 +运行以下命令查看内核版本: + +```bash +uname -a +``` + +示例输出: + +```output +Linux master 6.5.3-1.el7.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Sep 13 11:46:28 EDT 2023 x86_64 x86_64 x86_64 GNU/Linux +``` + +### CPU 需支持 x86-64-v2 及以上的指令集 + +使用以下脚本检查当前节点的 CPU 是否支持: + +!!! note + + 若出现与输出信息无关的报错(如下所示),可无需关注,不影响最终结果。 + + ```bash title="示例" + $ sh detect-cpu.sh + detect-cpu.sh: line 3: fpu: command not found + ``` + +```sh +cat < detect-cpu.sh +#!/bin/sh -eu + +flags=$(cat /proc/cpuinfo | grep flags | head -n 1 | cut -d: -f2) + +supports_v2='awk "/cx16/&&/lahf/&&/popcnt/&&/sse4_1/&&/sse4_2/&&/ssse3/ {found=1} END {exit !found}"' +supports_v3='awk "/avx/&&/avx2/&&/bmi1/&&/bmi2/&&/f16c/&&/fma/&&/abm/&&/movbe/&&/xsave/ {found=1} END {exit !found}"' +supports_v4='awk "/avx512f/&&/avx512bw/&&/avx512cd/&&/avx512dq/&&/avx512vl/ {found=1} END {exit !found}"' + +echo "$flags" | eval $supports_v2 || exit 2 && echo "CPU supports x86-64-v2" +echo "$flags" | eval $supports_v3 || exit 3 && echo "CPU supports x86-64-v3" +echo "$flags" | eval $supports_v4 || exit 4 && echo "CPU supports x86-64-v4" +EOF +chmod +x detect-cpu.sh +sh detect-cpu.sh +``` + +### 所有节点必须启用硬件虚拟化(嵌套虚拟化) + +* 运行以下命令检查: + + ```sh + virt-host-validate qemu + ``` + + ```sh + # 成功的情况 + QEMU: Checking for hardware virtualization : PASS + QEMU: Checking if device /dev/kvm exists : PASS + QEMU: Checking if device /dev/kvm is accessible : PASS + QEMU: Checking if device /dev/vhost-net exists : PASS + QEMU: Checking if device /dev/net/tun exists : PASS + QEMU: Checking for cgroup 'cpu' controller support : PASS + QEMU: Checking for cgroup 'cpuacct' controller support : PASS + QEMU: Checking for cgroup 'cpuset' controller support : PASS + QEMU: Checking for cgroup 'memory' controller support : PASS + QEMU: Checking for cgroup 'devices' controller support : PASS + QEMU: Checking for cgroup 'blkio' controller support : PASS + QEMU: Checking for device assignment IOMMU support : PASS + QEMU: Checking if IOMMU is enabled by kernel : PASS + QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support) + + # 失败的情况 + QEMU: Checking for hardware virtualization : FAIL (Only emulated CPUs are available, performance will be significantly limited) + QEMU: Checking if device /dev/vhost-net exists : PASS + QEMU: Checking if device /dev/net/tun exists : PASS + QEMU: Checking for cgroup 'memory' controller support : PASS + QEMU: Checking for cgroup 'memory' controller mount-point : PASS + QEMU: Checking for cgroup 'cpu' controller support : PASS + QEMU: Checking for cgroup 'cpu' controller mount-point : PASS + QEMU: Checking for cgroup 'cpuacct' controller support : PASS + QEMU: Checking for cgroup 'cpuacct' controller mount-point : PASS + QEMU: Checking for cgroup 'cpuset' controller support : PASS + QEMU: Checking for cgroup 'cpuset' controller mount-point : PASS + QEMU: Checking for cgroup 'devices' controller support : PASS + QEMU: Checking for cgroup 'devices' controller mount-point : PASS + QEMU: Checking for cgroup 'blkio' controller support : PASS + QEMU: Checking for cgroup 'blkio' controller mount-point : PASS + WARN (Unknown if this platform has IOMMU support) + ``` + +* 安装 virt-host-validate: + + === "在 CentOS 上安装" + + ```bash + yum install -y qemu-kvm libvirt virt-install bridge-utils + ``` + + === "在 Ubuntu 上安装" + + ```bash + apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils + ``` + +* 硬件虚拟化启用方法: + + 不同平台启用硬件虚拟化的方法也不一样,以 vsphere 为例, + 方法请参照 [vmware 官网文档](https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-2A98801C-68E8-47AF-99ED-00C63E4857F6.html)。 + +### 如果使用 Docker Engine 作为容器运行时 + +如果集群使用 Docker Engine 作为容器运行时,则 Docker Engine 版本需要大于 20.10.10 + +### 建议开启 IOMMU + +为了后续功能做准备,建议开启 IOMMU。 diff --git a/docs/zh/docs/admin/virtnest/install/offline-install.md b/docs/zh/docs/admin/virtnest/install/offline-install.md new file mode 100644 index 0000000..157fa9e --- /dev/null +++ b/docs/zh/docs/admin/virtnest/install/offline-install.md @@ -0,0 +1,208 @@ +# 离线升级 + +本页说明从[下载中心](https://docs.daocloud.io/download/)下载云主机模块后,应该如何安装或升级。 + +!!! info + + 下述命令或脚本内出现的 __virtnest__ 字样是云主机模块的内部开发代号。 + +## 从安装包中加载镜像 + +您可以根据下面两种方式之一加载镜像,当环境中存在镜像仓库时,建议选择chart-syncer同步镜像到镜像仓库,该方法更加高效便捷。 + +### chart-syncer 同步镜像到镜像仓库 + +1. 创建 load-image.yaml + + !!! note + + 该 YAML 文件中的各项参数均为必填项。您需要一个私有的镜像仓库,并修改相关配置。 + + === "已安装 chart repo" + + 若当前环境已安装 chart repo,chart-syncer 也支持将 chart 导出为 tgz 文件。 + + ```yaml title="load-image.yaml" + source: + intermediateBundlesPath: virtnest-offline # 到执行 charts-syncer 命令的相对路径,而不是此 YAML 文件和离线包之间的相对路径 + target: + containerRegistry: 10.16.10.111 # 需更改为你的镜像仓库 url + containerRepository: release.daocloud.io/virtnest # 需更改为你的镜像仓库 + repo: + kind: HARBOR # 也可以是任何其他支持的 Helm Chart 仓库类别 + url: http://10.16.10.111/chartrepo/release.daocloud.io # 需更改为 chart repo url + auth: + username: "admin" # 你的镜像仓库用户名 + password: "Harbor12345" # 你的镜像仓库密码 + containers: + auth: + username: "admin" # 你的镜像仓库用户名 + password: "Harbor12345" # 你的镜像仓库密码 + ``` + + === "未安装 chart repo" + + 若当前环境未安装 chart repo,chart-syncer 也支持将 chart 导出为 tgz 文件,并存放在指定路径。 + + ```yaml title="load-image.yaml" + source: + intermediateBundlesPath: virtnest-offline # 到执行 charts-syncer 命令的相对路径,而不是此 YAML 文件和离线包之间的相对路径 + target: + containerRegistry: 10.16.10.111 # 需更改为你的镜像仓库 url + containerRepository: release.daocloud.io/virtnest # 需更改为你的镜像仓库 + repo: + kind: LOCAL + path: ./local-repo # chart 本地路径 + containers: + auth: + username: "admin" # 你的镜像仓库用户名 + password: "Harbor12345" # 你的镜像仓库密码 + ``` + +1. 执行同步镜像命令。 + + ```shell + charts-syncer sync --config load-image.yaml + ``` + +### Docker 或 containerd 直接加载 + +解压并加载镜像文件。 + +1. 解压 tar 压缩包。 + + ```shell + tar xvf virtnest.bundle.tar + ``` + + 解压成功后会得到 3 个文件: + + - hints.yaml + - images.tar + - original-chart + +2. 从本地加载镜像到 Docker 或 containerd。 + + === "Docker" + + ```shell + docker load -i images.tar + ``` + + === "containerd" + + ```shell + ctr -n k8s.io image import images.tar + ``` + +!!! note + + 每个 node 都需要做 Docker 或 containerd 加载镜像操作, + 加载完成后需要 tag 镜像,保持 Registry、Repository 与安装时一致。 + +## 升级 + +有两种升级方式。您可以根据前置操作,选择对应的升级方案: + +=== "通过 helm repo 升级" + + 1. 检查云主机 helm 仓库是否存在。 + + ```shell + helm repo list | grep virtnest + ``` + + 若返回结果为空或如下提示,则进行下一步;反之则跳过下一步。 + + ```none + Error: no repositories to show + ``` + + 1. 添加云主机的 helm 仓库。 + + ```shell + helm repo add virtnest http://{harbor url}/chartrepo/{project} + ``` + + 1. 更新云主机的 helm 仓库。 + + ```shell + helm repo update virtnest # (1) + ``` + + 1. helm 版本过低会导致失败,若失败,请尝试执行 helm update repo + + 1. 选择您想安装的云主机版本(建议安装最新版本)。 + + ```shell + helm search repo virtnest/virtnest --versions + ``` + + ```none + [root@master ~]# helm search repo virtnest/virtnest --versions + NAME CHART VERSION APP VERSION DESCRIPTION + virtnest/virtnest 0.2.0 v0.2.0 A Helm chart for virtnest + ... + ``` + + 1. 备份 `--set` 参数。 + + 在升级云主机版本之前,建议您执行如下命令,备份老版本的 `--set` 参数。 + + ```shell + helm get values virtnest -n virtnest-system -o yaml > bak.yaml + ``` + + 1. 更新 virtnest crds + + ```shell + helm pull virtnest/virtnest --version 0.2.0 && tar -zxf virtnest-0.2.0.tgz + kubectl apply -f virtnest/crds + ``` + + 1. 执行 `helm upgrade`。 + + 升级前建议您覆盖 bak.yaml 中的 `global.imageRegistry` 字段为当前使用的镜像仓库地址。 + + ```shell + export imageRegistry={你的镜像仓库} + ``` + + ```shell + helm upgrade virtnest virtnest/virtnest \ + -n virtnest-system \ + -f ./bak.yaml \ + --set global.imageRegistry=$imageRegistry \ + --version 0.2.0 + ``` + +=== "通过 chart 包升级" + + 1. 备份 `--set` 参数。 + + 在升级云主机版本之前,建议您执行如下命令,备份老版本的 `--set` 参数。 + + ```shell + helm get values virtnest -n virtnest-system -o yaml > bak.yaml + ``` + + 1. 更新 virtnest crds + + ```shell + kubectl apply -f ./crds + ``` + + 1. 执行 `helm upgrade`。 + + 升级前建议您覆盖 bak.yaml 中的 `global.imageRegistry` 为当前使用的镜像仓库地址。 + + ```shell + export imageRegistry={你的镜像仓库} + ``` + + ```shell + helm upgrade virtnest . \ + -n virtnest-system \ + -f ./bak.yaml \ + --set global.imageRegistry=$imageRegistry + ``` diff --git a/docs/zh/docs/admin/virtnest/install/virtnest-agent.md b/docs/zh/docs/admin/virtnest/install/virtnest-agent.md new file mode 100644 index 0000000..510fa64 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/install/virtnest-agent.md @@ -0,0 +1,35 @@ +# 安装 virtnest-agent + +本文将介绍如何在指定集群内安装 virtnest-agent。 + +## 前提条件 + +安装 virtnest-agent 之前,需要满足以下前提条件: + +- 操作系统内核版本需要在 v4.11 以上。 + +## 安装步骤 + +初始集群需要在 Helm 中安装 virtnest-agent 组件后方可使用云主机的相关能力。 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,若未安装 virtnest-agent 组件,则无法正常使用云主机能力。将提醒用户在所需集群内进行安装。 + + ![安装提示](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/virtnest001.png) + +2. 选择所需集群,点击左侧导航栏的 __Helm 应用__ ,然后点击 __Helm 模板__ ,查看模板列表。 + + ![helm 模板](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/virtnest002.png) + +3. 搜索 __virtnest-agent__ 组件,进入组件详情,选择合适版本,点击 __安装__ 按钮,进行安装。 + + ![virtnest-agent 组件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/virtnest003.png) + + ![详情](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/virtnest004.png) + +4. 进入安装表单页面,填写基本信息后,点击 __确定__ ,安装完成。 + + ![安装信息](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/virtnest005.png) + +5. 重新点击 __云主机__ 导航栏,成功出现云主机列表,可以正常使用云主机能力。 + + ![云主机列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/virtnest006.png) diff --git a/docs/zh/docs/admin/virtnest/quickstart/access.md b/docs/zh/docs/admin/virtnest/quickstart/access.md new file mode 100644 index 0000000..2dcaca8 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/quickstart/access.md @@ -0,0 +1,26 @@ +--- +hide: + - toc +--- + +# 连接云主机 + +本文将介绍两种连接云主机的方式,分别为 控制台访问(VNC)和终端方式。 + +## 终端 + +通过终端访问云主机的方式更加灵活和轻量,但是无法直接展示图形界面,交互性较差,且无法多终端同时在线。 + +点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入列表页面,点击列表右侧的 __┇__ ,支持通过终端方式访问云主机。 + +![创建快照](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/console01.png) + +## 控制台访问(VNC) + +通过 VNC 访问云主机的方式可以实现对远程计算机的完整图形界面的访问和控制,能够直观地操作远程设备,交互性更加好,但是性能会受到一定影响,且无法多终端同时在线。 + +> Windows 系统选择 VNC。 + +点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入列表页面,点击列表右侧的 __┇__ ,支持通过控制台访问(VNC)的方式访问云主机。 + +![vnc](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/console02.png) diff --git a/docs/zh/docs/admin/virtnest/quickstart/detail.md b/docs/zh/docs/admin/virtnest/quickstart/detail.md new file mode 100644 index 0000000..93f64b9 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/quickstart/detail.md @@ -0,0 +1,57 @@ +# 云主机详情 + +成功[创建云主机](../quickstart/index.md)后,可进入云主机详情页面,支持查看基本信息、配置信息、GPU 信息、概览、存储、网络、快照、事件等。 + +点击左侧导航栏上的 __容器管理__ ,然后点击 __集群列表__ ,进入云主机所在集群详情,点击云主机名称查看云主机详情。 + +### 基本信息 + +云主机基本信息包含状态、别名、集群、命名空间、IP、标签、节点、用户名、密码、创建时间等。其中, + +- 状态:云主机当前的运行状态(运行中/处理中/关机/错误)。 +- IP :云主机的 IP 地址。对于添加多张网卡的云主机,会为其分配多个 IP 地址。 + +### 配置信息 & GPU 配置 + +云主机配置信息包括: + +- 操作系统:安装在云主机上用于执行程序的操作系统。 +- 镜像地址:向一个虚拟硬盘文件或操作系统安装介质的链接,这个地址用于在云主机软件中加载和安装操作系统。 +- 网络模式:云主机配置的网络模式,Bridge(桥接)或 Masquerade(NAT)。 +- CPU、内存:为云主机分配的资源。 + +GPU 配置信息包含 GPU 类型、GPU 型号以及卡数量。 + +![云主机详情](../images/detail01.png) + +### 其他信息 + +=== "概览" + + 云主机概览页可查看云主机的监控内容。请注意,若未安装 insight-agent 组件,则无法获取监控信息。 + + ![概览](../images/monitor02.png) + +=== "储存" + + 展示云主机所用的存储,包括系统盘和数据盘的信息。 + + ![存储](../images/detail-sc.png) + +=== "网络" + + 展示云主机的网络配置,包括 Multus CR、网卡名称、IP 地址等信息。 + + ![网络](../images/detail-network.png) + +=== "快照" + + 若已经[创建快照](../vm/snapshot.md),本页将展示云主机的快照信息,支持通过快照恢复云主机。 + + ![快照](../images/detail-snapshot.png) + +=== "事件列表" + + 事件列表包含云主机的生命周期中发生的各种状态变化、操作记录和系统消息等。 + + ![事件](../images/detail-event.png) diff --git a/docs/zh/docs/admin/virtnest/quickstart/index.md b/docs/zh/docs/admin/virtnest/quickstart/index.md new file mode 100644 index 0000000..c437ce1 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/quickstart/index.md @@ -0,0 +1,222 @@ +# 创建云主机 + +本文将介绍如何通过镜像和 YAML 文件两种方式创建云主机。 + +云主机基于 KubeVirt 技术将云主机作为云原生应用进行管理,与容器无缝地衔接在一起, +使用户能够轻松地部署云主机应用,享受与容器应用一致的丝滑体验。 + +## 前提条件 + +创建云主机之前,需要满足以下前提条件: + +- 向用户机操作系统公开硬件辅助的虚拟化。 +- 在指定集群[安装 virtnest-agent](../install/index.md),操作系统内核版本需要在 3.15 以上。 +- 创建一个[命名空间](../../kpanda/namespaces/createns.md)。 +- 提前准备好镜像,平台内置三种镜像 (如下文所示),如需制作镜像,可参考开源项目[制作镜像](https://github.com/Tedezed/kubevirt-images-generator/tree/master)。 +- 进行网络配置时,若选择使用 Passt 网络模式,则需要升级至 0.4.0 及以上版本。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个云主机。 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入 __云主机__ 页面。 + + ![云主机](../images/createvm01.png) + +2. 在云主机列表页面,点击 __创建云主机__ -> 选择 __通过镜像创建__ 。 + +3. 进入镜像创建页面,依次填写基本信息、镜像配置、存储与网络、登录设置后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回云主机列表。点击列表右侧的 __┇__ ,可以对云主机执行关机/开启、重启、克隆、更新、创建快照、控制台访问(VNC)、删除等操作。 + 克隆和快照能力依赖于存储池的选择。 + + ![云主机操作](../images/createvm03.png) + +### 基本信息 + +在 __创建云主机__ 页面中,根据下表输入信息后,点击 __下一步__ 。 + +![基础信息](../images/createvm04.png) + +- 名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。 + 同一命名空间内名称不得重复,而且名称在云主机创建好之后不可更改。 +- 别名:允许任何字符,最长 60 个字符。 +- 集群:选择将新建的云主机部署在哪个集群内,若有使用 GPU 能力的需求,则需要选择有 GPU/vGPU 卡的集群。 +- 命名空间:选择将新建的云主机部署在哪个命名空间。 + 找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../../admin/kpanda/namespaces/createns.md)。 +- 标签/注解:选择为云主机添加所需的标签/注解信息。 + +### 镜像配置 + +根据下表填写镜像相关信息后,点击 __下一步__ + +1. 镜像来源:支持三种类型的来源。 + + - 镜像仓库类型:镜像存储在容器镜像仓库中,支持从镜像仓库中按需选择镜像; + - HTTP 类型:镜像存储于 HTTP 协议的文件服务器中,支持 HTTPS://和 HTTP://前缀; + - 对象存储(S3):支持通过对象存储协议 (S3) 获取的云主机镜像,若是无需认证的对象存储文件,请使用 HTTP 来源。 + +2. 以下是平台内置的镜像信息,包括操作系统和版本、镜像地址。同时也支持自定义云主机镜像。 + + | 操作系统 | 对应版本 | 镜像地址 | + | :------: | :----------: | -------------------------------------------------------------------- | + | CentOS | CentOS 7.9 | release-ci.daocloud.io/virtnest/system-images/centos-7.9-x86_64:v1 | + | Ubuntu | Ubuntu 22.04 | release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 | + | Debian | Debian 12 | release-ci.daocloud.io/virtnest/system-images/debian-12-x86_64:v1 | + +3. 镜像密钥:仅支持默认(Opaque)类型密钥,具体格式请参考[创建密钥](../vm/create-secret.md)。 + + 平台内置镜像存储在点火集群中,而点火集群的镜像仓库未加密,因此当选择内置镜像时,无需选择密钥。 + +!!! note + + CPU 和内存的热加载配置要求:virtnest 的版本不低于 v0.10.0,并且 virtnest-agent 版本不低于 v0.7.0;支持实时迁移(确保 PVC 访问模式为 ReadWriteMany)。 + +1. 资源配置:CPU 建议使用整数,若填写小数则会向上取整。支持 CPU、内存的热加载。 + +2. GPU 配置:启用 GPU 功能需要需要满足前提条件,具体可参考 [云主机配置 GPU(Nvidia)](../gpu/vm-gpu.md)。 + 云主机支持 Nvidia—GPU 和 Nvidia—vGPU 两种类型,选择所需类型后,需要选择对应的 GPU 型号和卡的数量。 + + ![配置gpu](../images/gpu01.png) + + ![配置vgpu](../images/vgpu01.png) + +### 存储与网络配置 + +![存储与网络配置](../images/createvm06.png) + +- 存储: + + - 存储和云主机的功能息息相关,主要是通过使用 Kubernetes 的持久卷和存储类,提供了灵活且可扩展的云主机存储能力。比如云主机镜像存储在 pvc 里,支持和其他数据一起克隆、快照等。 + + - 系统盘:系统默认创建一个 VirtIO 类型的 rootfs 系统盘,用于存放操作系统和数据。 + + - 数据盘:数据盘是云主机中用于存储用户数据、应用程序数据或其他非操作系统相关文件的存储设备。与系统盘相比,数据盘是非必选的,可以根据需要动态添加或移除。数据盘的容量也可以根据需求进行灵活配置。 + + - 默认使用块存储。如果需要使用克隆和快照功能,请确保您的存储池已经创建了对应的 VolumeSnapshotClass, 可以参考以下示例。如果需要使用实时迁移功能,请确保您的存储支持并选择了 ReadWriteMany 的访问模式 。 + + 大多数情况下,存储在安装过程中不会自动创建这样的 VolumeSnapshotClass,因此您需要手动创建 VolumeSnapshotClass。 + 以下是一个 HwameiStor 创建 VolumeSnapshotClass 的示例: + + ```yaml + kind: VolumeSnapshotClass + apiVersion: snapshot.storage.k8s.io/v1 + metadata: + name: hwameistor-storage-lvm-snapshot + annotations: + snapshot.storage.kubernetes.io/is-default-class: "true" + parameters: + snapsize: "1073741824" + driver: lvm.hwameistor.io + deletionPolicy: Delete + ``` + + - 执行以下命令检查 VolumeSnapshotClass 是否创建成功。 + + ```sh + kubectl get VolumeSnapshotClass + ``` + + - 查看已创建的 Snapshotclass,并且确认 provisioner 属性同存储池中的 Driver 属性一致。 + +- 网络: + + - 网络配置可以根据表格信息按需组合。 + + | 网络模式 | CNI | 是否安装 Spiderpool | 网卡模式 | 固定 IP | 实时迁移 | + | ----------------- | ------- | ------------------- | ------------ | --------------- | ------------ | + | Masquerade(NAT) | Calico | ❌ | 单网卡 | ❌ | ✅ | + | | Cilium | ❌ | 单网卡 | ❌ | ✅ | + | | Flannel | ❌ | 单网卡 | ❌ | ✅ | + | Bridge(桥接) | OVS | ✅ | 多网卡 | ✅ | ✅ | + + ![网络配置](../images/createvm-net01.png) + + - 网络模式分为 Masquerade(NAT)和 Bridge(桥接),Bridge(桥接)模式需要安装了 Spiderpool 组件后方可使用。 + + - 默认选择 Masquerade(NAT)的网络模式,使用 eth0 默认网卡。 + - 若集群内安装了 spiderpool 组件,则支持选择 Bridge(桥接)模式,Bridge(桥接)模式支持多网卡形式。 + + ![网络模式](../images/createvm-net02.png) + + - 添加网卡 + + - Passt(直通)/Bridge(桥接)模式下支持手动添加网卡。点击 __添加网卡__ ,进行网卡 IP 池的配置。选择和网络模式匹配的 Multus CR,若没有则需要自行创建。 + - 若打开 __使用默认 IP 池__ 开关,则使用 multus CR 配置中的默认 IP 池。若关闭开关,则手动选择 IP 池。 + + ![添加网卡](../images/createvm-net03.png) + +### 登录设置 + +- 用户名/密码:可以通过用户名和密码登录至云主机。 +- SSH:选择 SSH 登录方式时可为云主机绑定 SSH 密钥,用于日后登录云主机。 + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建云主机。 + +进入云主机列表页,点击 __通过 YAML 创建__ 按钮。 + +??? note "点击查看创建云主机的 YAML 示例" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + name: demo + namespace: default + spec: + dataVolumeTemplates: + - metadata: + name: systemdisk-demo + namespace: default + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: hwameistor-storage-lvm-hdd + source: + registry: + url: >- + docker://release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + runStrategy: Always + template: + spec: + architecture: amd64 + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: systemdisk-demo + - disk: + bus: virtio + name: cloudinitdisk + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + volumes: + - dataVolume: + name: systemdisk-demo + name: systemdisk-demo + - cloudInitNoCloud: + userDataBase64: >- + I2Nsb3VkLWNvbmZpZwpzc2hfcHdhdXRoOiB0cnVlCmRpc2FibGVfcm9vdDogZmFsc2UKY2hwYXNzd2Q6IHsibGlzdCI6ICJyb290OjEyMzQ1NiIsIGV4cGlyZTogRmFsc2V9CgoKcnVuY21kOgogIC0gc2VkIC1pICIvI1w/UGVybWl0Um9vdExvZ2luL3MvXi4qJC9QZXJtaXRSb290TG9naW4geWVzL2ciIC9ldGMvc3NoL3NzaGRfY29uZmlnCiAgLSBzeXN0ZW1jdGwgcmVzdGFydCBzc2guc2VydmljZQ== + name: cloudinitdisk + ``` diff --git a/docs/zh/docs/admin/virtnest/quickstart/nodeport.md b/docs/zh/docs/admin/virtnest/quickstart/nodeport.md new file mode 100644 index 0000000..020a88b --- /dev/null +++ b/docs/zh/docs/admin/virtnest/quickstart/nodeport.md @@ -0,0 +1,52 @@ +# 通过 NodePort 访问云主机 + +本文将介绍如何通过 NodePort 访问云主机。 + +## 现有访问方式的缺陷 + +1. 云主机支持通过 VNC 或者 console 访问,但这两种访问方式都有一个弊端,无法多终端同时在线。 + +2. 通过 NodePort 形式的 Service,可以帮助解决这个问题。 + +## 创建 service 的方式 + +1. 通过容器管理页面 + + - 选择目标访问的云主机所在集群页面创建服务(Service) + - 选择访问类型为节点访问(NodePort) + - 选择命名空间(云主机所在 namespace) + - 标签选择器填写 `vm.kubevirt.io/name: you-vm-name` + - 端口配置:协议选择 TCP,端口名称自定义,服务端口、容器端口填写 22 + +2. 创建成功后,就可以通过 `ssh username@nodeip -p port` 来访问云主机 + +## 通过 kubectl 创建 svc + +1. 编写 YAML 文件,示例如下: + + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: test-ssh + spec: + ports: + - name: tcp-ssh + nodePort: 32090 + protocol: TCP + // 22 端口,不要更改 + port: 22 + targetPort: 22 + selector: + // 云主机的 name +    vm.kubevirt.io/name: test-image-s3 + type: NodePort + ``` + +2. 执行以下命令 + + ```sh + kubectl apply -f you-svc.yaml + ``` + +3. 创建成功后,就可以通过 `ssh username@nodeip -p 32090` 来访问云主机 diff --git a/docs/zh/docs/admin/virtnest/quickstart/update.md b/docs/zh/docs/admin/virtnest/quickstart/update.md new file mode 100644 index 0000000..5b79f29 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/quickstart/update.md @@ -0,0 +1,58 @@ +# 更新云主机 + +本文将介绍如何通过表单和 YAML 文件两种方式更新云主机。 + +## 前提条件 + +开机状态下更新云主机 CPU、内存、数据盘之前,需要满足以下前提条件: + +- 云主机支持实时迁移能力。 + +## 表单更新云主机 + +在云主机列表页面,点击 __更新__ 进入云主机更新页面。 + +![更新](../images/edit01.png) + +=== "基本信息" + + 基本信息页面中, __别名__ 与 __标签注解__ 支持更新,其他信息无法更改。完成更新后点击 __下一步__ 进入镜像配置的界面。 + + ![更新基本信息](../images/edit02.png) + +=== "镜像配置" + + 在镜像配置页面中,镜像来源、操作系统、版本等参数一旦选择后无法更改,允许用户更新 __GPU 配置__ , + 包括启用或禁用 GPU 支持,选择 GPU 的类型,指定所需的型号,以及配置 GPU 卡的数量,更新后需要重启才能生效。 + 完成更新后点击 __下一步__ 进入存储与网络的界面。 + + ![更新镜像配置](../images/edit03.png) + +=== "存储与网络" + + 在存储与网络页面中,系统盘的存储池和 PVC 访问模式一旦选择后无法更改,支持增加磁盘容量,不可减少。 + 此外,用户可以自由添加或者移除数据盘。不支持更新网络配置。完成更新后点击 __下一步__ 进入登录设置的界面。 + + !!! note + + 建议在修改存储容量或增加数据盘后重启云主机,以确保配置生效。 + + ![存储](../images/edit04.png) + + ![网络](../images/edit05.png) + +=== "登录设置" + + 在登录设置页面中,用户名、密码以及 SSH 密钥配置一旦设置,不允许更改。确认您的登录信息无误后,点击确定按钮以完成更新流程。 + + ![登录配置](../images/edit06.png) + +## 编辑 YAML + +除了通过表单方式更新云主机外,还可以通过 YAML 文件更快速地更新云主机。 + +进入云主机列表页,点击 __编辑 YAML__ 按钮。 + +![yaml 编辑](../images/edit07.png) + +![编辑 yaml](../images/edit08.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/virtnest/template/index.md b/docs/zh/docs/admin/virtnest/template/index.md new file mode 100644 index 0000000..6de6340 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/template/index.md @@ -0,0 +1,74 @@ +# 通过模板创建云主机 + +本文将介绍如何通过模板创建云主机。 + +通过内置模板和自定义模板,用户可以轻松创建新的云主机。此外,我们还提供将现有云主机转换为云主机模板的功能,让用户能够更加灵活地管理和使用资源。 + +## 模板创建 + +参考以下步骤,使用模板创建一个云主机。 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入 __云主机管理__ 页面。在云主机列表页面,点击创建云主机-选择模板创建云主机。 + + ![云主机模板创建](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep01.png) + +2. 进入镜像创建页面,依次填写基本信息、模板配置、存储与网络、登录设置后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回云主机列表。点击列表右侧的 __┇__ ,可以对云主机执行关机/开启、重启、克隆、更新、创建快照、配置转换为模板、控制台访问(VNC)、删除等操作。 + 克隆和快照能力依赖于存储池的选择。 + + ![云主机操作](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep02.png) + +### 基本信息 + +在创建云主机页面中,根据下表输入信息后,点击 __下一步__ 。 + +![云主机基础信息](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep03.png) + +- 名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。 + 同一命名空间内名称不得重复,而且名称在云主机创建好之后不可更改。 +- 别名:允许任何字符,最长60个字符。 +- 集群:选择将新建的云主机部署在哪个集群内。 +- 命名空间:选择将新建的云主机部署在哪个命名空间。 + 找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../../kpanda/namespaces/createns.md)。 + +### 模板配置 + +出现模板列表,按需选择内置模板/自定义模板。 + +- 选择内置模板:平台内置了2个标准模板,不允许编辑和删除。选择内置模板后,镜像来源、操作系统、镜像地址等将使用模板内的信息,无法修改;资源配额也将使用模板内的信息,允许修改。 + + ![内置模板](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep04.png) + + ![内置模板](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep05.png) + +- 选择自定义模板:由云主机配置转化而来的模板,支持编辑和删除。使用自定义模板则根据具体情况支持修改镜像来源等信息。 + + ![使用镜像仓库](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep06.png) + + ![使用镜像仓库](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep07.png) + +### 存储与网络配置 + +![存储与网络配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/create-tep08.png) + +- 存储:系统默认创建一个 VirtIO 类型的 rootfs 系统盘,用于存放操作系统和数据。 + 默认使用块存储。如果需要使用克隆和快照功能,请确保您的存储池支持 VolumeSnapshots 功能, + 并在存储池(SC)中进行创建。请注意,存储池(SC)还有其他一些先决条件需要满足。 + + - 先决条件: + + - KubeVirt 利用 Kubernetes CSI 驱动程序的 VolumeSnapshot功能来捕获持久化云主机状态。 + 因此,您需要确保您的云主机使用由支持 VolumeSnapshots 的 StorageClass 并配置了正确的 VolumeSnapshotClass。 + - 查看已创建的 Snapshotclass ,并且确认 provisioner 属性同存储池中的 Driver 属性一致。 + + - 支持添加一块系统盘和多块数据盘。 + +- 网络:若您不做任何配置,系统将默认创建一个 VirtIO 类型的网络。 + +### 登录设置 + +- 用户名/密码:可以通过用户名和密码登录至云主机。 +- SSH:选择 SSH 登录方式时可为云主机绑定 SSH 密钥,用于日后登录云主机。 + +![登录设置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/virtnest/images/createvm08_1.png) diff --git a/docs/zh/docs/admin/virtnest/template/tep.md b/docs/zh/docs/admin/virtnest/template/tep.md new file mode 100644 index 0000000..ad38be1 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/template/tep.md @@ -0,0 +1,39 @@ +# 云主机模板 + +本文将介绍内置云主机模板和自定义云主机模板。 + +通过内置模板和自定义模板,用户可以轻松创建新的云主机。此外,我们还提供将现有云主机转换为云主机模板的功能,让用户能够更加灵活地管理和使用资源。 + +## 云主机模板 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机模板__ ,进入 __云主机模板__ 页面,若该模板是由配置了 GPU 的云主机转换而来,模板也会带有 GPU 的信息,将在模板列表中展示。 + + ![云主机模板](../images/tep01.png) + +2. 点击列表右侧的 __┇__ ,可以对内置模板执行创建云主机和查看 YAML 操作;对自定义模板支持创建云主机、编辑 YAML 和删除操作。 + + ![内置模板操作](../images/tep02.png) + + ![自定义模板操作](../images/tep03.png) + + ![编辑自定义模板](../images/tep-yaml.png) + +### 内置模板 + +- 平台内内置两种模板,分别是 CentOS 和 Ubuntu。 + + ![内置模板](../images/vm-tep.png) + +### 自定义模板 + +自定义模板是由云主机配置转化而来的模板。以下介绍如何从云主机配置转换为模板。 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入列表页面,点击列表右侧的 __┇__ 支持将配置转换为模板。只有运行中/关闭状态下的云主机支持转化。 + +2. 填写新模板的名称,提示原始云主机将会保留并且可用。转换成功后,将会在模板列表新增一条数据。 + +### 模板详情 + +成功创建出来一个模板后,点击模板名称,可以查看云主机详情,包括基本信息、GPU 信息、存储、网络等。如果需要快速基于该模板部署新的云主机,只需点击页面右上角的 __创建云主机__ 按钮即可便捷操作。 + +![模板详情](../images/tep-detail.png) \ No newline at end of file diff --git a/docs/zh/docs/admin/virtnest/vm-image/index.md b/docs/zh/docs/admin/virtnest/vm-image/index.md new file mode 100644 index 0000000..bcbafe0 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm-image/index.md @@ -0,0 +1,47 @@ +# 构建云主机镜像 + +本文将介绍如何构建需要的云主机镜像。 + +云主机镜像其实就是副本文件,是安装有操作系统的一个磁盘分区。常见的镜像文件格式包括 raw、qcow2、vmdk等。 + +## 构建镜像 + +下面是构建云主机镜像的一些详细步骤: + +1. 下载系统镜像 + + 在构建云主机镜像之前,您需要下载所需的系统镜像。我们推荐使用 qcow2、raw 或 vmdk 格式的镜像。可以访问以下链接获取 CentOS 和 Fedora 的镜像: + + - [CentOS Cloud Images](https://cloud.centos.org/centos/7/images/?C=M;O=D):支持从官方 CentOS 项目或其他资源中获取 CentOS 镜像。请确保选择与您的虚拟化平台兼容的版本。 + - [Fedora Cloud Images](https://fedoraproject.org/zh-Hans/cloud/download): 支持从官方 Fedora 项目获取镜像。根据您的需求选择合适的版本。 + +2. 构建 Docker 镜像并推送到容器镜像仓库 + + 在此步骤中,我们将使用 Docker 构建一个镜像,并将其推送到容器镜像仓库,以便在需要时能够方便地部署和使用。 + + - 创建 Dockerfile 文件 + + ```Dockerfile + FROM scratch + ADD --chown=107:107 CentOS-7-x86_64-GenericCloud.qcow2 /disk/ + ``` + + 向基于空白镜像构建的镜像中添加名为 `CentOS-7-x86_64-GenericCloud.qcow2` 的文件,并将其放置在镜像中的 __/disk/__ 目录下。通过这个操作,镜像就包含了这个文件,可以在创建云主机时使用它来提供 CentOS 7 x86_64 的操作系统环境。 + + - 构建镜像 + + ```shell + docker build -t release-ci.daocloud.io/ghippo/kubevirt-demo/centos7:v1 . + ``` + + 上述命令将使用 Dockerfile 中的指令构建一个名为 `release-ci.daocloud.io/ghippo/kubevirt-demo/centos7:v1` 的镜像。您可以根据项目需求修改镜像名称。 + + - 推送镜像至容器镜像仓库 + + 执行以下命令将构建好的镜像推送到名为 `release-ci.daocloud.io` 的镜像仓库,您还可以根据需要修改镜像仓库的名称和地址。 + + ```shell + docker push release-ci.daocloud.io/ghippo/kubevirt-demo/centos7:v1 + ``` + +以上是构建云主机镜像的详细步骤和说明。通过按照这些步骤操作,您将能够成功构建并推送用于云主机的镜像,以满足您的使用需求。 diff --git a/docs/zh/docs/admin/virtnest/vm/auto-migrate.md b/docs/zh/docs/admin/virtnest/vm/auto-migrate.md new file mode 100644 index 0000000..2abb381 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/auto-migrate.md @@ -0,0 +1,61 @@ +# 云主机自动漂移 + +本文将介绍当集群内某个节点因为断电或网络故障,导致该节点上的云主机无法访问时, +如何将正在运行的云主机无缝迁移到其他的节点上,同时保证业务的连续性和数据的安全性。 + +与实时迁移相比,自动漂移不需要您在界面中主动操作,而是系统自动触发迁移过程。 + +## 前提条件 + +实现自动漂移之前,需要满足以下前提条件: + +- 云主机未进行磁盘落盘操作,或使用 Rook-Ceph、HwameiStor HA 模式作为存储系统 +- 节点失联时间超过五分钟 +- 确保集群内至少有两个节点可供使用,并且云主机没有指定调度节点 +- 云主机的 launcher pod 已被删除 + +## 操作步骤 + +1. 检查云主机 launcher pod 状态: + + ```sh + kubectl get pod + ``` + + 查看 launcher pod 是否处于 Terminating 状态。 + +2. 强制删除 launcher pod: + + 如果 launcher pod 状态为 Terminating,可以执行以下命令进行强制删除: + + ```sh + kubectl delete --force + ``` + + 替换 `` 为你的 launcher pod 名称。 + +3. 等待重新创建并检查状态: + + 删除后,系统将自动重新创建 launcher pod。 + 等待其状态变为 running,然后刷新云主机列表,观察云主机是否成功迁移到新节点。 + +## 注意事项 + +如果使用 rook-ceph 作为存储,需要配置为 ReadWriteOnce 模式: + +1. 强制删除 pod 后,需要等待大约六分钟以让 launcher pod 启动,或者可以通过以下命令立即启动 pod: + + ```sh + kubectl get pv | grep + kubectl get VolumeAttachment | grep + ``` + + 替换 `` 和 `` 为你的云主机名称和持久卷名称。 + +2. 然后执行以下命令删除对应的 VolumeAttachment: + + ```sh + kubectl delete VolumeAttachment + ``` + + 替换 `` 为你的云主机名称。 diff --git a/docs/zh/docs/admin/virtnest/vm/clone.md b/docs/zh/docs/admin/virtnest/vm/clone.md new file mode 100644 index 0000000..b975ca3 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/clone.md @@ -0,0 +1,33 @@ +# 克隆云主机 + +本文将介绍如何克隆一台新的云主机。 + +用户可以克隆一台新的云主机,克隆后的云主机将具有与原始云主机相同的操作系统和系统配置,能够实现快速部署和扩展,快速创建相似配置的新云主机,而无需从头开始安装。 + +## 前提条件 + +使用克隆功能之前,需要满足以下前提条件(和快照功能的前提条件一致): + +- 只有非错误状态下的云主机才能使用克隆功能。 +- 安装 Snapshot CRDs、Snapshot Controller、CSI Driver。 + 具体安装步骤可参考 [CSI Snapshotter](https://github.com/kubernetes-csi/external-snapshotter?tab=readme-ov-file#usage)。 +- 等待 snapshot-controller 组件准备就绪, 该组件会监控 VolumeSnapshot 和 VolumeSnapshotContent 相关事件,并触发相关操作。 +- 等待 CSI Driver 准备就绪, 确保 csi-snapshotter sidecar 跑在 CSI Driver 里,csi-snapshotter sidecar 会监控 VolumeSnapshotContent 相关事件,并触发相关操作。 + - 如存储是 Rook-Ceph,可参考 [ceph-csi-snapshot](https://rook.io/docs/rook/latest-release/Storage-Configuration/Ceph-CSI/ceph-csi-snapshot/) + - 如存储是 HwameiStor,可参考 [huameistor-snapshot](https://hwameistor.io/cn/docs/volumes/volume_snapshot) + +## 克隆云主机 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入列表页面,点击列表右侧的 __┇__ ,可以对非错误状态下的云主机执行快照操作。 + + ![克隆云主机](../images/clone01.png) + +2. 弹出弹框,需要填写克隆新的云主机的名称和描述,克隆操作可能需要一些时间,具体取决于云主机的大小和存储性能。 + + ![克隆过程](../images/clone02.png) + +3. 克隆成功后可以在云主机列表内查看到新的云主机,新创建出来的云主机处于关机状态,若需要开机需要手动操作。 + + ![新的云主机](../images/clone03.png) + +4. 克隆前建议对原有云主机进行快照,如果克隆过程中遇到问题,请检查先决条件是否满足,并尝试重新执行克隆操作。 \ No newline at end of file diff --git a/docs/zh/docs/admin/virtnest/vm/create-secret.md b/docs/zh/docs/admin/virtnest/vm/create-secret.md new file mode 100644 index 0000000..a65b968 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/create-secret.md @@ -0,0 +1,23 @@ +--- +hide: + - toc +--- + +# 创建密钥 + +当创建云主机使用对象存储(S3)作为镜像来源时,有时候需要填写密钥来获取通过 S3 的验证。以下将介绍如何创建符合云主机要求的密钥。 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __集群列表__ ,进入云主机所在集群详情,点击 __配置与密钥__ ,选择 __密钥__ ,点击 __创建密钥__ 。 + + + +2. 进入创建页面,填写密钥名称,选择和云主机相同的命名空间,注意需要选择 __默认(Opaque)__ 类型。密钥数据需要遵循以下原则 + + - accessKeyId: 需要以 Base64 编码方式表示的数据 + - secretKey: 需要以 Base64 编码方式表示的数据 + + + +3. 创建成功后可以在创建云主机时使用所需密钥,最后通过验证。 + + diff --git a/docs/zh/docs/admin/virtnest/vm/cross-cluster-migrate.md b/docs/zh/docs/admin/virtnest/vm/cross-cluster-migrate.md new file mode 100644 index 0000000..0f10520 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/cross-cluster-migrate.md @@ -0,0 +1,168 @@ +# 云主机跨集群迁移 + +本功能暂未做 UI 界面能力,请参考文档的操作步骤执行。 + +## 使用场景 + +- 当原集群发生故障或性能下降导致该集群上的云主机无法访问时,将云主机迁移到其他的集群上。 +- 需要对集群进行计划内的维护或升级时,将云主机迁移到其他的集群上。 +- 当特定应用的性能需求变化,需要调整资源分配时,迁移云主机到其他的集群上以匹配更合适的资源配置。 + +## 前提条件 + +实现云主机跨集群迁移之前,需要满足以下前提条件: + +- 集群网络互通:确保原有集群与目标迁移集群之间的网络是互通的 +- 相同存储类型:目标迁移集群需支持与原有集群相同的存储类型(例如,如果导出集群使用 rook-ceph-block 类型的 StorageClass,则导入集群也必须支持此类型)。 +- 在原有集群的 KubeVirt 中开启 VMExport Feature Gate。 + +## 开启 VMExport Feature Gate + +激活 VMExport Feature Gate,在原有集群内执行如下命令, +可参考[How to activate a feature gate](https://kubevirt.io/cluster_admin/activating_feature_gates/#how-to-activate-a-feature-gate) + +```sh +kubectl edit kubevirt kubevirt -n virtnest-system +``` + +这条命令将修改 `featureGates` ,增加 `VMExport` 。 + +```yaml +apiVersion: kubevirt.io/v1 +kind: KubeVirt +metadata: + name: kubevirt + namespace: virtnest-system +spec: + configuration: + developerConfiguration: + featureGates: + - DataVolumes + - LiveMigration + - VMExport +``` + +## 配置原有集群的 Ingress + +以 Nginx Ingress 为例,配置 Ingress 以指向 `virt-exportproxy` Service: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-vm-export + namespace: virtnest-system +spec: + tls: + - hosts: + - upgrade-test.com + secretName: nginx-tls + rules: + - host: upgrade-test.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: virt-exportproxy + port: + number: 8443 + ingressClassName: nginx +``` + +## 迁移步骤 + +1. 创建 VirtualMachineExport CR + + - 如果 **云主机关机状态** 下进行迁移(冷迁移): + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: example-token # 导出云主机所用 token + namespace: default # 云主机所在命名空间 + stringData: + token: 1234567890ab # 导出使用的 token,可修改 + + --- + apiVersion: export.kubevirt.io/v1alpha1 + kind: VirtualMachineExport + metadata: + name: example-export # 导出名称, 可自行修改 + namespace: default # 云主机所在命名空间 + spec: + tokenSecretRef: example-token # 和上面创建的token名称保持一致 + source: + apiGroup: "kubevirt.io" + kind: VirtualMachine + name: testvm # 云主机名称 + ``` + + - 如果要在 **云主机不关机** 的状态下,使用云主机快照进行迁移(热迁移): + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: example-token # 导出云主机所用 token + namespace: default # 云主机所在命名空间 + stringData: + token: 1234567890ab # 导出使用的 token ,可修改 + + --- + apiVersion: export.kubevirt.io/v1alpha1 + kind: VirtualMachineExport + metadata: + name: export-snapshot # 导出名称, 可自行修改 + namespace: default # 云主机所在命名空间 + spec: + tokenSecretRef: export-token # 和上面创建的token名称保持一致 + source: + apiGroup: "snapshot.kubevirt.io" + kind: VirtualMachineSnapshot + name: export-snap-202407191524 # 对应的云主机快照名称 + ``` + +1. 检查 VirtualMachineExport 是否准备就绪: + + ```sh + # 这里的 example-export 需要替换为创建的 VirtualMachineExport 名称 + kubectl get VirtualMachineExport example-export -n default + + NAME SOURCEKIND SOURCENAME PHASE + example-export VirtualMachine testvm Ready + ``` + +1. 当 VirtualMachineExport 准备就绪后,导出云主机 YAML。 + + - 如果已安装 **virtctl** ,使用以下命令导出云主机的 YAML: + + ```sh + # 自行将 example-export替换为创建的 VirtualMachineExport 名称 + # 自行通过 -n 指定命名空间 + virtctl vmexport download example-export --manifest --include-secret --output=manifest.yaml + ``` + + - 如果没有安装 **virtctl** ,使用以下命令导出云主机 YAML: + + ```sh + # 自行替换 example-export 替换为创建的 VirtualMachineExport 名称 和命名空间 + manifesturl=$(kubectl get VirtualMachineExport example-export -n default -o=jsonpath='{.status.links.internal.manifests[0].url}') + secreturl=$(kubectl get VirtualMachineExport example-export -n default -o=jsonpath='{.status.links.internal.manifests[1].url}') + # 自行替换 secert 名称和命名空间 + token=$(kubectl get secret example-token -n default -o=jsonpath='{.data.token}' | base64 -d) + + curl -H "Accept: application/yaml" -H "x-kubevirt-export-token: $token" --insecure $secreturl > manifest.yaml + curl -H "Accept: application/yaml" -H "x-kubevirt-export-token: $token" --insecure $manifesturl >> manifest.yaml + ``` + +1. 导入云主机 + + 将导出的 `manifest.yaml` 复制到目标迁移集群并执行以下命令(如果命名空间不存在则需要提前创建): + + ```sh + kubectl apply -f manifest.yaml + ``` + 创建成功后,重启云主机,云主机成功运行后,在原有集群内删除原云主机(云主机未启动成功时,请勿删除原云主机)。 diff --git a/docs/zh/docs/admin/virtnest/vm/health-check.md b/docs/zh/docs/admin/virtnest/vm/health-check.md new file mode 100644 index 0000000..86c9c20 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/health-check.md @@ -0,0 +1,335 @@ +# 健康检查 + +当配置云主机的存活(Liveness)和就绪(Readiness)探针时,与 Kubernetes 的配置过程相似。本文将介绍如何通过 YAML 为云主机配置健康检查参数。 + +但是需要注意:需要在云主机创建成功并且处于关机状态下,修改 YAML 进行配置。 + +## 配置 HTTP Liveness Probe + +1. 在 spec.template.spec 中配置 livenessProbe.httpGet。 +2. 修改 cloudInitNoCloud 以启动一个 HTTP 服务器。 + + ??? note "点击查看 YAML 示例配置" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + virtnest.io/alias-name: '' + virtnest.io/image-secret: '' + virtnest.io/image-source: docker + virtnest.io/os-image: release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + creationTimestamp: '2024-10-15T02:39:45Z' + finalizers: + - kubevirt.io/virtualMachineControllerFinalize + generation: 1 + labels: + virtnest.io/os-family: Ubuntu + virtnest.io/os-version: '22.04' + name: test-probe + namespace: amamba-team + resourceVersion: '254032135' + uid: 6d92779d-7415-4721-8c7b-a2dde163d758 + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: test-probe-rootdisk + namespace: amamba-team + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: hwameistor-storage-lvm-hdd + source: + registry: + url: >- + docker://release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + runStrategy: Halted + template: + metadata: + creationTimestamp: null + spec: + architecture: amd64 + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: rootdisk + - disk: + bus: virtio + name: cloudinitdisk + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + memory: + guest: 2Gi + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + livenessProbe: + initialDelaySeconds: 120 + periodSeconds: 20 + httpGet: + port: 1500 + timeoutSeconds: 10 + volumes: + - dataVolume: + name: test-probe-rootdisk + name: rootdisk + - cloudInitNoCloud: + userData: | + #cloud-config + ssh_pwauth: true + disable_root: false + chpasswd: {"list": "root:dangerous", expire: False} + runcmd: + - sed -i "/#\?PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config + - systemctl restart ssh.service + - dhclient -r && dhclient + - apt-get update && apt-get install -y ncat + - ["systemd-run", "--unit=httpserver", "ncat", "-klp", "1500", "-e", '/usr/bin/echo -e HTTP/1.1 200 OK\nContent-Length: 12\n\nHello World!'] + name: cloudinitdisk + ``` + +3. 根据操作系统(如 Ubuntu/Debian 或 CentOS),userData 的配置可能有所不同。主要区别: + + - 包管理器: + + Ubuntu/Debian 使用 apt-get 作为包管理器。 + CentOS 使用 yum 作为包管理器。 + + - SSH 服务重启命令: + + Ubuntu/Debian 使用 systemctl restart ssh.service。 + CentOS 使用 systemctl restart sshd.service(注意 CentOS 7 及之前版本使用 service sshd restart)。 + + - 安装的软件包: + + Ubuntu/Debian 安装 ncat。 + CentOS 安装 nmap-ncat(因为 ncat 在 CentOS 的默认仓库中可能不可用)。 + +## 配置 TCP Liveness Probe + +在 spec.template.spec 中配置 livenessProbe.tcpSocket。 + +??? note "点击查看 YAML 示例配置" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + virtnest.io/alias-name: '' + virtnest.io/image-secret: '' + virtnest.io/image-source: docker + virtnest.io/os-image: release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + creationTimestamp: '2024-10-15T02:39:45Z' + finalizers: + - kubevirt.io/virtualMachineControllerFinalize + generation: 1 + labels: + virtnest.io/os-family: Ubuntu + virtnest.io/os-version: '22.04' + name: test-probe + namespace: amamba-team + resourceVersion: '254032135' + uid: 6d92779d-7415-4721-8c7b-a2dde163d758 + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: test-probe-rootdisk + namespace: amamba-team + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: hwameistor-storage-lvm-hdd + source: + registry: + url: >- + docker://release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + runStrategy: Halted + template: + metadata: + creationTimestamp: null + spec: + architecture: amd64 + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: rootdisk + - disk: + bus: virtio + name: cloudinitdisk + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + memory: + guest: 2Gi + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + livenessProbe: + initialDelaySeconds: 120 + periodSeconds: 20 + tcpSocket: + port: 1500 + timeoutSeconds: 10 + volumes: + - dataVolume: + name: test-probe-rootdisk + name: rootdisk + - cloudInitNoCloud: + userData: | + #cloud-config + ssh_pwauth: true + disable_root: false + chpasswd: {"list": "root:dangerous", expire: False} + runcmd: + - sed -i "/#\?PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config + - systemctl restart ssh.service + - dhclient -r && dhclient + - apt-get update && apt-get install -y ncat + - ["systemd-run", "--unit=httpserver", "ncat", "-klp", "1500", "-e", '/usr/bin/echo -e HTTP/1.1 200 OK\nContent-Length: 12\n\nHello World!'] + name: cloudinitdisk + ``` + +## 配置 Readiness Probes + +在 spec.template.spec 中配置 readiness。 + +??? note "点击查看 YAML 示例配置" + + ```yaml + apiVersion: kubevirt.io/v1 + kind: VirtualMachine + metadata: + annotations: + kubevirt.io/latest-observed-api-version: v1 + kubevirt.io/storage-observed-api-version: v1 + virtnest.io/alias-name: '' + virtnest.io/image-secret: '' + virtnest.io/image-source: docker + virtnest.io/os-image: release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + creationTimestamp: '2024-10-15T02:39:45Z' + finalizers: + - kubevirt.io/virtualMachineControllerFinalize + generation: 1 + labels: + virtnest.io/os-family: Ubuntu + virtnest.io/os-version: '22.04' + name: test-probe + namespace: amamba-team + resourceVersion: '254032135' + uid: 6d92779d-7415-4721-8c7b-a2dde163d758 + spec: + dataVolumeTemplates: + - metadata: + creationTimestamp: null + name: test-probe-rootdisk + namespace: amamba-team + spec: + pvc: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: hwameistor-storage-lvm-hdd + source: + registry: + url: >- + docker://release-ci.daocloud.io/virtnest/system-images/ubuntu-22.04-x86_64:v1 + runStrategy: Halted + template: + metadata: + creationTimestamp: null + spec: + architecture: amd64 + domain: + cpu: + cores: 1 + sockets: 1 + threads: 1 + devices: + disks: + - bootOrder: 1 + disk: + bus: virtio + name: rootdisk + - disk: + bus: virtio + name: cloudinitdisk + interfaces: + - masquerade: {} + name: default + machine: + type: q35 + memory: + guest: 2Gi + resources: + requests: + memory: 2Gi + networks: + - name: default + pod: {} + readiness: + initialDelaySeconds: 120 + periodSeconds: 20 + httpGet: + port: 1500 + timeoutSeconds: 10 + volumes: + - dataVolume: + name: test-probe-rootdisk + name: rootdisk + - cloudInitNoCloud: + userData: | + #cloud-config + ssh_pwauth: true + disable_root: false + chpasswd: {"list": "root:dangerous", expire: False} + runcmd: + - sed -i "/#\?PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config + - systemctl restart ssh.service + - dhclient -r && dhclient + - apt-get update && apt-get install -y ncat + - ["systemd-run", "--unit=httpserver", "ncat", "-klp", "1500", "-e", '/usr/bin/echo -e HTTP/1.1 200 OK\nContent-Length: 12\n\nHello World!'] + name: cloudinitdisk + ``` diff --git a/docs/zh/docs/admin/virtnest/vm/live-migration.md b/docs/zh/docs/admin/virtnest/vm/live-migration.md new file mode 100644 index 0000000..192b954 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/live-migration.md @@ -0,0 +1,27 @@ +# 实时迁移 + +本文将介绍如何将云主机从一个节点移动到另一个节点。 + +当节点维护或者升级时,用户可以将正在运行的云主机无缝迁移到其他的节点上,同时可以保证业务的连续性和数据的安全性。 + +## 前提条件 + +使用实时迁移之前,需要满足以下前提条件: + +- 云主机必须处于运行状态才能进行实时迁移。 +- 确保您的 PVC 访问模式为 ReadWriteMany,以便使用实时迁移功能。 +- 确保集群内至少有两个节点可供使用。 + +## 实时迁移 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入列表页面,点击列表右侧的 __┇__ ,可以对运行状态下的云主机进行迁移动作。目前云主机所在节点为 __controller-node-3__ 。 + + ![实时迁移](../images/live01.png) + +2. 弹出弹框,提示在实时迁移期间,正在运行的云主机实例会移动到另一个节点,可以选择指定节点迁移,也可以随机迁移,请确保其他节点资源充足。 + + ![迁移提示](../images/live02.png) + +3. 迁移需要一段时间,请耐心等待,成功后可以在云主机列表内查看节点信息,此时节点迁移到 __controller-node-1__ 。 + + ![迁移结果](../images/live03.png) diff --git a/docs/zh/docs/admin/virtnest/vm/migratiom.md b/docs/zh/docs/admin/virtnest/vm/migratiom.md new file mode 100644 index 0000000..f304e13 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/migratiom.md @@ -0,0 +1,34 @@ +# 集群内冷迁移 + +本文将介绍在关机状态下如何将云主机在同一集群内从一个节点移动到另一个节点。 + +冷迁移的主要特点是,云主机在迁移过程中会处于离线状态,这可能会对业务连续性产生影响。因此, +在实施冷迁移时需要仔细规划迁移时间窗口,并考虑业务需求和系统可用性。通常,冷迁移适用于对停机时间要求不是非常严格的场景。 + +## 前提条件 + +使用冷迁移之前,需要满足以下前提条件: + +- 云主机必须处于关机状态才能进行冷迁移。 + +## 冷迁移 + +1. 点击左侧导航栏上的 __容器管理__ ,然后点击 __云主机__ ,进入列表页面,点击列表右侧的 __┇__ , + 可以对关机状态下的云主机进行迁移动作。云主机在关机状态下时无法查看所在节点,需要提前规划或者开机查询。 + + ![迁移前](../images/cold01.png) + + ![关机后迁移](../images/cold02.png) + + !!! note + + 如果您在原始节点的存储池中使用了 local-path,跨节点迁移时可能出现问题,请谨慎选择。 + +1. 点击迁移后,提示在迁移期间,可以选择指定节点迁移,也可以随机迁移,若需要修改存储池, + 需要确保目标节点内有可用存储池。同时需要目标节点资源充足,迁移过程耗费时间较长,请耐心等待。 + + ![迁移提示](../images/cold03.png) + +1. 迁移需要一段时间,请耐心等待,成功后需要重启查看是否迁移成功。本示例已经开机查看迁移效果。 + + ![迁移结果](../images/cold04.png) diff --git a/docs/zh/docs/admin/virtnest/vm/monitor.md b/docs/zh/docs/admin/virtnest/vm/monitor.md new file mode 100644 index 0000000..7e3f276 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/monitor.md @@ -0,0 +1,39 @@ +# 云主机监控 + +云主机基于 Kubevirt 开源的 Grafana Dashboard,为了每一个云主机生成了监控看板 + +云主机的监控信息可以更好的了解云主机的资源消耗情况,比如 CPU、内存、存储和网络等资源的使用情况, +从而进行资源的优化和规划,提升整体的资源利用效率。 + +## 前提条件 + +查看云主机监控的相关信息之前,需要满足以下前提条件: + +- 在云主机所在的同一集群内安装 Insight-agent 组件,并且保证 Insight-agent 组件正常可用。 + +## 云主机监控 + +进入云主机的详细信息并点击 __概览__ ,即可查看云主机的监控内容。请注意,若未安装 Insight-agent 组件,则无法获取监控信息。以下是详细信息: + +- CPU 总量、CPU 使用量、内存总量、内存使用量。 + + ![监控](../images/monitor01.png) + +- CPU 使用率:指当前云主机正在使用的 CPU 资源的百分比; +- 内存使用率:指当前云主机正在使用的内存资源占总可用内存的百分比。 + + ![CPU、内存使用率](../images/monitor02.png) + +- 网络流量:指云主机在特定时间段内发送和接收的网络数据量; +- 网络丢包率:指在数据传输过程中丢失的数据包占总发送数据包数量的比例。 + + ![网络流量、丢包率](../images/monitor03.png) + +- 网络错误率:指在网络传输过程中发生的错误的比率; +- 磁盘吞吐:指云主机系统在一定时间内读取和写入磁盘的速度和能力。 + + ![网络错误率、磁盘吞吐](../images/monitor04.png) + +- IOPS:指的是在一秒钟内云主机系统进行的输入/输出操作的次数。磁盘延迟:指云主机系统在进行磁盘读写操作时所经历的时间延迟。 + + ![IOPS、磁盘延迟](../images/monitor05.png) diff --git a/docs/zh/docs/admin/virtnest/vm/scheduled-snapshot.md b/docs/zh/docs/admin/virtnest/vm/scheduled-snapshot.md new file mode 100644 index 0000000..2f3d975 --- /dev/null +++ b/docs/zh/docs/admin/virtnest/vm/scheduled-snapshot.md @@ -0,0 +1,73 @@ +# 定时快照 + +本文将介绍如何为云主机定时创建快照。 + +用户可以为云主机定时创建快照,能够为数据提供持续的保护,确保在发生数据丢失、损坏或删除的情况下可以进行有效的数据恢复。 + +## 定时快照步骤 + +1. 点击左侧导航栏上的 __容器管理__ -> __集群列表__ ,在列表页面,选择目标云主机所在的集群。 + 进入集群后,点击 __工作负载__ -> __定时任务__ ,选择 __YAML 创建__ 定时任务,参考以下 YAML 示例可为指定云主机定时创建快照。 + + ![yaml创建定时任务](../images/cronjob.jpg) + + ??? note "点击查看创建定时任务的 YAML 示例" + + ```yaml + apiVersion: batch/v1 + kind: CronJob + metadata: + name: xxxxx-xxxxx-cronjob # 定时任务名称, 可自定义 + namespace: virtnest-system # 请勿修改此namespace + spec: + schedule: "5 * * * *" # 按需修改定时任务执行间隔 + concurrencyPolicy: Allow + suspend: false + successfulJobsHistoryLimit: 10 + failedJobsHistoryLimit: 3 + startingDeadlineSeconds: 60 + jobTemplate: + spec: + template: + metadata: + labels: + virtnest.io/vm: xxxx # 修改为需要快照的云主机名称 + virtnest.io/namespace: xxxx # 修改为云主机所在的命名空间 + spec: + serviceAccountName: kubevirt-operator + containers: + - name: snapshot-job + image: release.daocloud.io/virtnest/tools:v0.1.5 # 离线环境下,仓库地址修改为对应火种集群仓库地址 + imagePullPolicy: IfNotPresent + env: + - name: NS + valueFrom: + fieldRef: + fieldPath: metadata.labels['virtnest.io/namespace'] + - name: VM + valueFrom: + fieldRef: + fieldPath: metadata.labels['virtnest.io/vm'] + command: + - /bin/sh + - -c + - | + export SUFFIX=$(date +"%Y%m%d-%H%M%S") + cat < **数据集列表** ,点击右侧的 **创建** 按钮。 + + ![点击创建](../images/dataset01.png) + +2. 选择数据集归属的工作集群、命名空间 **下一步** 。 + + ![填写参数](../images/dataset02.png) + +3. 配置目标数据的数据源类型,然后点击 **确定** 。 + + ![任务资源配置](../images/dataset03.png) + + 目前支持这几种数据源: + + - GIT:支持 GitHub、GitLab、Gitee 等仓库 + - S3:支持 Amazon 云等对象存储 + - HTTP:直接输入一个有效的 HTTP 网址 + - PVC:支持预先创建的 Kubernetes PersistentVolumeClaim + - NFS:支持 NFS 共享存储 + +4. 数据集创建成功将返回数据集列表。你可以通过右侧的 **┇** 执行更多操作。 + + ![数据集列表](../images/dataset04.png) + +!!! info + + 系统自动会在数据集创建成功后,立即进行一次性的数据预加载;在预加载完成之前,数据集不可以使用。 + +## 数据集使用 + +数据集创建成功后,可以在模型训练、推理等任务中使用。 + +### 在 Notebook 中使用 + +在创建 Notebook 中,可以直接使用数据集;使用方式如下: + +- 使用数据集做训练数据挂载 +- 使用数据集做代码挂载 + +![数据集列表](../images/dataset05.png) + +### 在 训练任务 中使用 + +- 使用数据集指定任务输出 +- 使用数据集指定任务输入 +- 使用数据集指定 TensorBoard 输出 + +![任务管理](../images/dataset06.png) + +### 在推理服务 中使用 + +- 使用数据集挂载模型 + +![推理服务](../images/dataset07.png) + +## 删除数据集 + +如果发现数据集冗余、过期或因其他缘故不再需要,可以从数据集列表中删除。 + +1. 在数据集列表右侧点击 **┇** ,在弹出菜单中选择 **删除** 。 + + ![删除](../images/ds-delete01.png) + +1. 在弹窗中确认要删除的数据集,输入数据集名称后点击 **删除** 。 + + ![确认删除](../images/ds-delete02.png) + +1. 屏幕提示删除成功,该数据集从列表中消失。 + +!!! caution + + 数据集一旦删除将不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/end-user/baize/dataset/environments.md b/docs/zh/docs/end-user/baize/dataset/environments.md new file mode 100644 index 0000000..5d3ccaf --- /dev/null +++ b/docs/zh/docs/end-user/baize/dataset/environments.md @@ -0,0 +1,79 @@ +# 管理环境 + +本文说明如何在 AI Lab 中管理你的环境依赖库,以下是具体操作步骤和注意事项。 + +1. [环境管理概述](#_2) +2. [创建新环境](#_3) +3. [配置环境](#_4) +4. [故障排除](#_5) + +## 环境管理概述 + +传统方式,一般会将 Python 环境依赖在镜像中构建,镜像带有 Python 版本和依赖包的镜像,维护成本较高且更新不方便,往往需要重新构建镜像。 + +而在 AI Lab 中,用户可以通过 **环境管理** 模块来管理纯粹的环境依赖,将这部分从镜像中解耦,带来的优势有: + +- 一份环境多处使用,同时可以在 Notebook、分布式训练任务、乃至推理服务中使用。 +- 更新依赖包更加方便,只需要更新环境依赖即可,无需重新构建镜像。 + +以下为环境管理的主要组成部分: + +- **集群** :选择需要操作的集群。 +- **命名空间** :选择命名空间以限定操作范围。 +- **环境列表** :展示当前集群和命名空间下的所有环境及其状态。 + +![环境管理概述](../images/conda01.png) + +| 字段 | 描述 | 举例值 | +|-----|------|-------| +| 名称 | 环境的名称 | my-environment | +| 状态 | 环境当前的状态(正常或失败),新创建环境有一个预热过程,预热成功后即可在其他任务中使用 | 正常 | +| 创建时间 | 环境创建的时间 | 2023-10-01 10:00:00 | + +## 创建新环境 + +在 **环境管理** 界面,点击右上角的 **创建** 按钮,进入创建环境的流程。 + +![创建新环境](../images/conda02.png) + +| 字段 | 描述 | 举例值 | +|-----|------|------| +| 名称 | 输入环境的名称,长度为 2-63 个字符,必须以小写字母、数字开头和结尾。 | my-environment | +| 部署位置 | **集群** :选择需要部署的集群 | `gpu-cluster` | +| | **命名空间** :选择命名空间 | `default` | +| 备注 | 填写备注信息。 | 这是一个测试环境 | +| 标签 | 为环境添加标签。 | env:test | +| 注解 | 为环境添加注解。填写完成后,点击 **下一步** 进入环境配置。 | 注解示例 | + +## 配置环境 + +在环境配置步骤中,用户需要配置 Python 版本和依赖包管理工具。 + +![配置环境](../images/conda03.png) + +| 字段 | 描述 | 举例值 | +|-----|-----|--------| +| Python 版本 | 选择所需的 Python 版本 | 3.12.3 | +| 包管理器 | 选择包管理工具,可选 `PIP` 或 `CONDA` | PIP | +| Environment Data | 如果选择 `PIP`:在下方编辑器中输入 `requirements.txt` 格式的依赖包列表。 | numpy==1.21.0 | +| | 如果选择 `CONDA`:在下方编辑器中输入 `environment.yaml` 格式的依赖包列表。 | | +| 其他选项 | **pip 额外索引地址** :配置 pip 额外的索引地址;适用于企业内部有自己的私有仓库或者 PIP 加速站点。 | `https://pypi.example.com` | +| | **GPU 配置** :启用或禁用 GPU 配置;部分涉及到 GPU 的依赖包需要在预加载时配置 GPU 资源。 | 启用 | +| | **关联存储** :选择关联的存储配置;环境依赖包会存储在关联存储中。注意:需要使用支持 `ReadWriteMany` 的存储。 | my-storage-config | + +配置完成后,点击 **创建** 按钮,系统会自动创建并配置新的 Python 环境。 + +## 故障排除 + +- 如果环境创建失败: + - 检查网络连接是否正常。 + - 确认填写的 Python 版本和包管理器配置无误。 + - 确保所选集群和命名空间可用。 + +- 如果依赖预热失败: + - 检查 `requirements.txt` 或 `environment.yaml` 文件格式是否正确。 + - 确认依赖包名称和版本是否正确无误。如遇到其他问题,请联系平台管理员或查看平台帮助文档获取更多支持。 + +--- + +以上即为在 AI Lab 中管理 Python 依赖库的基本操作步骤和注意事项。 diff --git a/docs/zh/docs/end-user/baize/images/agent-helm.png b/docs/zh/docs/end-user/baize/images/agent-helm.png new file mode 100644 index 0000000..30fb946 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/agent-helm.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-01.png b/docs/zh/docs/end-user/baize/images/baize-01.png new file mode 100644 index 0000000..b515142 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-01.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-02.png b/docs/zh/docs/end-user/baize/images/baize-02.png new file mode 100644 index 0000000..de75df4 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-02.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-03.png b/docs/zh/docs/end-user/baize/images/baize-03.png new file mode 100644 index 0000000..bae2181 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-03.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-04.png b/docs/zh/docs/end-user/baize/images/baize-04.png new file mode 100644 index 0000000..8e31919 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-04.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-05.png b/docs/zh/docs/end-user/baize/images/baize-05.png new file mode 100644 index 0000000..b360c85 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-05.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-06.png b/docs/zh/docs/end-user/baize/images/baize-06.png new file mode 100644 index 0000000..50dd98f Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-06.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-07.png b/docs/zh/docs/end-user/baize/images/baize-07.png new file mode 100644 index 0000000..2d9c1a4 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-07.png differ diff --git a/docs/zh/docs/end-user/baize/images/baize-08.png b/docs/zh/docs/end-user/baize/images/baize-08.png new file mode 100644 index 0000000..b2c9b88 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/baize-08.png differ diff --git a/docs/zh/docs/end-user/baize/images/bind01.png b/docs/zh/docs/end-user/baize/images/bind01.png new file mode 100644 index 0000000..e4b8d90 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/bind01.png differ diff --git a/docs/zh/docs/end-user/baize/images/bind02.png b/docs/zh/docs/end-user/baize/images/bind02.png new file mode 100644 index 0000000..c8273ea Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/bind02.png differ diff --git a/docs/zh/docs/end-user/baize/images/bind03.png b/docs/zh/docs/end-user/baize/images/bind03.png new file mode 100644 index 0000000..5b2f0f7 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/bind03.png differ diff --git a/docs/zh/docs/end-user/baize/images/bind04.png b/docs/zh/docs/end-user/baize/images/bind04.png new file mode 100644 index 0000000..29db3cb Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/bind04.png differ diff --git a/docs/zh/docs/end-user/baize/images/change-ws.png b/docs/zh/docs/end-user/baize/images/change-ws.png new file mode 100644 index 0000000..8299ea2 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/change-ws.png differ diff --git a/docs/zh/docs/end-user/baize/images/cluster.png b/docs/zh/docs/end-user/baize/images/cluster.png new file mode 100644 index 0000000..3ea2aa8 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/cluster.png differ diff --git a/docs/zh/docs/end-user/baize/images/conda01.png b/docs/zh/docs/end-user/baize/images/conda01.png new file mode 100644 index 0000000..f8e6f09 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/conda01.png differ diff --git a/docs/zh/docs/end-user/baize/images/conda02.png b/docs/zh/docs/end-user/baize/images/conda02.png new file mode 100644 index 0000000..1af809e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/conda02.png differ diff --git a/docs/zh/docs/end-user/baize/images/conda03.png b/docs/zh/docs/end-user/baize/images/conda03.png new file mode 100644 index 0000000..e2d196c Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/conda03.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset01.png b/docs/zh/docs/end-user/baize/images/dataset01.png new file mode 100644 index 0000000..5f585de Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset01.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset02.png b/docs/zh/docs/end-user/baize/images/dataset02.png new file mode 100644 index 0000000..187d157 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset02.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset03.png b/docs/zh/docs/end-user/baize/images/dataset03.png new file mode 100644 index 0000000..1087fe5 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset03.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset04.png b/docs/zh/docs/end-user/baize/images/dataset04.png new file mode 100644 index 0000000..eb44eb2 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset04.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset05.png b/docs/zh/docs/end-user/baize/images/dataset05.png new file mode 100644 index 0000000..cea3afb Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset05.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset06.png b/docs/zh/docs/end-user/baize/images/dataset06.png new file mode 100644 index 0000000..bfb04b8 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset06.png differ diff --git a/docs/zh/docs/end-user/baize/images/dataset07.png b/docs/zh/docs/end-user/baize/images/dataset07.png new file mode 100644 index 0000000..69e04a0 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dataset07.png differ diff --git a/docs/zh/docs/end-user/baize/images/delete01.png b/docs/zh/docs/end-user/baize/images/delete01.png new file mode 100644 index 0000000..5602ed4 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/delete01.png differ diff --git a/docs/zh/docs/end-user/baize/images/delete02.png b/docs/zh/docs/end-user/baize/images/delete02.png new file mode 100644 index 0000000..c661e2d Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/delete02.png differ diff --git a/docs/zh/docs/end-user/baize/images/delete03.png b/docs/zh/docs/end-user/baize/images/delete03.png new file mode 100644 index 0000000..655a640 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/delete03.png differ diff --git a/docs/zh/docs/end-user/baize/images/dev-view.png b/docs/zh/docs/end-user/baize/images/dev-view.png new file mode 100644 index 0000000..5ab7ca0 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/dev-view.png differ diff --git a/docs/zh/docs/end-user/baize/images/ds-delete01.png b/docs/zh/docs/end-user/baize/images/ds-delete01.png new file mode 100644 index 0000000..38a3896 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/ds-delete01.png differ diff --git a/docs/zh/docs/end-user/baize/images/ds-delete02.png b/docs/zh/docs/end-user/baize/images/ds-delete02.png new file mode 100644 index 0000000..63f8426 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/ds-delete02.png differ diff --git a/docs/zh/docs/end-user/baize/images/ds-delete03.png b/docs/zh/docs/end-user/baize/images/ds-delete03.png new file mode 100644 index 0000000..fcca8ac Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/ds-delete03.png differ diff --git a/docs/zh/docs/end-user/baize/images/enable-analy.png b/docs/zh/docs/end-user/baize/images/enable-analy.png new file mode 100644 index 0000000..aba5c22 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/enable-analy.png differ diff --git a/docs/zh/docs/end-user/baize/images/image01.png b/docs/zh/docs/end-user/baize/images/image01.png new file mode 100644 index 0000000..ac52a69 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/image01.png differ diff --git a/docs/zh/docs/end-user/baize/images/inference-interface.png b/docs/zh/docs/end-user/baize/images/inference-interface.png new file mode 100644 index 0000000..199f08e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/inference-interface.png differ diff --git a/docs/zh/docs/end-user/baize/images/job-mpi01.png b/docs/zh/docs/end-user/baize/images/job-mpi01.png new file mode 100644 index 0000000..77335a8 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job-mpi01.png differ diff --git a/docs/zh/docs/end-user/baize/images/job01.png b/docs/zh/docs/end-user/baize/images/job01.png new file mode 100644 index 0000000..7660646 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job01.png differ diff --git a/docs/zh/docs/end-user/baize/images/job02.png b/docs/zh/docs/end-user/baize/images/job02.png new file mode 100644 index 0000000..3eb3eba Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job02.png differ diff --git a/docs/zh/docs/end-user/baize/images/job03.png b/docs/zh/docs/end-user/baize/images/job03.png new file mode 100644 index 0000000..be5ba4b Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job03.png differ diff --git a/docs/zh/docs/end-user/baize/images/job04.png b/docs/zh/docs/end-user/baize/images/job04.png new file mode 100644 index 0000000..a5e8651 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job04.png differ diff --git a/docs/zh/docs/end-user/baize/images/job05.png b/docs/zh/docs/end-user/baize/images/job05.png new file mode 100644 index 0000000..f98d434 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job05.png differ diff --git a/docs/zh/docs/end-user/baize/images/job06.png b/docs/zh/docs/end-user/baize/images/job06.png new file mode 100644 index 0000000..ec230d0 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job06.png differ diff --git a/docs/zh/docs/end-user/baize/images/job07.png b/docs/zh/docs/end-user/baize/images/job07.png new file mode 100644 index 0000000..a038540 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/job07.png differ diff --git a/docs/zh/docs/end-user/baize/images/mxnet_job.png b/docs/zh/docs/end-user/baize/images/mxnet_job.png new file mode 100644 index 0000000..e431c2e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/mxnet_job.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-delete01.png b/docs/zh/docs/end-user/baize/images/nb-delete01.png new file mode 100644 index 0000000..ac097be Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-delete01.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-delete02.png b/docs/zh/docs/end-user/baize/images/nb-delete02.png new file mode 100644 index 0000000..4aa5ac2 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-delete02.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-delete03.png b/docs/zh/docs/end-user/baize/images/nb-delete03.png new file mode 100644 index 0000000..44c5b74 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-delete03.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-start01.png b/docs/zh/docs/end-user/baize/images/nb-start01.png new file mode 100644 index 0000000..c0b2995 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-start01.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-workload01.png b/docs/zh/docs/end-user/baize/images/nb-workload01.png new file mode 100644 index 0000000..08e11a2 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-workload01.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-workload02.png b/docs/zh/docs/end-user/baize/images/nb-workload02.png new file mode 100644 index 0000000..a3be64e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-workload02.png differ diff --git a/docs/zh/docs/end-user/baize/images/nb-workload03.png b/docs/zh/docs/end-user/baize/images/nb-workload03.png new file mode 100644 index 0000000..97e4447 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/nb-workload03.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook-idle.png b/docs/zh/docs/end-user/baize/images/notebook-idle.png new file mode 100644 index 0000000..91e9e6e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook-idle.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook-idle02.png b/docs/zh/docs/end-user/baize/images/notebook-idle02.png new file mode 100644 index 0000000..722d870 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook-idle02.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook-images.png b/docs/zh/docs/end-user/baize/images/notebook-images.png new file mode 100644 index 0000000..e96841e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook-images.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook01.png b/docs/zh/docs/end-user/baize/images/notebook01.png new file mode 100644 index 0000000..99855ae Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook01.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook02.png b/docs/zh/docs/end-user/baize/images/notebook02.png new file mode 100644 index 0000000..951a289 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook02.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook03.png b/docs/zh/docs/end-user/baize/images/notebook03.png new file mode 100644 index 0000000..8500c0c Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook03.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook04.png b/docs/zh/docs/end-user/baize/images/notebook04.png new file mode 100644 index 0000000..1545522 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook04.png differ diff --git a/docs/zh/docs/end-user/baize/images/notebook05.png b/docs/zh/docs/end-user/baize/images/notebook05.png new file mode 100644 index 0000000..d34f8e7 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/notebook05.png differ diff --git a/docs/zh/docs/end-user/baize/images/oam-overview.png b/docs/zh/docs/end-user/baize/images/oam-overview.png new file mode 100644 index 0000000..03a6dab Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/oam-overview.png differ diff --git a/docs/zh/docs/end-user/baize/images/othera.png b/docs/zh/docs/end-user/baize/images/othera.png new file mode 100644 index 0000000..a70eb7f Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/othera.png differ diff --git a/docs/zh/docs/end-user/baize/images/paddle_job.png b/docs/zh/docs/end-user/baize/images/paddle_job.png new file mode 100644 index 0000000..6c88c66 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/paddle_job.png differ diff --git a/docs/zh/docs/end-user/baize/images/q-delete01.png b/docs/zh/docs/end-user/baize/images/q-delete01.png new file mode 100644 index 0000000..cca9c84 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/q-delete01.png differ diff --git a/docs/zh/docs/end-user/baize/images/q-delete02.png b/docs/zh/docs/end-user/baize/images/q-delete02.png new file mode 100644 index 0000000..5abd4c1 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/q-delete02.png differ diff --git a/docs/zh/docs/end-user/baize/images/queue01.png b/docs/zh/docs/end-user/baize/images/queue01.png new file mode 100644 index 0000000..8bb910b Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/queue01.png differ diff --git a/docs/zh/docs/end-user/baize/images/queue02.png b/docs/zh/docs/end-user/baize/images/queue02.png new file mode 100644 index 0000000..2822456 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/queue02.png differ diff --git a/docs/zh/docs/end-user/baize/images/queue03.png b/docs/zh/docs/end-user/baize/images/queue03.png new file mode 100644 index 0000000..a42b286 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/queue03.png differ diff --git a/docs/zh/docs/end-user/baize/images/resource.png b/docs/zh/docs/end-user/baize/images/resource.png new file mode 100644 index 0000000..f648647 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/resource.png differ diff --git a/docs/zh/docs/end-user/baize/images/tensorboard-01.png b/docs/zh/docs/end-user/baize/images/tensorboard-01.png new file mode 100644 index 0000000..2679fac Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/tensorboard-01.png differ diff --git a/docs/zh/docs/end-user/baize/images/tensorboard-02.png b/docs/zh/docs/end-user/baize/images/tensorboard-02.png new file mode 100644 index 0000000..29b0488 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/tensorboard-02.png differ diff --git a/docs/zh/docs/end-user/baize/images/tensorboard-03.png b/docs/zh/docs/end-user/baize/images/tensorboard-03.png new file mode 100644 index 0000000..3ba9d9e Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/tensorboard-03.png differ diff --git a/docs/zh/docs/end-user/baize/images/tensorboard.png b/docs/zh/docs/end-user/baize/images/tensorboard.png new file mode 100644 index 0000000..ae63654 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/tensorboard.png differ diff --git a/docs/zh/docs/end-user/baize/images/triton-infer-0.png b/docs/zh/docs/end-user/baize/images/triton-infer-0.png new file mode 100644 index 0000000..6d77950 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/triton-infer-0.png differ diff --git a/docs/zh/docs/end-user/baize/images/triton-infer-1.png b/docs/zh/docs/end-user/baize/images/triton-infer-1.png new file mode 100644 index 0000000..e1298e4 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/triton-infer-1.png differ diff --git a/docs/zh/docs/end-user/baize/images/triton-infer-2.png b/docs/zh/docs/end-user/baize/images/triton-infer-2.png new file mode 100644 index 0000000..df4bdde Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/triton-infer-2.png differ diff --git a/docs/zh/docs/end-user/baize/images/triton-infer-3.png b/docs/zh/docs/end-user/baize/images/triton-infer-3.png new file mode 100644 index 0000000..937cdfb Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/triton-infer-3.png differ diff --git a/docs/zh/docs/end-user/baize/images/update-baize.png b/docs/zh/docs/end-user/baize/images/update-baize.png new file mode 100644 index 0000000..d22c9f5 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/update-baize.png differ diff --git a/docs/zh/docs/end-user/baize/images/view-wl01.png b/docs/zh/docs/end-user/baize/images/view-wl01.png new file mode 100644 index 0000000..ba30542 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/view-wl01.png differ diff --git a/docs/zh/docs/end-user/baize/images/view-wl02.png b/docs/zh/docs/end-user/baize/images/view-wl02.png new file mode 100644 index 0000000..d5ddbe3 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/view-wl02.png differ diff --git a/docs/zh/docs/end-user/baize/images/view-wl03.png b/docs/zh/docs/end-user/baize/images/view-wl03.png new file mode 100644 index 0000000..c6a21d4 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/view-wl03.png differ diff --git a/docs/zh/docs/end-user/baize/images/view-wl04.png b/docs/zh/docs/end-user/baize/images/view-wl04.png new file mode 100644 index 0000000..d8b783b Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/view-wl04.png differ diff --git a/docs/zh/docs/end-user/baize/images/vllm-infer-0.png b/docs/zh/docs/end-user/baize/images/vllm-infer-0.png new file mode 100644 index 0000000..142b965 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/vllm-infer-0.png differ diff --git a/docs/zh/docs/end-user/baize/images/vllm-infer-1.png b/docs/zh/docs/end-user/baize/images/vllm-infer-1.png new file mode 100644 index 0000000..8aaa198 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/vllm-infer-1.png differ diff --git a/docs/zh/docs/end-user/baize/images/vllm-infer-2.png b/docs/zh/docs/end-user/baize/images/vllm-infer-2.png new file mode 100644 index 0000000..ac22933 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/vllm-infer-2.png differ diff --git a/docs/zh/docs/end-user/baize/images/workspace.png b/docs/zh/docs/end-user/baize/images/workspace.png new file mode 100644 index 0000000..019a1b3 Binary files /dev/null and b/docs/zh/docs/end-user/baize/images/workspace.png differ diff --git a/docs/zh/docs/end-user/baize/inference/models.md b/docs/zh/docs/end-user/baize/inference/models.md new file mode 100644 index 0000000..0155875 --- /dev/null +++ b/docs/zh/docs/end-user/baize/inference/models.md @@ -0,0 +1,45 @@ +# 了解模型支持情况 + +随着 AI Lab 的快速迭代,我们已经支持了多种模型的推理服务,您可以在这里看到所支持的模型信息。 + +- AI Lab v0.3.0 上线了模型推理服务,针对传统的深度学习模型,方便用户可以直接使用AI Lab 的推理服务,无需关心模型的部署和维护。 +- AI Lab v0.6.0 支持了完整版本的 vLLM 推理能力,支持诸多大语言模型,如 `LLama`、`Qwen`、`ChatGLM` 等。 + +您可以在 AI Lab 中使用经过算丰 AI 算力平台验证过的 GPU 类型; +更多细节参阅 [GPU 支持矩阵](../../kpanda/gpu/gpu_matrix.md)。 + +![点击创建](../images/inference-interface.png) + +## Triton Inference Server + +通过 Triton Inference Server 可以很好的支持传统的深度学习模型,我们目前支持主流的推理后端服务: + +| Backend | 支持模型格式 | 介绍 | +| ------- | ---------- | --- | +| pytorch | TorchScript、PyTorch 2.0 格式的模型 | [triton-inference-server/pytorch_backend](https://github.com/triton-inference-server/pytorch_backend) | +| tensorflow | TensorFlow 2.x | [triton-inference-server/tensorflow_backend](https://github.com/triton-inference-server/tensorflow_backend) | +| vLLM(Deprecated) | 与 vLLM 一致 | 支持的模型和 vLLM support Model 一致 | + +!!! danger + + 使用 Triton 的 Backend vLLM 的方式已被弃用,推荐使用最新支持 vLLM 来部署您的大语言模型。 + +## vLLM + +通过 vLLM 我们可以很快的使用大语言模型,您可以在这里看到我们支持的模型列表,这通常和 `vLLM Support Models` 保持一致。 + +- HuggingFace 模型:我们支持了 HuggingFace 的大部分模型,您可以在 [HuggingFace Model Hub](https://huggingface.co/models) 查看更多模型。 +- [vLLM 支持模型](https://docs.vllm.ai/en/stable/models/supported_models.html)列出了支持的大语言模型和视觉语言模型。 +- 使用 vLLM 支持框架的模型进行微调后的模型。 + +### vLLM 新特性 + +目前,AI Lab 还支持在使用 vLLM 作为推理工具时的一些新特性: + +- 在推理模型时,启用 `Lora Adapter` 来优化模型推理服务 +- 提供兼容 `OpenAI` 的 `OpenAPI` 接口,方便用户切换到本地推理服务时,可以低成本的快速切换 + +## 下一步 + +- [创建 Triton 推理服务](./triton-inference.md) +- [创建 vLLM 推理服务](./vllm-inference.md) diff --git a/docs/zh/docs/end-user/baize/inference/triton-inference.md b/docs/zh/docs/end-user/baize/inference/triton-inference.md new file mode 100644 index 0000000..b8d8c87 --- /dev/null +++ b/docs/zh/docs/end-user/baize/inference/triton-inference.md @@ -0,0 +1,117 @@ +# 创建 Triton 推理服务 + +AI Lab 目前提供以 Triton、vLLM 作为推理框架,用户只需简单配置即可快速启动一个高性能的推理服务。 + +!!! danger + + 使用 Triton 的 Backend vLLM 的方式已被弃用,推荐使用最新支持 vLLM 来部署您的大语言模型。 + +## Triton介绍 + +Triton 是由 NVIDIA 开发的一个开源推理服务器,旨在简化机器学习模型的部署和推理服务。它支持多种深度学习框架,包括 TensorFlow、PyTorch 等,使得用户能够轻松管理和部署不同类型的模型。 + +## 前提条件 + +准备模型数据:在数据集管理中纳管模型代码,并保证数据成功预加载,下面以 mnist 手写数字识别的 PyTorch 模型为例。 + +!!! note + + 待推理的模型在数据集中需要遵以下目录格式: + + ```bash + + └── + └── + └── + ``` + +本例中的目录格式为: + +```bash + model-repo + └── mnist-cnn + └── 1 + └── model.pt +``` + +## 创建推理服务 + +目前已经支持表单创建,可以界面字段提示,进行服务创建。 + +![点击创建](../images/triton-infer-0.png) + +### 配置模型路径 + +模型路径 `model-repo/mnist-cnn/1/model.pt` 需要和数据集中的模型目录格式一致。 + +## 模型配置 + +![点击创建](../images/triton-infer-1.png) + +### 配置输入和输出参数 + +!!! note + + 输入和输出参数的第一个维度默认为 `batchsize` 的大小,设置为 `-1` 可以根据输入的推理数据自动计算 batchsize。参数其余维度和数据类型需要与模型输入匹配。 + +### 配置环境 + +可以导入 [环境管理](../dataset/environments.md) 中创建的环境作为推理时的运行环境。 + +## 高级配置 + +![点击创建](../images/triton-infer-2.png) + +### 配置认证策略 + +支持 `API key` 的请求方式认证,用户可以自定义增加认证参数。 + +### 亲和性调度 + +支持 根据 GPU 资源等节点配置实现自动化的亲和性调度,同时也方便用户自定义调度策略。 + +## 访问 + +![点击创建](../images/triton-infer-3.png) + +### API 访问 + +- Triton 提供了一个基于 REST 的 API,允许客户端通过 HTTP POST 请求进行模型推理。 +- 客户端可以发送 JSON 格式的请求体,其中包含输入数据和相关的元数据。 + +#### HTTP 访问 + +1. **发送 HTTP POST 请求**:使用工具如 `curl` 或 HTTP 客户端库(如 Python 的 `requests` 库)向 Triton Server 发送 POST 请求。 + +2. **设置 HTTP 头**:根据用户配置项自动生成的配置,包含模型输入和输出的元数据。 + +3. **构建请求体**:请求体通常包含要进行推理的输入数据,以及模型特定的元数据。 + +##### 示例 curl 命令 + +```bash + curl -X POST "http://:/v2/models//infer" \ + -H "Content-Type: application/json" \ + -d '{ + "inputs": [ + { + "name": "model_input", + "shape": [1, 1, 32, 32], + "datatype": "FP32", + "data": [ + [0.1234, 0.5678, 0.9101, ... ] + ] + } + ] + }' +``` + +- `` 是 Triton Inference Server 运行的主机地址。 +- `` 是 Triton Inference Server 运行的主机端口号。 +- `` 是所创建的推理服务的名称。 +- `"name"` 要与模型配置中的输入参数的 `name` 一致。 +- `"shape"` 要与模型配置中的输入参数的 `dims` 一致。 +- `"datatype"` 要与模型配置中的输入参数的 `Data Type` 一致。 +- `"data"` 替换为实际的推理数据。 + +请注意,上述示例代码需要根据你的具体模型和环境进行调整,输入数据的格式和内容也需要符合模型的要求。 diff --git a/docs/zh/docs/end-user/baize/inference/vllm-inference.md b/docs/zh/docs/end-user/baize/inference/vllm-inference.md new file mode 100644 index 0000000..aeab8c5 --- /dev/null +++ b/docs/zh/docs/end-user/baize/inference/vllm-inference.md @@ -0,0 +1,49 @@ +# 创建 vLLM 推理服务 + +AI Lab 支持以 vLLM 作为推理服务,提供全部 vLLM 的能力,同时提供了完全适配 OpenAI 接口定义。 + +## vLLM 介绍 + +vLLM 是一个快速且易于使用的用于推理和服务的库,vLLM 旨在极大地提升实时场景下的语言模型服务的吞吐与内存使用效率。vLLM 在速度、灵活性方面具有以下部分特点: + +- 连续批处理传入请求; +- 使用 PagedAttention 高效管理注意力键和值内存; +- 与流行的 HuggingFace 型号无缝集成; +- 兼容 OpenAI 的 API 服务器。 + +## 前提条件 + +准备模型数据:在数据集管理中纳管模型代码,并保证数据成功预加载。 + +## 创建推理服务 + +1. 选择 `vLLM` 推理框架,并在选择模型模块选择提前创建好的模型数据集 `hdd-models` 并填写数据集中模型所在的`路径`信息。 + + 本文推理服务的创建使用 ChatGLM3 模型。 + + ![模型选择](../images/vllm-infer-0.png) + +2. 配置推理服务的资源,并调整推理服务运行的参数。 + + ![数据选择](../images/vllm-infer-1.png) + + | 参数名 | 描述 | + | -- | -- | + | GPU 资源 | 根据模型规模以及集群资源可以为推理配置 GPU 资源。| + | 允许远程代码 | 控制 vLLM 是否信任并执行来自远程源的代码 | + | LoRA | **LoRA** 是一种针对深度学习模型的参数高效调整技术。它通过将原始模型参数矩阵分解为低秩矩阵,从而减少参数数量和计算复杂度。

1. `--lora-modules`:用来指定特定模块或层进行低秩近似
2. `max_loras_rank`:用来指定 LoRA 模型中每个适配层的最大秩,对于简单的任务,可以选择较小的秩值,而对于复杂任务,可能需要较大的秩值来保证模型性能。
3. `max_loras`:表示模型中可以包含的 LoRA 层的最大数量,根据模型大小、推理复杂度等因素自定
4. `max_cpu_loras`:用于指定在 CPU 环境中可以处理的 LoRA 层的最大数。 | + | 关联环境 | 通过选择环境预定义推理时所需的环境依赖。| + + !!! info + + 支持配置 LoRA 参数的模型可参考 [vLLM 支持的模型](https://docs.vllm.ai/en/latest/models/supported_models.html)。 + +3. 在 **高级配置** 中,支持根据 GPU 资源等节点配置实现自动化的亲和性调度,同时也方便用户自定义调度策略。 + +## 验证推理服务 + +推理服务创建完成之后,点击推理服务名称进入详情,查看 API 调用方法。通过使用 Curl、Python、Nodejs 等方式验证执行结果。 + +拷贝详情中的 `curl` 命令,并在终端中执行命令发送一条模型推理请求,预期输出: + +![推理接口](../images/vllm-infer-2.png) diff --git a/docs/zh/docs/end-user/baize/jobs/create.md b/docs/zh/docs/end-user/baize/jobs/create.md new file mode 100644 index 0000000..c87aeb6 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/create.md @@ -0,0 +1,39 @@ +# 创建任务(Job) + +任务管理是指通过作业调度和管控组件来创建和管理任务生命周期的功能。 + +AI Lab 采用 Kubernetes 的 Job 机制来调度各项 AI 推理、训练任务。 + +## 通用步骤 + +1. 在左侧导航栏中点击 **任务中心** -> **训练任务** ,点击右侧的 **创建** 按钮。 + + ![点击创建](../images/job01.png) + +1. 系统会预先填充基础配置数据,包括要部署的集群、命名空间、任务类型、队列、优先级等。 + 调整这些参数后点击 **下一步** 。 + + ![填写参数](../images/job02.png) + +1. 配置镜像地址、运行参数以及关联的数据集、环境和资源后,点击 **下一步** 。 + + ![任务资源配置](../images/job03.png) + +1. 按需添加标签、注解、环境变量等任务参数,选择调度策略后点击 **确定** 。 + + ![高级配置](../images/job04.png) + +1. 任务创建成功后,会有几种运行状态: + + - 运行中 + - 排队中 + - 提交成功、提交失败 + - 任务成功、任务失败 + +## 创建特定任务 + +- [创建 Pytorch 任务](./pytorch.md) +- [创建 TensorFlow 任务](./tensorflow.md) +- [创建 MPI 任务](./mpi.md) +- [创建 MXNet 任务](./mxnet.md) +- [创建 PaddlePaddle 任务](./paddle.md) diff --git a/docs/zh/docs/end-user/baize/jobs/delete.md b/docs/zh/docs/end-user/baize/jobs/delete.md new file mode 100644 index 0000000..ac49409 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/delete.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 删除任务(Job) + +如果发现任务冗余、过期或因其他缘故不再需要,可以从训练任务列表中删除。 + +1. 在训练任务列表右侧点击 **┇** ,在弹出菜单中选择 **删除** 。 + + ![删除](../images/delete01.png) + +1. 在弹窗中确认要删除的任务,输入任务名称后点击 **删除** 。 + + ![确认删除](../images/delete02.png) + +1. 屏幕提示删除成功,该任务从列表中消失。 + + ![已删除](../images/delete03.png) + +!!! caution + + 任务一旦删除将不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/end-user/baize/jobs/mpi.md b/docs/zh/docs/end-user/baize/jobs/mpi.md new file mode 100644 index 0000000..fc28833 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/mpi.md @@ -0,0 +1,224 @@ +# MPI 任务 + +MPI(Message Passing Interface)是一种用于并行计算的通信协议,它允许多个计算节点之间进行消息传递和协作。 +MPI 任务是使用 MPI 协议进行并行计算的任务,适用于需要大规模并行处理的应用场景,例如分布式训练、科学计算等。 + +在 AI Lab 中,我们提供了 MPI 任务的支持,您可以通过界面化操作,快速创建 MPI 任务,进行高性能的并行计算。 +本教程将指导您如何在 AI Lab 中创建和运行一个 MPI 任务。 + +## 任务配置介绍 + +- **任务类型** :`MPI`,用于运行并行计算任务。 +- **运行环境** :选用预装了 MPI 环境的镜像,或者在任务中指定安装必要的依赖。 +- **MPIJob 配置** :理解并配置 MPIJob 的各项参数,如副本数、资源请求等。 + +## 任务运行环境 + +在这里我们使用 `baize-notebook` 基础镜像和 **关联环境** 的方式来作为任务的基础运行环境。 +确保运行环境中包含 MPI 及相关库,如 OpenMPI、`mpi4py` 等。 + +> **注意** :了解如何创建环境,请参考[环境列表](../dataset/environments.md)。 + +## 创建 MPI 任务 + +### MPI 任务创建步骤 + +![MPI 任务](../images/job-mpi01.png) + +1. **登录平台** :登录 AI Lab 平台,点击左侧导航栏中的 **任务中心**,进入 **训练任务** 页面。 +2. **创建任务** :点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型** :在弹出的窗口中,选择任务类型为 `MPI`,然后点击 **下一步**。 +4. **填写任务信息** :填写任务名称和描述,例如 “benchmarks-mpi”,然后点击 **下一步**。 +5. **配置任务参数** :根据您的需求,配置任务的运行参数、镜像、资源等信息。 + +#### 运行参数 + +- **启动命令** :使用 `mpirun`,这是运行 MPI 程序的命令。 +- **命令参数** :输入您要运行的 MPI 程序的参数。 + +**示例:运行 TensorFlow Benchmarks** + +在本示例中,我们将运行一个 TensorFlow 的基准测试程序,使用 Horovod 进行分布式训练。 +首先,确保您使用的镜像中包含所需的依赖项,例如 TensorFlow、Horovod、Open MPI 等。 + +**镜像选择** :使用包含 TensorFlow 和 MPI 的镜像,例如 `mai.daocloud.io/docker.io/mpioperator/tensorflow-benchmarks:latest`。 + +**命令参数** : + +```bash +mpirun --allow-run-as-root -np 2 -bind-to none -map-by slot \ + -x NCCL_DEBUG=INFO -x LD_LIBRARY_PATH -x PATH \ + -mca pml ob1 -mca btl ^openib \ + python scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py \ + --model=resnet101 --batch_size=64 --variable_update=horovod +``` + +**说明** : + +- `mpirun`:MPI 的启动命令。 +- `--allow-run-as-root`:允许以 root 用户运行(在容器中通常是 root 用户)。 +- `-np 2`:指定运行的进程数为 2。 +- `-bind-to none`,`-map-by slot`:MPI 进程绑定和映射的配置。 +- `-x NCCL_DEBUG=INFO`:设置 NCCL(NVIDIA Collective Communication Library)的调试信息级别。 +- `-x LD_LIBRARY_PATH`,`-x PATH`:在 MPI 环境中传递必要的环境变量。 +- `-mca pml ob1 -mca btl ^openib`:MPI 的配置参数,指定传输层和消息层协议。 +- `python scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py`:运行 TensorFlow 基准测试脚本。 +- `--model=resnet101`,`--batch_size=64`,`--variable_update=horovod`:TensorFlow 脚本的参数,指定模型、批量大小和使用 Horovod 进行参数更新。 + +#### 资源配置 + +在任务配置中,需要为每个节点(Launcher 和 Worker)分配适当的资源,例如 CPU、内存和 GPU。 + +**资源示例** : + +- **Launcher(启动器)** : + + - **副本数** :1 + - **资源请求** : + - CPU:2 核 + - 内存:4 GiB + +- **Worker(工作节点)** : + + - **副本数** :2 + - **资源请求** : + - CPU:2 核 + - 内存:4 GiB + - GPU:根据需求分配 + +#### 完整的 MPIJob 配置示例 + +以下是完整的 MPIJob 配置示例,供您参考。 + +```yaml +apiVersion: kubeflow.org/v1 +kind: MPIJob +metadata: + name: tensorflow-benchmarks +spec: + slotsPerWorker: 1 + runPolicy: + cleanPodPolicy: Running + mpiReplicaSpecs: + Launcher: + replicas: 1 + template: + spec: + containers: + - name: tensorflow-benchmarks + image: mai.daocloud.io/docker.io/mpioperator/tensorflow-benchmarks:latest + command: + - mpirun + - --allow-run-as-root + - -np + - "2" + - -bind-to + - none + - -map-by + - slot + - -x + - NCCL_DEBUG=INFO + - -x + - LD_LIBRARY_PATH + - -x + - PATH + - -mca + - pml + - ob1 + - -mca + - btl + - ^openib + - python + - scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py + - --model=resnet101 + - --batch_size=64 + - --variable_update=horovod + resources: + limits: + cpu: "2" + memory: 4Gi + requests: + cpu: "2" + memory: 4Gi + Worker: + replicas: 2 + template: + spec: + containers: + - name: tensorflow-benchmarks + image: mai.daocloud.io/docker.io/mpioperator/tensorflow-benchmarks:latest + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpumem: 1k + nvidia.com/vgpu: "1" + requests: + cpu: "2" + memory: 4Gi +``` + +**配置解析** : + +- `apiVersion` 和 `kind`:表示资源的 API 版本和类型,`MPIJob` 是 Kubeflow 定义的自定义资源,用于创建 MPI 类型的任务。 +- `metadata`:元数据,包含任务的名称等信息。 +- `spec`:任务的详细配置。 + - `slotsPerWorker`:每个 Worker 节点的槽位数量,通常设置为 1。 + - `runPolicy`:运行策略,例如任务完成后是否清理 Pod。 + - `mpiReplicaSpecs`:MPI 任务的副本配置。 + - `Launcher`:启动器,负责启动 MPI 任务。 + - `replicas`:副本数,通常为 1。 + - `template`:Pod 模板,定义容器运行的镜像、命令、资源等。 + - `Worker`:工作节点,实际执行任务的计算节点。 + - `replicas`:副本数,根据并行需求设置,这里设置为 2。 + - `template`:Pod 模板,同样定义容器的运行环境和资源。 + +#### 设置任务副本数 + +在创建 MPI 任务时,需要根据 `mpiReplicaSpecs` 中配置的副本数,正确设置 **任务副本数**。 + +- **总副本数** = `Launcher` 副本数 + `Worker` 副本数 +- 本示例中: + + - `Launcher` 副本数:1 + - `Worker` 副本数:2 + - **总副本数** :1 + 2 = 3 + +因此,在任务配置中,您需要将 **任务副本数** 设置为 **3**。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 MPI 任务。 + +## 查看运行结果 + +任务提交成功后,您可以进入 **任务详情** 页面,查看资源的使用情况和任务的运行状态。 +从右上角进入 **工作负载详情**,可以查看运行过程中每个节点的日志输出。 + +**示例输出**: + +```bash +TensorFlow: 1.13 +Model: resnet101 +Mode: training +Batch size: 64 +... + +Total images/sec: 125.67 +``` + +这表示 MPI 任务成功运行,TensorFlow 基准测试程序完成了分布式训练。 + +--- + +## 小结 + +通过本教程,您学习了如何在 AI Lab 平台上创建和运行一个 MPI 任务。我们详细介绍了 MPIJob 的配置方式, +以及如何在任务中指定运行的命令和资源需求。希望本教程对您有所帮助,如有任何问题,请参考平台提供的其他文档或联系技术支持。 + +--- + +**附录** : + +- 如果您的运行环境未预装所需的库(如 `mpi4py`、Horovod 等),请在任务中添加安装命令,或者使用预装了相关依赖的镜像。 +- 在实际应用中,您可以根据需求修改 MPIJob 的配置,例如更改镜像、命令参数、资源请求等。 diff --git a/docs/zh/docs/end-user/baize/jobs/mxnet.md b/docs/zh/docs/end-user/baize/jobs/mxnet.md new file mode 100644 index 0000000..5c6e588 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/mxnet.md @@ -0,0 +1,334 @@ +# MXNet 任务 + +!!! warning + + 由于 Apache MXNet 项目已存档,因此 Kubeflow MXJob 将在未来的 Training Operator 1.9 版本中弃用和删除。 + +Apache MXNet 是一个高性能的深度学习框架,支持多种编程语言。MXNet 任务可以使用多种方式进行训练,包括单机模式和分布式模式。在 AI Lab 中,我们提供了对 MXNet 任务的支持,您可以通过界面化操作,快速创建 MXNet 任务,进行模型训练。 + +本教程将指导您如何在 AI Lab 平台上创建和运行 MXNet 的单机和分布式任务。 + +## 任务配置介绍 + +- **任务类型**:`MXNet`,支持单机和分布式两种模式。 +- **运行环境**:选择包含 MXNet 框架的镜像,或在任务中安装必要的依赖。 + +## 任务运行环境 + +我们使用 `release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest` 镜像作为任务的基础运行环境。该镜像预装了 MXNet 及其相关依赖,支持 GPU 加速。 + +> **注意**:了解如何创建和管理环境,请参考 [环境列表](../dataset/environments.md)。 + +## 创建 MXNet 任务 + +![mxnet](../images/mxnet_job.png) + +### MXNet 单机任务 + +#### 创建步骤 + +1. **登录平台**:登录 AI Lab 平台,点击左侧导航栏中的 **任务中心**,进入 **训练任务** 页面。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:在弹出的窗口中,选择任务类型为 `MXNet`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “MXNet 单机训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据您的需求,配置任务的运行参数、镜像、资源等信息。 + +#### 运行参数 + +- **启动命令**:`python3` +- **命令参数**: + + ```bash + /mxnet/mxnet/example/gluon/mnist/mnist.py --epochs 10 --cuda + ``` + + **说明**: + + - `/mxnet/mxnet/example/gluon/mnist/mnist.py`:MXNet 提供的 MNIST 手写数字识别示例脚本。 + - `--epochs 10`:设置训练轮数为 10。 + - `--cuda`:使用 CUDA 进行 GPU 加速。 + +#### 资源配置 + +- **副本数**:1(单机任务) +- **资源请求**: + - **CPU**:2 核 + - **内存**:4 GiB + - **GPU**:1 块 + +#### 完整的 MXJob 配置示例 + +以下是单机 MXJob 的 YAML 配置: + +```yaml +apiVersion: "kubeflow.org/v1" +kind: "MXJob" +metadata: + name: "mxnet-single-job" +spec: + jobMode: MXTrain + mxReplicaSpecs: + Worker: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + command: ["python3"] + args: + [ + "/mxnet/mxnet/example/gluon/mnist/mnist.py", + "--epochs", + "10", + "--cuda", + ] + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 +``` + +**配置解析**: + +- `apiVersion` 和 `kind`:指定资源的 API 版本和类型,这里是 `MXJob`。 +- `metadata`:元数据,包括任务名称等信息。 +- `spec`:任务的详细配置。 + - `jobMode`:设置为 `MXTrain`,表示训练任务。 + - `mxReplicaSpecs`:MXNet 任务的副本配置。 + - `Worker`:指定工作节点的配置。 + - `replicas`:副本数,这里为 1。 + - `restartPolicy`:重启策略,设为 `Never`,表示任务失败时不重启。 + - `template`:Pod 模板,定义容器的运行环境和资源。 + - `containers`:容器列表。 + - `name`:容器名称。 + - `image`:使用的镜像。 + - `command` 和 `args`:启动命令和参数。 + - `ports`:容器端口配置。 + - `resources`:资源请求和限制。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 MXNet 单机任务。 + +#### 查看运行结果 + +任务提交成功后,您可以进入 **任务详情** 页面,查看资源的使用情况和任务的运行状态。从右上角进入 **工作负载详情**,可以查看运行过程中的日志输出。 + +**示例输出**: + +```bash +Epoch 1: accuracy=0.95 +Epoch 2: accuracy=0.97 +... +Epoch 10: accuracy=0.98 +Training completed. +``` + +这表示 MXNet 单机任务成功运行,模型训练完成。 + +--- + +### MXNet 分布式任务 + +在分布式模式下,MXNet 任务可以使用多台计算节点共同完成训练,提高训练效率。 + +#### 创建步骤 + +1. **登录平台**:同上。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:选择任务类型为 `MXNet`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “MXNet 分布式训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据需求,配置运行参数、镜像、资源等。 + +#### 运行参数 + +- **启动命令**:`python3` +- **命令参数**: + + ```bash + /mxnet/mxnet/example/image-classification/train_mnist.py --num-epochs 10 --num-layers 2 --kv-store dist_device_sync --gpus 0 + ``` + + **说明**: + + - `/mxnet/mxnet/example/image-classification/train_mnist.py`:MXNet 提供的图像分类示例脚本。 + - `--num-epochs 10`:训练轮数为 10。 + - `--num-layers 2`:模型的层数为 2。 + - `--kv-store dist_device_sync`:使用分布式设备同步模式。 + - `--gpus 0`:使用 GPU 进行加速。 + +#### 资源配置 + +- **任务副本数**:3(包括 Scheduler、Server 和 Worker) +- **各角色资源请求**: + - **Scheduler**(调度器): + - **副本数**:1 + - **资源请求**: + - CPU:2 核 + - 内存:4 GiB + - GPU:1 块 + - **Server**(参数服务器): + - **副本数**:1 + - **资源请求**: + - CPU:2 核 + - 内存:4 GiB + - GPU:1 块 + - **Worker**(工作节点): + - **副本数**:1 + - **资源请求**: + - CPU:2 核 + - 内存:4 GiB + - GPU:1 块 + +#### 完整的 MXJob 配置示例 + +以下是分布式 MXJob 的 YAML 配置: + +```yaml +apiVersion: "kubeflow.org/v1" +kind: "MXJob" +metadata: + name: "mxnet-job" +spec: + jobMode: MXTrain + mxReplicaSpecs: + Scheduler: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi + Server: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi + Worker: + replicas: 1 + restartPolicy: Never + template: + spec: + containers: + - name: mxnet + image: release-ci.daocloud.io/baize/kubeflow/mxnet-gpu:latest + command: ["python3"] + args: + [ + "/mxnet/mxnet/example/image-classification/train_mnist.py", + "--num-epochs", + "10", + "--num-layers", + "2", + "--kv-store", + "dist_device_sync", + "--gpus", + "0", + ] + ports: + - containerPort: 9991 + name: mxjob-port + resources: + limits: + cpu: "2" + memory: 4Gi + nvidia.com/gpu: 1 + requests: + cpu: "2" + memory: 4Gi +``` + +**配置解析**: + +- **Scheduler(调度器)**:负责协调集群中各节点的任务调度。 +- **Server(参数服务器)**:用于存储和更新模型参数,实现分布式参数同步。 +- **Worker(工作节点)**:实际执行训练任务。 +- **资源配置**:为各角色分配适当的资源,确保任务顺利运行。 + +#### 设置任务副本数 + +在创建 MXNet 分布式任务时,需要根据 `mxReplicaSpecs` 中配置的副本数,正确设置 **任务副本数**。 + +- **总副本数** = Scheduler 副本数 + Server 副本数 + Worker 副本数 +- 本示例中: + - Scheduler 副本数:1 + - Server 副本数:1 + - Worker 副本数:1 + - **总副本数**:1 + 1 + 1 = 3 + +因此,在任务配置中,需要将 **任务副本数** 设置为 **3**。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 MXNet 分布式任务。 + +#### 查看运行结果 + +进入 **任务详情** 页面,查看任务的运行状态和资源使用情况。您可以查看每个角色(Scheduler、Server、Worker)的日志输出。 + +**示例输出**: + +```bash +INFO:root:Epoch[0] Batch [50] Speed: 1000 samples/sec accuracy=0.85 +INFO:root:Epoch[0] Batch [100] Speed: 1200 samples/sec accuracy=0.87 +... +INFO:root:Epoch[9] Batch [100] Speed: 1300 samples/sec accuracy=0.98 +Training completed. +``` + +这表示 MXNet 分布式任务成功运行,模型训练完成。 + +--- + +## 小结 + +通过本教程,您学习了如何在 AI Lab 平台上创建和运行 MXNet 的单机和分布式任务。我们详细介绍了 MXJob 的配置方式,以及如何在任务中指定运行的命令和资源需求。希望本教程对您有所帮助,如有任何问题,请参考平台提供的其他文档或联系技术支持。 + +--- + +## 附录 + +- **注意事项**: + - 确保您使用的镜像包含所需的 MXNet 版本和依赖。 + - 根据实际需求调整资源配置,避免资源不足或浪费。 + - 如需使用自定义的训练脚本,请修改启动命令和参数。 + +- **参考文档**: + - [MXNet 官方文档](https://mxnet.apache.org/) + - [Kubeflow MXJob 指南](https://v1-8-branch.kubeflow.org/docs/components/training/mxnet/) diff --git a/docs/zh/docs/end-user/baize/jobs/paddle.md b/docs/zh/docs/end-user/baize/jobs/paddle.md new file mode 100644 index 0000000..26a5f22 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/paddle.md @@ -0,0 +1,235 @@ +# PaddlePaddle 任务 + +PaddlePaddle(飞桨)是百度开源的深度学习平台,支持丰富的神经网络模型和分布式训练方式。PaddlePaddle 任务可以通过单机或分布式模式进行训练。在 AI Lab 平台中,我们提供了对 PaddlePaddle 任务的支持,您可以通过界面化操作,快速创建 PaddlePaddle 任务,进行模型训练。 + +本教程将指导您如何在 AI Lab 平台上创建和运行 PaddlePaddle 的单机和分布式任务。 + +## 任务配置介绍 + +- **任务类型**:`PaddlePaddle`,支持单机和分布式两种模式。 +- **运行环境**:选择包含 PaddlePaddle 框架的镜像,或在任务中安装必要的依赖。 + +## 任务运行环境 + +我们使用 `registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-cpu` 镜像作为任务的基础运行环境。该镜像预装了 PaddlePaddle 框架,适用于 CPU 计算。如果需要使用 GPU,请选择对应的 GPU 版本镜像。 + +> **注意**:了解如何创建和管理环境,请参考 [环境列表](../dataset/environments.md)。 + +## 创建 PaddlePaddle 任务 + +![paddle](../images/paddle_job.png) + +### PaddlePaddle 单机训练任务 + +#### 创建步骤 + +1. **登录平台**:登录 AI Lab 平台,点击左侧导航栏中的 **任务中心**,进入 **训练任务** 页面。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:在弹出的窗口中,选择任务类型为 `PaddlePaddle`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “PaddlePaddle 单机训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据您的需求,配置任务的运行参数、镜像、资源等信息。 + +#### 运行参数 + +- **启动命令**:`python` +- **命令参数**: + + ```bash + -m paddle.distributed.launch run_check + ``` + + **说明**: + + - `-m paddle.distributed.launch`:使用 PaddlePaddle 提供的分布式启动模块,即使在单机模式下也可以使用,方便将来迁移到分布式。 + - `run_check`:PaddlePaddle 提供的测试脚本,用于检查分布式环境是否正常。 + +#### 资源配置 + +- **副本数**:1(单机任务) +- **资源请求**: + - **CPU**:根据需求设置,建议至少 1 核 + - **内存**:根据需求设置,建议至少 2 GiB + - **GPU**:如果需要使用 GPU,选择 GPU 版本的镜像,并分配相应的 GPU 资源 + +#### 完整的 PaddleJob 配置示例 + +以下是单机 PaddleJob 的 YAML 配置: + +```yaml +apiVersion: kubeflow.org/v1 +kind: PaddleJob +metadata: + name: paddle-simple-cpu + namespace: kubeflow +spec: + paddleReplicaSpecs: + Worker: + replicas: 1 + restartPolicy: OnFailure + template: + spec: + containers: + - name: paddle + image: registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-cpu + command: + [ + 'python', + '-m', + 'paddle.distributed.launch', + 'run_check', + ] +``` + +**配置解析**: + +- `apiVersion` 和 `kind`:指定资源的 API 版本和类型,这里是 `PaddleJob`。 +- `metadata`:元数据,包括任务名称和命名空间。 +- `spec`:任务的详细配置。 + - `paddleReplicaSpecs`:PaddlePaddle 任务的副本配置。 + - `Worker`:指定工作节点的配置。 + - `replicas`:副本数,这里为 1,表示单机训练。 + - `restartPolicy`:重启策略,设为 `OnFailure`,表示任务失败时自动重启。 + - `template`:Pod 模板,定义容器的运行环境和资源。 + - `containers`:容器列表。 + - `name`:容器名称。 + - `image`:使用的镜像。 + - `command`:启动命令和参数。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 PaddlePaddle 单机任务。 + +#### 查看运行结果 + +任务提交成功后,您可以进入 **任务详情** 页面,查看资源的使用情况和任务的运行状态。从右上角进入 **工作负载详情**,可以查看运行过程中的日志输出。 + +**示例输出**: + +```bash +run check success, PaddlePaddle is installed correctly on this node :) +``` + +这表示 PaddlePaddle 单机任务成功运行,环境配置正常。 + +--- + +### PaddlePaddle 分布式训练任务 + +在分布式模式下,PaddlePaddle 任务可以使用多台计算节点共同完成训练,提高训练效率。 + +#### 创建步骤 + +1. **登录平台**:同上。 +2. **创建任务**:点击右上角的 **创建** 按钮,进入任务创建页面。 +3. **选择任务类型**:选择任务类型为 `PaddlePaddle`,然后点击 **下一步**。 +4. **填写任务信息**:填写任务名称和描述,例如 “PaddlePaddle 分布式训练任务”,然后点击 **确定**。 +5. **配置任务参数**:根据需求,配置运行参数、镜像、资源等。 + +#### 运行参数 + +- **启动命令**:`python` +- **命令参数**: + + ```bash + -m paddle.distributed.launch train.py --epochs=10 + ``` + + **说明**: + + - `-m paddle.distributed.launch`:使用 PaddlePaddle 提供的分布式启动模块。 + - `train.py`:您的训练脚本,需要放在镜像中或挂载到容器内。 + - `--epochs=10`:训练的轮数,这里设置为 10。 + +#### 资源配置 + +- **任务副本数**:根据 `Worker` 副本数设置,这里为 2。 +- **资源请求**: + - **CPU**:根据需求设置,建议至少 1 核 + - **内存**:根据需求设置,建议至少 2 GiB + - **GPU**:如果需要使用 GPU,选择 GPU 版本的镜像,并分配相应的 GPU 资源 + +#### 完整的 PaddleJob 配置示例 + +以下是分布式 PaddleJob 的 YAML 配置: + +```yaml +apiVersion: kubeflow.org/v1 +kind: PaddleJob +metadata: + name: paddle-distributed-job + namespace: kubeflow +spec: + paddleReplicaSpecs: + Worker: + replicas: 2 + restartPolicy: OnFailure + template: + spec: + containers: + - name: paddle + image: registry.baidubce.com/paddlepaddle/paddle:2.4.0rc0-cpu + command: + [ + 'python', + '-m', + 'paddle.distributed.launch', + 'train.py', + ] + args: + - '--epochs=10' +``` + +**配置解析**: + +- `Worker`: + - `replicas`:副本数,设置为 2,表示使用 2 个工作节点进行分布式训练。 + - 其他配置与单机模式类似。 + +#### 设置任务副本数 + +在创建 PaddlePaddle 分布式任务时,需要根据 `paddleReplicaSpecs` 中配置的副本数,正确设置 **任务副本数**。 + +- **总副本数** = `Worker` 副本数 +- 本示例中: + - `Worker` 副本数:2 + - **总副本数**:2 + +因此,在任务配置中,需要将 **任务副本数** 设置为 **2**。 + +#### 提交任务 + +配置完成后,点击 **提交** 按钮,开始运行 PaddlePaddle 分布式任务。 + +#### 查看运行结果 + +进入 **任务详情** 页面,查看任务的运行状态和资源使用情况。您可以查看每个工作节点的日志输出,确认分布式训练是否正常运行。 + +**示例输出**: + +```bash +Worker 0: Epoch 1, Batch 100, Loss 0.5 +Worker 1: Epoch 1, Batch 100, Loss 0.6 +... +Training completed. +``` + +这表示 PaddlePaddle 分布式任务成功运行,模型训练完成。 + +--- + +## 小结 + +通过本教程,您学习了如何在 AI Lab 平台上创建和运行 PaddlePaddle 的单机和分布式任务。我们详细介绍了 PaddleJob 的配置方式,以及如何在任务中指定运行的命令和资源需求。希望本教程对您有所帮助,如有任何问题,请参考平台提供的其他文档或联系技术支持。 + +--- + +## 附录 + +- **注意事项**: + - **训练脚本**:确保 `train.py`(或其他训练脚本)在容器内存在。您可以通过自定义镜像、挂载持久化存储等方式将脚本放入容器。 + - **镜像选择**:根据您的需求选择合适的镜像,例如使用 GPU 时选择 `paddle:2.4.0rc0-gpu` 等。 + - **参数调整**:可以通过修改 `command` 和 `args` 来传递不同的训练参数。 + +- **参考文档**: + - [PaddlePaddle 官方文档](https://www.paddlepaddle.org.cn/documentation/docs/zh/2.6/guides/index_cn.html) + - [Kubeflow PaddleJob 指南](https://www.kubeflow.org/docs/components/training/user-guides/paddle/) diff --git a/docs/zh/docs/end-user/baize/jobs/pytorch.md b/docs/zh/docs/end-user/baize/jobs/pytorch.md new file mode 100644 index 0000000..ff0f113 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/pytorch.md @@ -0,0 +1,227 @@ +# Pytorch 任务 + +Pytorch 是一个开源的深度学习框架,它提供了一个灵活的训练和部署环境。 +Pytorch 任务是一个使用 Pytorch 框架的任务。 + +在 AI Lab 中,我们提供了 Pytorch 任务支持和适配,您可以通过界面化操作, +快速创建 Pytorch 任务,进行模型训练。 + +## 任务配置介绍 + +- 任务类型同时支持 `Pytorch 单机` 和 `Pytorch 分布式` 两种模式。 +- 运行镜像内已经默认支持 Pytorch 框架,无需额外安装。 + +## 任务运行环境 + +在这里我们使用 `baize-notebook` 基础镜像 和 `关联环境` 的方式来作为任务基础运行环境。 + +> 了解如何创建环境,请参考[环境列表](../dataset/environments.md)。 + +## 创建任务 + +### Pytorch 单机任务 + +![Pytorch 单机任务](../images/job05.png) + +1. 登录 AI Lab 平台,点击左侧导航栏中的 **任务中心** ,进入 **训练任务** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Pytorch 单机`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 + +```python +import torch +import torch.nn as nn +import torch.optim as optim + +# 定义一个简单的神经网络 +class SimpleNet(nn.Module): + def __init__(self): + super(SimpleNet, self).__init__() + self.fc = nn.Linear(10, 1) + + def forward(self, x): + return self.fc(x) + +# 创建模型、损失函数和优化器 +model = SimpleNet() +criterion = nn.MSELoss() +optimizer = optim.SGD(model.parameters(), lr=0.01) + +# 生成一些随机数据 +x = torch.randn(100, 10) +y = torch.randn(100, 1) + +# 训练模型 +for epoch in range(100): + # 前向传播 + outputs = model(x) + loss = criterion(outputs, y) + + # 反向传播和优化 + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if (epoch + 1) % 10 == 0: + print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}') + +print('Training finished.') +``` + +#### 运行结果 + +任务提交成功,我们可以进入任务详情查看到资源的使用情况,从右上角去往 **工作负载详情** ,可以查看训练过程中的日志输出 + +```bash +[HAMI-core Warn(1:140244541377408:utils.c:183)]: get default cuda from (null) +[HAMI-core Msg(1:140244541377408:libvgpu.c:855)]: Initialized +Epoch [10/100], Loss: 1.1248 +Epoch [20/100], Loss: 1.0486 +Epoch [30/100], Loss: 0.9969 +Epoch [40/100], Loss: 0.9611 +Epoch [50/100], Loss: 0.9360 +Epoch [60/100], Loss: 0.9182 +Epoch [70/100], Loss: 0.9053 +Epoch [80/100], Loss: 0.8960 +Epoch [90/100], Loss: 0.8891 +Epoch [100/100], Loss: 0.8841 +Training finished. +[HAMI-core Msg(1:140244541377408:multiprocess_memory_limit.c:468)]: Calling exit handler 1 +``` + +### Pytorch 分布式任务 + +1. 登录 AI Lab 平台,点击左侧导航栏中的 **任务中心** ,进入 **任务列表** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Pytorch 分布式`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 + +```python +import os +import torch +import torch.distributed as dist +import torch.nn as nn +import torch.optim as optim +from torch.nn.parallel import DistributedDataParallel as DDP + +class SimpleModel(nn.Module): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = nn.Linear(10, 1) + + def forward(self, x): + return self.fc(x) + +def train(): + # 打印环境信息 + print(f'PyTorch version: {torch.__version__}') + print(f'CUDA available: {torch.cuda.is_available()}') + if torch.cuda.is_available(): + print(f'CUDA version: {torch.version.cuda}') + print(f'CUDA device count: {torch.cuda.device_count()}') + + rank = int(os.environ.get('RANK', '0')) + world_size = int(os.environ.get('WORLD_SIZE', '1')) + + print(f'Rank: {rank}, World Size: {world_size}') + + # 初始化分布式环境 + try: + if world_size > 1: + dist.init_process_group('nccl') + print('Distributed process group initialized successfully') + else: + print('Running in non-distributed mode') + except Exception as e: + print(f'Error initializing process group: {e}') + return + + # 设置设备 + try: + if torch.cuda.is_available(): + device = torch.device(f'cuda:{rank % torch.cuda.device_count()}') + print(f'Using CUDA device: {device}') + else: + device = torch.device('cpu') + print('CUDA not available, using CPU') + except Exception as e: + print(f'Error setting device: {e}') + device = torch.device('cpu') + print('Falling back to CPU') + + try: + model = SimpleModel().to(device) + print('Model moved to device successfully') + except Exception as e: + print(f'Error moving model to device: {e}') + return + + try: + if world_size > 1: + ddp_model = DDP(model, device_ids=[rank % torch.cuda.device_count()] if torch.cuda.is_available() else None) + print('DDP model created successfully') + else: + ddp_model = model + print('Using non-distributed model') + except Exception as e: + print(f'Error creating DDP model: {e}') + return + + loss_fn = nn.MSELoss() + optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) + + # 生成一些随机数据 + try: + data = torch.randn(100, 10, device=device) + labels = torch.randn(100, 1, device=device) + print('Data generated and moved to device successfully') + except Exception as e: + print(f'Error generating or moving data to device: {e}') + return + + for epoch in range(10): + try: + ddp_model.train() + outputs = ddp_model(data) + loss = loss_fn(outputs, labels) + optimizer.zero_grad() + loss.backward() + optimizer.step() + + if rank == 0: + print(f'Epoch {epoch}, Loss: {loss.item():.4f}') + except Exception as e: + print(f'Error during training epoch {epoch}: {e}') + break + + if world_size > 1: + dist.destroy_process_group() + +if __name__ == '__main__': + train() +``` + +#### 任务副本数 + +注意 `Pytorch 分布式` 训练任务会创建一组 `Master` 和 `Worker` 的训练 Pod, +`Master` 负责协调训练任务,`Worker` 负责实际的训练工作。 + +!!! note + + 本次演示中:`Master` 副本数为 1,`Worker` 副本数为 2; + 所以我们需要在 **任务配置** 中设置副本数为 3,即 `Master` 副本数 + `Worker` 副本数。 + Pytorch 会自动调谐 `Master` 和 `Worker` 的角色。 + +#### 运行结果 + +同样,我们可以进入任务详情,查看资源的使用情况,以及每个 Pod 的日志输出。 diff --git a/docs/zh/docs/end-user/baize/jobs/tensorboard.md b/docs/zh/docs/end-user/baize/jobs/tensorboard.md new file mode 100644 index 0000000..604e97a --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/tensorboard.md @@ -0,0 +1,122 @@ +# 任务分析介绍 + +在 AI Lab 模块中,提供了模型开发过程重要的可视化分析工具,用于展示机器学习模型的训练过程和结果。 +本文将介绍 任务分析(Tensorboard)的基本概念、在 AI Lab 系统中的使用方法,以及如何配置数据集的日志内容。 + +!!! note + + Tensorboard 是 TensorFlow 提供的一个可视化工具,用于展示机器学习模型的训练过程和结果。 + 它可以帮助开发者更直观地理解模型的训练动态,分析模型性能,调试模型问题等。 + +![Tensorboard](../images/tensorboard.png) + +Tensorboard 在模型开发过程中的作用及优势: + +- **可视化训练过程**:通过图表展示训练和验证的损失、精度等指标,帮助开发者直观地观察模型的训练效果。 +- **调试和优化模型**:通过查看不同层的权重、梯度分布等,帮助开发者发现和修正模型中的问题。 +- **对比不同实验**:可以同时展示多个实验的结果,方便开发者对比不同模型和超参数配置的效果。 +- **追踪训练数据**:记录训练过程中使用的数据集和参数,确保实验的可复现性。 + +## 如何创建 Tensorboard + +在 AI Lab 系统中,我们提供了便捷的方式来创建和管理 Tensorboard。以下是具体步骤: + +### 在创建时 Notebook 启用 Tensorboard + +1. **创建 Notebook**:在 AI Lab 平台上创建一个新的 Notebook。 +2. **启用 Tensorboard**:在创建 Notebook 的页面中,启用 **Tensorboard** 选项,并指定数据集和日志路径。 + + ![Tensorboard](../images/tensorboard-03.png) + +### 在分布式任务创建及完成后启用 Tensorboard + +1. **创建分布式任务**:在 AI Lab 平台上创建一个新的分布式训练任务。 +2. **配置 Tensorboard**:在任务配置页面中,启用 **Tensorboard** 选项,并指定数据集和日志路径。 +3. **任务完成后查看 Tensorboard**:任务完成后,可以在任务详情页面中查看 Tensorboard 的链接,点击链接即可查看训练过程的可视化结果。 + + ![Tensorboard](../images/tensorboard-02.png) + +### 在 Notebook 中直接引用 Tensorboard + +在 Notebook 中,可以通过代码直接启动 Tensorboard。以下是一个示例代码: + +```python +# 导入必要的库 +import tensorflow as tf +import datetime + +# 定义日志目录 +log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + +# 创建 Tensorboard 回调 +tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1) + +# 构建并编译模型 +model = tf.keras.models.Sequential([ + tf.keras.layers.Flatten(input_shape=(28, 28)), + tf.keras.layers.Dense(512, activation='relu'), + tf.keras.layers.Dropout(0.2), + tf.keras.layers.Dense(10, activation='softmax') +]) + +model.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + +# 训练模型并启用 Tensorboard 回调 +model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test), callbacks=[tensorboard_callback]) +``` + +## 如何配置数据集的日志内容 + +在使用 Tensorboard 时,可以记录和配置不同的数据集和日志内容。以下是一些常见的配置方式: + +### 配置训练和验证数据集的日志 + +在训练模型时,可以通过 TensorFlow 的 `tf.summary` API 来记录训练和验证数据集的日志。以下是一个示例代码: + +```python +# 导入必要的库 +import tensorflow as tf + +# 创建日志目录 +train_log_dir = 'logs/gradient_tape/train' +val_log_dir = 'logs/gradient_tape/val' +train_summary_writer = tf.summary.create_file_writer(train_log_dir) +val_summary_writer = tf.summary.create_file_writer(val_log_dir) + +# 训练模型并记录日志 +for epoch in range(EPOCHS): + for (x_train, y_train) in train_dataset: + # 训练步骤 + train_step(x_train, y_train) + with train_summary_writer.as_default(): + tf.summary.scalar('loss', train_loss.result(), step=epoch) + tf.summary.scalar('accuracy', train_accuracy.result(), step=epoch) + + for (x_val, y_val) in val_dataset: + # 验证步骤 + val_step(x_val, y_val) + with val_summary_writer.as_default(): + tf.summary.scalar('loss', val_loss.result(), step=epoch) + tf.summary.scalar('accuracy', val_accuracy.result(), step=epoch) +``` + +### 配置自定义日志 + +除了训练和验证数据集的日志外,还可以记录其他自定义的日志内容,例如学习率、梯度分布等。以下是一个示例代码: + +```python +# 记录自定义日志 +with train_summary_writer.as_default(): + tf.summary.scalar('learning_rate', learning_rate, step=epoch) + tf.summary.histogram('gradients', gradients, step=epoch) +``` + +## Tensorboard 管理 + +在 AI Lab 中,通过各种方式创建出来的 Tensorboard 会统一展示在任务分析的页面中,方便用户查看和管理。 + +![Tensorboard](../images/tensorboard-01.png) + +用户可以在任务分析页面中查看 Tensorboard 的链接、状态、创建时间等信息,并通过链接直接访问 Tensorboard 的可视化结果。 diff --git a/docs/zh/docs/end-user/baize/jobs/tensorflow.md b/docs/zh/docs/end-user/baize/jobs/tensorflow.md new file mode 100644 index 0000000..e3f1914 --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/tensorflow.md @@ -0,0 +1,160 @@ +# Tensorflow 任务 + +Tensorflow 是除了 Pytorch 另外一个非常活跃的开源的深度学习框架,它提供了一个灵活的训练和部署环境。 + +在 AI Lab 中,我们同样提供了 Tensorflow 框架的支持和适配,您可以通过界面化操作,快速创建 Tensorflow 任务,进行模型训练。 + +## 任务配置介绍 + +- 任务类型同时支持 `Tensorflow 单机` 和 `Tensorflow 分布式` 两种模式。 +- 运行镜像内已经默认支持 Tensorflow 框架,无需额外安装。 + +## 任务运行环境 + +在这里我们使用 `baize-notebook` 基础镜像 和 `关联环境` 的方式来作为任务基础运行环境。 + +> 了解如何创建环境,请参考[环境列表](../dataset/environments.md)。 + +## 创建任务 + +### 示例 TFJob 单机任务 + +![Tensorflow 单机任务](../images/job06.png) + +1. 登录 AI Lab 平台,点击左侧导航栏中的 **任务中心** ,进入 **训练任务** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Tensorflow 单机`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 提前预热代码仓库 + +使用 **AI Lab** -> **数据集列表** ,创建一个数据集,并将远端 Github 的代码拉取到数据集中, +这样在创建任务时,可以直接选择数据集,将代码挂载到任务中。 + +演示代码仓库地址:[https://github.com/d-run/training-sample-code/](https://github.com/d-run/training-sample-code/) + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 `python /code/tensorflow/tf-single.py` + +```python +""" + pip install tensorflow numpy +""" + +import tensorflow as tf +import numpy as np + +# 创建一些随机数据 +x = np.random.rand(100, 1) +y = 2 * x + 1 + np.random.rand(100, 1) * 0.1 + +# 创建一个简单的模型 +model = tf.keras.Sequential([ + tf.keras.layers.Dense(1, input_shape=(1,)) +]) + +# 编译模型 +model.compile(optimizer='adam', loss='mse') + +# 训练模型,将 epochs 改为 10 +history = model.fit(x, y, epochs=10, verbose=1) + +# 打印最终损失 +print('Final loss: {' + str(history.history['loss'][-1]) +'}') + +# 使用模型进行预测 +test_x = np.array([[0.5]]) +prediction = model.predict(test_x) +print(f'Prediction for x=0.5: {prediction[0][0]}') +``` + +#### 运行结果 + +任务提交成功后,可以进入任务详情查看到资源的使用情况,从右上角去往 **工作负载详情** ,可以查看训练过程中的日志输出。 + +### TFJob 分布式任务 + +1. 登录 **AI Lab** ,点击左侧导航栏中的 **任务中心** ,进入 **任务列表** 页面。 +2. 点击右上角的 **创建** 按钮,进入任务创建页面。 +3. 选择任务类型为 `Tensorflow 分布式`,点击 **下一步** 。 +4. 填写任务名称、描述后点击 **确定** 。 + +#### 示例任务介绍 + +![Tensorflow 单机任务](../images/job07.png) + +本次包含了三种角色:`Chief`、`Worker` 和 `Parameter Server (PS)`。 + +- Chief: 主要负责协调训练过程和模型检查点的保存。 +- Worker: 执行实际的模型训练。 +- PS: 在异步训练中用于存储和更新模型参数。 + +为不同的角色分配了不同的资源。`Chief` 和 `Worker` 使用 GPU,而 `PS` 使用 CPU 和较大的内存。 + +#### 运行参数 + +- 启动命令 使用 `bash` +- 命令参数使用 `python /code/tensorflow/tensorflow-distributed.py` + +```python +import os +import json +import tensorflow as tf + +class SimpleModel(tf.keras.Model): + def __init__(self): + super(SimpleModel, self).__init__() + self.fc = tf.keras.layers.Dense(1, input_shape=(10,)) + + def call(self, x): + return self.fc(x) + +def train(): + # 打印环境信息 + print(f"TensorFlow version: {tf.__version__}") + print(f"GPU available: {tf.test.is_gpu_available()}") + if tf.test.is_gpu_available(): + print(f"GPU device count: {len(tf.config.list_physical_devices('GPU'))}") + + # 获取分布式训练信息 + tf_config = json.loads(os.environ.get('TF_CONFIG') or '{}') + task_type = tf_config.get('task', {}).get('type') + task_id = tf_config.get('task', {}).get('index') + + print(f"Task type: {task_type}, Task ID: {task_id}") + + # 设置分布式策略 + strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy() + + with strategy.scope(): + model = SimpleModel() + loss_fn = tf.keras.losses.MeanSquaredError() + optimizer = tf.keras.optimizers.SGD(learning_rate=0.001) + + # 生成一些随机数据 + data = tf.random.normal((100, 10)) + labels = tf.random.normal((100, 1)) + + @tf.function + def train_step(inputs, labels): + with tf.GradientTape() as tape: + predictions = model(inputs) + loss = loss_fn(labels, predictions) + gradients = tape.gradient(loss, model.trainable_variables) + optimizer.apply_gradients(zip(gradients, model.trainable_variables)) + return loss + + for epoch in range(10): + loss = train_step(data, labels) + if task_type == 'chief': + print(f'Epoch {epoch}, Loss: {loss.numpy():.4f}') + +if __name__ == '__main__': + train() +``` + +#### 运行结果 + +同样,我们可以进入任务详情,查看资源的使用情况,以及每个 Pod 的日志输出。 diff --git a/docs/zh/docs/end-user/baize/jobs/view.md b/docs/zh/docs/end-user/baize/jobs/view.md new file mode 100644 index 0000000..d73a82c --- /dev/null +++ b/docs/zh/docs/end-user/baize/jobs/view.md @@ -0,0 +1,207 @@ +# 查看任务(Job)工作负载 + +任务创建好后,都会显示在训练任务列表中。 + +1. 在训练训练任务列表中,点击某个任务右侧的 **┇** -> **任务负载详情** 。 + + ![点击菜单项](../images/view-wl01.png) + +1. 出现一个弹窗选择要查看哪个 Pod 后,点击 **进入** 。 + + ![弹窗进入](../images/view-wl02.png) + +1. 跳转到容器管理界面,可以查看容器的工作状态、标签与注解以及发生的事件。 + + ![查看详情](../images/view-wl03.png) + +1. 你还可以查看当前 Pod 最近一段时间的详细日志。 + 此处默认展示 100 行日志,如果要查看更详细的日志活下载日志,请点击顶部的蓝色 **可观测性** 文字。 + + ![日志](../images/view-wl04.png) + +1. 当然你还可以通过右上角的 **...** ,查看当前 Pod 的 YAML、上传和下载文件。 + 以下是一个 Pod 的 YAML 示例。 + +```yaml +kind: Pod +apiVersion: v1 +metadata: + name: neko-tensorboard-job-test-202404181843-skxivllb-worker-0 + namespace: default + uid: ddedb6ff-c278-47eb-ae1e-0de9b7c62f8c + resourceVersion: '41092552' + creationTimestamp: '2024-04-18T10:43:36Z' + labels: + training.kubeflow.org/job-name: neko-tensorboard-job-test-202404181843-skxivllb + training.kubeflow.org/operator-name: pytorchjob-controller + training.kubeflow.org/replica-index: '0' + training.kubeflow.org/replica-type: worker + annotations: + cni.projectcalico.org/containerID: 0cfbb9af257d5e69027c603c6cb2d3890a17c4ae1a145748d5aef73a10d7fbe1 + cni.projectcalico.org/podIP: '' + cni.projectcalico.org/podIPs: '' + hami.io/bind-phase: success + hami.io/bind-time: '1713437016' + hami.io/vgpu-devices-allocated: GPU-29d5fa0d-935b-2966-aff8-483a174d61d1,NVIDIA,1024,20:; + hami.io/vgpu-devices-to-allocate: ; + hami.io/vgpu-node: worker-a800-1 + hami.io/vgpu-time: '1713437016' + k8s.v1.cni.cncf.io/network-status: |- + [{ + "name": "kube-system/calico", + "ips": [ + "10.233.97.184" + ], + "default": true, + "dns": {} + }] + k8s.v1.cni.cncf.io/networks-status: |- + [{ + "name": "kube-system/calico", + "ips": [ + "10.233.97.184" + ], + "default": true, + "dns": {} + }] + ownerReferences: + - apiVersion: kubeflow.org/v1 + kind: PyTorchJob + name: neko-tensorboard-job-test-202404181843-skxivllb + uid: e5a8b05d-1f03-4717-8e1c-4ec928014b7b + controller: true + blockOwnerDeletion: true +spec: + volumes: + - name: 0-dataset-pytorch-examples + persistentVolumeClaim: + claimName: pytorch-examples + - name: kube-api-access-wh9rh + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + defaultMode: 420 + containers: + - name: pytorch + image: m.daocloud.io/docker.io/pytorch/pytorch + command: + - bash + args: + - '-c' + - >- + ls -la /root && which pip && pip install pytorch_lightning tensorboard + && python /root/Git/pytorch/examples/mnist/main.py + ports: + - name: pytorchjob-port + containerPort: 23456 + protocol: TCP + env: + - name: PYTHONUNBUFFERED + value: '1' + - name: PET_NNODES + value: '1' + resources: + limits: + cpu: '4' + memory: 8Gi + nvidia.com/gpucores: '20' + nvidia.com/gpumem: '1024' + nvidia.com/vgpu: '1' + requests: + cpu: '4' + memory: 8Gi + nvidia.com/gpucores: '20' + nvidia.com/gpumem: '1024' + nvidia.com/vgpu: '1' + volumeMounts: + - name: 0-dataset-pytorch-examples + mountPath: /root/Git/pytorch/examples + - name: kube-api-access-wh9rh + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + restartPolicy: Never + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + nodeName: worker-a800-1 + securityContext: {} + affinity: {} + schedulerName: hami-scheduler + tolerations: + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + priorityClassName: baize-high-priority + priority: 100000 + enableServiceLinks: true + preemptionPolicy: PreemptLowerPriority +status: + phase: Succeeded + conditions: + - type: Initialized + status: 'True' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:43:36Z' + reason: PodCompleted + - type: Ready + status: 'False' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:46:34Z' + reason: PodCompleted + - type: ContainersReady + status: 'False' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:46:34Z' + reason: PodCompleted + - type: PodScheduled + status: 'True' + lastProbeTime: null + lastTransitionTime: '2024-04-18T10:43:36Z' + hostIP: 10.20.100.211 + podIP: 10.233.97.184 + podIPs: + - ip: 10.233.97.184 + startTime: '2024-04-18T10:43:36Z' + containerStatuses: + - name: pytorch + state: + terminated: + exitCode: 0 + reason: Completed + startedAt: '2024-04-18T10:43:39Z' + finishedAt: '2024-04-18T10:46:34Z' + containerID: >- + containerd://09010214bcf3315e81d38fba50de3943c9d2b48f50a6cc2e83f8ef0e5c6eeec1 + lastState: {} + ready: false + restartCount: 0 + image: m.daocloud.io/docker.io/pytorch/pytorch:latest + imageID: >- + m.daocloud.io/docker.io/pytorch/pytorch@sha256:11691e035a3651d25a87116b4f6adc113a27a29d8f5a6a583f8569e0ee5ff897 + containerID: >- + containerd://09010214bcf3315e81d38fba50de3943c9d2b48f50a6cc2e83f8ef0e5c6eeec1 + started: false + qosClass: Guaranteed +``` diff --git a/docs/zh/docs/end-user/ghippo/images/1.png b/docs/zh/docs/end-user/ghippo/images/1.png new file mode 100644 index 0000000..39a59ce Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/1.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/10.png b/docs/zh/docs/end-user/ghippo/images/10.png new file mode 100644 index 0000000..338b014 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/10.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/11.png b/docs/zh/docs/end-user/ghippo/images/11.png new file mode 100644 index 0000000..974a513 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/11.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/12.png b/docs/zh/docs/end-user/ghippo/images/12.png new file mode 100644 index 0000000..11dcdf5 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/12.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/13.png b/docs/zh/docs/end-user/ghippo/images/13.png new file mode 100644 index 0000000..7224083 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/13.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/14.png b/docs/zh/docs/end-user/ghippo/images/14.png new file mode 100644 index 0000000..ce16822 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/14.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/2.png b/docs/zh/docs/end-user/ghippo/images/2.png new file mode 100644 index 0000000..947221b Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/2.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/3.png b/docs/zh/docs/end-user/ghippo/images/3.png new file mode 100644 index 0000000..002d4a2 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/3.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/4.png b/docs/zh/docs/end-user/ghippo/images/4.png new file mode 100644 index 0000000..d1d95f4 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/4.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/5.png b/docs/zh/docs/end-user/ghippo/images/5.png new file mode 100644 index 0000000..b9e64dc Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/5.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/6.png b/docs/zh/docs/end-user/ghippo/images/6.png new file mode 100644 index 0000000..29c39fa Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/6.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/7.png b/docs/zh/docs/end-user/ghippo/images/7.png new file mode 100644 index 0000000..2935252 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/7.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/8.png b/docs/zh/docs/end-user/ghippo/images/8.png new file mode 100644 index 0000000..82a3839 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/8.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/9.png b/docs/zh/docs/end-user/ghippo/images/9.png new file mode 100644 index 0000000..b87c349 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/9.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/about05.png b/docs/zh/docs/end-user/ghippo/images/about05.png new file mode 100644 index 0000000..abb5865 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/about05.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/access.png b/docs/zh/docs/end-user/ghippo/images/access.png new file mode 100644 index 0000000..990f48f Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/access.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/beian.png b/docs/zh/docs/end-user/ghippo/images/beian.png new file mode 100644 index 0000000..c0b882c Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/beian.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/gmagpiereport.png b/docs/zh/docs/end-user/ghippo/images/gmagpiereport.png new file mode 100644 index 0000000..0d2e271 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/gmagpiereport.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/ldap00.png b/docs/zh/docs/end-user/ghippo/images/ldap00.png new file mode 100644 index 0000000..c70395e Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/ldap00.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/ldap01.png b/docs/zh/docs/end-user/ghippo/images/ldap01.png new file mode 100644 index 0000000..4a3d198 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/ldap01.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/logindesign.png b/docs/zh/docs/end-user/ghippo/images/logindesign.png new file mode 100644 index 0000000..c5ee0f0 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/logindesign.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/menu1.png b/docs/zh/docs/end-user/ghippo/images/menu1.png new file mode 100644 index 0000000..87fb42d Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/menu1.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/menu2.png b/docs/zh/docs/end-user/ghippo/images/menu2.png new file mode 100644 index 0000000..6f8ebd4 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/menu2.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/menu3.png b/docs/zh/docs/end-user/ghippo/images/menu3.png new file mode 100644 index 0000000..043fe92 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/menu3.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/menu4.png b/docs/zh/docs/end-user/ghippo/images/menu4.png new file mode 100644 index 0000000..4e4a9a3 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/menu4.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/mybusiness.png b/docs/zh/docs/end-user/ghippo/images/mybusiness.png new file mode 100644 index 0000000..ff2cfd3 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/mybusiness.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/note.svg b/docs/zh/docs/end-user/ghippo/images/note.svg new file mode 100644 index 0000000..5e473ae --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/images/note.svg @@ -0,0 +1,18 @@ + + + + Icon/16/Prompt备份@0.5x + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/end-user/ghippo/images/oauth2.png b/docs/zh/docs/end-user/ghippo/images/oauth2.png new file mode 100644 index 0000000..916499d Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/oauth2.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/oidc-button.png b/docs/zh/docs/end-user/ghippo/images/oidc-button.png new file mode 100644 index 0000000..a45f90e Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/oidc-button.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/oidc02.png b/docs/zh/docs/end-user/ghippo/images/oidc02.png new file mode 100644 index 0000000..8be9dff Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/oidc02.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/password01zh.png b/docs/zh/docs/end-user/ghippo/images/password01zh.png new file mode 100644 index 0000000..696dd14 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/password01zh.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/password02zh.png b/docs/zh/docs/end-user/ghippo/images/password02zh.png new file mode 100644 index 0000000..887ea43 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/password02zh.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/password03zh-en.png b/docs/zh/docs/end-user/ghippo/images/password03zh-en.png new file mode 100644 index 0000000..96ebb54 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/password03zh-en.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/password04zh.png b/docs/zh/docs/end-user/ghippo/images/password04zh.png new file mode 100644 index 0000000..5d3b380 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/password04zh.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/password05zh.png b/docs/zh/docs/end-user/ghippo/images/password05zh.png new file mode 100644 index 0000000..a9acea4 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/password05zh.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/report01.png b/docs/zh/docs/end-user/ghippo/images/report01.png new file mode 100644 index 0000000..b0a1cf1 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/report01.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/security-policy.png b/docs/zh/docs/end-user/ghippo/images/security-policy.png new file mode 100644 index 0000000..375eb0e Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/security-policy.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/selfapplication.png b/docs/zh/docs/end-user/ghippo/images/selfapplication.png new file mode 100644 index 0000000..62cb8ee Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/selfapplication.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/sso2.png b/docs/zh/docs/end-user/ghippo/images/sso2.png new file mode 100644 index 0000000..ff81e45 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/sso2.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/system-message1.png b/docs/zh/docs/end-user/ghippo/images/system-message1.png new file mode 100644 index 0000000..7e1b4b3 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/system-message1.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/system-message2.png b/docs/zh/docs/end-user/ghippo/images/system-message2.png new file mode 100644 index 0000000..3a363e4 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/system-message2.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/system-message3.png b/docs/zh/docs/end-user/ghippo/images/system-message3.png new file mode 100644 index 0000000..146c506 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/system-message3.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/system-message4.png b/docs/zh/docs/end-user/ghippo/images/system-message4.png new file mode 100644 index 0000000..7a0126e Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/system-message4.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/ws01.png b/docs/zh/docs/end-user/ghippo/images/ws01.png new file mode 100644 index 0000000..8691d56 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/ws01.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/wsbind1.png b/docs/zh/docs/end-user/ghippo/images/wsbind1.png new file mode 100644 index 0000000..de5ddb5 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/wsbind1.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/wsbind2.png b/docs/zh/docs/end-user/ghippo/images/wsbind2.png new file mode 100644 index 0000000..26fe126 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/wsbind2.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/wsbind3.png b/docs/zh/docs/end-user/ghippo/images/wsbind3.png new file mode 100644 index 0000000..3f78166 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/wsbind3.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/wsbind4.png b/docs/zh/docs/end-user/ghippo/images/wsbind4.png new file mode 100644 index 0000000..591d786 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/wsbind4.png differ diff --git a/docs/zh/docs/end-user/ghippo/images/wsbind5.png b/docs/zh/docs/end-user/ghippo/images/wsbind5.png new file mode 100644 index 0000000..6b0f556 Binary files /dev/null and b/docs/zh/docs/end-user/ghippo/images/wsbind5.png differ diff --git a/docs/zh/docs/end-user/ghippo/personal-center/accesstoken.md b/docs/zh/docs/end-user/ghippo/personal-center/accesstoken.md new file mode 100644 index 0000000..f14de70 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/personal-center/accesstoken.md @@ -0,0 +1,53 @@ +# 访问密钥 + +访问密钥(Access Key)可用于访问开放 API 和持续发布,用户可在个人中心参照以下步骤获取密钥并访问 API。 + +## 获取密钥 + +登录 AI 算力平台,在右上角的下拉菜单中找到 __个人中心__ ,可以在 __访问密钥__ 页面管理账号的访问密钥。 + +![ak list](../../../images/platform02.png) + +![created a key](../../../images/platform03.png) + +!!! info + + 访问密钥信息仅显示一次。如果您忘记了访问密钥信息,您需要重新创建新的访问密钥。 + +## 使用密钥访问 API + +在访问算丰 AI 算力平台openAPI 时,在请求中加上请求头 `Authorization:Bearer ${token}` 以标识访问者的身份, +其中 `${token}` 是上一步中获取到的密钥,具体接口信息参见 [OpenAPI 接口文档](../../../openapi/index.md)。 + +**请求示例** + +```bash +curl -X GET -H 'Authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRKVjlBTHRBLXZ4MmtQUC1TQnVGS0dCSWc1cnBfdkxiQVVqM2U3RVByWnMiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjE0MTU5NjksImlhdCI6MTY2MDgxMTE2OSwiaXNzIjoiZ2hpcHBvLmlvIiwic3ViIjoiZjdjOGIxZjUtMTc2MS00NjYwLTg2MWQtOWI3MmI0MzJmNGViIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJncm91cHMiOltdfQ.RsUcrAYkQQ7C6BxMOrdD3qbBRUt0VVxynIGeq4wyIgye6R8Ma4cjxG5CbU1WyiHKpvIKJDJbeFQHro2euQyVde3ygA672ozkwLTnx3Tu-_mB1BubvWCBsDdUjIhCQfT39rk6EQozMjb-1X1sbLwzkfzKMls-oxkjagI_RFrYlTVPwT3Oaw-qOyulRSw7Dxd7jb0vINPq84vmlQIsI3UuTZSNO5BCgHpubcWwBss-Aon_DmYA-Et_-QtmPBA3k8E2hzDSzc7eqK0I68P25r9rwQ3DeKwD1dbRyndqWORRnz8TLEXSiCFXdZT2oiMrcJtO188Ph4eLGut1-4PzKhwgrQ' https://demo-dev.daocloud.io/apis/ghippo.io/v1alpha1/users?page=1&pageSize=10 -k +``` + +**请求结果** + +```json +{ + "items": [ + { + "id": "a7cfd010-ebbe-4601-987f-d098d9ef766e", + "name": "a", + "email": "", + "description": "", + "firstname": "", + "lastname": "", + "source": "locale", + "enabled": true, + "createdAt": "1660632794800", + "updatedAt": "0", + "lastLoginAt": "" + } + ], + "pagination": { + "page": 1, + "pageSize": 10, + "total": 1 + } +} +``` diff --git a/docs/zh/docs/end-user/ghippo/personal-center/language.md b/docs/zh/docs/end-user/ghippo/personal-center/language.md new file mode 100644 index 0000000..7e7aca8 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/personal-center/language.md @@ -0,0 +1,31 @@ +--- +hide: + - toc +--- + +# 语言设置 + +本节说明如何设置界面语言。目前支持中文、English 两个语言。 + +语言设置是平台提供多语言服务的入口,平台默认显示为中文,用户可根据需要选择英语或自动检测浏览器语言首选项的方式来切换平台语言。 +每个用户的多语言服务是相互独立的,切换后不会影响其他用户。 + +平台提供三种切换语言方式:中文、英语-English、自动检测您的浏览器语言首选项。 + +操作步骤如下。 + +1. 使用您的用户名/密码登录 AI 算力平台。点击左侧导航栏底部的 __全局管理__ 。 + + ![全局管理](../../../images/ws01_6.png) + +2. 点击右上角的用户名位置,选择 __个人中心__ 。 + + ![个人中心](../../../images/lang01.png) + +3. 点击 __语言设置__ 页签。 + + ![语言设置](../../../images/lang02.png) + +4. 切换语言选项。 + + ![切换语言](../../../images/lang03.png) diff --git a/docs/zh/docs/end-user/ghippo/personal-center/security-setting.md b/docs/zh/docs/end-user/ghippo/personal-center/security-setting.md new file mode 100644 index 0000000..6381009 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/personal-center/security-setting.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 安全设置 + +功能说明:用于填写邮箱地址和修改登录密码。 + +- 邮箱:当管理员配置邮箱服务器地址之后,用户能够通过登录页的忘记密码按钮,填写该处的邮箱地址以找回密码。 +- 密码:用于登录平台的密码,建议定期修改密码。 + +具体操作步骤如下: + +1. 点击右上角的用户名位置,选择 __个人中心__ 。 + + ![个人中心](../../../images/lang01_1.png) + +2. 点击 __安全设置__ 页签。填写您的邮箱地址或修改登录密码。 + + ![安全设置](../../../images/security01.png) diff --git a/docs/zh/docs/end-user/ghippo/personal-center/ssh-key.md b/docs/zh/docs/end-user/ghippo/personal-center/ssh-key.md new file mode 100644 index 0000000..39b665a --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/personal-center/ssh-key.md @@ -0,0 +1,103 @@ +# 配置 SSH 公钥 + +本文说明如何配置 SSH 公钥。 + +## 步骤 1:查看已存在的 SSH 密钥 + +在生成新的 SSH 密钥前,请先确认是否需要使用本地已生成的 SSH 密钥,SSH 密钥对一般存放在本地用户的根目录下。 +Linux、Mac 请直接使用以下命令查看已存在的公钥,Windows 用户在 WSL(需要 Windows 10 或以上)或 Git Bash 下使用以下命令查看已生成的公钥。 + +- **ED25519 算法:** + + ```bash + cat ~/.ssh/id_ed25519.pub + ``` + +- **RSA 算法:** + + ```bash + cat ~/.ssh/id_rsa.pub + ``` + +如果返回一长串以 ssh-ed25519 或 ssh-rsa 开头的字符串,说明已存在本地公钥, +您可以跳过[步骤 2 生成 SSH 密钥](#2-ssh),直接操作[步骤 3](#3)。 + +## 步骤 2:生成 SSH 密钥 + +若[步骤 1](#1-ssh) 未返回指定的内容字符串,表示本地暂无可用 SSH 密钥,需要生成新的 SSH 密钥,请按如下步骤操作: + +1. 访问终端(Windows 请使用 [WSL](https://docs.microsoft.com/zh-cn/windows/wsl/install) 或 [Git Bash](https://gitforwindows.org/)), + 运行 `ssh-keygen -t`。 + +2. 输入密钥算法类型和可选的注释。 + + 注释会出现在 .pub 文件中,一般可使用邮箱作为注释内容。 + + - 基于 `ED25519` 算法,生成密钥对命令如下: + + ```bash + ssh-keygen -t ed25519 -C "<注释内容>" + ``` + + - 基于 `RSA` 算法,生成密钥对命令如下: + + ```bash + ssh-keygen -t rsa -C "<注释内容>" + ``` + +3. 点击回车,选择 SSH 密钥生成路径。 + + 以 ED25519 算法为例,默认路径如下: + + ```console + Generating public/private ed25519 key pair. + Enter file in which to save the key (/home/user/.ssh/id_ed25519): + ``` + + 密钥默认生成路径:`/home/user/.ssh/id_ed25519`,公钥与之对应为:`/home/user/.ssh/id_ed25519.pub`。 + +4. 设置一个密钥口令。 + + ```console + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + ``` + + 口令默认为空,您可以选择使用口令保护私钥文件。 + 如果您不想在每次使用 SSH 协议访问仓库时,都要输入用于保护私钥文件的口令,可以在创建密钥时,输入空口令。 + +5. 点击回车,完成密钥对创建。 + +## 步骤 3:拷贝公钥 + +除了在命令行打印出已生成的公钥信息手动复制外,可以使用命令拷贝公钥到粘贴板下,请参考操作系统使用以下命令进行拷贝。 + +- Windows(在 [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) 或 [Git Bash](https://gitforwindows.org/) 下): + + ```bash + cat ~/.ssh/id_ed25519.pub | clip + ``` + +- Mac: + + ```bash + tr -d '\n'< ~/.ssh/id_ed25519.pub | pbcopy + ``` + +- GNU/Linux (requires xclip): + + ```bash + xclip -sel clip < ~/.ssh/id_ed25519.pub + ``` + +## 步骤 4:在算丰 AI 算力平台上设置公钥 + +1. 登录算丰 AI 算力平台UI 页面,在页面右上角选择 **个人中心** -> **SSH 公钥** 。 + +2. 添加生成的 SSH 公钥信息。 + + 1. SSH 公钥内容。 + + 2. 公钥标题:支持自定义公钥名称,用于区分管理。 + + 3. 过期时间:设置公钥过期时间,到期后公钥将自动失效,不可使用;如果不设置,则永久有效。 diff --git a/docs/zh/docs/end-user/ghippo/workspace/folder-permission.md b/docs/zh/docs/end-user/ghippo/workspace/folder-permission.md new file mode 100644 index 0000000..90a40b0 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/folder-permission.md @@ -0,0 +1,39 @@ +# 文件夹权限说明 + +文件夹具有权限映射能力,能够将用户/用户组在本文件夹的权限映射到其下的子文件夹、工作空间以及资源上。 + +若用户/用户组在本文件夹是 Folder Admin 角色,映射到子文件夹仍为 Folder Admin 角色,映射到其下的工作空间则为 Workspace Admin; +若在 __工作空间与层级__ -> __资源组__ 中绑定了 Namespace,则映射后该用户/用户组同时还是 Namespace Admin。 + +!!! note + + 文件夹的权限映射能力不会作用到共享资源上,因为共享是将集群的使用权限共享给多个工作空间,而不是将管理权限受让给工作空间,因此不会实现权限继承和角色映射。 + +## 应用场景 + +文件夹具有层级能力,因此将文件夹对应于企业中的部门/供应商/项目等层级时, + +- 若用户/用户组在一级部门具有管理权限(Admin),其下的二级、三级、四级部门或项目同样具有管理权限; +- 若用户/用户组在一级部门具有使用权限(Editor),其下的二级、三级、四级部门或项目同样具有使用权限; +- 若用户/用户组在一级部门具有只读权限(Viewer),其下的二级、三级、四级部门或项目同样具有只读权限。 + +| 对象 | 操作 | Folder Admin | Folder Editor | Folder Viewer | +| --------------------------- | -------- | ------------ | ------------- | ------------- | +| 对文件夹本身 | 查看 | ✓ | ✓ | ✓ | +| | 授权 | ✓ | ✗ | ✗ | +| | 修改别名 | ✓ | ✗ | ✗ | +| 对子文件夹 | 创建 | ✓ | ✗ | ✗ | +| | 查看 | ✓ | ✓ | ✓ | +| | 授权 | ✓ | ✗ | ✗ | +| | 修改别名 | ✓ | ✗ | ✗ | +| 对其下的工作空间 | 创建 | ✓ | ✗ | ✗ | +| | 查看 | ✓ | ✓ | ✓ | +| | 授权 | ✓ | ✗ | ✗ | +| | 修改别名 | ✓ | ✗ | ✗ | +| 对其下的工作空间 - 资源组 | 查看 | ✓ | ✓ | ✓ | +| | 资源绑定 | ✓ | ✗ | ✗ | +| | 解除绑定 | ✓ | ✗ | ✗ | +| 对其下的工作空间 - 共享资源 | 查看 | ✓ | ✓ | ✓ | +| | 新增共享 | ✓ | ✗ | ✗ | +| | 解除共享 | ✓ | ✗ | ✗ | +| | 资源限额 | ✓ | ✗ | ✗ | diff --git a/docs/zh/docs/end-user/ghippo/workspace/folders.md b/docs/zh/docs/end-user/ghippo/workspace/folders.md new file mode 100644 index 0000000..78fe786 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/folders.md @@ -0,0 +1,36 @@ +--- +hide: + - toc +--- + +# 创建/删除文件夹 + +文件夹具有权限映射能力,能够将用户/用户组在本文件夹的权限映射到其下的子文件夹、工作空间以及资源上。 + +参照以下步骤创建一个文件夹。 + +1. 使用 admin/folder admin 角色的用户登录 AI 算力平台,点击左侧导航栏底部的 __全局管理__ -> __工作空间与层级__ 。 + + ![全局管理](../../../images/ws01_1.png) + +1. 点击右上角的 __创建文件夹__ 按钮。 + + ![创建文件夹](../../../images/fd02.png) + +1. 填写文件夹名称、上一级文件夹等信息后,点击 __确定__ ,完成创建文件夹。 + + ![确定](../../../images/fd03.png) + +!!! tip + + 创建成功后文件夹名称将显示在左侧的树状结构中,以不同的图标表示工作空间和文件夹。 + + ![工作空间和文件夹](../../../images/ws04_1.png) + +!!! note + + 选中某一个文件夹或文件夹,点击右侧的 __┇__ 可以进行编辑或删除。 + + - 当该文件夹下资源组、共享资源中存在资源时,该文件夹无法被删除,需要将所有资源解绑后再删除。 + + - 当微服务引擎模块在该文件夹下存在接入注册中心资源时,该文件夹无法被删除,需要将所有接入注册中心移除后再删除文件夹。 diff --git a/docs/zh/docs/end-user/ghippo/workspace/quota.md b/docs/zh/docs/end-user/ghippo/workspace/quota.md new file mode 100644 index 0000000..2bc8e0a --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/quota.md @@ -0,0 +1,93 @@ +# 资源配额(Quota) + +共享资源并非意味着被共享者可以无限制地使用被共享的资源。 +Admin、Kpanda Owner 和 Workspace Admin 可以通过共享资源中的 __资源配额__ 功能限制某个用户的最大使用额度。 +若不限制,则表示可以无限制使用。 + +- CPU 请求(Core) +- CPU 限制(Core) +- 内存请求(MB) +- 内存限制(MB) +- 存储请求总量(GB) +- 存储卷声明(个) +- GPU 类型、规格、数量(包括但不限于 Nvidia、Ascend、lluvatar等GPU卡类型) + +一个资源(集群)可以被多个工作空间共享,一个工作空间也可以同时使用多个共享集群中的资源。 + +## 资源组和共享资源 + +共享资源和资源组中的集群资源均来自容器管理,但是集群绑定和共享给同一个工作空间将会产生两种截然不同的效果。 + +1. 绑定资源 + + 使工作空间中的用户/用户组具有该集群的全部管理和使用权限,Workspace Admin 将被映射为 Cluster Admin。 + Workspace Admin 能够进入[容器管理模块](../../../kpanda/permissions/permission-brief.md)管理该集群。 + + ![资源组](../../../images/quota01.png) + + !!! note + + 当前容器管理模块暂无 Cluster Editor 和 Cluster Viewer 角色,因此 Workspace Editor、Workspace Viewer 还无法映射。 + +2. 新增共享资源 + + 使工作空间中的用户/用户组具有该集群资源的使用权限,这些资源可以在创建命名空间(Namespace)时使用。 + + ![共享资源](../../../images/quota02.png) + + 与资源组不同,将集群共享到工作空间时,用户在工作空间的角色不会映射到资源上,因此 Workspace Admin 不会被映射为 Cluster admin。 + +本节展示 3 个与资源配额有关的场景。 + +## 创建命名空间 + +创建命名空间时会涉及到资源配额。 + +1. 在工作空间 ws01 新增一个共享集群。 + + ![新增共享集群](../../../images/quota03.png) + +1. 在应用工作台选择工作空间 ws01 和共享集群,创建命名空间 ns01。 + + ![创建命名空间](../../../images/quota04.png) + + - 若在共享集群中未设置资源配额,则创建命名空间时可不设置资源配额。 + - 若在共享集群中已设置资源配额(例如 CPU 请求 = 100 core),则创建命名空间时 __CPU 请求 ≤ 100 core__ 。 + +## 命名空间绑定到工作空间 + +前提:工作空间 ws01 已新增共享集群,操作者为 Workspace Admin + Kpanda Owner 或 Admin 角色。 + +以下两种绑定方式的效果相同。 + +- 在容器管理中将创建的命名空间 ns01 绑定到 ws01 + + ![绑定到工作空间](../../../images/quota05.png) + + - 若在共享集群未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,均可成功绑定。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,则命名空间 ns01 必须满足 __CPU 请求 ≤ 100 core__ 才能绑定成功。 + +- 在全局管理中,将命名空间 ns01 绑定到 ws01 + + ![绑定到工作空间](../../../images/quota06.png) + + - 若在共享集群未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,均可成功绑定。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,则命名空间 ns01 必须满足 __CPU 请求 ≤ 100 core__ 才能绑定成功。 + +## 从工作空间解绑命名空间 + +以下两种解绑方式的效果相同。 + +- 在容器管理中将命名空间 ns01 从工作空间 ws01 解绑 + + ![绑定到工作空间](../../../images/quota07.png) + + - 若在共享集群中未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,解绑后均不会对资源配额产生影响。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,命名空间 ns01 也设置了资源配额,则解绑后将释放相应的资源额度。 + +- 在全局管理中将命名空间 ns01 从工作空间 ws01 解绑 + + ![绑定到工作空间](../../../images/quota08.png) + + - 若在共享集群未设置资源配额,则命名空间 ns01 无论是否已设置资源配额,解绑后均不会对资源配额产生影响。 + - 若在共享集群已设置资源配额 __CPU 请求 = 100 core__ ,命名空间 ns01 也设置了资源配额,则解绑后将释放相应的资源额度。 diff --git a/docs/zh/docs/end-user/ghippo/workspace/res-gp-and-shared-res.md b/docs/zh/docs/end-user/ghippo/workspace/res-gp-and-shared-res.md new file mode 100644 index 0000000..06e5546 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/res-gp-and-shared-res.md @@ -0,0 +1,30 @@ +# 资源组与共享资源的区别 + +资源组与共享资源均支持绑定集群,但使用上存在很大区别。 + +## 使用场景区别 + +- 资源组绑定集群:资源组绑定集群通常被用来批量授权。资源组绑定集群后, + 工作空间管理员将被映射为集群管理员,能够管理并使用集群资源。 +- 共享资源绑定集群:资源共享绑定集群通常被用来做资源限额。 + 典型的场景是平台管理员将集群分配给一级供应商后,再由一级供应商分配给二级供应商并对二级供应商进行资源限额。 + +![diff](../../../images/res-gp01.png) + +说明:在该场景中,需要平台管理员对二级供应商进行资源限制,暂时还不支持一级供应商限制二级供应商的集群额度。 + +## 集群额度的使用区别 + +- 资源组绑定集群:工作空间的管理员将被映射为该集群的管理员,相当于在容器管理-权限管理中被授予 Cluster Admin 角色, + 能够无限制支配该集群资源,管理节点等重要内容,且资源组不能够被资源限额。 +- 共享资源绑定资源:工作空间管理员仅能够使用集群中的额度在应用工作台创建命名空间,不具备集群的管理权限。 + 若对该工作空间限制额度,则工作空间管理仅能够在额度范围内创建并使用命名空间。 + +## 资源类型的区别 + +- 资源组:能够绑定集群、集群-命名空间、多云、多云-命名空间、网格、网格-命名空间 +- 共享资源:仅能够绑定集群 + +## 资源组与共享资源的相同点 + +在资源组/共享资源绑定集群后都可以前往应用工作台创建命名空间,创建后命名空间将自动绑定到工作空间。 diff --git a/docs/zh/docs/end-user/ghippo/workspace/workspace.md b/docs/zh/docs/end-user/ghippo/workspace/workspace.md new file mode 100644 index 0000000..7f7b991 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/workspace.md @@ -0,0 +1,38 @@ +--- +hide: + - toc +--- + +# 创建/删除工作空间 + +工作空间是一种资源范畴,代表一种资源层级关系。 +工作空间可以包含集群、命名空间、注册中心等资源。 +通常一个工作空间对应一个项目,可以为每个工作空间分配不同的资源,指派不同的用户和用户组。 + +参照以下步骤创建一个工作空间。 + +1. 使用 admin/folder admin 角色的用户登录 AI 算力平台,点击左侧导航栏底部的 __全局管理__ -> __工作空间与层级__ 。 + + ![全局管理](../../../images/ws01.png) + +3. 点击右上角的 __创建工作空间__ 按钮。 + + ![创建工作空间](../../../images/ws02.png) + +4. 填写工作空间名称、所属文件夹等信息后,点击 __确定__ ,完成创建工作空间。 + + ![确定](../../../images/ws03.png) + +!!! tip + + 创建成功后工作空间名称将显示在左侧的树状结构中,以不同的图标表示文件夹和工作空间。 + + ![文件夹与工作空间](../../../images/ws04.png) + +!!! note + + 选中某一个工作空间或文件夹,点击右侧的 __...__ 可以进行编辑或删除。 + + - 当该工作空间下资源组、共享资源中存在资源时,该工作空间无法被删除,需要将所有资源解绑后再删除。 + - 当微服务引擎模块在该工作空间下存在接入注册中心资源时,该工作空间无法被删除,需要将所有接入注册中心移除后再删除工作空间。 + - 当镜像仓库模块在该工作空间下存在镜像空间或集成仓库时,该工作空间无法被删除,需要将镜像空间解绑,将仓库集成删除后再删除工作空间。 diff --git a/docs/zh/docs/end-user/ghippo/workspace/ws-folder.md b/docs/zh/docs/end-user/ghippo/workspace/ws-folder.md new file mode 100644 index 0000000..696924f --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/ws-folder.md @@ -0,0 +1,66 @@ +--- +hide: + - toc +--- + +# 工作空间与层级 + + __工作空间与层级__ 是一个具有层级的资源隔离和资源分组特性,主要解决资源统一授权、资源分组以及资源限额问题。 + +![层级结构](../../../images/fdpractice.png) + + __工作空间与层级__ 有两个概念:工作空间和文件夹。 + +## 工作空间 + +工作空间可通过 __授权__ 、 __资源组__ 和 __共享资源__ 来管理资源,使用户(用户组)之间能够共享工作空间中的资源。 + +![工作空间](../../../images/wsfd01.png) + +- 资源 + + 资源处于资源管理模块层级结构的最低层级,资源包括 Cluster、Namespace、Pipeline、网关等。 + 所有这些资源的父级只能是工作空间,而工作空间作为资源容器是一种资源分组单位。 + +- 工作空间 + + 工作空间通常代指一个项目或环境,每个工作空间的资源相对于其他工作空间中的资源时逻辑隔离的。 + 您可以通过工作空间中的授权,授予用户(用户组)同一组资源的不同访问权限。 + + 从层次结构的底层算起,工作空间位于第一层,且包含资源。 + 除共享资源外,所有资源有且仅有一个父项。所有工作空间也有且仅有一个父级文件夹。 + + 资源通过工作空间进行分组,而工作空间中存在两种分组模式,分别是 __资源组__ 和 __共享资源__ 。 + +- 资源组 + + 一个资源只能加入一个资源组,资源组与工作空间一一对应。 + 资源被加入到资源组后,Workspace Admin 将获得资源的管理权限,相当于该资源的所有者。 + +- 共享资源 + + 而对于共享资源来说,多个工作空间可以共享同一个或者多个资源。 + 资源的所有者,可以选择将自己拥有的资源共享给工作空间使用,一般共享时资源所有者会限制被共享工作空间能够使用的资源额度。 + 资源被共享后,Workspace Admin 仅具有资源限额下的资源使用权限,无法管理资源或者调整工作空间能够使用的资源量。 + + 同时共享资源对于资源本身也具有一定的要求,只有 Cluster(集群)资源可以被共享。 + Cluster Admin 能够将 Cluster 资源分享给不同的工作空间使用,并且限制工作空间在此 Cluster 上的使用额度。 + + Workspace Admin 在资源限额内能够创建多个 Namespace,但是 Namespace 的资源额度总和不能超过 Cluster 在该工作空间的资源限额。 + 对于 Kubernetes 资源,当前能够分享的资源类型仅有 Cluster。 + +## 文件夹 + +文件夹可用于构建企业业务层级关系。 + +- 文件夹是在工作空间基础之上的进一步分组机制,具有层级结构。 + 一个文件夹可以包含工作空间、其他文件夹或两者的组合,能够形成树状的组织关系。 + +- 借助文件夹您可以映射企业业务层级关系,按照部门对工作空间进行分组。 + 文件夹不直接与资源挂钩,而是通过工作空间间接实现资源分组。 + +- 文件夹有且仅有一个父级文件夹,而根文件夹是层次结构的最高层级。 + 根文件夹没有父级,文件夹和工作空间均挂靠到根文件夹下。 + +另外,用户(用户组)在文件夹中能够通过层级结构继承来自父项的权限。 +用户在层次结构中的权限来自当前层级的权限以及继承其父项权限的组合结果,权限之间是加合关系不存在互斥。 diff --git a/docs/zh/docs/end-user/ghippo/workspace/ws-permission.md b/docs/zh/docs/end-user/ghippo/workspace/ws-permission.md new file mode 100644 index 0000000..9ac0a04 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/ws-permission.md @@ -0,0 +1,55 @@ +# 工作空间权限说明 + +工作空间具有权限映射和资源隔离能力,能够将用户/用户组在工作空间的权限映射到其下的资源上。 +若用户/用户组在工作空间是 Workspace Admin 角色,同时工作空间-资源组中绑定了资源 Namespace,则映射后该用户/用户组将成为 Namespace Admin。 + +!!! note + + 工作空间的权限映射能力不会作用到共享资源上,因为共享是将集群的使用权限共享给多个工作空间,而不是将管理权限受让给工作空间,因此不会实现权限继承和角色映射。 + +## 应用场景 + +通过将资源绑定到不同的工作空间能够实现资源隔离。 +因此借助权限映射、资源隔离和共享资源能力能够将资源灵活分配给各个工作空间(租户)。 + +通常适用于以下两个场景: + +- 集群一对一 + + | 普通集群 | 部门/租户(工作空间) | 用途 | + | -------- | ---------------- | -------- | + | 集群 01 | A | 管理和使用 | + | 集群 02 | B | 管理和使用 | + +- 集群一对多 + + | 集群 | 部门/租户(工作空间) | 资源限额 | + | ------- | ---------------- | ---------- | + | 集群 01 | A | 100 核 CPU | + | | B | 50 核 CPU | + +## 权限说明 + +| 操作对象 | 操作 | Workspace Admin | Workspace Editor | Workspace Viewer | +| :------- | :---------------- | :-------------- | :--------------- | :--------------- | +| 本身 | 查看 | ✓ | ✓ | ✓ | +| - | 授权 | ✓ | ✗ | ✗ | +| - | 修改别名 | ✓ | ✓ | ✗ | +| 资源组 | 查看 | ✓ | ✓ | ✓ | +| - | 资源绑定 | ✓ | ✗ | ✗ | +| - | 解除绑定 | ✓ | ✗ | ✗ | +| 共享资源 | 查看 | ✓ | ✓ | ✓ | +| - | 新增共享 | ✓ | ✗ | ✗ | +| - | 解除共享 | ✓ | ✗ | ✗ | +| - | 资源限额 | ✓ | ✗ | ✗ | +| - | 使用共享资源 [^1] | ✓ | ✗ | ✗ | + +[^1]: + 授权用户可前往应用工作台、微服务引擎、中间件、多云编排、服务网格等模块使用工作空间中的资源。 + 有关 Workspace Admin、Workspace Editor、Workspace Viewer 角色在各产品模块的操作范围,请查阅各模块的权限说明: + + - [应用工作台权限说明](../../permissions/amamba.md) + - [服务网格权限说明](../../permissions/mspider.md) + - [中间件权限说明](../../permissions/mcamel.md) + - [微服务引擎权限说明](../../permissions/skoala.md) + - [容器管理权限说明](../../../kpanda/permissions/permission-brief.md) diff --git a/docs/zh/docs/end-user/ghippo/workspace/wsbind-permission.md b/docs/zh/docs/end-user/ghippo/workspace/wsbind-permission.md new file mode 100644 index 0000000..e85e343 --- /dev/null +++ b/docs/zh/docs/end-user/ghippo/workspace/wsbind-permission.md @@ -0,0 +1,36 @@ +# 资源绑定权限说明 + +假如用户小明(“小明”代表任何有资源绑定需求的用户)已经具备了 +Workspace Admin 角色或已通过自定义角色授权, +同时自定义角色中包含[工作空间的“资源绑定”权限](./ws-permission.md#_3),希望将某个集群或者某个命名空间绑定到其所在的工作空间中。 + +要将集群/命名空间资源绑定到工作空间,不仅需要该[工作空间的“资源绑定”权限](./ws-permission.md#_3),还需要 +[Cluster Admin](../../../kpanda/permissions/permission-brief.md#cluster-admin) 的资源权限。 + +## 给小明授权 + +1. 使用平台 Admin 角色, + 在 **工作空间** -> **授权** 页面给小明授予 Workspace Admin 角色。 + + ![资源绑定](../images/wsbind1.png) + +1. 然后在 **容器管理** -> **权限管理** 页面,通过 **添加授权** 将小明授权为 Cluster Admin。 + + ![集群授权1](../images/wsbind2.png) + + ![集群授权2](../images/wsbind3.png) + +## 绑定到工作空间 + +使用小明的账号登录 AI 算力平台,在 **容器管理** -> **集群列表** 页面,通过 **绑定工作空间** 功能, +小明可以将指定集群绑定到自己的工作空间中。 + +!!! note + + 小明能且只能在容器管理模块将集群或者该集群下的命名空间绑定到某个工作空间,无法在全局管理模块完成此操作。 + +![cluster绑定](../images/wsbind4.png) + +绑定命名空间到工作空间也至少需要 Workspace Admin + Cluster Admin 权限。 + +![ns绑定](../images/wsbind5.png) diff --git a/docs/zh/docs/end-user/host/createhost.md b/docs/zh/docs/end-user/host/createhost.md new file mode 100644 index 0000000..5747f91 --- /dev/null +++ b/docs/zh/docs/end-user/host/createhost.md @@ -0,0 +1,41 @@ +# 创建和启动云主机 + +用户完成注册,为其分配了工作空间、命名空间和资源后,即可以创建并启动云主机。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](../register/index.md) +- 管理员为用户绑定了工作空间 +- 管理员为工作空间分配了资源 + +## 操作步骤 + +1. 用户登录 AI 算力平台 +1. 点击 **创建云主机** -> **通过模板创建** + + ![create](../images/host01.png) + +1. 定义的云主机各项配置后点击 **下一步** + + === "基本配置" + + ![basic](../images/host02.png) + + === "模板配置" + + ![template](../images/host03.png) + + === "存储与网络" + + ![storage](../images/host05.png) + +1. 配置 root 密码或 ssh 密钥后点击 **确定** + + ![pass](../images/host06.png) + +1. 返回主机列表,等待状态变为 **运行中** 之后,可以通过右侧的 **┇** 启动主机。 + + ![pass](../images/host07.png) + +下一步:[使用云主机](./usehost.md) diff --git a/docs/zh/docs/end-user/host/usehost.md b/docs/zh/docs/end-user/host/usehost.md new file mode 100644 index 0000000..6513d8d --- /dev/null +++ b/docs/zh/docs/end-user/host/usehost.md @@ -0,0 +1,31 @@ +# 使用云主机 + +创建并启动云主机之后,用户就可以开始使用云主机。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已创建并启动云主机](./createhost.md) + +## 操作步骤 + +1. 以管理员身份登录 AI 算力平台 +1. 导航到 **容器管理** -> **容器网络** -> **服务** ,点击服务的名称,进入服务详情页,在右上角点击 **更新** + + ![service](../images/usehost01.png) + +1. 更改端口范围为 30900-30999,但不能冲突。 + + ![port](../images/usehost02.png) + +1. 以终端用户登录 AI 算力平台,导航到对应的服务,查看访问端口。 + + ![port](../images/usehost03.png) + +1. 在外网使用 SSH 客户端登录云主机 + + ![ssh](../images/usehost04.png) + +1. 至此,你可以在云主机上执行各项操作。 + +下一步:[使用 Notebook](../share/notebook.md) diff --git a/docs/zh/docs/end-user/images/add01.png b/docs/zh/docs/end-user/images/add01.png new file mode 100644 index 0000000..9abedc0 Binary files /dev/null and b/docs/zh/docs/end-user/images/add01.png differ diff --git a/docs/zh/docs/end-user/images/add02.png b/docs/zh/docs/end-user/images/add02.png new file mode 100644 index 0000000..ff6dca8 Binary files /dev/null and b/docs/zh/docs/end-user/images/add02.png differ diff --git a/docs/zh/docs/end-user/images/add03.png b/docs/zh/docs/end-user/images/add03.png new file mode 100644 index 0000000..4e6172f Binary files /dev/null and b/docs/zh/docs/end-user/images/add03.png differ diff --git a/docs/zh/docs/end-user/images/add04.png b/docs/zh/docs/end-user/images/add04.png new file mode 100644 index 0000000..03e968d Binary files /dev/null and b/docs/zh/docs/end-user/images/add04.png differ diff --git a/docs/zh/docs/end-user/images/add05.png b/docs/zh/docs/end-user/images/add05.png new file mode 100644 index 0000000..b5018eb Binary files /dev/null and b/docs/zh/docs/end-user/images/add05.png differ diff --git a/docs/zh/docs/end-user/images/bindws01.png b/docs/zh/docs/end-user/images/bindws01.png new file mode 100644 index 0000000..52c64ac Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws01.png differ diff --git a/docs/zh/docs/end-user/images/bindws02.png b/docs/zh/docs/end-user/images/bindws02.png new file mode 100644 index 0000000..cc53748 Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws02.png differ diff --git a/docs/zh/docs/end-user/images/bindws03.png b/docs/zh/docs/end-user/images/bindws03.png new file mode 100644 index 0000000..78d2bf4 Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws03.png differ diff --git a/docs/zh/docs/end-user/images/bindws04.png b/docs/zh/docs/end-user/images/bindws04.png new file mode 100644 index 0000000..91fc55f Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws04.png differ diff --git a/docs/zh/docs/end-user/images/bindws05.png b/docs/zh/docs/end-user/images/bindws05.png new file mode 100644 index 0000000..a1bbe21 Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws05.png differ diff --git a/docs/zh/docs/end-user/images/bindws06.png b/docs/zh/docs/end-user/images/bindws06.png new file mode 100644 index 0000000..c157644 Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws06.png differ diff --git a/docs/zh/docs/end-user/images/bindws07.png b/docs/zh/docs/end-user/images/bindws07.png new file mode 100644 index 0000000..0239d61 Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws07.png differ diff --git a/docs/zh/docs/end-user/images/bindws08.png b/docs/zh/docs/end-user/images/bindws08.png new file mode 100644 index 0000000..bc5881f Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws08.png differ diff --git a/docs/zh/docs/end-user/images/bindws09.png b/docs/zh/docs/end-user/images/bindws09.png new file mode 100644 index 0000000..ee587b0 Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws09.png differ diff --git a/docs/zh/docs/end-user/images/bindws10.png b/docs/zh/docs/end-user/images/bindws10.png new file mode 100644 index 0000000..1e99f7e Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws10.png differ diff --git a/docs/zh/docs/end-user/images/bindws11.png b/docs/zh/docs/end-user/images/bindws11.png new file mode 100644 index 0000000..53fa67d Binary files /dev/null and b/docs/zh/docs/end-user/images/bindws11.png differ diff --git a/docs/zh/docs/end-user/images/home.png b/docs/zh/docs/end-user/images/home.png new file mode 100644 index 0000000..139dcdf Binary files /dev/null and b/docs/zh/docs/end-user/images/home.png differ diff --git a/docs/zh/docs/end-user/images/host01.png b/docs/zh/docs/end-user/images/host01.png new file mode 100644 index 0000000..692e221 Binary files /dev/null and b/docs/zh/docs/end-user/images/host01.png differ diff --git a/docs/zh/docs/end-user/images/host02.png b/docs/zh/docs/end-user/images/host02.png new file mode 100644 index 0000000..6091415 Binary files /dev/null and b/docs/zh/docs/end-user/images/host02.png differ diff --git a/docs/zh/docs/end-user/images/host03.png b/docs/zh/docs/end-user/images/host03.png new file mode 100644 index 0000000..2eecbed Binary files /dev/null and b/docs/zh/docs/end-user/images/host03.png differ diff --git a/docs/zh/docs/end-user/images/host04.png b/docs/zh/docs/end-user/images/host04.png new file mode 100644 index 0000000..b1d0c2e Binary files /dev/null and b/docs/zh/docs/end-user/images/host04.png differ diff --git a/docs/zh/docs/end-user/images/host05.png b/docs/zh/docs/end-user/images/host05.png new file mode 100644 index 0000000..67806a5 Binary files /dev/null and b/docs/zh/docs/end-user/images/host05.png differ diff --git a/docs/zh/docs/end-user/images/host06.png b/docs/zh/docs/end-user/images/host06.png new file mode 100644 index 0000000..dae145f Binary files /dev/null and b/docs/zh/docs/end-user/images/host06.png differ diff --git a/docs/zh/docs/end-user/images/host07.png b/docs/zh/docs/end-user/images/host07.png new file mode 100644 index 0000000..e94e450 Binary files /dev/null and b/docs/zh/docs/end-user/images/host07.png differ diff --git a/docs/zh/docs/end-user/images/k8s01.png b/docs/zh/docs/end-user/images/k8s01.png new file mode 100644 index 0000000..a06d26a Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s01.png differ diff --git a/docs/zh/docs/end-user/images/k8s02.png b/docs/zh/docs/end-user/images/k8s02.png new file mode 100644 index 0000000..4ae0a2d Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s02.png differ diff --git a/docs/zh/docs/end-user/images/k8s03.png b/docs/zh/docs/end-user/images/k8s03.png new file mode 100644 index 0000000..f6e2fc5 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s03.png differ diff --git a/docs/zh/docs/end-user/images/k8s04.png b/docs/zh/docs/end-user/images/k8s04.png new file mode 100644 index 0000000..579e978 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s04.png differ diff --git a/docs/zh/docs/end-user/images/k8s05.png b/docs/zh/docs/end-user/images/k8s05.png new file mode 100644 index 0000000..54e89ee Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s05.png differ diff --git a/docs/zh/docs/end-user/images/k8s06.png b/docs/zh/docs/end-user/images/k8s06.png new file mode 100644 index 0000000..87a9478 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s06.png differ diff --git a/docs/zh/docs/end-user/images/k8s07.png b/docs/zh/docs/end-user/images/k8s07.png new file mode 100644 index 0000000..512762b Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s07.png differ diff --git a/docs/zh/docs/end-user/images/k8s08.png b/docs/zh/docs/end-user/images/k8s08.png new file mode 100644 index 0000000..8407336 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s08.png differ diff --git a/docs/zh/docs/end-user/images/k8s09.png b/docs/zh/docs/end-user/images/k8s09.png new file mode 100644 index 0000000..a27d8fd Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s09.png differ diff --git a/docs/zh/docs/end-user/images/k8s10.png b/docs/zh/docs/end-user/images/k8s10.png new file mode 100644 index 0000000..d6e5c78 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s10.png differ diff --git a/docs/zh/docs/end-user/images/k8s11.png b/docs/zh/docs/end-user/images/k8s11.png new file mode 100644 index 0000000..0965c31 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s11.png differ diff --git a/docs/zh/docs/end-user/images/k8s12.png b/docs/zh/docs/end-user/images/k8s12.png new file mode 100644 index 0000000..63592d1 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s12.png differ diff --git a/docs/zh/docs/end-user/images/k8s13.png b/docs/zh/docs/end-user/images/k8s13.png new file mode 100644 index 0000000..da71956 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s13.png differ diff --git a/docs/zh/docs/end-user/images/k8s14.png b/docs/zh/docs/end-user/images/k8s14.png new file mode 100644 index 0000000..ef07530 Binary files /dev/null and b/docs/zh/docs/end-user/images/k8s14.png differ diff --git a/docs/zh/docs/end-user/images/notebook01.png b/docs/zh/docs/end-user/images/notebook01.png new file mode 100644 index 0000000..4888a93 Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook01.png differ diff --git a/docs/zh/docs/end-user/images/notebook02.png b/docs/zh/docs/end-user/images/notebook02.png new file mode 100644 index 0000000..79699cb Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook02.png differ diff --git a/docs/zh/docs/end-user/images/notebook03.png b/docs/zh/docs/end-user/images/notebook03.png new file mode 100644 index 0000000..3098322 Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook03.png differ diff --git a/docs/zh/docs/end-user/images/notebook04.png b/docs/zh/docs/end-user/images/notebook04.png new file mode 100644 index 0000000..b34a57e Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook04.png differ diff --git a/docs/zh/docs/end-user/images/notebook05.png b/docs/zh/docs/end-user/images/notebook05.png new file mode 100644 index 0000000..07329e4 Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook05.png differ diff --git a/docs/zh/docs/end-user/images/notebook06.png b/docs/zh/docs/end-user/images/notebook06.png new file mode 100644 index 0000000..50d43ff Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook06.png differ diff --git a/docs/zh/docs/end-user/images/notebook07.png b/docs/zh/docs/end-user/images/notebook07.png new file mode 100644 index 0000000..18c9e6d Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook07.png differ diff --git a/docs/zh/docs/end-user/images/notebook08.png b/docs/zh/docs/end-user/images/notebook08.png new file mode 100644 index 0000000..015c025 Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook08.png differ diff --git a/docs/zh/docs/end-user/images/notebook09.png b/docs/zh/docs/end-user/images/notebook09.png new file mode 100644 index 0000000..bb7fcc5 Binary files /dev/null and b/docs/zh/docs/end-user/images/notebook09.png differ diff --git a/docs/zh/docs/end-user/images/quota01.png b/docs/zh/docs/end-user/images/quota01.png new file mode 100644 index 0000000..389b47d Binary files /dev/null and b/docs/zh/docs/end-user/images/quota01.png differ diff --git a/docs/zh/docs/end-user/images/quota02.png b/docs/zh/docs/end-user/images/quota02.png new file mode 100644 index 0000000..ac37f40 Binary files /dev/null and b/docs/zh/docs/end-user/images/quota02.png differ diff --git a/docs/zh/docs/end-user/images/quota03.png b/docs/zh/docs/end-user/images/quota03.png new file mode 100644 index 0000000..2635d7c Binary files /dev/null and b/docs/zh/docs/end-user/images/quota03.png differ diff --git a/docs/zh/docs/end-user/images/remove01.png b/docs/zh/docs/end-user/images/remove01.png new file mode 100644 index 0000000..f3491b2 Binary files /dev/null and b/docs/zh/docs/end-user/images/remove01.png differ diff --git a/docs/zh/docs/end-user/images/remove02.png b/docs/zh/docs/end-user/images/remove02.png new file mode 100644 index 0000000..8160244 Binary files /dev/null and b/docs/zh/docs/end-user/images/remove02.png differ diff --git a/docs/zh/docs/end-user/images/remove03.png b/docs/zh/docs/end-user/images/remove03.png new file mode 100644 index 0000000..1a80f89 Binary files /dev/null and b/docs/zh/docs/end-user/images/remove03.png differ diff --git a/docs/zh/docs/end-user/images/remove04.png b/docs/zh/docs/end-user/images/remove04.png new file mode 100644 index 0000000..8cf2feb Binary files /dev/null and b/docs/zh/docs/end-user/images/remove04.png differ diff --git a/docs/zh/docs/end-user/images/remove05.png b/docs/zh/docs/end-user/images/remove05.png new file mode 100644 index 0000000..a7b59fa Binary files /dev/null and b/docs/zh/docs/end-user/images/remove05.png differ diff --git a/docs/zh/docs/end-user/images/ssh01.png b/docs/zh/docs/end-user/images/ssh01.png new file mode 100644 index 0000000..7384554 Binary files /dev/null and b/docs/zh/docs/end-user/images/ssh01.png differ diff --git a/docs/zh/docs/end-user/images/ssh02.png b/docs/zh/docs/end-user/images/ssh02.png new file mode 100644 index 0000000..293ceff Binary files /dev/null and b/docs/zh/docs/end-user/images/ssh02.png differ diff --git a/docs/zh/docs/end-user/images/ssh03.png b/docs/zh/docs/end-user/images/ssh03.png new file mode 100644 index 0000000..268c245 Binary files /dev/null and b/docs/zh/docs/end-user/images/ssh03.png differ diff --git a/docs/zh/docs/end-user/images/ssh04.png b/docs/zh/docs/end-user/images/ssh04.png new file mode 100644 index 0000000..2f9ebd9 Binary files /dev/null and b/docs/zh/docs/end-user/images/ssh04.png differ diff --git a/docs/zh/docs/end-user/images/ssh05.png b/docs/zh/docs/end-user/images/ssh05.png new file mode 100644 index 0000000..b34d72a Binary files /dev/null and b/docs/zh/docs/end-user/images/ssh05.png differ diff --git a/docs/zh/docs/end-user/images/usehost01.png b/docs/zh/docs/end-user/images/usehost01.png new file mode 100644 index 0000000..c4a5a39 Binary files /dev/null and b/docs/zh/docs/end-user/images/usehost01.png differ diff --git a/docs/zh/docs/end-user/images/usehost02.png b/docs/zh/docs/end-user/images/usehost02.png new file mode 100644 index 0000000..a8f46c6 Binary files /dev/null and b/docs/zh/docs/end-user/images/usehost02.png differ diff --git a/docs/zh/docs/end-user/images/usehost03.png b/docs/zh/docs/end-user/images/usehost03.png new file mode 100644 index 0000000..cc36100 Binary files /dev/null and b/docs/zh/docs/end-user/images/usehost03.png differ diff --git a/docs/zh/docs/end-user/images/usehost04.png b/docs/zh/docs/end-user/images/usehost04.png new file mode 100644 index 0000000..caa09c2 Binary files /dev/null and b/docs/zh/docs/end-user/images/usehost04.png differ diff --git a/docs/zh/docs/end-user/images/workload01.png b/docs/zh/docs/end-user/images/workload01.png new file mode 100644 index 0000000..1db6174 Binary files /dev/null and b/docs/zh/docs/end-user/images/workload01.png differ diff --git a/docs/zh/docs/end-user/images/workload02.png b/docs/zh/docs/end-user/images/workload02.png new file mode 100644 index 0000000..27ab3af Binary files /dev/null and b/docs/zh/docs/end-user/images/workload02.png differ diff --git a/docs/zh/docs/end-user/images/workload03.png b/docs/zh/docs/end-user/images/workload03.png new file mode 100644 index 0000000..e517c14 Binary files /dev/null and b/docs/zh/docs/end-user/images/workload03.png differ diff --git a/docs/zh/docs/end-user/images/workload04.png b/docs/zh/docs/end-user/images/workload04.png new file mode 100644 index 0000000..5abe7a4 Binary files /dev/null and b/docs/zh/docs/end-user/images/workload04.png differ diff --git a/docs/zh/docs/end-user/images/workload05.png b/docs/zh/docs/end-user/images/workload05.png new file mode 100644 index 0000000..26efad6 Binary files /dev/null and b/docs/zh/docs/end-user/images/workload05.png differ diff --git a/docs/zh/docs/end-user/images/workload06.png b/docs/zh/docs/end-user/images/workload06.png new file mode 100644 index 0000000..9c3bd86 Binary files /dev/null and b/docs/zh/docs/end-user/images/workload06.png differ diff --git a/docs/zh/docs/end-user/images/wsres01.png b/docs/zh/docs/end-user/images/wsres01.png new file mode 100644 index 0000000..779e2e2 Binary files /dev/null and b/docs/zh/docs/end-user/images/wsres01.png differ diff --git a/docs/zh/docs/end-user/images/wsres02.png b/docs/zh/docs/end-user/images/wsres02.png new file mode 100644 index 0000000..bc2094c Binary files /dev/null and b/docs/zh/docs/end-user/images/wsres02.png differ diff --git a/docs/zh/docs/end-user/images/wsres03.png b/docs/zh/docs/end-user/images/wsres03.png new file mode 100644 index 0000000..563cd3a Binary files /dev/null and b/docs/zh/docs/end-user/images/wsres03.png differ diff --git a/docs/zh/docs/end-user/index.md b/docs/zh/docs/end-user/index.md new file mode 100644 index 0000000..d1738f7 --- /dev/null +++ b/docs/zh/docs/end-user/index.md @@ -0,0 +1,72 @@ +--- +hide: + - toc +--- + +# 算丰 AI 算力平台 - 终端用户 + +这是算丰 AI 算力平台面向终端用户的使用文档。 + +
+ +- :fontawesome-solid-user:{ .lg .middle } __用户注册__ + + --- + + 用户注册是使用 AI 算力平台的第一步。 + + - [用户注册](register/index.md) + +- :octicons-fiscal-host-16:{ .lg .middle } __云主机__ + + --- + + 云主机是部署在云端的虚拟机。 + + - [创建云主机](host/createhost.md) + - [使用云主机](host/usehost.md) + +- :simple-kubernetes:{ .lg .middle } __容器管理__ + + --- + + 容器管理是 AI 算力中心的核心模块。 + + - [云上 K8s 集群](./kpanda/clusters/integrate-cluster.md) + - [节点管理](./kpanda/nodes/labels-annotations.md) + - [工作负载](./kpanda/workloads/create-deployment.md) + - [Helm 应用和模板](./kpanda/helm/README.md) + +- :simple-smart:{ .lg .middle } __算法开发__ + + --- + + 管理数据集,执行 AI 训练和推理任务。 + + - [创建 AI 工作负载](./share/workload.md) + - [使用 Notebook](share/notebook.md) + - [创建训练任务](baize/jobs/create.md) + - [创建推理服务](./baize/developer/inference/models.md) + +- :fontawesome-solid-diagram-project:{ .lg .middle } __可观测性__ + + --- + + 通过仪表盘监控集群、节点、工作负载状况。 + + - [监控集群/节点](./insight/infra/cluster.md) + - [指标](./insight/data-query/metric.md) + - [日志](./insight/data-query/log.md) + - [链路追踪](./insight/trace/trace.md) + +- :octicons-gear-16:{ .lg .middle } __个人中心__ + + --- + + 在个人中心设置密码、密钥和语言。 + + - [安全设置](./ghippo/personal-center/security-setting.md) + - [访问密钥](./ghippo/personal-center/accesstoken.md) + - [语言设置](./ghippo/personal-center/language.md) + +
diff --git a/docs/zh/docs/end-user/insight/alert-center/alert-policy.md b/docs/zh/docs/end-user/insight/alert-center/alert-policy.md new file mode 100644 index 0000000..6aee842 --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/alert-policy.md @@ -0,0 +1,128 @@ +# 告警策略 + +告警策略是在可观测性系统中定义的一组规则和条件,用于检测和触发警报,以便在系统出现异常或达到预定的阈值时及时通知相关人员或系统。 + +每条告警策略是一组告警规则的集合,支持对集群、节点、工作负载等资源、日志、事件设置告警规则。当告警对象达到策略下任一规则设定的阈值,则会自动触发告警并发送通知。 + +## 查看告警策略 + +1. 点击一级导航栏进入 __可观测性__。 +2. 左侧导航栏中,选择 __告警中心__ -> __告警策略__。 + + - 集群:单击集群下拉框可切换集群; + - 命名空间:单击命名空间切换下拉框。 + + ![告警策略](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy00.png) + +3. 点击告警策略名称可查看策略的基本信息、规则以及通知配置。 + + 1. 在规则列表中可查看规则类型、规则的表达式、级别、状态等信息。 + 2. 进入策略详情,可以添加、编辑、删除其下的告警规则。 + + ![告警策略](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy06.png) + +## 创建告警策略 + +1. 填写基本信息,选择一个或多个集群、节点或工作负载为告警对象后点击 __下一步__。 + + ![基本信息](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy01.png) + + !!! note + + - 选择`全部集群、节点或工作负载`:创建的告警规则对所有已安装 insight-agent 的集群生效。 + - 选择单个或多个集群集群、节点或工作负载:创建的告警规则仅对所选的资源对象生效。 + - 同时,用户只能对已权限的集群、命名空间设置告警规则。 + +### 手动添加规则 + +1. 在创建告警策略的第二部中,点击列表右上角的`添加规则`。 + + ![添加规则](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/alert-policy04.png) + +2. 在弹窗中创建告警规则,填写各项参数后点击 __确定__。 + + ![创建规则](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy04.png) + + - 模板规则:预定义了基础指标,可以按 CPU、内存、磁盘、网络设定要监控的指标。 + - PromQL 规则:输入一个 PromQL 表达式,具体请[查询 Prometheus 表达式](https://prometheus.io/docs/prometheus/latest/querying/basics/)。 + - 持续时长:告警被触发且持续时间达到该设定值后,告警策略将变为触发中状态。 + - 告警级别:包含紧急、警告、信息三种级别。 + - 高级设置:可以自定义标签和注解。 + + !!! info + + 系统定义了内置标签,若自定义标签与内置标签的`键`值相同,则自定义标签不生效。 + 内置标签有:`severity`、`rule_id`,`source`、`cluster_name`、`group_id`、 `target_type` 和 `target`。 + +#### 创建日志规则 + +完成基本信息的填写后,点击 __添加规则__,规则类型选择 __日志规则__。 + +!!! note + + 仅当资源对象选择节点或工作负载时,支持创建日志规则。 + +![通知配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy10.png) + +**字段说明:** + +- __过滤条件__:查询日志内容的字段,支持与、或、正则匹配、模糊匹配四种过滤条件。 +- __判断条件__:根据 __过滤条件__,输入关键字或匹配条件。 +- __时间范围__:日志查询的时间范围。 +- __阈值条件__:在输入框中输入告警阈值。当达到设置的阈值时,则触发告警。支持的比较运算符有: >、≥、=、≤、<。 +- __告警级别__:选择告警级别,用于表示告警的严重程度。 + +#### 创建事件规则 + +完成基本信息的填写后,点击 __添加规则__,规则类型选择 __事件规则__。 + +!!! note + + 仅当资源对象选择工作负载时,支持创建事件规则。 + +![通知配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy04.png) + +**字段说明:** + +- __事件规则__:仅支持资源对象选择工作负载 +- __事件原因__:不同的工作负载类型的事件原因不同,事件原因之间是“和”的关系。 +- __时间范围__:检测该时间范围内产生数据,若达到设置的阈值条件,则触发告警事件。 +- __阈值条件__:当产生的事件达到设置的阈值时,则触发告警事件。 +- __趋势图__:默认查询 10 分钟内的事件变化趋势,每个点的数值统计的是当前时间点到之前的某段时间(时间范围)内发生的总次数。 + +### 导入规则模板 + +1. 可点击 __模板导入__,选择平台管理员已创建好的告警模板批量导入告警规则。 + + ![告警模板](../images/import-template.png){ width=1000px} + +1. 点击 __下一步__ 后配置通知。 + + ![通知配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/policy05.png) + +2. 配置完成后,点击 __确定__ 按钮,返回告警策略列表。 + +!!! tip + + 新建的告警策略为 __未触发__ 状态。一旦满足规则中的阈值条件和持续时间后,将变为 __触发中__ 状态。 + + +!!! warning + + 删除后的告警策略将完全消失,请谨慎操作。 + +## 通过 YAML 导入告警策略 + +1. 进入告警策略列表,点击 __YAML 创建__。 + + - 集群、命名空间的选择是为了告警策略的管理权限。 + - YAML 编辑器中请填写 __spec__ 及其中的内容,仅支持导入一个 group。 + - __告警规则名称__ 需要符合规范:名称只能包含大小写字母、数字、下划线(_)和连字符(-),必须以字母开头,最长 63 个字符。 + - 必填 __severity__ 且符合规范:critical、warning、info。 + - 必填表达式 __expr__。 + + ![yaml 创建](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/create-from-yaml.png){ width=1000px} + +2. 导入 YAML 文件后,点击 __预览__,可以对导入的 YAML 格式进行验证,并快速确认导入的告警规则。 + + ![yaml 创建](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/create-from-yaml01.png){ width=1000px} diff --git a/docs/zh/docs/end-user/insight/alert-center/alert-template.md b/docs/zh/docs/end-user/insight/alert-center/alert-template.md new file mode 100644 index 0000000..6b9bc0a --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/alert-template.md @@ -0,0 +1,37 @@ +# 告警模板 + +告警模板可支持平台管理员创建告警模板及规则,业务侧可以直接使用告警模板创建告警策略。 +这个功能可以减少业务人员对告警规则的管理,且可以根据环境实际情况自行修改告警阈值。 + +## 创建告警模板 + +1. 左侧导航栏中,选择 **告警中心** -> **告警策略**,单击顶部的 **告警模板** 。 + + ![告警模板](../images/template01.png){ width=1000px} + +2. 点击 **创建告警模板** ,设置告警模板的名称、描述等信息。 + + ![设置名称](../images/template02.png){ width=1000px} + + ![添加规则](../images/template03.png){ width=1000px} + + | 参数 | 说明 | + | ---- | ---- | + | 模板名称 | 名称只能包含小写字母、数字和连字符(-),必须以小写字母或数字开头和结尾,最长 63 个字符。 | + | 描述 | 描述可包含任意字符,最长 256 个字符。| + | 资源类型 | 用于指定告警模板的匹配类型。 | + | 告警规则 | 支持预定义多个告警规则,可添加模板规则、PromQL 规则。 | + +3. 点击 **确定** 完成创建后返回告警模板列表,点击模板名称后可查看模板详情。 + +## 编辑告警模板 + +点击目标规则后的 **┇** ,点击 **编辑**,进入抑制规则的编辑页。 + +![告警模板](../images/template04.png){ width=1000px} + +## 删除告警模板 + +点击目标模板后侧的 **┇** ,点击 **删除**,在输入框中输入告警模板的名称即可删除。 + +![告警模板](../images/template05.png){ width=1000px} diff --git a/docs/zh/docs/end-user/insight/alert-center/index.md b/docs/zh/docs/end-user/insight/alert-center/index.md new file mode 100644 index 0000000..c21138c --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/index.md @@ -0,0 +1,28 @@ +# 告警中心 + +告警中心是 AI 算力平台 提供的一个重要功能,它让用户可以通过图形界面方便地按照集群和命名空间查看所有活动和历史告警, +并根据告警级别(紧急、警告、提示)来搜索告警。 + +![alert list](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/alert00.png) + +所有告警都是基于预设的告警规则设定的阈值条件触发的。在 AI 算力平台中,内置了一些全局告警策略,同时您也可以随时创建、删除告警策略,对以下指标进行设置: + +- CPU 使用量 +- 内存使用量 +- 磁盘使用量 +- 磁盘每秒读次数 +- 磁盘每秒写次数 +- 集群磁盘读取吞吐量 +- 集群磁盘写入吞吐量 +- 网络发送速率 +- 网络接收速率 + +还可以为告警规则添加标签和注解。告警规则分为活跃和过期规则,支持启用/禁用某些规则来实现告警静默。 + +当达到阈值条件后,可以配置告警通知方式,包括邮件、钉钉、企业微信、Webhook 和短信通知。 +所有通知的消息模板都可以自定义,同时还支持按设定的间隔时间发送通知。 + +此外,告警中心还支持通过阿里云、腾讯云等提供的短信服务将告警消息发送给指定用户,实现多种方式的告警通知。 + +AI 算力平台 告警中心是一个功能强大的告警管理平台,可帮助用户及时发现和解决集群中出现的问题, +提高业务稳定性和可用性,便于集群巡检和故障排查。 diff --git a/docs/zh/docs/end-user/insight/alert-center/inhibition.md b/docs/zh/docs/end-user/insight/alert-center/inhibition.md new file mode 100644 index 0000000..67484bc --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/inhibition.md @@ -0,0 +1,67 @@ +# 告警抑制 + +告警抑制主要是对于某些不需要立即关注的告警进行临时隐藏或者降低其优先级的一种机制。这个功能的目的是为了减少不必要的告警信息对运维人员的干扰,使他们能够集中精力处理更重要的问题。 + +告警抑制通过定义一组规则来识别和忽略某些告警,当它们在特定条件下发生时。主要有以下几种情况: + +- 父子关系抑制:当一个父告警(例如某个节点的崩溃)触发时,可以抑制所有由此引起的子告警(例如该节点上运行的容器崩溃)。 +- 相似告警抑制:当多个告警具有相同的特征(例如同一实例上的相同问题)时,可以抑制重复的告警通知。 + +## 创建抑制规则 + +1. 左侧导航栏中,选择 **告警中心** -> **告警降噪**,单击顶部的 **告警抑制** 。 + + ![告警抑制](../images/inhibition01.png){ width=1000px} + +2. 点击 **新建抑制规则** ,设置抑制规则的名称、规则等。 + + !!! note + + 通过[规则标签](#_3)和[告警标签](#_4)定义一组规则来识别和忽略某些告警,达到避免同一问题可能会触发多个相似或相关的告警的问题。 + + ![新建规则](../images/inhibition02.png){ width=1000px} + + | 参数时间 | 说明 | + | ---- | ---- | + | 抑制规则名称 | 抑制规则名称只能包含小写字母、数字和连字符(-),必须以小写字母或数字开头和结尾,最长 63 个字符。 | + | 描述 | 描述可包含任意字符,最长 256 个字符。 | + | 集群 | 该抑制规则作用的集群。 | + | 命名空间 | 该抑制规则作用的命名空间。 | + | 根源告警 | 通过填写的标签条件匹配告警,会将符合所有标签条件的告警与符合抑制条件的进行对比,不符合抑制条件的告警将照常发送消息给用户。

取值范围说明:
- **告警级别**:指标或事件告警的级别,可以设置为:紧急、重要、提示。
- **资源类型**:告警对象所对应的资源类型,可以设置为:集群、节点、无状态负载、有状容负载、守护进程、容器组。
- **标签**:告警标识属性,由标签名和标签值构成,支持用户自定义。 | + | 抑制告警 | 用于指定目标警报(将被抑制的警报)的匹配条件,符合所有标签条件的告警将不会再发送消息给用户。 | + | 匹配标签 | 用于指定应该比较的标签列表,以确定源警报和目标警报是否匹配。只有在 equal 中指定的标签在源和目标警报中的值完全相同的情况下,才会触发抑制。equal 字段是可选的。如果省略 equal 字段,则会将所有标签用于匹配 | + +3. 点击**确定**完成创建后返回告警抑制列表,点击告警抑制名称后可查看抑制规则详情。 + +### 查看规则标签 + +1. 点击右侧导航栏选择 **告警中心** -> **告警策略** ,点击规则所在的策略详情。 +2. 点击目标规则名称,查看规则详情,查看对应告警规则的标签。 + + ![查看规则标签](../images/inhibition.png) + + !!! note + + 在`添加规则`时可添加`自定义标签`。 + +### 查看告警标签 + +1. 点击右侧导航栏选择 **告警中心** -> **告警列表** ,点击告警所在行查看告警详情。 + + ![查看告警标签](../images/inhibition-1.png) + + !!! note + + 告警标签用于描述告警的详细信息和属性,可以用来创建抑制规则。 + +## 编辑抑制规则 + +1. 点击目标规则后侧的 **┇** ,点击 **编辑**,进入抑制规则的编辑页。 + + ![编辑抑制规则](../images/inhibition03.png){ width=1000px} + +## 删除抑制规则 + +点击目标规则后侧的 **┇** ,点击 **删除**,在输入框中输入抑制规则的名称即可删除。 + +![删除抑制规则](../images/inhibition04.png){ width=1000px} diff --git a/docs/zh/docs/end-user/insight/alert-center/message.md b/docs/zh/docs/end-user/insight/alert-center/message.md new file mode 100644 index 0000000..80127ae --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/message.md @@ -0,0 +1,106 @@ +# 通知配置 + +在 __通知配置__ 页面,可以配置通过邮件、企业微信、钉钉、Webhook 和短信等方式向用户发送消息。 + +## 邮件组 + +1. 进入 __可观测性__ 后,在左侧导航栏中点击 __告警中心__ -> __通知配置__,默认位于邮件通知对象。 + + ![邮件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/email00.png) + +2. 点击 __添加邮箱组__,添加一个或多个邮件地址。 + + ![添加邮箱组](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/email01.png) + +3. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,可以编辑或删除邮箱组。 + +## 企业微信 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __企业微信__。 + + ![企业微信](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/wechatbot00.png) + + 有关企业微信群机器人的 URL,请参阅[企业微信官方文档:如何使用群机器人](https://developer.work.weixin.qq.com/document/path/91770)。 + +2. 点击 __添加群机器人__,添加一个或多个群机器人。 + + ![企业微信](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/wechatbot01.png) + +3. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除群机器人。 + +## 钉钉 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __钉钉__,点击 __添加群机器人__,添加一个或多个群机器人。 + + ![钉钉](../images/dingding.png) + + 有关钉钉群机器人的 URL,请参阅[钉钉官方文档:自定义机器人接入](https://open.dingtalk.com/document/robots/custom-robot-access)。 + + !!! note + + 加签的方式是钉钉机器人与开发者双向进行安全认证,若在创建钉钉机器人时开启了加签,则需要在此处输入钉钉生成的密钥。 + 可参考[钉钉自定义机器人安全设置](https://open.dingtalk.com/document/robots/customize-robot-security-settings)。 + +1. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除群机器人。 + +## 飞书 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __飞书__,点击 __添加群机器人__,添加一个或多个群机器人。 + + ![飞书](../images/notify-01.png) + + !!! note + + 当飞书的群机器人开启签名校验时,添加飞书通知时需要填写对应的签名密钥。请查阅 [自定义机器人使用指南](https://open.feishu.cn/document/ukTMukTMukTM/ucTM5YjL3ETO24yNxkjN?lang=zh-CN)。 + +2. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除群机器人。 + +## Webhook + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __Webhook__。 + + ![webhook](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/webhook00.png) + + 有关 Webhook URL 及更多配置方式,请参阅 [webhook 文档](https://github.com/webhooksite/webhook.site)。 + +2. 点击 __新建 Webhook__,添加一个或多个 Webhook。 + + ![alt text](../images/webhook.png) + + `HTTP Headers`:非必填,设置请求头。可以添加多个 Headers。 + + !!! note + + 有关 Webhook URL 及更多配置方式,请参阅 [webhook 文档](https://github.com/webhooksite/webhook.site)。 + +3. 配置完成后自动返回通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__,还可以编辑或删除 Webhook。 + +## 站内信 + +!!! note + + 告警消息发送至用户个人的`站内信`,点击顶部的 🔔 符号可以查看通知消息。 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __站内信__,点击创建。 + + - 站内信通知允许添加多个用户。 + + ![message](../images/notify-02.png) + +2. 配置完成后自动返回 站内信通知列表,点击列表右侧的 __┇__,选择 __发送测试信息__。 + +## 短信组 + +1. 在左侧导航栏中点击 __告警中心__ -> __通知配置__ -> __短信__,点击 __添加短信组__,添加一个或多个短信组。 + + ![messsage](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/notify06.png) + +2. 在弹窗中输入名称、接收短信的对象、手机号以及通知服务器。 + + ![mobile](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/notify07.png) + + 通知服务器需要预先在 __通知配置__ -> __通知服务器__ 中添加创建。目前支持阿里云、腾讯云两种云服务器,具体配置的参数请参阅自己的云服务器信息。 + + ![cloud-notify](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/notify08.png) + +3. 短信组添加成功后,自动返回通知列表,点击列表右侧的 __┇__,可以编辑或删除短信组。 diff --git a/docs/zh/docs/end-user/insight/alert-center/msg-template.md b/docs/zh/docs/end-user/insight/alert-center/msg-template.md new file mode 100644 index 0000000..3ae240c --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/msg-template.md @@ -0,0 +1,49 @@ +# 消息模板 + +可观测性提供自定义消息模板内容的能力,支持邮件、企业微信、钉钉、Webhook、飞书、站内信等不同的通知对象定义不同的消息通知内容。 + +## 创建消息模板 + +1. 在左侧导航栏中,选择 __告警中心__ -> __消息模板__。 + + Insight 默认内置中英文两个模板,以便用户使用。 + + ![点击按钮](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/template00.png) + +2. 点击 __新建消息模板__ 按钮,填写模板内容。 + + ![点击按钮](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/template01.png) + +!!! info + + 可观测性预置了消息模板。若需要定义模板的内容,请参考[配置通知模板](../../reference/notify-helper.md)。 + +## 消息模板详情 + +点击某一消息模板的名称,右侧滑块可查看消息模板的详情。 + +![消息模板](../images/msg-detail.png) + +| 参数 | 变量 | 描述 | +| -- | -- | -- | +| 规则名称 | {{ .Labels.alertname }} | 触发告警的规则名称 | +| 策略名称 | {{ .Labels.alertgroup }} | 触发告警规则所属的告警策略名称 | +| 告警级别 | {{ .Labels.severity }} | 触发告警的级别 | +| 集群 | {{ .Labels.cluster }} | 触发告警的资源所在的集群 | +| 命名空间 | {{ .Labels.namespace }} | 触发告警的资源所在的命名空间 | +| 节点 | {{ .Labels.node }} | 触发告警的资源所在的节点 | +| 资源类型 | {{ .Labels.target_type }} | 告警对象的资源类型 | +| 资源名称 | {{ .Labels.target }} | 触发告警的对象名称 | +| 触发值 | {{ .Annotations.value }} | 触发告警通知时的指标值 | +| 发生时间 | {{ .StartsAt }} | 告警开始发生的时间 | +| 结束时间 | {{ .EndsAT }} | 告警结束的时间 | +| 描述 | {{ .Annotations.description }} | 告警的详细描述 | +| 标签 | {{ for .labels}} {{end}} | 告警的所有标签,使用 for 函数遍历 labels 列表,获取告警的所有标签内容。 | + +## 编辑或删除消息模板 + +在列表右侧点击 __┇__,在弹出菜单中选择 __编辑__ 或 __删除__,可以修改或删除消息模板。 + +!!! warning + + 请注意,删除模板后无法恢复,请谨慎操作。 diff --git a/docs/zh/docs/end-user/insight/alert-center/silent.md b/docs/zh/docs/end-user/insight/alert-center/silent.md new file mode 100644 index 0000000..740d901 --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/silent.md @@ -0,0 +1,20 @@ +# 告警静默 + +告警静默是指在特定的时间范围内,根据定义好的规则对符合条件的告警不再发送告警通知。该功能可以帮助运维人员避免在某些操作或事件期间接收到过多的噪声告警,同时便于更加精确地处理真正需要解决的问题。 + +在告警静默页面上,用户可以看到两个页签:活跃规则和过期规则。 +其中,活跃规则表示目前正在生效的规则,而过期规则则是以前定义过但已经过期(或者用户主动删除)的规则。 + +## 操作步骤 + +1. 在左侧导航栏中,选择 __告警中心__ -> __告警静默__ ,点击 __新建静默规则__ 按钮。 + + ![点击按钮](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/silence00.png) + +2. 填写静默规则的各项参数,如集群、命名空间、标签、时间等,以定义这条规则的作用范围和生效时间。 + + ![静默规则](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/silence01.png) + +3. 返回规则列表,在列表右侧点击 __┇__ ,可以编辑或删除静默规则。 + +通过告警静默功能,您可以灵活地控制哪些告警需要被忽略,在什么时间段内生效,从而提高运维效率,减少误报的可能性。 diff --git a/docs/zh/docs/end-user/insight/alert-center/sms-provider.md b/docs/zh/docs/end-user/insight/alert-center/sms-provider.md new file mode 100644 index 0000000..68981f7 --- /dev/null +++ b/docs/zh/docs/end-user/insight/alert-center/sms-provider.md @@ -0,0 +1,52 @@ +# 配置通知服务器 + +可观测性 Insight 支持短信通知,目前通过集成阿里云、腾讯云的短信服务发送告警消息。本文介绍了如何在 insight 中配置短信通知的服务器。短信签名中支持的变量为消息模板中的默认变量,同时由于短信字数有限,建议选择较为明确的变量。 + +> 如何配置短信接收人可参考文档:[配置短信通知组](./message.md)。 + +## 操作步骤 + +1. 进入 __告警中心__ -> __通知配置__ -> __通知服务器__ 。 + + ![通知服务器](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/smsserver00.png) + +2. 点击 __添加通知服务器__ 。 + + 1. 配置阿里云服务器。 + + > 申请阿里云短信服务,请参考[阿里云短信服务](https://help.aliyun.com/document_detail/108062.html?spm=a2c4g.57535.0.0.2cec637ffna8ye)。 + + **字段说明:** + + - __AccessKey ID__ :阿里云用于标识用户的参数。 + - __AccessKey Secret__ :阿里云用于验证用户的密钥。AccessKey Secret 必须保密。 + - __短信签名__ :短信服务支持根据用户需求创建符合要求的签名。发送短信时,短信平台会将已审核通过的短信签名添加到短信内容中,再发送给短信接收方。 + - __模板 CODE__ :短信模板是发送短信的具体内容。 + - __参数模板__ :短信正文模板可以包含变量,用户可通过变量实现自定义短信内容。 + + 请参考[阿里云变量规范](https://help.aliyun.com/document_detail/463270.html)。 + + ![通知服务器](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sms02.png) + + !!! note + + 举例:在阿里云定义的模板内容为:${severity}:${alertname} 在 ${startat} 被触发。参数模板中的配置参考上图。 + + 2. 配置腾讯云服务器。 + + > 申请腾讯云短信服务,请参考[腾讯云短信](https://cloud.tencent.com/document/product/382/37794)。 + + 字段说明: + + - __Secret ID__ :腾讯云用于标识 API 调用者身份参数。 + - __SecretKey__ :腾讯云用于验证 API 调用者的身份的参数。 + - __短信模板 ID__ :短信模板 ID,由腾讯云系统自动生成。 + - __签名内容__ :短信签名内容,即在腾讯云短信签名中定义的实际网站名的全称或简称。 + - __SdkAppId__ :短信 SdkAppId,在腾讯云短信控制台添加应用后生成的实际 SdkAppId。 + - __参数模板__ :短信正文模板可以包含变量,用户可通过变量实现自定义短信内容。请参考:[腾讯云变量规范](https://cloud.tencent.com/document/product/382/39023#.E5.8F.98.E9.87.8F.E8.A7.84.E8.8C.83.3Ca-id.3D.22variable.22.3E.3C.2Fa.3E)。 + + ![通知服务器](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/sms03.png) + + !!! note + + 举例:在腾讯云定义的模板内容为:{1}:{2} 在 {3} 被触发。参数模板中的配置参考上图。 diff --git a/docs/zh/docs/end-user/insight/collection-manag/agent-status.md b/docs/zh/docs/end-user/insight/collection-manag/agent-status.md new file mode 100644 index 0000000..9f74d17 --- /dev/null +++ b/docs/zh/docs/end-user/insight/collection-manag/agent-status.md @@ -0,0 +1,36 @@ +# insight-agent 组件状态说明 + +在 AI 算力平台中可观测性 Insight 作为多集群观测产品,为了实现多集群观测数据的统一采集,需要用户安装 Helm 应用 __insight-agent__ +(默认安装在 insight-system 命名空间)。参阅[如何安装 __insight-agent__ ](../quickstart/install/install-agent.md)。 + +## 状态说明 + +在 __可观测性__ -> __采集管理__ 部分可查看各集群安装 __insight-agent__ 的情况。 + +- __未安装__ :该集群中未在 insight-system 命名空间下安装 __insight-agent__ +- __运行中__ :该集群中成功安装 __insight-agent__ ,且部署的所有组件均处于运行中状态 +- __异常__ :若 insight-agent 处于此状态,说明 helm 部署失败或存在部署的组件处于非运行中状态 + +可通过以下方式排查: + +1. 执行以下命令,若状态为 __deployed__ ,则执行下一步。若为 __failed__ ,由于会影响应用的升级,建议在 __容器管理 -> helm 应用__ 卸载后重新安装 : + + ```bash + helm list -n insight-system + ``` + +2. 执行以下命令或在 __可观测性 -> 采集管理__ 中查看该集群部署的组件的状态,若存在非 __运行中__ 状态的容器组,请重启异常的容器组。 + + ```bash + kubectl get pods -n insight-system + ``` + +## 补充说明 + +1. __insight-agent__ 中指标采集组件 Prometheus 的资源消耗与集群中运行的容器组数量存在正比关系, + 请根据集群规模调整 Prometheus 的资源,请参考:[Prometheus 资源规划](../quickstart/res-plan/prometheus-res.md) + +2. 由于全局服务集群中指标存储组件 vmstorage 的存储容量与各个集群容器组数量总和存在正比关系。 + + - 请联系平台管理员根据集群规模调整 vmstorage 的磁盘容量,参阅 [vmstorage 磁盘容量规划](../quickstart/res-plan/vms-res-plan.md) + - 根据多集群规模调整 vmstorage 磁盘,参阅 [vmstorge 磁盘扩容](../quickstart/res-plan/modify-vms-disk.md) diff --git a/docs/zh/docs/end-user/insight/collection-manag/collection-manag.md b/docs/zh/docs/end-user/insight/collection-manag/collection-manag.md new file mode 100644 index 0000000..f2994db --- /dev/null +++ b/docs/zh/docs/end-user/insight/collection-manag/collection-manag.md @@ -0,0 +1,26 @@ +--- +hide: + - toc +--- + +# 采集管理 + + __采集管理__ 主要是集中管理、展示集群安装采集插件 __insight-agent__ 的入口,帮助用户快速的查看集群采集插件的健康状态,并提供了快捷入口配置采集规则。 + +具体操作步骤如下: + +1. 点击左上角的,选择 __可观测性__ 。 + + ![一级导航](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/collectmanage01.png){ width="1000"} + +2. 选择左侧导航栏的 __采集管理__ ,查看全部集群采集插件的状态。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/collect00.png){ width="1000"} + +3. 集群接入 __insight-agent__ 且处于运行中状态时,点击某个集群名称进入详情。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/collect01.png){ width="1000"} + +4. 在 __服务监控__ 页签中,点击快捷链接跳转到 __容器管理__ -> __自定义资源__ 添加服务发现规则。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/collect02.png){ width="1000"} diff --git a/docs/zh/docs/end-user/insight/collection-manag/metric-collect.md b/docs/zh/docs/end-user/insight/collection-manag/metric-collect.md new file mode 100644 index 0000000..0fd8003 --- /dev/null +++ b/docs/zh/docs/end-user/insight/collection-manag/metric-collect.md @@ -0,0 +1,341 @@ +# 指标抓取方式 + +Prometheus 主要通过 Pull 的方式来抓取目标服务暴露出来的监控接口,因此需要配置对应的抓取任务来请求监控数据并写入到 Prometheus 提供的存储中,目前 Prometheus 服务提供了如下几个任务的配置: + +- 原生 Job 配置:提供 Prometheus 原生抓取 Job 的配置。 +- Pod Monitor:在 K8S 生态下,基于 Prometheus Operator 来抓取 Pod 上对应的监控数据。 +- Service Monitor:在 K8S 生态下,基于 Prometheus Operator 来抓取 Service 对应 Endpoints 上的监控数据。 + +!!! note + + `[ ]` 中的配置项为可选。 + +## 原生 Job 配置 + +相应配置项说明如下: + +```yaml +# 抓取任务名称,同时会在对应抓取的指标中加了一个 label(job=job_name) +job_name: + +# 抓取任务时间间隔 +[ scrape_interval: | default = ] + +# 抓取请求超时时间 +[ scrape_timeout: | default = ] + +# 抓取任务请求 URI 路径 +[ metrics_path: | default = /metrics ] + +# 解决当抓取的 label 与后端 Prometheus 添加 label 冲突时的处理。 +# true: 保留抓取到的 label,忽略与后端 Prometheus 冲突的 label; +# false: 对冲突的 label,把抓取的 label 前加上 exported_,添加后端 Prometheus 增加的 label; +[ honor_labels: | default = false ] + +# 是否使用抓取到 target 上产生的时间。 +# true: 如果 target 中有时间,使用 target 上的时间; +# false: 直接忽略 target 上的时间; +[ honor_timestamps: | default = true ] + +# 抓取协议: http 或者 https +[ scheme: | default = http ] + +# 抓取请求对应 URL 参数 +params: + [ : [, ...] ] + +# 通过 basic auth 设置抓取请求头中 `Authorization` 的值,password/password_file 互斥,优先取 password_file 里面的值。 +basic_auth: + [ username: ] + [ password: ] + [ password_file: ] + +# 通过 bearer token 设置抓取请求头中 `Authorization` bearer_token/bearer_token_file 互斥,优先取 bearer_token 里面的值。 +[ bearer_token: ] + +# 通过 bearer token 设置抓取请求头中 `Authorization` bearer_token/bearer_token_file 互斥,优先取 bearer_token 里面的值。 +[ bearer_token_file: ] + +# 抓取连接是否通过 TLS 安全通道,配置对应的 TLS 参数 +tls_config: + [ ] + +# 通过代理服务来抓取 target 上的指标,填写对应的代理服务地址。 +[ proxy_url: ] + +# 通过静态配置来指定 target,详见下面的说明。 +static_configs: + [ - ... ] + +# CVM 服务发现配置,详见下面的说明。 +cvm_sd_configs: + [ - ... ] + +# 在抓取数据之后,把 target 上对应的 label 通过 relabel 的机制进行改写,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明。 +relabel_configs: + [ - ... ] + +# 数据抓取完成写入之前,通过 relabel 机制进行改写 label 对应的值,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明。 +metric_relabel_configs: + [ - ... ] + +# 一次抓取数据点限制,0:不作限制,默认为 0 +[ sample_limit: | default = 0 ] + +# 一次抓取 Target 限制,0:不作限制,默认为 0 +[ target_limit: | default = 0 ] +``` + +## Pod Monitor + +相应配置项说明如下: + +```yaml +# Prometheus Operator CRD 版本 +apiVersion: monitoring.coreos.com/v1 +# 对应 K8S 的资源类型,这里面 Pod Monitor +kind: PodMonitor +# 对应 K8S 的 Metadata,这里只用关心 name,如果没有指定 jobLabel,对应抓取指标 label 中 job 的值为 / +metadata: + name: redis-exporter # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不需要修改 +# 描述抓取目标 Pod 的选取及抓取任务的配置 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识 +spec: + # 填写对应 Pod 的 label,pod monitor 会取对应的值作为 job label 的值。 + # 如果查看的是 Pod Yaml,取 pod.metadata.labels 中的值。 + # 如果查看的是 Deployment/Daemonset/Statefulset,取 spec.template.metadata.labels。 + [ jobLabel: string ] + # 把对应 Pod 上的 Label 添加到 Target 的 Label 中 + [ podTargetLabels: []string ] + # 一次抓取数据点限制,0:不作限制,默认为 0 + [ sampleLimit: uint64 ] + # 一次抓取 Target 限制,0:不作限制,默认为 0 + [ targetLimit: uint64 ] + # 配置需要抓取暴露的 Prometheus HTTP 接口,可以配置多个 Endpoint + podMetricsEndpoints: + [ - ... ] # 详见下面 endpoint 说明 + # 选择要监控 Pod 所在的 namespace,不填为选取所有 namespace + [ namespaceSelector: ] + # 是否选取所有 namespace + [ any: bool ] + # 需要选取 namespace 列表 + [ matchNames: []string ] + # 填写要监控 Pod 的 Label 值,以定位目标 Pod [K8S metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#labelselector-v1-meta) + selector: + [ matchExpressions: array ] + [ example: - {key: tier, operator: In, values: [cache]} ] + [ matchLabels: object ] + [ example: k8s-app: redis-exporter ] +``` + +### 举例 1 + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: redis-exporter # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不要修改 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识,必填。 +spec: + podMetricsEndpoints: + - interval: 30s + port: metric-port # 填写 pod yaml 中 Prometheus Exporter 对应的 Port 的 Name + path: /metrics # 填写 Prometheus Exporter 对应的 Path 的值,不填默认 /metrics + relabelings: + - action: replace + sourceLabels: + - instance + regex: (.*) + targetLabel: instance + replacement: "crs-xxxxxx" # 调整成对应的 Redis 实例 ID + - action: replace + sourceLabels: + - instance + regex: (.*) + targetLabel: ip + replacement: "1.x.x.x" # 调整成对应的 Redis 实例 IP + namespaceSelector: # 选择要监控 Pod 所在的 namespace + matchNames: + - redis-test + selector: # 填写要监控 Pod 的 Label 值,以定位目标 pod + matchLabels: + k8s-app: redis-exporter +``` + +### 举例 2 + +```yaml +job_name: prometheus +scrape_interval: 30s +static_configs: +- targets: + - 127.0.0.1:9090 +``` + +## Service Monitor + +相应配置项说明如下: + +```yaml +# Prometheus Operator CRD 版本 +apiVersion: monitoring.coreos.com/v1 +# 对应 K8S 的资源类型,这里面 Service Monitor +kind: ServiceMonitor +# 对应 K8S 的 Metadata,这里只用关心 name,如果没有指定 jobLabel,对应抓取指标 label 中 job 的值为 Service 的名称。 +metadata: + name: redis-exporter # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不需要修改 +# 描述抓取目标 Pod 的选取及抓取任务的配置 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识,必填。 +spec: + # 填写对应 Pod 的 label(metadata/labels),service monitor 会取对应的值作为 job label 的值 + [ jobLabel: string ] + # 把对应 service 上的 Label 添加到 Target 的 Label 中 + [ targetLabels: []string ] + # 把对应 Pod 上的 Label 添加到 Target 的 Label 中 + [ podTargetLabels: []string ] + # 一次抓取数据点限制,0:不作限制,默认为 0 + [ sampleLimit: uint64 ] + # 一次抓取 Target 限制,0:不作限制,默认为 0 + [ targetLimit: uint64 ] + # 配置需要抓取暴露的 Prometheus HTTP 接口,可以配置多个 Endpoint + endpoints: + [ - ... ] # 详见下面 endpoint 说明 + # 选择要监控 Pod 所在的 namespace,不填为选取所有 namespace + [ namespaceSelector: ] + # 是否选取所有 namespace + [ any: bool ] + # 需要选取 namespace 列表 + [ matchNames: []string ] + # 填写要监控 Pod 的 Label 值,以定位目标 Pod [K8S metav1.LabelSelector](https://v1-17.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) + selector: + [ matchExpressions: array ] + [ example: - {key: tier, operator: In, values: [cache]} ] + [ matchLabels: object ] + [ example: k8s-app: redis-exporter ] +``` + +### 举例 + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: go-demo # 填写一个唯一名称 + namespace: cm-prometheus # namespace 固定,不要修改 + label: + operator.insight.io/managed-by: insight # Insight 管理的标签标识,必填。 +spec: + endpoints: + - interval: 30s + # 填写 service yaml 中 Prometheus Exporter 对应的 Port 的 Name + port: 8080-8080-tcp + # 填写 Prometheus Exporter 对应的 Path 的值,不填默认 /metrics + path: /metrics + relabelings: + # ** 必须要有一个 label 为 application,这里假设 k8s 有一个 label 为 app, + # 我们通过 relabel 的 replace 动作把它替换成了 application + - action: replace + sourceLabels: [__meta_kubernetes_pod_label_app] + targetLabel: application + # 选择要监控 service 所在的 namespace + namespaceSelector: + matchNames: + - golang-demo + # 填写要监控 service 的 Label 值,以定位目标 service + selector: + matchLabels: + app: golang-app-demo +``` + +### endpoint_config + +相应配置项说明如下: + +```yaml +# 对应 port 的名称,这里需要注意不是对应的端口,默认:80,对应的取值如下: +# ServiceMonitor: 对应 Service>spec/ports/name; +# PodMonitor: 说明如下: +# 如果查看的是 Pod Yaml,取 pod.spec.containers.ports.name 中的值。 +# 如果查看的是 Deployment/Daemonset/Statefulset,取值 spec.template.spec.containers.ports.name +[ port: string | default = 80] +# 抓取任务请求 URI 路径 +[ path: string | default = /metrics ] +# 抓取协议: http 或者 https +[ scheme: string | default = http] +# 抓取请求对应 URL 参数 +[ params: map[string][]string] +# 抓取任务间隔的时间 +[ interval: string | default = 30s ] +# 抓取任务超时 +[ scrapeTimeout: string | default = 30s] +# 抓取连接是否通过 TLS 安全通道,配置对应的 TLS 参数 +[ tlsConfig: TLSConfig ] +# 通过对应的文件读取 bearer token 对应的值,放到抓取任务的 header 中 +[ bearerTokenFile: string ] +# 通过对应的 K8S secret key 读取对应的 bearer token,注意 secret namespace 需要和 PodMonitor/ServiceMonitor 相同 +[ bearerTokenSecret: string ] +# 解决当抓取的 label 与后端 Prometheus 添加 label 冲突时的处理。 +# true: 保留抓取到的 label,忽略与后端 Prometheus 冲突的 label; +# false: 对冲突的 label,把抓取的 label 前加上 exported_,添加后端 Prometheus 增加的 label; +[ honorLabels: bool | default = false ] +# 是否使用抓取到 target 上产生的时间。 +# true: 如果 target 中有时间,使用 target 上的时间; +# false: 直接忽略 target 上的时间; +[ honorTimestamps: bool | default = true ] +# basic auth 的认证信息,username/password 填写对应 K8S secret key 的值,注意 secret namespace 需要和 PodMonitor/ServiceMonitor 相同。 +[ basicAuth: BasicAuth ] +# 通过代理服务来抓取 target 上的指标,填写对应的代理服务地址 +[ proxyUrl: string ] +# 在抓取数据之后,把 target 上对应的 label 通过 relabel 的机制进行改写,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明 +relabelings: +[ - ...] +# 数据抓取完成写入之前,通过 relabel 机制进行改写 label 对应的值,按顺序执行多个 relabel 规则。 +# relabel_config 详见下文说明 +metricRelabelings: +[ - ...] +``` + +### relabel_config + +相应配置项说明如下: + +```yaml +# 从原始 labels 中取哪些 label 的值进行 relabel,取出来的值通过 separator 中的定义进行字符拼接。 +# 如果是 PodMonitor/ServiceMonitor 对应的配置项为 sourceLabels +[ source_labels: '[' [, ...] ']' ] +# 定义需要 relabel 的 label 值拼接的字符,默认为 ';' +[ separator: | default = ; ] + +# action 为 replace/hashmod 时,通过 target_label 来指定对应 label name。 +# 如果是 PodMonitor/ServiceMonitor 对应的配置项为 targetLabel +[ target_label: ] + +# 需要对 source labels 对应值进行正则匹配的表达式 +[ regex: | default = (.*) ] + +# action 为 hashmod 时用到,根据 source label 对应值 md5 取模值 +[ modulus: ] + +# action 为 replace 的时候,通过 replacement 来定义当 regex 匹配之后需要替换的表达式,可以结合 regex 正规则表达式替换 +[ replacement: | default = $1 ] + +# 基于 regex 匹配到的值进行相关的操作,对应的 action 如下,默认为 replace: +# replace: 如果 regex 匹配到,通过 replacement 中定义的值替换相应的值,并通过 target_label 设值并添加相应的 label +# keep: 如果 regex 没有匹配到,丢弃 +# drop: 如果 regex 匹配到,丢弃 +# hashmod: 通过 moduels 指定的值把 source label 对应的 md5 值取模 +# 并添加一个新的 label,label name 通过 target_label 指定 +# labelmap: 如果 regex 匹配到,使用 replacement 替换对就的 label name +# labeldrop: 如果 regex 匹配到,删除对应的 label +# labelkeep: 如果 regex 没有匹配到,删除对应的 label +[ action: | default = replace ] +``` diff --git a/docs/zh/docs/end-user/insight/collection-manag/probe-module.md b/docs/zh/docs/end-user/insight/collection-manag/probe-module.md new file mode 100644 index 0000000..ce98720 --- /dev/null +++ b/docs/zh/docs/end-user/insight/collection-manag/probe-module.md @@ -0,0 +1,309 @@ +# 自定义探测方式 + +Insight 使用 Prometheus 官方提供的 Blackbox Exporter 作为黑盒监控解决方案,可以通过 HTTP、HTTPS、DNS、ICMP、TCP 和 gRPC 方式对目标实例进行检测。可用于以下使用场景: + +- HTTP/HTTPS:URL/API可用性检测 +- ICMP:主机存活检测 +- TCP:端口存活检测 +- DNS:域名解析 + +在本文中,我们将介绍如何在已有的 Blackbox ConfigMap 中配置自定义的探测方式。 + +Insight 默认未开启 ICMP 探测方式,因为 ICMP 需要更高权限,因此,我们将以 ICMP 和 HTTP 探测方式作为示例,展示如何修改 ConfigMap 以实现自定义的 ICMP 和 HTTP 探测。 + +## 操作步骤 + +1. 进入 __容器管理__ 的 __集群列表__ ,点击进入目标集群的详情; +2. 点击左侧导航,选择 __配置与密钥__ -> __配置项__ ; +3. 找到名为 __insight-agent-prometheus-blackbox-exporter__ 的配置项,点击 __编辑 YAML__; + + 在 __modules__ 下添加自定义探测方式: + +=== "HTTP 探测" + + ```yaml + module: + http_2xx: + prober: http + timeout: 5s + http: + valid_http_versions: [HTTP/1.1, HTTP/2] + valid_status_codes: [] # Defaults to 2xx + method: GET + ``` + +=== "ICMP 探测" + + ```yaml + module: + ICMP: # ICMP 探测配置的示例 + prober: icmp + timeout: 5s + icmp: + preferred_ip_protocol: ip4 + icmp_example: # ICMP 探测配置的示例 2 + prober: icmp + timeout: 5s + icmp: + preferred_ip_protocol: "ip4" + source_ip_address: "127.0.0.1" + ``` + 由于 ICMP 需要更高权限,因此,我们还需要提升 Pod 权限,否则会出现 `operation not permitted` 的错误。有以下两种方式提升权限: + + - 方式一: 直接编辑 `BlackBox Exporter` 部署文件开启 + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: insight-agent-prometheus-blackbox-exporter + namespace: insight-system + spec: + template: + spec: + containers: + - name: blackbox-exporter + image: # ... (image, args, ports 等保持不变) + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_RAW + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + ``` + + - 方式二: 通过 Helm Upgrade 方式提权 + + ```diff + prometheus-blackbox-exporter: + enabled: true + securityContext: + runAsUser: 0 + runAsGroup: 0 + readOnlyRootFilesystem: true + runAsNonRoot: false + allowPrivilegeEscalation: false + capabilities: + add: ["NET_RAW"] + ``` + +!!! info + + 更多探测方式可参考 [blackbox_exporter Configuration](https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md)。 + +## 其他参考 + +以下 YAML 文件中包含了 HTTP、TCP、SMTP、ICMP、DNS 等多种探测方式,可根据需求自行修改 `insight-agent-prometheus-blackbox-exporter` 的配置文件。 + +??? note "点击查看完整的 YAML 文件" + + ```yaml + kind: ConfigMap + apiVersion: v1 + metadata: + name: insight-agent-prometheus-blackbox-exporter + namespace: insight-system + labels: + app.kubernetes.io/instance: insight-agent + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-blackbox-exporter + app.kubernetes.io/version: v0.24.0 + helm.sh/chart: prometheus-blackbox-exporter-8.8.0 + annotations: + meta.helm.sh/release-name: insight-agent + meta.helm.sh/release-namespace: insight-system + data: + blackbox.yaml: | + modules: + HTTP_GET: + prober: http + timeout: 5s + http: + method: GET + valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] + follow_redirects: true + preferred_ip_protocol: "ip4" + HTTP_POST: + prober: http + timeout: 5s + http: + method: POST + body_size_limit: 1MB + TCP: + prober: tcp + timeout: 5s + # 默认未开启: + # ICMP: + # prober: icmp + # timeout: 5s + # icmp: + # preferred_ip_protocol: ip4 + SSH: + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "^SSH-2.0-" + POP3S: + prober: tcp + tcp: + query_response: + - expect: "^+OK" + tls: true + tls_config: + insecure_skip_verify: false + http_2xx_example: # http 探测示例 + prober: http + timeout: 5s # 探测的超时时间 + http: + valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] # 返回信息中的 Version,一般默认即可 + valid_status_codes: [] # Defaults to 2xx # 有效的返回码范围,如果请求的返回码在该范围内,视为探测成功 + method: GET # 请求方法 + headers: # 请求的头部 + Host: vhost.example.com + Accept-Language: en-US + Origin: example.com + no_follow_redirects: false # 是否允许重定向 + fail_if_ssl: false + fail_if_not_ssl: false + fail_if_body_matches_regexp: + - "Could not connect to database" + fail_if_body_not_matches_regexp: + - "Download the latest version here" + fail_if_header_matches: # Verifies that no cookies are set + - header: Set-Cookie + allow_missing: true + regexp: '.*' + fail_if_header_not_matches: + - header: Access-Control-Allow-Origin + regexp: '(\*|example\.com)' + tls_config: # 针对 https 请求的 tls 的配置 + insecure_skip_verify: false + preferred_ip_protocol: "ip4" # defaults to "ip6" # 首选的 IP 协议版本 + ip_protocol_fallback: false # no fallback to "ip6" + http_post_2xx: # 带 Body 的 http 探测的示例 + prober: http + timeout: 5s + http: + method: POST # 探测的请求方法 + headers: + Content-Type: application/json + body: '{"username":"admin","password":"123456"}' # 探测时携带的 body + http_basic_auth_example: # 带用户名密码的探测的示例 + prober: http + timeout: 5s + http: + method: POST + headers: + Host: "login.example.com" + basic_auth: # 探测时要加的用户名密码 + username: "username" + password: "mysecret" + http_custom_ca_example: + prober: http + http: + method: GET + tls_config: # 指定探测时使用的根证书 + ca_file: "/certs/my_cert.crt" + http_gzip: + prober: http + http: + method: GET + compression: gzip # 探测时使用的压缩方法 + http_gzip_with_accept_encoding: + prober: http + http: + method: GET + compression: gzip + headers: + Accept-Encoding: gzip + tls_connect: # TCP 探测的示例 + prober: tcp + timeout: 5s + tcp: + tls: true # 是否使用 TLS + tcp_connect_example: + prober: tcp + timeout: 5s + imap_starttls: # 探测 IMAP 邮箱服务器的配置示例 + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "OK.*STARTTLS" + - send: ". STARTTLS" + - expect: "OK" + - starttls: true + - send: ". capability" + - expect: "CAPABILITY IMAP4rev1" + smtp_starttls: # 探测 SMTP 邮箱服务器的配置示例 + prober: tcp + timeout: 5s + tcp: + query_response: + - expect: "^220 ([^ ]+) ESMTP (.+)$" + - send: "EHLO prober\r" + - expect: "^250-STARTTLS" + - send: "STARTTLS\r" + - expect: "^220" + - starttls: true + - send: "EHLO prober\r" + - expect: "^250-AUTH" + - send: "QUIT\r" + irc_banner_example: + prober: tcp + timeout: 5s + tcp: + query_response: + - send: "NICK prober" + - send: "USER prober prober prober :prober" + - expect: "PING :([^ ]+)" + send: "PONG ${1}" + - expect: "^:[^ ]+ 001" + # icmp_example: # ICMP 探测配置的示例 + # prober: icmp + # timeout: 5s + # icmp: + # preferred_ip_protocol: "ip4" + # source_ip_address: "127.0.0.1" + dns_udp_example: # 使用 UDP 进行 DNS 查询的示例 + prober: dns + timeout: 5s + dns: + query_name: "www.prometheus.io" # 要解析的域名 + query_type: "A" # 该域名对应的类型 + valid_rcodes: + - NOERROR + validate_answer_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + fail_if_all_match_regexp: + - ".*127.0.0.1" + fail_if_not_matches_regexp: + - "www.prometheus.io.\t300\tIN\tA\t127.0.0.1" + fail_if_none_matches_regexp: + - "127.0.0.1" + validate_authority_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + validate_additional_rrs: + fail_if_matches_regexp: + - ".*127.0.0.1" + dns_soa: + prober: dns + dns: + query_name: "prometheus.io" + query_type: "SOA" + dns_tcp_example: # 使用 TCP 进行 DNS 查询的示例 + prober: dns + dns: + transport_protocol: "tcp" # defaults to "udp" + preferred_ip_protocol: "ip4" # defaults to "ip6" + query_name: "www.prometheus.io" + ``` diff --git a/docs/zh/docs/end-user/insight/collection-manag/service-monitor.md b/docs/zh/docs/end-user/insight/collection-manag/service-monitor.md new file mode 100644 index 0000000..05128c3 --- /dev/null +++ b/docs/zh/docs/end-user/insight/collection-manag/service-monitor.md @@ -0,0 +1,67 @@ +# 配置服务发现规则 + +可观测 Insight 支持通过 __容器管理__ 创建 CRD ServiceMonitor 的方式来满足您自定义服务发现的采集需求。 +用户可以通过使用 ServiceMonitor 自行定义 Pod 发现的 Namespace 范围以及通过 __matchLabel__ 来选择监听的 Service。 + +## 前提条件 + +集群已安装 Helm 应用 __insight-agent__ 且处于 __运行中__ 状态。 + +## 操作步骤 + +1. 选择左侧导航栏的 __采集管理__ ,查看全部集群采集插件的状态。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/collectmanage02.png) + +2. 点击列表中的某个集群名称进入采集配置详情。 + + ![集群列表](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/service-discover.png) + +3. 点击链接跳转到 __容器管理__ 中创建 Service Monitor。 + + ```yaml + apiVersion: monitoring.coreos.com/v1 + kind: ServiceMonitor + metadata: + name: micrometer-demo # (1) + namespace: insight-system # (2) + labels: + operator.insight.io/managed-by: insight + spec: + endpoints: # (3) + - honorLabels: true + interval: 15s + path: /actuator/prometheus + port: http + namespaceSelector: # (4) + matchNames: + - insight-system # (5) + selector: # (6) + matchLabels: + micrometer-prometheus-discovery: "true" + ``` + + 1. 指定 ServiceMonitor 的名称 + 2. 指定 ServiceMonitor 的命名空间 + 3. 这是服务端点,代表 Prometheus 所需的采集 Metrics 的地址。 __endpoints__ 为一个数组, + 同时可以创建多个 __endpoints__ 。每个 __endpoints__ 包含三个字段,每个字段的含义如下: + + - __interval__ :指定 Prometheus 对当前 __endpoints__ 采集的周期。单位为秒,在本次示例中设定为 __15s__ 。 + - __path__ :指定 Prometheus 的采集路径。在本次示例中,指定为 __/actuator/prometheus__ 。 + - __port__ :指定采集数据需要通过的端口,设置的端口为采集的 Service 端口所设置的 __name__ 。 + + 4. 这是需要发现的 Service 的范围。 __namespaceSelector__ 包含两个互斥字段,字段的含义如下: + + - __any__ :有且仅有一个值 __true__ ,当该字段被设置时,将监听所有符合 Selector 过滤条件的 Service 的变动。 + - __matchNames__ :数组值,指定需要监听的 __namespace__ 的范围。例如,只想监听 default 和 insight-system + 两个命名空间中的 Service,那么 __matchNames__ 设置如下: + + ```yaml + namespaceSelector: + matchNames: + - default + - insight-system + ``` + + 5. 此处匹配的命名空间为需要暴露指标的应用所在的命名空间 + 6. 用于选择 Service diff --git a/docs/zh/docs/end-user/insight/dashboard/dashboard.md b/docs/zh/docs/end-user/insight/dashboard/dashboard.md new file mode 100644 index 0000000..bf73f0d --- /dev/null +++ b/docs/zh/docs/end-user/insight/dashboard/dashboard.md @@ -0,0 +1,32 @@ +--- +hide: + - toc +--- + +# 仪表盘 + +Grafana 是一种开源的数据可视化和监控平台,它提供了丰富的图表和面板,用于实时监控、分析和可视化各种数据源的指标和日志。可观测性 Insight 使用开源 Grafana 提供监控服务,支持从集群、节点、命名空间等多维度查看资源消耗情况, + +关于开源 Grafana 的详细信息,请参见 [Grafana 官方文档](https://grafana.com/docs/grafana/latest/getting-started/?spm=a2c4g.11186623.0.0.1f34de53ksAH9a)。 + +## 操作步骤 + +1. 在左侧导航栏选择 __仪表盘__ 。 + + - 在 __Insight /概览__ 仪表盘中,可查看多选集群的资源使用情况,并以命名空间、容器组等多个维度分析了资源使用、网络、存储等情况。 + + - 点击仪表盘左上侧的下拉框可切换集群。 + + - 点击仪表盘右下侧可切换查询的时间范围。 + + ![dashboard](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/dashboard00.png){ width="1000"} + +2. Insight 精选多个社区推荐仪表盘,可从节点、命名空间、工作负载等多个维度进行监控。点击 __insight-system / Insight /概览__ 区域切换仪表盘。 + + ![dashboard](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/dashboard01.png){ width="1000"} + +!!! note + + 1. 访问 Grafana UI 请参考[以管理员身份登录 Grafana](./login-grafana.md)。 + + 2. 导入自定义仪表盘请参考[导入自定义仪表盘](./import-dashboard.md)。 diff --git a/docs/zh/docs/end-user/insight/dashboard/import-dashboard.md b/docs/zh/docs/end-user/insight/dashboard/import-dashboard.md new file mode 100644 index 0000000..299468f --- /dev/null +++ b/docs/zh/docs/end-user/insight/dashboard/import-dashboard.md @@ -0,0 +1,65 @@ +# 导入自定义仪表盘 + +通过使用 Grafana CRD,可以将仪表板的管理和部署纳入到 Kubernetes 的生命周期管理中,实现仪表板的版本控制、自动化部署和集群级的管理。本页介绍如何通过 CRD 和 UI 界面导入自定义的仪表盘。 + +## 操作步骤 + +1. 登录 AI 算力平台 平台,进入 __容器管理__ ,在集群列表中选择 __kpanda-global-cluster__ 。 + +2. 选择左侧导航栏的 __自定义资源__ ,在列表中查找 __grafanadashboards.integreatly.org__ 文件,进入详情。 + + ![导入仪表盘](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/importboard00.png){ width="1000"} + +3. 点击 __Yaml 创建__ ,使用以下模板,在 __Json__ 字段中替换仪表盘 JSON。 + + - __namespace__ :填写目标命名空间; + - __name__ :填写仪表盘的名称。 + - __label__ :必填, __operator.insight.io/managed-by: insight__ 。 + + ```yaml + apiVersion: integreatly.org/v1alpha1 + kind: GrafanaDashboard + metadata: + labels: + app: insight-grafana-operator + operator.insight.io/managed-by: insight + name: sample-dashboard + namespace: insight-system + spec: + json: > + { + "id": null, + "title": "Simple Dashboard", + "tags": [], + "style": "dark", + "timezone": "browser", + "editable": true, + "hideControls": false, + "graphTooltip": 1, + "panels": [], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "time_options": [], + "refresh_intervals": [] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": "5s", + "schemaVersion": 17, + "version": 0, + "links": [] + } + ``` + +4. 点击 __确认__ 后,稍等片刻即可在 __仪表盘__ 中查看刚刚导入的仪表盘。 + +!!! info + + 自定义设计仪表盘,请参考[添加仪表盘面板](https://grafana.com/docs/grafana/latest/dashboards/add-organize-panels/)。 diff --git a/docs/zh/docs/end-user/insight/dashboard/login-grafana.md b/docs/zh/docs/end-user/insight/dashboard/login-grafana.md new file mode 100644 index 0000000..5bf6696 --- /dev/null +++ b/docs/zh/docs/end-user/insight/dashboard/login-grafana.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 访问原生 Grafana + +Insight 借助 Grafana 提供了丰富的可视化能力,同时保留了访问原生 Grafana 的入口。 + +## 操作步骤 + +1. 登录浏览器,在浏览器中输入 Grafana 地址。 + + 访问地址: `http://ip:访问端口/ui/insight-grafana/login` + + 例如: `http://10.6.10.233:30209/ui/insight-grafana/login` + +2. 点击右下角的登录,使用默认用户名、密码(admin/admin)进行登录。 + + ![登录 grafana](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/grafana02.png){ width=1000px} + +3. 点击 __Log in__ 完成登录。 + + ![成功登录 grafana](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/grafana03.png){ width=1000px} diff --git a/docs/zh/docs/end-user/insight/dashboard/overview.md b/docs/zh/docs/end-user/insight/dashboard/overview.md new file mode 100644 index 0000000..95f210e --- /dev/null +++ b/docs/zh/docs/end-user/insight/dashboard/overview.md @@ -0,0 +1,20 @@ +--- +hide: + - toc +--- + +# 概览 + +__概率__ 仅统计已安装 __insight-agent__ 且其运行状态为正常的集群数据。可在概览中多集群的资源概况: + +- 告警统计:可查看所有集群的正在告警的统计数据。 +- 资源消耗:可按 CPU 使用率、内存使用率和磁盘使用率分别查看近一小时 TOP5 集群、节点的资源变化趋势。 +- 默认按照根据 CPU 使用率排序。您可切换指标切换集群、节点的排序方式。 +- 资源变化趋势:可查看近 15 天的节点个数趋势以及一小时 Pod 的运行趋势。 +- 服务请求排行:可查看多集群中请求延时、错误率排行 TOP5 的服务及所在集群和命名空间。 + +## 操作步骤 + +在左边导航栏选择 __概览__ 。 + +![概览](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/overview.png){ width="1000"} diff --git a/docs/zh/docs/end-user/insight/data-query/log.md b/docs/zh/docs/end-user/insight/data-query/log.md new file mode 100644 index 0000000..defe755 --- /dev/null +++ b/docs/zh/docs/end-user/insight/data-query/log.md @@ -0,0 +1,60 @@ +# 日志查询 + +Insight 默认采集节点日志、容器日志以及 kubernetes 审计日志。在日志查询页面中,可查询登录账号权限内的标准输出 (stdout) 日志,包括节点日志、产品日志、Kubenetes 审计日志等,快速在大量日志中查询到所需的日志,同时结合日志的来源信息和上下文原始数据辅助定位问题。 + +## 操作步骤 + +1. 点击一级导航栏进入 __可观测性__ 。 +2. 左侧导航栏中,选择 __日志__ 。 + + - 默认查询最近 24 小时; + - 第一次进入时,默认根据登录账号权限查询有权限的集群或命名空间的容器日志; + + ![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/log00.png) + +3. 顶部 Tab 默认进入 __普通查询__ 。 + + 1. 点击 __筛选__ 展开过滤面板,可切换日志搜索条件和类型。 + 2. 日志类型: + + - __容器日志__ :记录集群中容器内部的活动和事件,包括应用程序的输出、错误消息、警告和调试信息等。支持通过集群、命名空间、容器组、容器过滤日志。 + - __节点日志__ :记录集群中每个节点的系统级别日志。这些日志包含节点的操作系统、内核、服务和组件的相关信息。支持通过集群、节点、文件路径过滤日志。 + + 3. 支持对单个关键字进行模糊搜索。 + + ![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/log03.png) + +4. 顶部切换 Tab 选择 __Lucene 语法查询__ 。 + + 第一次进入时,默认选择登录账号权限查询有权限的集群或命名空间的容器日志。 + + ![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/log01.png) + + **Lucene 语法说明:** + + 1. 使用 逻辑操作符(AND、OR、NOT、"" )符查询多个关键字,例如:keyword1 AND (keyword2 OR keyword3) NOT keyword4。 + 2. 使用波浪号 (~) 实现模糊查询,在 "~" 后可指定可选的参数,用于控制模糊查询的相似度,不指定则默认使用 0.5。例如:error~。 + 3. 使用通配符 (*、?) 用作单字符通配符,表示匹配任意一个字符。 + 4. 使用方括号 [ ] 或花括号 { } 来查询范围,方括号 [ ] 表示闭区间,包含边界值。花括号 { } 表示开区间,排除边界值。范围查询只适用于能够进行排序的字段类型,如数字、日期等。例如:timestamp:[2022-01-01 TO 2022-01-31]。 + 5. 更多用法请查看:[Lucene 语法说明](../../reference/lucene.md)。 + +### 其他操作 + +#### 查看日志上下文 + +点击日志后的按钮,在右侧划出面板中可查看该条日志的默认 100 条上下文。可切换 __显示行数__ 查看更多上下文内容。 + +![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/logcontext.png) + +#### 导出日志数据 + +点击列表右上侧的下载按钮。 + +- 支持配置导出的日志字段,根据日志类型可配置的字段不同,其中 __日志内容__ 字段为必选。 +- 支持将日志查询结果导出为 **.txt** 或 **.csv** 格式。 + +![log](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/logexport.png){ width="500"} + +!!! note + + 若需指定不采集某一些容器组的日志,可参考:[容器日志黑名单](../../faq/ignore-pod-log-collect.md)。 \ No newline at end of file diff --git a/docs/zh/docs/end-user/insight/data-query/metric.md b/docs/zh/docs/end-user/insight/data-query/metric.md new file mode 100644 index 0000000..a485aa5 --- /dev/null +++ b/docs/zh/docs/end-user/insight/data-query/metric.md @@ -0,0 +1,27 @@ +# 指标查询 + +指标查询支持查询容器各资源的指标数据,可查看监控指标的趋势变化。同时,高级查询支持原生 PromQL 语句进行指标查询。 + +## 前提条件 + +- 集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 点击一级导航栏进入 __可观测性__ 。 + +2. 左侧导航栏中,选择 __指标__ 。 + +3. 选择集群、类型、节点、指标名称查询条件后,点击 __搜索__ ,屏幕右侧将显示对应指标图表及数据详情。 + + - 支持自定义时间范围。可手动点击 __刷新__ 图标或选择默认时间间隔进行刷新。 + + ![查询结果](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/metrics00.png) + +4. 点击 __高级查询__ 页签通过原生的 PromQL 查询。 + + ![高级查询](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/metics01.png) + +!!! NOTE + + 参阅 [PromQL 语法](https://prometheus.io/docs/prometheus/latest/querying/basics/)。 diff --git a/docs/zh/docs/end-user/insight/images/big-log01.png b/docs/zh/docs/end-user/insight/images/big-log01.png new file mode 100644 index 0000000..b178b19 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/big-log01.png differ diff --git a/docs/zh/docs/end-user/insight/images/big-log02.png b/docs/zh/docs/end-user/insight/images/big-log02.png new file mode 100644 index 0000000..a28c76a Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/big-log02.png differ diff --git a/docs/zh/docs/end-user/insight/images/big-log03.png b/docs/zh/docs/end-user/insight/images/big-log03.png new file mode 100644 index 0000000..f6616d8 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/big-log03.png differ diff --git a/docs/zh/docs/end-user/insight/images/big-log04.png b/docs/zh/docs/end-user/insight/images/big-log04.png new file mode 100644 index 0000000..bac3d72 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/big-log04.png differ diff --git a/docs/zh/docs/end-user/insight/images/big-log05.png b/docs/zh/docs/end-user/insight/images/big-log05.png new file mode 100644 index 0000000..db60fa0 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/big-log05.png differ diff --git a/docs/zh/docs/end-user/insight/images/big-log06.png b/docs/zh/docs/end-user/insight/images/big-log06.png new file mode 100644 index 0000000..6e9b8be Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/big-log06.png differ diff --git a/docs/zh/docs/end-user/insight/images/cluster-1.png b/docs/zh/docs/end-user/insight/images/cluster-1.png new file mode 100644 index 0000000..7d864a3 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/cluster-1.png differ diff --git a/docs/zh/docs/end-user/insight/images/cluster.png b/docs/zh/docs/end-user/insight/images/cluster.png new file mode 100644 index 0000000..9f1b922 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/cluster.png differ diff --git a/docs/zh/docs/end-user/insight/images/container01.png b/docs/zh/docs/end-user/insight/images/container01.png new file mode 100644 index 0000000..546b73c Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/container01.png differ diff --git a/docs/zh/docs/end-user/insight/images/dingding.png b/docs/zh/docs/end-user/insight/images/dingding.png new file mode 100644 index 0000000..0e5f35d Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/dingding.png differ diff --git a/docs/zh/docs/end-user/insight/images/find_root_cause/10.png b/docs/zh/docs/end-user/insight/images/find_root_cause/10.png new file mode 100644 index 0000000..7d83883 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/find_root_cause/10.png differ diff --git a/docs/zh/docs/end-user/insight/images/import-template.png b/docs/zh/docs/end-user/insight/images/import-template.png new file mode 100644 index 0000000..a56214b Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/import-template.png differ diff --git a/docs/zh/docs/end-user/insight/images/inhibition-1.png b/docs/zh/docs/end-user/insight/images/inhibition-1.png new file mode 100644 index 0000000..afcac8e Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/inhibition-1.png differ diff --git a/docs/zh/docs/end-user/insight/images/inhibition.png b/docs/zh/docs/end-user/insight/images/inhibition.png new file mode 100644 index 0000000..2fc334d Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/inhibition.png differ diff --git a/docs/zh/docs/end-user/insight/images/inhibition01.png b/docs/zh/docs/end-user/insight/images/inhibition01.png new file mode 100644 index 0000000..5653387 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/inhibition01.png differ diff --git a/docs/zh/docs/end-user/insight/images/inhibition02.png b/docs/zh/docs/end-user/insight/images/inhibition02.png new file mode 100644 index 0000000..2ce4352 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/inhibition02.png differ diff --git a/docs/zh/docs/end-user/insight/images/inhibition03.png b/docs/zh/docs/end-user/insight/images/inhibition03.png new file mode 100644 index 0000000..e9c86a0 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/inhibition03.png differ diff --git a/docs/zh/docs/end-user/insight/images/inhibition04.png b/docs/zh/docs/end-user/insight/images/inhibition04.png new file mode 100644 index 0000000..2d63479 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/inhibition04.png differ diff --git a/docs/zh/docs/end-user/insight/images/insight-agent.svg b/docs/zh/docs/end-user/insight/images/insight-agent.svg new file mode 100644 index 0000000..97cbf4a --- /dev/null +++ b/docs/zh/docs/end-user/insight/images/insight-agent.svg @@ -0,0 +1,11 @@ + + + Icon / Logo 20*20 / Insight Agent@green + + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/end-user/insight/images/insight-ns-toleration.png b/docs/zh/docs/end-user/insight/images/insight-ns-toleration.png new file mode 100644 index 0000000..b2eaa81 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/insight-ns-toleration.png differ diff --git a/docs/zh/docs/end-user/insight/images/insight.svg b/docs/zh/docs/end-user/insight/images/insight.svg new file mode 100644 index 0000000..1727286 --- /dev/null +++ b/docs/zh/docs/end-user/insight/images/insight.svg @@ -0,0 +1,9 @@ + + + insight + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/end-user/insight/images/installagent01.png b/docs/zh/docs/end-user/insight/images/installagent01.png new file mode 100644 index 0000000..edb3c27 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/installagent01.png differ diff --git a/docs/zh/docs/end-user/insight/images/installagent02.png b/docs/zh/docs/end-user/insight/images/installagent02.png new file mode 100644 index 0000000..b9f8e1f Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/installagent02.png differ diff --git a/docs/zh/docs/end-user/insight/images/installagent03.png b/docs/zh/docs/end-user/insight/images/installagent03.png new file mode 100644 index 0000000..cf298d0 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/installagent03.png differ diff --git a/docs/zh/docs/end-user/insight/images/ipavo.svg b/docs/zh/docs/end-user/insight/images/ipavo.svg new file mode 100644 index 0000000..d9476d1 --- /dev/null +++ b/docs/zh/docs/end-user/insight/images/ipavo.svg @@ -0,0 +1,10 @@ + + + Icon / 00_Action / bar-chart + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/end-user/insight/images/kpandaservice.png b/docs/zh/docs/end-user/insight/images/kpandaservice.png new file mode 100644 index 0000000..9f789fa Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/kpandaservice.png differ diff --git a/docs/zh/docs/end-user/insight/images/log04.png b/docs/zh/docs/end-user/insight/images/log04.png new file mode 100644 index 0000000..e72fd36 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/log04.png differ diff --git a/docs/zh/docs/end-user/insight/images/logfilter00.png b/docs/zh/docs/end-user/insight/images/logfilter00.png new file mode 100644 index 0000000..ade153c Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/logfilter00.png differ diff --git a/docs/zh/docs/end-user/insight/images/map-setting.png b/docs/zh/docs/end-user/insight/images/map-setting.png new file mode 100644 index 0000000..9c9539c Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/map-setting.png differ diff --git a/docs/zh/docs/end-user/insight/images/msg-detail.png b/docs/zh/docs/end-user/insight/images/msg-detail.png new file mode 100644 index 0000000..4fd4dab Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/msg-detail.png differ diff --git a/docs/zh/docs/end-user/insight/images/node.png b/docs/zh/docs/end-user/insight/images/node.png new file mode 100644 index 0000000..c8d1efe Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/node.png differ diff --git a/docs/zh/docs/end-user/insight/images/notify-01.png b/docs/zh/docs/end-user/insight/images/notify-01.png new file mode 100644 index 0000000..5b80920 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/notify-01.png differ diff --git a/docs/zh/docs/end-user/insight/images/notify-02.png b/docs/zh/docs/end-user/insight/images/notify-02.png new file mode 100644 index 0000000..70049ed Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/notify-02.png differ diff --git a/docs/zh/docs/end-user/insight/images/policy-builtin.png b/docs/zh/docs/end-user/insight/images/policy-builtin.png new file mode 100644 index 0000000..ab2d8a4 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/policy-builtin.png differ diff --git a/docs/zh/docs/end-user/insight/images/policy02.png b/docs/zh/docs/end-user/insight/images/policy02.png new file mode 100644 index 0000000..2a4e13e Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/policy02.png differ diff --git a/docs/zh/docs/end-user/insight/images/policy03.png b/docs/zh/docs/end-user/insight/images/policy03.png new file mode 100644 index 0000000..a8aa01b Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/policy03.png differ diff --git a/docs/zh/docs/end-user/insight/images/policy07.png b/docs/zh/docs/end-user/insight/images/policy07.png new file mode 100644 index 0000000..1302794 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/policy07.png differ diff --git a/docs/zh/docs/end-user/insight/images/policy08.png b/docs/zh/docs/end-user/insight/images/policy08.png new file mode 100644 index 0000000..9758b47 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/policy08.png differ diff --git a/docs/zh/docs/end-user/insight/images/probe03.png b/docs/zh/docs/end-user/insight/images/probe03.png new file mode 100644 index 0000000..d3c5a11 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/probe03.png differ diff --git a/docs/zh/docs/end-user/insight/images/service-1.png b/docs/zh/docs/end-user/insight/images/service-1.png new file mode 100644 index 0000000..c815654 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/service-1.png differ diff --git a/docs/zh/docs/end-user/insight/images/service-map.png b/docs/zh/docs/end-user/insight/images/service-map.png new file mode 100644 index 0000000..091169b Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/service-map.png differ diff --git a/docs/zh/docs/end-user/insight/images/service.png b/docs/zh/docs/end-user/insight/images/service.png new file mode 100644 index 0000000..c9e01fc Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/service.png differ diff --git a/docs/zh/docs/end-user/insight/images/service01.png b/docs/zh/docs/end-user/insight/images/service01.png new file mode 100644 index 0000000..4a4f557 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/service01.png differ diff --git a/docs/zh/docs/end-user/insight/images/servicemap.png b/docs/zh/docs/end-user/insight/images/servicemap.png new file mode 100644 index 0000000..8c6d448 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/servicemap.png differ diff --git a/docs/zh/docs/end-user/insight/images/servicemap01.png b/docs/zh/docs/end-user/insight/images/servicemap01.png new file mode 100644 index 0000000..5abde06 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/servicemap01.png differ diff --git a/docs/zh/docs/end-user/insight/images/servicemap02.png b/docs/zh/docs/end-user/insight/images/servicemap02.png new file mode 100644 index 0000000..857fa5f Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/servicemap02.png differ diff --git a/docs/zh/docs/end-user/insight/images/silence03.png b/docs/zh/docs/end-user/insight/images/silence03.png new file mode 100644 index 0000000..c7b2220 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/silence03.png differ diff --git a/docs/zh/docs/end-user/insight/images/sms00.png b/docs/zh/docs/end-user/insight/images/sms00.png new file mode 100644 index 0000000..4e58ac4 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/sms00.png differ diff --git a/docs/zh/docs/end-user/insight/images/sms01.png b/docs/zh/docs/end-user/insight/images/sms01.png new file mode 100644 index 0000000..e4e18b8 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/sms01.png differ diff --git a/docs/zh/docs/end-user/insight/images/sms02.png b/docs/zh/docs/end-user/insight/images/sms02.png new file mode 100644 index 0000000..3da97b3 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/sms02.png differ diff --git a/docs/zh/docs/end-user/insight/images/smsserver01.png b/docs/zh/docs/end-user/insight/images/smsserver01.png new file mode 100644 index 0000000..22c5fce Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/smsserver01.png differ diff --git a/docs/zh/docs/end-user/insight/images/smsserver02.png b/docs/zh/docs/end-user/insight/images/smsserver02.png new file mode 100644 index 0000000..3660ead Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/smsserver02.png differ diff --git a/docs/zh/docs/end-user/insight/images/template01.png b/docs/zh/docs/end-user/insight/images/template01.png new file mode 100644 index 0000000..d7f6144 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/template01.png differ diff --git a/docs/zh/docs/end-user/insight/images/template02.png b/docs/zh/docs/end-user/insight/images/template02.png new file mode 100644 index 0000000..5e908b3 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/template02.png differ diff --git a/docs/zh/docs/end-user/insight/images/template03.png b/docs/zh/docs/end-user/insight/images/template03.png new file mode 100644 index 0000000..c516692 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/template03.png differ diff --git a/docs/zh/docs/end-user/insight/images/template04.png b/docs/zh/docs/end-user/insight/images/template04.png new file mode 100644 index 0000000..86b1477 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/template04.png differ diff --git a/docs/zh/docs/end-user/insight/images/template05.png b/docs/zh/docs/end-user/insight/images/template05.png new file mode 100644 index 0000000..1c2d870 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/template05.png differ diff --git a/docs/zh/docs/end-user/insight/images/trace02.png b/docs/zh/docs/end-user/insight/images/trace02.png new file mode 100644 index 0000000..bde1b94 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/trace02.png differ diff --git a/docs/zh/docs/end-user/insight/images/tracelog.png b/docs/zh/docs/end-user/insight/images/tracelog.png new file mode 100644 index 0000000..3810728 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/tracelog.png differ diff --git a/docs/zh/docs/end-user/insight/images/vmdisk14.png b/docs/zh/docs/end-user/insight/images/vmdisk14.png new file mode 100644 index 0000000..ca100a8 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/vmdisk14.png differ diff --git a/docs/zh/docs/end-user/insight/images/webhook.png b/docs/zh/docs/end-user/insight/images/webhook.png new file mode 100644 index 0000000..69ef57a Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/webhook.png differ diff --git a/docs/zh/docs/end-user/insight/images/workload-1.png b/docs/zh/docs/end-user/insight/images/workload-1.png new file mode 100644 index 0000000..63f5a62 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/workload-1.png differ diff --git a/docs/zh/docs/end-user/insight/images/workload-2.png b/docs/zh/docs/end-user/insight/images/workload-2.png new file mode 100644 index 0000000..525dd78 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/workload-2.png differ diff --git a/docs/zh/docs/end-user/insight/images/workload.png b/docs/zh/docs/end-user/insight/images/workload.png new file mode 100644 index 0000000..90e5453 Binary files /dev/null and b/docs/zh/docs/end-user/insight/images/workload.png differ diff --git a/docs/zh/docs/end-user/insight/infra/cluster.md b/docs/zh/docs/end-user/insight/infra/cluster.md new file mode 100644 index 0000000..6eac1cd --- /dev/null +++ b/docs/zh/docs/end-user/insight/infra/cluster.md @@ -0,0 +1,33 @@ +# 集群监控 + +通过集群监控,你可以查看集群的基本信息、该集群中的资源消耗以及一段时间的资源消耗变化趋势等。 + +## 前提条件 + +集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ -> __集群__ 。在该页面可查看以下信息: + + - **资源概览** :多选集群中的节点、工作负载的正常和全部的数量统计; + - **故障** :统计当前集群产生的告警数量; + - **资源消耗** :所选集群的 CPU、内存、磁盘的实际使用量和总量; + - **指标说明** :所选集群的 CPU、内存、磁盘读写、网络接收发送的变化趋势。 + + ![集群监控](../images/cluster.png){ width="1000"} + +3. 切换到 __资源水位线监控__ 页签,可查看当前集群的更多监控数据。 + + ![集群监控](../images/cluster-1.png){ width="1000"} + +## 参考指标说明 + +| 指标名 | 说明 | +| -- | -- | +| CPU 使用率 | 该指标是指集群中所有 Pod 资源的实际 CPU 用量与所有节点的 CPU 总量的比率。| +| CPU 分配率 | 该指标是指集群中所有 Pod 的 CPU 请求量的总和与所有节点的 CPU 总量的比率。| +| 内存使用率 | 该指标是指集群中所有 Pod 资源的实际内存用量与所有节点的内存总量的比率。| +| 内存分配率 | 该指标是指集群中所有 Pod 的内存请求量的总和与所有节点的内存总量的比率。| diff --git a/docs/zh/docs/end-user/insight/infra/container.md b/docs/zh/docs/end-user/insight/infra/container.md new file mode 100644 index 0000000..a9c18c0 --- /dev/null +++ b/docs/zh/docs/end-user/insight/infra/container.md @@ -0,0 +1,56 @@ +# 容器监控 + +容器监控是对集群管理中工作负载的监控,在列表中可查看工作负载的基本信息和状态。在工作负载详情页,可查看正在告警的数量以及 CPU、内存等资源消耗的变化趋势。 + +## 前提条件 + +集群已安装 insight-agent,且所有的容器组处于 __运行中__ 状态。 + +- 安装 insight-agent,请参考[在线安装 insight-agent](../quickstart/install/install-agent.md) + 或[离线升级 insight-agent](../quickstart/install/offline-install.md)。 + +## 操作步骤 + +请按照以下步骤查看服务监控指标: + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ -> __工作负载__ 。 + +3. 切换顶部 Tab,查看不同类型工作负载的数据。 + + ![容器监控](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/workload00.png){ width="1000"} + +4. 点击目标工作负载名称查看详情。 + + 1. 故障:在故障卡片中统计该工作负载当前正在告警的总数。 + 2. 资源消耗:在该卡片可查看工作负载的 CPU、内存、网络的使用情况。 + 3. 监控指标:可查看工作负载默认 1 小时的 CPU、内存、网络和磁盘的变化趋势。 + + ![容器监控](../images/workload.png){ width="1000"} + +5. 切换 Tab 到 __容器组列表__ ,可查看工作负载的各个容器组状态、所在节点、重启次数等信息。 + + ![容器监控](../images/workload-1.png){ width="1000"} + +6. 切换 Tab 到 __JVM 监控__ ,可查看各个容器组的 JVM 指标。 + + ![JVM 监控](../images/workload-2.png) + + !!! note + + 1. JVM 监控功能仅支持 Java 语言。 + 2. 开启 JVM 监控功能,请参考[开始监控 Java 应用](../quickstart/otel/java/index.md)。 + +## 指标参考说明 + +| **指标名称** | **说明** | +| -- | -- | +| CPU 使用量 |工作负载下所有容器组的 CPU 使用量之和。| +| CPU 请求量 | 工作负载下所有容器组的 CPU 请求量之和。| +| CPU 限制量 | 工作负载下所有容器组的 CPU 限制量之和。| +| 内存使用量 | 工作负载下所有容器组的内存使用量之和。| +| 内存请求量 | 工作负载下所有容器组的内存使用量之和。| +| 内存限制量 | 工作负载下所有容器组的内存限制量之和。| +| 磁盘读写速率 | 指定时间范围内磁盘每秒连续读取和写入的总和,表示磁盘每秒读取和写入操作数的性能度量。| +| 网络发送接收速率 | 指定时间范围内,按工作负载统计的网络流量的流入、流出速率。| diff --git a/docs/zh/docs/end-user/insight/infra/event.md b/docs/zh/docs/end-user/insight/infra/event.md new file mode 100644 index 0000000..eac30c1 --- /dev/null +++ b/docs/zh/docs/end-user/insight/infra/event.md @@ -0,0 +1,49 @@ +# 事件查询 + +AI 算力平台 Insight 支持按集群、命名空间查询事件,并提供了事件状态分布图,对重要事件进行统计。 + +## 操作步骤 + +1. 点击一级导航栏进入 __可观测性__ 。 +2. 左侧导航栏中,选择 __基础设置 > 事件__ 。 + + ![事件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/event00.png) + +### 事件状态分布 + +默认显示最近 12 小时内发生的事件,您可以在右上角选择不同的时间范围来查看较长或较短的时间段。 +您还可以自定义采样间隔为 1 分钟至 5 小时。 + +通过事件状态分布图,您可以直观地了解事件的密集程度和分散情况。 +这有助于对后续的集群运维进行评估,并做好准备和安排工作。 +如果事件密集发生在特定时段,您可能需要调配更多的资源或采取相应措施来确保集群稳定性和高可用性。 +而如果事件较为分散,在此期间您可以合理安排其他运维工作,例如系统优化、升级或处理其他任务。 + +通过综合考虑事件状态分布图和时间范围,您能更好地规划和管理集群的运维工作,确保系统稳定性和可靠性。 + +### 事件总数和统计 + +通过重要事件统计,您可以方便地了解镜像拉取失败次数、健康检查失败次数、容器组(Pod)运行失败次数、 +Pod 调度失败次数、容器 OOM 内存耗尽次数、存储卷挂载失败次数以及所有事件的总数。这些事件通常分为「Warning」和「Normal」两类。 + +### 事件列表 + +事件列表以时间为轴,以流水的形式展示发生的事件。您可以根据「最近发生时间」和「级别」进行排序。 + +点击右侧的 ⚙️ 图标,您可以根据自己的喜好和需求来自定义显示的列。 + +在需要的时候,您还可以点击刷新图标来更新当前的事件列表。 + +## 其他操作 + +1. 在事件列表中操作列的图标,可查看某一事件的元数据信息。 + + ![history](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/event01.png){ width="1000"} + +2. 点击顶部页签的 __上下文__ 可查看该事件对应资源的历史事件记录。 + + ![history](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/event02.png){ width="1000"} + +## 参考 + +有关系统自带的 Event 事件的详细含义,请参阅 [Kubenetest API 事件列表](https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/cluster-resources/event-v1/)。 diff --git a/docs/zh/docs/end-user/insight/infra/namespace.md b/docs/zh/docs/end-user/insight/infra/namespace.md new file mode 100644 index 0000000..7cdc392 --- /dev/null +++ b/docs/zh/docs/end-user/insight/infra/namespace.md @@ -0,0 +1,35 @@ +--- +hide: + - toc +--- + +# 命名空间监控 + +以命名空间为维度,快速查询命名空间内的资源消耗和变化趋势。 + +## 前提条件 + +集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ > __命名空间__ 。在该页面可查看以下信息: + + 1. **切换命名空间**:在顶部切换集群或命名空间; + 2. **资源概览**:统计所选命名空间下的正常和全部工作负载的数量; + 3. **故障**:统计所选命名空间下产生的告警数量; + 4. **事件**:统计所选命名空间下 24 小时内 Warning 级别的事件数量; + 5. **资源消耗**:统计所选命名空间下容器组的 CPU、内存使用量之和 及 CPU、内存配额情况。 + + ![命名空间](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/namespace00.png){ width="1000"} + +### 指标说明 + +| 指标名 | 说明 | +| -- | -- | +| CPU 使用量 | 所选命名空间中容器组的 CPU 使用量之和 | +| 内存使用量 | 所选命名空间中容器组的内存使用量之和 | +| 容器组 CPU 使用量 | 命名空间中各容器组的 CPU 使用量 | +| 容器组内存使用量 | 命名空间中各容器组的内存使用量 | diff --git a/docs/zh/docs/end-user/insight/infra/node.md b/docs/zh/docs/end-user/insight/infra/node.md new file mode 100644 index 0000000..9ca8e4f --- /dev/null +++ b/docs/zh/docs/end-user/insight/infra/node.md @@ -0,0 +1,26 @@ +# 节点监控 + +通过节点监控,你可以概览所选集群下节点的当前健康状态、对应容器组的异常数量; +在当前节点详情页,你可以查看正在告警的数量以及 CPU、内存、磁盘等资源消耗的变化趋势图。 + +## 前提条件 + +集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 + +## 操作步骤 + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __基础设施__ -> __节点__ 。在该页面可查看以下信息: + + - **集群切换** :切换顶部的下拉框可切换集群; + - **节点列表** :所选集群中的节点列表,单击切换节点。 + - **故障** :统计当前集群产生的告警数量; + - **资源消耗** :所选节点的 CPU、内存、磁盘的实际使用量和总量; + - **指标说明** :所选节点的 CPU、内存、磁盘读写、网络接收发送的变化趋势。 + + ![节点监控](../images/node.png){ width="1000"} + +3. 切换到 __资源水位线监控__ 页签,可查看当前节点的更多监控数据。 + + ![节点监控](../images/cluster-1.png){ width="1000"} diff --git a/docs/zh/docs/end-user/insight/infra/probe.md b/docs/zh/docs/end-user/insight/infra/probe.md new file mode 100644 index 0000000..50aad73 --- /dev/null +++ b/docs/zh/docs/end-user/insight/infra/probe.md @@ -0,0 +1,86 @@ +# 拨测 + +拨测(Probe)指的是基于黑盒监控,定期通过 HTTP、TCP 等方式对目标进行连通性测试,快速发现正在发生的故障。 + +Insight 基于 [Prometheus Blackbox Exporter](https://github.com/prometheus/blackbox_exporter) +工具通过 HTTP、HTTPS、DNS、TCP 和 ICMP 等协议,对网络进行探测并返回探测结果以便了解网络状态。 + +## 前提条件 + +目标集群中[已成功部署 insight-agent](../quickstart/install/install-agent.md),且处于 __运行中__ 状态。 + +## 查看拨测任务 + +1. 进入 __可观测性__ 产品模块; +2. 在左边导航栏选择 __基础设施__ -> __拨测__。 + + - 点击表格中的集群或命名空间下拉框,可切换集群和命名空间 + - 你可以点击右侧的 ⚙️ 修改显示的列,默认为拨测名称、探测方式、探测目标、连通状态、创建时间 + - 连通状态有 3 种: + - 正常:Probe 成功连接到了目标,目标返回了预期的响应 + - 异常:Probe 无法连接到目标,或目标没有返回预期的响应 + - Pending:Probe 正在尝试连接目标 + - 你可以在 🔍 搜索框中键入名称,模糊搜索某些拨测任务 + + ![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe00.png){ width=1000px} + +## 创建拨测任务 + +1. 点击 __创建拨测任务__。 +2. 填写基本信息后点击 __下一步__ + + - 集群:选择需要拨测的集群 + - 命名空间:拨测所在的命名空间 + + ![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe01.png){ width=1000px} + +3. 配置探测参数。 + + - Blackbox 实例:选择负责探测的 blackbox 实例 + - 探测方式: + - HTTP:通过发送 HTTP 或 HTTPS 请求到目标 URL,检测其连通性和响应时间,这可以用于监测网站或 Web 应用的可用性和性能 + - TCP:通过建立到目标主机和端口的 TCP 连接,检测其连通性和响应时间。这可以用于监测基于 TCP 的服务,如 Web 服务器、数据库服务器等 + - 其他:支持通过配置 ConfigMap 自定义探测方式,可参考[自定义拨测方式](../collection-manag/probe-module.md) + - 探测目标:探测的目标地址,支持域名或 IP 地址等 + - 标签:自定义标签,该标签会自动添加到 Prometheus 的 Label 中 + - 探测间隔:探测间隔时间 + - 探测超时:探测目标时的最长等待时间 + + ![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe02.png){ width=1000px} + +4. 配置完成后,点击 __确定__ 即可完成创建。 + +!!! warning + + 拨测任务创建完成后,需要大概 3 分钟的时间来同步配置。在此期间,不会进行探测,无法查看探测结果。 + +## 编辑拨测任务 + +点击列表右侧的 __┇__ -> __编辑__,完成编辑后点击 __确定__。 + +![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe04.png){ width=1000px} + +## 查看监控面板 + +点击`拨测名称` 查看拨测任务中每个目标的监控状态,以图表方式显示针对网络状况的探测结果。 + +![probe](../images/probe03.png){ width=1000px} + +| 指标名称 | 描述 | +| -- | -- | +| Current Status Response | 表示 HTTP 探测请求的响应状态码。| +| Ping Status | 表示探测请求是否成功。1 表示探测请求成功,0 表示探测请求失败。 | +| IP Protocol | 表示探测请求使用的 IP 协议版本。 | +| SSL Expiry | 表示 SSL/TLS 证书的最早到期时间。 | +| DNS Response (Latency) | 表示整个探测过程的持续时间,单位是秒。 | +| HTTP Duration | 表示从发送请求到接收到完整响应的整个过程的时间。| + +## 删除拨测任务 + +点击列表右侧的 __┇__ -> __删除__,确认无误后点击 __确定__。 + +![probe](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/probe05.png){ width=1000px} + +!!! caution + + 删除操作不可恢复,请谨慎操作。 diff --git a/docs/zh/docs/end-user/insight/quickstart/install/big-log-and-trace.md b/docs/zh/docs/end-user/insight/quickstart/install/big-log-and-trace.md new file mode 100644 index 0000000..4822cae --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/big-log-and-trace.md @@ -0,0 +1,281 @@ +# 开启大日志和大链路模式 + +可观测性模块为了提高大规模环境下的数据写入能力,支持将日志切换为 +**大日志** 模式、将链路切换为 **大链路** 模式。本文将介绍以下几种开启方式: + +- 通过[安装器开启或升级](#_8)至大日志和大链路模式(通过 manifest.yaml 中同一个参数值控制) +- 通过 [Helm 命令手动开启](#helm)大日志和大链路模式 + +## 日志 + +本节说明普通日志模式和大日志模式的区别。 + +### 日志模式 + +组件:Fluentbit + Elasticsearch + +该模式简称为 ES 模式,数据流图如下所示: + +![日志模式](../../images/big-log01.png) + +### 大日志模式 + +组件:Fluentbit + **Kafka** + **Vector** + Elasticsearch + +该模式简称为 Kafka 模式,数据流图如下所示: + +![大日志模式](../../images/big-log02.png) + +## 链路 + +本节说明普通链路模式和大链路模式的区别。 + +### 链路模式 + +组件:Agent opentelemetry-collector + Global opentelemetry-collector + Jaeger-collector + Elasticsearch + +该模式简称为 OTlp 模式,数据流图如下所示: + +![链路模式](../../images/big-log03.png) + +### 大链路模式 + +组件:Agent opentelemetry-collector + Kafka + Global opentelemetry-collector + Jaeger-collector + Elasticsearch + +该模式简称为 Kafka 模式,数据流图如下所示: + +![大链路模式](../../images/big-log04.png) + +## 通过安装器开启 + +通过安装器部署/升级 AI 算力中心 时使用的 manifest.yaml 中存在 infrastructures.kafka 字段, +如果想开启可观测的大日志和大链路模式,则需要启用 kafka: + +```yaml title="manifest.yaml" +apiVersion: manifest.daocloud.io/v1alpha1 +kind: DCEManifest +... +infrastructures: + ... + kafka: + enable: true # 默认为 false + cpuLimit: 1 + memLimit: 2Gi + pvcSize: 15Gi +``` + +### 开启 + +安装时使用启用 `kafka` 的 manifest.yaml,则会默认安装 kafka 中间件, +并在安装 Insight 时默认开启大日志和大链路模式。安装命令为: + +```bash +./dce5-installer cluster-create -c clusterConfig.yaml -m manifest.yaml +``` + +### 升级 + +升级同样是修改 `kafka` 字段。但需要注意的是,因为老环境安装时使用的是 `kafka: false`, +所以环境中无 kafka。此时升级需要指定升级 `middleware`,才会同时安装 kafka 中间件。升级命令为: + +```bash +./dce5-installer cluster-create -c clusterConfig.yaml -m manifest.yaml -u gproduct,middleware +``` + +!!! note + + 在升级完成后,需要手动重启以下组件: + + - insight-agent-fluent-bit + - insight-agent-opentelemetry-collector + - insight-opentelemetry-collector + +## 通过 Helm 命令开启 + +前提条件:需要保证存在 **可用的 kafka** 且地址可正常访问。 + +根据以下命令获取老版本 insight 和 insight-agent 的 values(建议做好备份): + +```bash +helm get values insight -n insight-system -o yaml > insight.yaml +helm get values insight-agent -n insight-system -o yaml > insight-agent.yaml +``` + +### 开启大日志 + +有以下几种方式开启或升级至大日志模式: + +=== "在 `helm upgrade` 命令中使用 --set" + + 先运行以下 insight 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --set global.kafka.brokers="10.6.216.111:30592" \ + --set global.kafka.enabled=true \ + --set vector.enabled=true \ + --version 0.30.1 + ``` + + 然后运行以下 insight-agent 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --set global.exporters.logging.kafka.brokers="10.6.216.111:30592" \ + --set global.exporters.logging.output=kafka \ + --version 0.30.1 + ``` + +=== "修改 YAML 后运行 helm upgrade" + + 参照以下步骤修改 YAMl 后运行 `helm upgrade` 命令: + + 1. 修改 insight.yaml + + ```yaml title="insight.yaml" + global: + ... + kafka: + brokers: 10.6.216.111:30592 + enabled: true + ... + vector: + enabled: true + ``` + + 1. 升级 insight 组件: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version 0.30.1 + ``` + + 1. 修改 insight-agent.yaml + + ```yaml title="insight-agent.yaml" + global: + ... + exporters: + ... + logging: + ... + kafka: + brokers: 10.6.216.111:30592 + output: kafka + ``` + + 1. 升级 insight-agent: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version 0.30.1 + ``` + +=== "容器管理 UI 升级" + + 在容器管理模块中,找到对应的集群,从左侧导航栏选择 **Helm 应用** ,找到并更新 insight-agent。 + + 在 **Logging Settings** 中,为 **output** 选择 **kafka**,并填写正确的 **brokers** 地址。 + + ![kpanda](../../images/big-log05.png) + + 需要注意的是,在升级完成后,需手动重启 **insight-agent-fluent-bit** 组件。 + +### 开启大链路 + +有以下几种方式开启或升级至大链路模式: + +=== "在 `helm upgrade` 命令中使用 --set" + + 先运行以下 insight 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --set global.kafka.brokers="10.6.216.111:30592" \ + --set global.kafka.enabled=true \ + --set global.tracing.kafkaReceiver.enabled=true \ + --version 0.30.1 + ``` + + 然后运行以下 insight-agent 升级命令,注意 kafka brokers 地址需正确: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --set global.exporters.trace.kafka.brokers="10.6.216.111:30592" \ + --set global.exporters.trace.output=kafka \ + --version 0.30.1 + ``` + +=== "修改 YAML 后运行 helm upgrade" + + 参照以下步骤修改 YAMl 后运行 `helm upgrade` 命令: + + 1. 修改 insight.yaml + + ```yaml title="insight.yaml" + global: + ... + kafka: + brokers: 10.6.216.111:30592 + enabled: true + ... + tracing: + ... + kafkaReceiver: + enabled: true + ``` + + 1. 升级 insight 组件: + + ```bash + helm upgrade insight insight-release/insight \ + -n insight-system \ + -f ./insight.yaml \ + --version 0.30.1 + ``` + + 1. 修改 insight-agent.yaml + + ```yaml title="insight-agent.yaml" + global: + ... + exporters: + ... + trace: + ... + kafka: + brokers: 10.6.216.111:30592 + output: kafka + ``` + + 1. 升级 insight-agent: + + ```bash + helm upgrade insight-agent insight-release/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version 0.30.1 + ``` + +=== "容器管理 UI 升级" + + 在容器管理模块中,找到对应的集群,从左侧导航栏选择 **Helm 应用** ,找到并更新 insight-agent。 + + 在 **Trace Settings** 中,为 **output** 选择 **kafka**,并填写正确的 **brokers** 地址。 + + ![UI 上升级](../../images/big-log06.png) + + 需要注意的是,在升级完成后,需手动 + **重启 insight-agent-opentelemetry-collector** 和 **insight-opentelemetry-collector** 组件。 diff --git a/docs/zh/docs/end-user/insight/quickstart/install/component-scheduling.md b/docs/zh/docs/end-user/insight/quickstart/install/component-scheduling.md new file mode 100644 index 0000000..3490c2e --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/component-scheduling.md @@ -0,0 +1,318 @@ +# 自定义 Insight 组件调度策略 + +当部署可观测平台 Insight 到 Kubernetes 环境时,正确的资源管理和优化至关重要。 +Insight 包含多个核心组件,如 Prometheus、OpenTelemetry、FluentBit、Vector、Elasticsearch 等, +这些组件在运行过程中可能因为资源占用问题对集群内其他 Pod 的性能产生负面影响。 +为了有效地管理资源并优化集群的运行,节点亲和性成为一项重要的配置选项。 + +本文将重点探讨如何通过[污点](#insight)和[节点亲和性](#label)的配置策略,使得每个组件能够在适当的节点上运行, +并避免资源竞争或争用,从而确保整个 Kubernetes 集群的稳定性和高效性。 + +## 通过污点为 Insight 配置专有节点 + +由于 Insight Agent 包含了 DaemonSet 组件,所以本节所述的配置方式是让除了 Insight DameonSet 之外的其余组件均运行在专有节点上。 + +该方式是通过为专有节点添加污点(taint),并配合污点容忍度(tolerations)来实现的。 +更多细节可以参考 [Kubernetes 官方文档](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)。 + +可以参考如下命令为节点添加及移除污点: + +```bash +# 添加污点 +kubectl taint nodes worker1 node.daocloud.io=insight-only:NoSchedule + +# 移除污点 +kubectl taint nodes worker1 node.daocloud.io:NoSchedule- +``` + +有以下两种途径让 Insight 组件调度至专有节点: + +### 1. 为每个组件添加污点容忍度 + +针对 `insight-server` 和 `insight-agent` 两个 Chart 分别进行配置: + +=== "insight-server Chart 配置" + + ```yaml + server: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + ui: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + runbook: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + # mysql: + victoria-metrics-k8s-stack: + victoria-metrics-operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmcluster: + spec: + vmstorage: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmselect: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vminsert: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + vmalert: + spec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + alertmanager: + spec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + jaeger: + collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + query: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + opentelemetry-collector-aggregator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + opentelemetry-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + grafana-operator: + operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + grafana: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + kibana: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + elastic-alert: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + vector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + ``` + +=== "insight-agent Chart 配置" + + ```yaml + kube-prometheus-stack: + prometheus: + prometheusSpec: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + prometheus-node-exporter: + tolerations: + - effect: NoSchedule + operator: Exists + prometheusOperator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + + kube-state-metrics: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + tailing-sidecar-operator: + operator: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + opentelemetry-kubernetes-collector: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + prometheus-blackbox-exporter: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + etcd-exporter: + tolerations: + - key: "node.daocloud.io" + operator: "Equal" + value: "insight-only" + effect: "NoSchedule" + ``` + +### 2. 通过命名空间级别配置 + +让 `insight-system` 命名空间的 Pod 都容忍 `node.daocloud.io=insight-only` 污点。 + +1. 调整 `apiserver` 的配置文件 `/etc/kubernetes/manifests/kube-apiserver.yaml`,放开 `PodTolerationRestriction,PodNodeSelector`, 参考下图: + + ![insight-ns-toleration](../../images/insight-ns-toleration.png) + +2. 给 `insight-system` 命名空间增加注解: + + ```yaml + apiVersion: v1 + kind: Namespace + metadata: + name: insight-system + annotations: + scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Equal", "effect": "NoSchedule", "key": "node.daocloud.io", "value": "insight-only"}]' + ``` + +重启 insight-system 命名空间下面的组件即可正常容忍 insight-system 下的 Pod 调度。 + +## 为节点添加 Label 和节点亲和性来管理组件调度 + +!!! info + + 节点亲和性概念上类似于 `nodeSelector`,它使你可以根据节点上的 **标签(label)** 来约束 Pod 可以调度到哪些节点上。 + 节点亲和性有两种: + + 1. requiredDuringSchedulingIgnoredDuringExecution:调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。 + 2. preferredDuringSchedulingIgnoredDuringExecution:调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。 + + 更过细节请参考 [kubernetes 官方文档](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)。 + +为了实现不同用户对 Insight 组件调度的灵活需求,Insight 分别提供了较为细粒度的 Label 来实现不同组件的调度策略,以下是标签与组件的关系说明: + +| 标签 Key | 标签 Value | 说明 | +| --- | ------- | ------------ | +| `node.daocloud.io/insight-any` | 任意值,推荐用 `true` | 代表 Insight 所有组件优先考虑带了该标签的节点 | +| `node.daocloud.io/insight-prometheus` | 任意值,推荐用 `true` | 特指 Prometheus 组件 | +| `node.daocloud.io/insight-vmstorage` | 任意值,推荐用 `true` | 特指 VictoriaMetrics vmstorage 组件 | +| `node.daocloud.io/insight-vector` | 任意值,推荐用 `true` | 特指 Vector 组件 | +| `node.daocloud.io/insight-otel-col` | 任意值,推荐用 `true` | 特指 OpenTelemetry 组件 | + +可以参考如下命令为节点添加及移除标签: + +```bash +# 为 node8 添加标签,先将 insight-prometheus 调度到 node8 +kubectl label nodes node8 node.daocloud.io/insight-prometheus=true + +# 移除 node8 的 node.daocloud.io/insight-prometheus 标签 +kubectl label nodes node8 node.daocloud.io/insight-prometheus- +``` + +以下是 insight-prometheus 组件在部署时默认的亲和性偏好: + +```yaml +affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: DoesNotExist + weight: 1 + - preference: + matchExpressions: + - key: node.daocloud.io/insight-prometheus # (1)! + operator: Exists + weight: 2 + - preference: + matchExpressions: + - key: node.daocloud.io/insight-any + operator: Exists + weight: 3 + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - insight-agent-kube-prometh-prometheus +``` + +1. 先将 insight-prometheus 调度到带有 node.daocloud.io/insight-prometheus 标签的节点 diff --git a/docs/zh/docs/end-user/insight/quickstart/install/gethosturl.md b/docs/zh/docs/end-user/insight/quickstart/install/gethosturl.md new file mode 100644 index 0000000..0697ee8 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/gethosturl.md @@ -0,0 +1,176 @@ +# 获取全局服务集群的数据存储地址 + +可观测性是多集群统一观测的产品,为实现对多集群观测数据的统一存储、查询, +子集群需要将采集的观测数据上报给[全局服务集群](../../../kpanda/clusters/cluster-role.md#_2)进行统一存储。 +本文提供了在安装采集组件 insight-agent 时必填的存储组件的地址。 + +## 在全局服务集群安装 insight-agent + +如果在全局服务集群安装 insight-agent,推荐通过域名来访问集群: + +```shell +export vminsert_host="vminsert-insight-victoria-metrics-k8s-stack.insight-system.svc.cluster.local" # (1)! +export es_host="insight-es-master.insight-system.svc.cluster.local" # (2)! +export otel_col_host="insight-opentelemetry-collector.insight-system.svc.cluster.local" # (3)! +``` + +## 在其他集群安装 insight-agent + +### 通过 Insight Server 提供的接口获取地址 + +1. [管理集群](../../../kpanda/clusters/cluster-role.md#_3)使用默认的 LoadBalancer 方式暴露 + + 登录全局服务集群的控制台,执行以下命令: + + ```bash + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' + ``` + + !!! note + + 请替换命令中的 `${INSIGHT_SERVER_IP}` 参数。 + + 获得如下返回值: + + ```json + { + "values": { + "global": { + "exporters": { + "logging": { + "host": "10.6.182.32" + }, + "metric": { + "host": "10.6.182.32" + }, + "auditLog": { + "host": "10.6.182.32" + }, + "trace": { + "host": "10.6.182.32" + } + } + }, + "opentelemetry-operator": { + "enabled": true + }, + "opentelemetry-collector": { + "enabled": true + } + } + } + ``` + + - `global.exporters.logging.host` 是日志服务地址,不需要再设置对应服务的端口,都会使用相应默认值 + - `global.exporters.metric.host` 是指标服务地址 + - `global.exporters.trace.host` 是链路服务地址 + - `global.exporters.auditLog.host` 是审计日志服务地址(和链路使用的同一个服务不同端口) + +1. 管理集群禁用 LoadBalancer + + 调用接口时需要额外传递集群中任意外部可访问的节点 IP,会使用该 IP 拼接出对应服务的完整访问地址。 + + ```bash + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' --data '{"extra": {"EXPORTER_EXTERNAL_IP": "10.5.14.51"}}' + ``` + + 将获得如下的返回值: + + ```json + { + "values": { + "global": { + "exporters": { + "logging": { + "scheme": "https", + "host": "10.5.14.51", + "port": 32007, + "user": "elastic", + "password": "j8V1oVoM1184HvQ1F3C8Pom2" + }, + "metric": { + "host": "10.5.14.51", + "port": 30683 + }, + "auditLog": { + "host": "10.5.14.51", + "port": 30884 + }, + "trace": { + "host": "10.5.14.51", + "port": 30274 + } + } + }, + "opentelemetry-operator": { + "enabled": true + }, + "opentelemetry-collector": { + "enabled": true + } + } + } + ``` + + - `global.exporters.logging.host` 是日志服务地址 + - `global.exporters.logging.port` 是日志服务暴露的 NodePort + - `global.exporters.metric.host` 是指标服务地址 + - `global.exporters.metric.port` 是指标服务暴露的 NodePort + - `global.exporters.trace.host` 是链路服务地址 + - `global.exporters.trace.port` 是链路服务暴露的 NodePort + - `global.exporters.auditLog.host` 是审计日志服务地址(和链路使用的同一个服务不同端口) + - `global.exporters.auditLog.host` 是审计日志服务暴露的 NodePort + +### 通过 LoadBalancer 连接 + +1. 若集群中开启 `LoadBalancer` 且为 Insight 设置了 `VIP` 时,您也可以手动执行以下命令获取 `vminsert` 以及 `opentelemetry-collector` 的地址信息: + + ```shell + $ kubectl get service -n insight-system | grep lb + lb-insight-opentelemetry-collector LoadBalancer 10.233.23.12 4317:31286/TCP,8006:31351/TCP 24d + lb-vminsert-insight-victoria-metrics-k8s-stack LoadBalancer 10.233.63.67 8480:31629/TCP 24d + ``` + + - `lb-vminsert-insight-victoria-metrics-k8s-stack` 是指标服务的地址 + - `lb-insight-opentelemetry-collector` 是链路服务的地址 + +1. 执行以下命令获取 ` elasticsearch` 地址信息: + + ```shell + $ kubectl get service -n mcamel-system | grep es + mcamel-common-es-cluster-masters-es-http NodePort 10.233.16.120 9200:30465/TCP 47d + ``` + + `mcamel-common-es-cluster-masters-es-http` 是日志服务的地址 + +### 通过 NodePort 连接 + +全局服务集群禁用 LB 特性 + +在该情况下,默认不会创建上述的 LoadBalancer 资源,对应服务名为: + +- vminsert-insight-victoria-metrics-k8s-stack(指标服务) +- common-es(日志服务) +- insight-opentelemetry-collector(链路服务) + +上面两种情况获取到对应服务的对应端口信息后,进行如下设置: + +```shell +--set global.exporters.logging.host= # (1)! +--set global.exporters.logging.port= # (2)! +--set global.exporters.metric.host= # (3)! +--set global.exporters.metric.port= # (4)! +--set global.exporters.trace.host= # (5)! +--set global.exporters.trace.port= # (6)! +--set global.exporters.auditLog.host= # (7)! +``` + +1. 外部可访问的管理集群 NodeIP +2. 日志服务 9200 端口对应的 NodePort +3. 外部可访问的管理集群 NodeIP +4. 指标服务 8480 端口对应的 NodePort +5. 外部可访问的管理集群 NodeIP +6. 链路服务 4317 端口对应的 NodePort +7. 外部可访问的管理集群 NodeIP diff --git a/docs/zh/docs/end-user/insight/quickstart/install/helm-installagent.md b/docs/zh/docs/end-user/insight/quickstart/install/helm-installagent.md new file mode 100644 index 0000000..7b1d92c --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/helm-installagent.md @@ -0,0 +1,142 @@ +# 通过 Helm 部署 Insight Agent + +本文描述了在命令行中通过 Helm 命令安装 Insight Agent 社区版的操作步骤。 + +## 安装 Insight Agent + +1. 使用以下命令添加镜像仓库的地址 + + ```shell + helm repo add insight https://release.daocloud.io/chartrepo/insight + helm repo upgrade + helm search repo insight/insight-agent --versions + ``` + +2. 安装 __Insight Agent__ 需要确保全局服务集群中的 __Insight Server__ 正常运行,执行以下安装命令安装 __Insight Agent__ 社区版,该配置不启用 Tracing 功能: + + ```shell + helm upgrade --install --create-namespace --cleanup-on-fail \ + --version ${version} \ # 请指定部署版本 + insight-agent insight/insight-agent \ + --set global.exporters.logging.elasticsearch.host=10.10.10.x \ # 请替换“10.10.10.x" 为全局服务集群或外置的 Elasticsearch 的地址 + --set global.exporters.logging.elasticsearch.port=32517 \ # 请替换“32517" 为全局服务集群或外置的 Elasticsearch 暴露的端口 + --set global.exporters.logging.elasticsearch.user=elastic \ # 请替换“elastic" 为全局服务集群或外置的 Elasticsearch 的用户名 + --set global.exporters.logging.elasticsearch.password=dangerous \ # 请替换“dangerous" 为全局服务集群或外置的 Elasticsearch 的密码 + --set global.exporters.metric.host=${vminsert_address} \ # 请替换“10.10.10.x" 为全局服务集群中 vminsert 的地址 + --set global.exporters.metric.port=${vminsert_port} \ # 请替换“32517" 为全局服务集群中 vminsert 的地址 + --set global.exporters.auditLog.host=${opentelemetry-collector address} \ # 请替换“32517" 为全局服务集群中 opentelemetry-collector 的端口 + --set global.exporters.auditLog.port=${otel_col_auditlog_port}\ # 请替换“32517" 为全局服务集群中 opentelemetry-collector 容器端口为 8006 的 service 对外访问的地址 + -n insight-system + ``` + + !!! info + + 可参考 __如何获取连接地址__ 获取地址信息。 + +3. 执行以下命令确认安装状态: + + ```shell + helm list -A + kubectl get pods -n insight-system + ``` + +### 如何获取连接地址 + +#### 在全局服务集群安装 Insight Agent + +如果 Agent 是安装在管理集群,推荐通过域名来访问集群: + +```shell +export vminsert_host="vminsert-insight-victoria-metrics-k8s-stack.insight-system.svc.cluster.local" # 指标 +export es_host="insight-es-master.insight-system.svc.cluster.local" # 日志 +export otel_col_host="insight-opentelemetry-collector.insight-system.svc.cluster.local" # 链路 +``` + +#### 在工作集群安装 Insight Agent + +=== "全局服务集群使用默认的 LoadBalancer" + + 全局服务集群使用默认的 LoadBalancer 方式暴露服务时,登录全局服务集群的控制台,执行以下命令: + + ```shell + export INSIGHT_SERVER_IP=$(kubectl get service insight-server -n insight-system --output=jsonpath={.spec.clusterIP}) + curl --location --request POST 'http://'"${INSIGHT_SERVER_IP}"'/apis/insight.io/v1alpha1/agentinstallparam' + ``` + + 将获得如下的返回值: + + ```shell + {"global":{"exporters":{"logging":{"output":"elasticsearch","elasticsearch":{"host":"10.6.182.32"},"kafka":{},"host":"10.6.182.32"},"metric":{"host":"10.6.182.32"},"auditLog": {"host":"10.6.182.32"}}},"opentelemetry-operator":{"enabled":true},"opentelemetry-collector":{"enabled":true}} + ``` + + 其中: + + - __global.exporters.logging.elasticsearch.host__ 是日志服务地址【不需要再设置对应服务的端口,都会使用相应默认值】; + - __global.exporters.metric.host__ 是指标服务地址; + - __global.exporters.trace.host__ 是链路服务地址; + - __global.exporters.auditLog.host__ 是审计日志服务地址 (和链路使用的同一个服务不同端口); + +=== "登录全局服务集群的控制台操作" + + 登录全局服务集群的控制台,执行以下命令: + + ```shell + kubectl get service -n insight-system | grep lb + kubectl get service -n mcamel-system | grep es + ``` + + 其中: + + - __lb-vminsert-insight-victoria-metrics-k8s-stack__ 是指标服务的地址; + - __lb-insight-opentelemetry-collector__ 是链路服务的地址; + - __mcamel-common-es-cluster-masters-es-http__ 是日志服务的地址; + +=== "全局服务集群使用 Nodeport" + + 全局服务集群使用 Nodeport 方式暴露服务时,登录全局服务集群的控制台,执行以下命令: + + ```shell + kubectl get service -n insight-system + kubectl get service -n mcamel-system + ``` + + 其中: + + - __vminsert-insight-victoria-metrics-k8s-stack__ 是指标服务的地址; + - __insight-opentelemetry-collector__ 是链路服务的地址; + - __mcamel-common-es-cluster-masters-es-http__ 是日志服务的地址; + +## 升级 Insight Agent + +1. 登录目标集群的控制台,执行以下命令备份 `--set` 参数。 + + ```shell + helm get values insight-agent -n insight-system -o yaml > insight-agent.yaml + ``` + +2. 执行以下命令更新仓库。 + + ```shell + helm repo upgrade + ``` + +3. 执行以下命令进行升级。 + + ```shell + helm upgrade insight-agent insight/insight-agent \ + -n insight-system \ + -f ./insight-agent.yaml \ + --version ${version} # 指定升级版本 + ``` + +4. 执行以下命令确认安装状态: + + ```shell + kubectl get pods -n insight-system + ``` + +## 卸载 Insight Agent + +```shell +helm uninstall insight-agent -n insight-system --timeout 10m +``` diff --git a/docs/zh/docs/end-user/insight/quickstart/install/index.md b/docs/zh/docs/end-user/insight/quickstart/install/index.md new file mode 100644 index 0000000..0efe4bc --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/index.md @@ -0,0 +1,21 @@ +# 开始观测 + +AI 算力中心 平台实现了对多云多集群的纳管,并支持创建集群。在此基础上,可观测性 Insight 作为多集群统一观测方案,通过部署 insight-agent 插件实现对多集群观测数据的采集,并支持通过 AI 算力中心 可观测性产品实现对指标、日志、链路数据的查询。 + + __insight-agent__ 是可观测性实现对多集群数据采集的工具,安装后无需任何修改,即可实现对指标、日志以及链路数据的自动化采集。 + +通过 __容器管理__ 创建的集群默认会安装 insight-agent,故在此仅针对接入的集群如何开启观测能力提供指导。 + +- [在线安装 insight-agent](install-agent.md) + +可观测性 Insight 作为多集群的统一观测平台,其部分组件的资源消耗与创建集群的数据、接入集群的数量息息相关,在安装 insight-agent 时,需要根据集群规模对相应组件的资源进行调整。 + +1. 根据创建集群的规模或接入集群的规模,调整 insight-agent 中采集组件 __Prometheus__ 的 CPU 和内存,请参考: [Prometheus 资源规划](../res-plan/prometheus-res.md) + +2. 由于多集群的指标数据会统一存储,则需要 AI 算力中心 平台管理员根据创建集群的规模、接入集群的规模对应调整 vmstorage 的磁盘,请参考:[vmstorage 磁盘容量规划](../res-plan/vms-res-plan.md)。 + +- 如何调整 vmstorage 的磁盘,请参考:[vmstorge 磁盘扩容](../res-plan/modify-vms-disk.md)。 + +由于 AI 算力中心 支持对多云多集群的纳管,insight-agent 目前也完成了部分验证,由于监控组件冲突问题导致在 AI 算力中心4.0 集群和 Openshift 4.x 集群中安装 insight-agent 会出现问题,若您遇到同样问题,请参考以下文档: + +- [在 Openshift 4.x 安装 insight-agent](../other/install-agent-on-ocp.md) diff --git a/docs/zh/docs/end-user/insight/quickstart/install/install-agent.md b/docs/zh/docs/end-user/insight/quickstart/install/install-agent.md new file mode 100644 index 0000000..77083d4 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/install-agent.md @@ -0,0 +1,43 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# 在线安装 insight-agent + + __insight-agent__ 是集群观测数据采集的插件,支持对指标、链路、日志数据的统一观测。本文描述了如何在在线环境中为接入集群安装 insight-agent。 + +## 前提条件 + +- 集群已成功接入 __容器管理__ 模块。如何接入集群,请参考:[接入集群](../../../kpanda/clusters/integrate-cluster.md) + +## 操作步骤 + +1. 进入 __容器管理__ 模块,在 __集群列表__ 中找到要安装 insight-agent 的集群名称。 + + ![确定集群](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent01.png) + +2. 选择 __立即安装__ 跳转,或点击集群,在左侧导航栏内点击 __Helm 应用__ -> __Helm 模板__ ,搜索框查询 __insight-agent__ ,点击该卡片进入详情。 + + ![查询 insight-agent](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent02.png) + +3. 查看 insight-agent 的安装页面,点击 __安装__ 进入下一步。 + + ![安装](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent03.png) + +4. 选择安装的版本并在下方表单分别填写全局服务集群中对应数据存储组件的地址,确认填写的信息无误后,点击 __确定__ 。 + + - insight-agent 默认部署在集群的 insight-system 命名空间下。 + - 建议安装最新版本的 insight-agent。 + - 系统默认已填写数据上报的组件的地址,仍请您检查无误后再点击 __确定__ 进行安装。 如需修改数据上报地址,请参考:[获取数据上报地址](../install/gethosturl.md)。 + + ![填写表单](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent04.png) + +5. 系统将自动返回  __Helm 应用__ 列表,当应用 insight-agent 的状态从  __未就绪__ 变为 __已部署__ ,且所有的组件状态为 __运行中__ 时,则安装成功。等待一段时间后,可在 __可观测性__ 模块查看该集群的数据。 + + ![结束界面](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/insight-agent05.png) + +!!! note + + - 点击最右侧的 __┇__ ,您可以在弹出菜单中执行更多操作,如 __更新__ 、 __查看 YAML__ 和 __删除__ 。 diff --git a/docs/zh/docs/end-user/insight/quickstart/install/knownissues.md b/docs/zh/docs/end-user/insight/quickstart/install/knownissues.md new file mode 100644 index 0000000..bad326a --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/knownissues.md @@ -0,0 +1,73 @@ +# 已知问题 + +本页列出一些 Insight Agent 安装和卸载有关的问题及其解决办法。 + +## v0.23.0 + +### Insight Agent + +#### Insight Agent 卸载失败 + +当你运行以下命令卸载 Insight Agent 时。 + +```sh +helm uninstall insight-agent -n insight-system +``` + +`otel-oprator` 所使用的 `tls secret` 未被卸载掉。 + +`otel-operator` 定义的“重复利用 tls secret”的逻辑中,会去判断 `otel-oprator` 的 `MutationConfiguration` +是否存在并重复利用 MutationConfiguration 中绑定的 CA cert。但是由于 `helm uninstall` 已卸载 `MutationConfiguration`,导致出现空值。 + +综上请手动删除对应的 `secret`,以下两种方式任选一种即可: + +- **通过命令行删除**:登录目标集群的控制台,执行以下命令: + + ```sh + kubectl -n insight-system delete secret insight-agent-opentelemetry-operator-controller-manager-service-cert + ``` + +- **通过 UI 删除**:登录 AI 算力中心 容器管理,选择目标集群,从左侧导航进入`密钥`,输入 + `insight-agent-opentelemetry-operator-controller-manager-service-cert`,选择`删除`。 + +## v0.22.0 + +### Insight Agent + +#### 升级 Insight Agent 时更新日志收集端,未生效 + +更新 insight-agent 日志配置从 elasticsearch 改为 kafka 或者从 kafka 改为 elasticsearch,实际上都未生效,还是使用更新前配置。 + +**解决方案** : + +手动重启集群中的 fluentbit。 + +## v0.21.0 + +### Insight Agent + +#### PodMonitor 采集多份 JVM 指标数据 + +1. 这个版本的 **PodMonitor/insight-kubernetes-pod** 存在缺陷:会错误地创建 Job 去采集标记了 + `insight.opentelemetry.io/metric-scrape=true` 的 Pod 的所有 container;而实际上只需采集 + `insight.opentelemetry.io/metric-port` 所对应 container 的端口。 + +2. 因为 PodMonitor 声明之后,**PromethuesOperator** 会预设置一些服务发现配置。 + 再考虑到 CRD 的兼容性的问题。因此,放弃通过 PodMonitor 来配置通过 **annotation** 创建采集任务的机制。 + +3. 通过 Prometheus 自带的 additional scrape config 机制,将服务发现规则配置在 secret 中,在引入 Prometheus 里。 + +综上: + +1. 删除这个 **PodMonitor** 的当前 **insight-kubernetes-pod** +2. 使用新的规则 + +新的规则里通过 **action: keepequal** 来比较 **source_labels** 和 **target_label** 的一致性, +来判断是否要给某个 container 的 port 创建采集任务。需要注意,这个是 Prometheus 2.41.0(2022-12-20)和更高版本才具备的功能。 + +```diff ++ - source_labels: [__meta_kubernetes_pod_annotation_insight_opentelemetry_io_metric_port] ++ separator: ; ++ target_label: __meta_kubernetes_pod_container_port_number ++ action: keepequal +``` diff --git a/docs/zh/docs/end-user/insight/quickstart/install/upgrade-note.md b/docs/zh/docs/end-user/insight/quickstart/install/upgrade-note.md new file mode 100644 index 0000000..0c5b4b9 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/install/upgrade-note.md @@ -0,0 +1,149 @@ +# 升级注意事项 + +本页介绍一些升级 insight-server 和 insight-agent 的注意事项。 + +## insight-agent + +### 从 v0.28.x(或更低版本)升级到 v0.29.x + +由于 v0.29.0 升级了 Opentelemetry 社区的 operator chart 版本,values 中的 featureGates 的支持的值有所变化,因此,在 upgrade 之前,需要将 `featureGates` 的值设置为空, 即: + +```diff +- --set opentelemetry-operator.manager.featureGates="+operator.autoinstrumentation.go,+operator.autoinstrumentation.multi-instrumentation,+operator.autoinstrumentation.nginx" \ ++ --set opentelemetry-operator.manager.featureGates="" +``` + +## insight-server + +### 从 v0.26.x(或更低版本)升级到 v0.27.x 或更高版本 + +在 v0.27.x 版本中将 vector 组件的开关单独抽出。故原有环境开启了 vector,那在升级 insight-server 时,需要指定 `--set vector.enabled=true` 。 + +### 从 v0.19.x(或更低版本)升级到 0.20.x + +在升级 __Insight__ 之前,您需要执行以下命令手动删除 __jaeger-collector__ 和 __jaeger-query__ 部署: + +```bash +kubectl -n insight-system delete deployment insight-jaeger-collector +kubectl -n insight-system delete deployment insight-jaeger-query +``` + +### 从 v0.17.x(或更低版本)升级到 v0.18.x + +由于 0.18.x 中更新了 Jaeger 相关部署文件,因此需要在升级 insight-server 前手动执行如下命令: + +```bash +kubectl -n insight-system delete deployment insight-jaeger-collector +kubectl -n insight-system delete deployment insight-jaeger-query +``` + +由于 0.18.x 中指标名产生了变动,因此,需要在升级 insight-server 之后,insight-agent 也应该做升级。 + +此外,调整了开启链路模块的参数,以及 ElasticSearch 连接调整。具体参考以下参数: + +```diff ++ --set global.tracing.enable=true \ +- --set jaeger.collector.enabled=true \ +- --set jaeger.query.enabled=true \ ++ --set global.elasticsearch.scheme=${your-external-elasticsearch-scheme} \ ++ --set global.elasticsearch.host=${your-external-elasticsearch-host} \ ++ --set global.elasticsearch.port=${your-external-elasticsearch-port} \ ++ --set global.elasticsearch.user=${your-external-elasticsearch-username} \ ++ --set global.elasticsearch.password=${your-external-elasticsearch-password} \ +- --set jaeger.storage.elasticsearch.scheme=${your-external-elasticsearch-scheme} \ +- --set jaeger.storage.elasticsearch.host=${your-external-elasticsearch-host} \ +- --set jaeger.storage.elasticsearch.port=${your-external-elasticsearch-port} \ +- --set jaeger.storage.elasticsearch.user=${your-external-elasticsearch-username} \ +- --set jaeger.storage.elasticsearch.password=${your-external-elasticsearch-password} \ +``` + +### 从 v0.15.x(或更低版本)升级到 v0.16.x + +由于 0.16.x 中使用了 vmalertmanagers CRD 的新特性参数 disableRouteContinueEnforce, +因此需要在升级 insight-server 前手动执行如下命令。 + +```shell +kubectl apply --server-side -f https://raw.githubusercontent.com/VictoriaMetrics/operator/v0.33.0/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml --force-conflicts +``` + +!!! note + + 如您是离线安装,可以在解压 Insight 离线包后,请执行以下命令更新 CRD。 + + ```shell + kubectl apply --server-side -f insight/dependency-crds --force-conflicts + ``` + +## insight-agent + +### 从 v0.23.x(或更低版本)升级到 v0.24.x + +由于 0.24.x 版本中 `OTEL operator chart` 中新增了 CRD,但由于 Helm Upgrade 时并不会更新 CRD,因此,需要手动执行以下命令: + +```shell +kubectl apply -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-helm-charts/main/charts/opentelemetry-operator/crds/crd-opentelemetry.io_opampbridges.yaml +``` + +如您是离线安装,可以在解压 insight-agent 离线包后可找到上述 CRD 的 yaml,解压 Insight-Agent Chart 之后手动执行以下命令: + +```shell +kubectl apply -f charts/agent/crds/crd-opentelemetry.io_opampbridges.yaml +``` + +### 从 v0.19.x(或更低版本)升级到 v0.20.x + +由于 0.20.x 中增加了 Kafka 日志导出配置,日志导出配置做了一些调整。升级 __insight-agent__ 之前需要注意参数变化, +即原来 logging 的配置已经移到了配置中 logging.elasticsearch: + +```diff +- --set global.exporters.logging.host \ +- --set global.exporters.logging.port \ ++ --set global.exporters.logging.elasticsearch.host \ ++ --set global.exporters.logging.elasticsearch.port \ +``` + +### 从 v0.17.x(或更低版本)升级到 v0.18.x + +由于 0.18.x 中更新了 Jaeger 相关部署文件,因此需要在升级 insight-agent 前需要注意参数的改动。 + +```diff ++ --set global.exporters.trace.enable=true \ +- --set opentelemetry-collector.enabled=true \ +- --set opentelemetry-operator.enabled=true \ +``` + +### 从 v0.16.x(或更低版本)升级到 v0.17.x + +在 v0.17.x 版本中将 kube-prometheus-stack chart 版本从 41.9.1 升级至 45.28.1, 其中使用的 CRD 也存在一些字段的升级,如 servicemonitor 的 __attachMetadata__ 字段,因此需要在升级 insight-agent 前执行如下命令: + +```bash +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.65.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --force-conflicts +``` + +如您是离线安装,可以在解压 insight-agent 离线包后,在 insight-agent/dependency-crds 中找到上述 CRD 的 yaml。 + +### 从 v0.11.x(或更低版本)升级到 v0.12.x + +在 v0.12.x 将 kube-prometheus-stack chart 从 39.6.0 升级到 41.9.1,其中包括 prometheus-operator 升级到 v0.60.1, prometheus-node-exporter chart 升级到 4.3.0 等。 +prometheus-node-exporter 升级后使用了 [Kubernetes 推荐 label](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/),因此需要在升级前删除 __node-exporter__ 的 DaemonSet。 +prometheus-operator 更新了 CRD,因此需要在升级 insight-agent 前执行如下命令: + +```shell linenums="1" +kubectl delete daemonset insight-agent-prometheus-node-exporter -n insight-system +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagerconfigs.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_alertmanagers.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheuses.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --force-conflicts +kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.60.1/example/prometheus-operator-crd/monitoring.coreos.com_thanosrulers.yaml --force-conflicts +``` + +!!! note + + 如您是离线安装,可以在解压 insight-agent 离线包后,执行以下命令更新 CRD。 + + ```shell + kubectl apply --server-side -f insight-agent/dependency-crds --force-conflicts + ``` diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/golang/golang.md b/docs/zh/docs/end-user/insight/quickstart/otel/golang/golang.md new file mode 100644 index 0000000..8eb650d --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/golang/golang.md @@ -0,0 +1,361 @@ +# 使用 OTel SDK 增强 Go 应用程序 + +Golang 无侵入式接入链路请参考 [通过 Operator 实现应用程序无侵入增强](../operator.md) 文档,通过注解实现自动接入链路。 + +OpenTelemetry 也简称为 OTel,是一个开源的可观测性框架,可以帮助在 Go 应用程序中生成和收集遥测数据:链路、指标和日志。 + +本文主要讲解如何在 Go 应用程序中通过 OpenTelemetry Go SDK 增强并接入链路监控。 + +## 使用 OTel SDK 增强 Go 应用 + +### 安装相关依赖 + +必须先安装与 OpenTelemetry exporter 和 SDK 相关的依赖项。如果您正在使用其他请求路由器,请参考[请求路由](#_3)。 +切换/进入到应用程序源文件夹后运行以下命令: + +```golang +go get go.opentelemetry.io/otel@v1.19.0 \ + go.opentelemetry.io/otel/trace@v1.19.0 \ + go.opentelemetry.io/otel/sdk@v1.19.0 \ + go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin@v0.46.1 \ + go.opentelemetry.io/otel/exporters/otlp/otlptrace@v1.19.0 \ + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@v1.19.0 +``` + +### 使用 OTel SDK 创建初始化函数 + +为了让应用程序能够发送数据,需要一个函数来初始化 OpenTelemetry。在 __main.go__ 文件中添加以下代码片段: + +```golang +import ( + "context" + "os" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" + "go.uber.org/zap" + "google.golang.org/grpc" +) + +var tracerExp *otlptrace.Exporter + +func retryInitTracer() func() { + var shutdown func() + go func() { + for { + // otel will reconnected and re-send spans when otel col recover. so, we don't need to re-init tracer exporter. + if tracerExp == nil { + shutdown = initTracer() + } else { + break + } + time.Sleep(time.Minute * 5) + } + }() + return shutdown +} + +func initTracer() func() { + // temporarily set timeout to 10s + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + serviceName, ok := os.LookupEnv("OTEL_SERVICE_NAME") + if !ok { + serviceName = "server_name" + os.Setenv("OTEL_SERVICE_NAME", serviceName) + } + otelAgentAddr, ok := os.LookupEnv("OTEL_EXPORTER_OTLP_ENDPOINT") + if !ok { + otelAgentAddr = "http://localhost:4317" + os.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", otelAgentAddr) + } + zap.S().Infof("OTLP Trace connect to: %s with service name: %s", otelAgentAddr, serviceName) + + traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithDialOption(grpc.WithBlock())) + if err != nil { + handleErr(err, "OTLP Trace gRPC Creation") + return nil + } + + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithBatcher(traceExporter), + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(resource.NewWithAttributes(semconv.SchemaURL))) + + otel.SetTracerProvider(tracerProvider) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + + tracerExp = traceExporter + return func() { + // Shutdown will flush any remaining spans and shut down the exporter. + handleErr(tracerProvider.Shutdown(ctx), "failed to shutdown TracerProvider") + } +} + +func handleErr(err error, message string) { + if err != nil { + zap.S().Errorf("%s: %v", message, err) + } +} +``` + +### 在 main.go 中初始化跟踪器 + +修改 main 函数以在 main.go 中初始化跟踪器。另外当您的服务关闭时,应该调用 __TracerProvider.Shutdown()__ 确保导出所有 Span。该服务将该调用作为主函数中的延迟函数: + +```golang +func main() { + // start otel tracing + if shutdown := retryInitTracer(); shutdown != nil { + defer shutdown() + } + ...... +} +``` + +### 为应用添加 OTel Gin 中间件 + +通过在 __main.go__ 中添加以下行来配置 Gin 以使用中间件: + +```golang +import ( + .... + "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" +) + +func main() { + ...... + r := gin.Default() + r.Use(otelgin.Middleware("my-app")) + ...... +} +``` + +### 运行应用程序 + +- 本地调试运行 + + > 注意: 此步骤仅用于本地开发调试,生产环境中 Operator 会自动完成以下环境变量的注入。 + + 以上步骤已经完成了初始化 SDK 的工作,现在如果需要在本地开发进行调试,需要提前获取到 insight-system 命名空间下 insight-agent-opentelemerty-collector 的地址,假设为: __insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317__ 。 + + 因此,可以在你本地启动应用程序的时候添加如下环境变量: + + ```bash + OTEL_SERVICE_NAME=my-golang-app OTEL_EXPORTER_OTLP_ENDPOINT=http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317 go run main.go... + ``` + +- 生产环境运行 + + 请参考[通过 Operator 实现应用程序无侵入增强](../operator.md) 中 __只注入环境变量注解__ 相关介绍,为 deployment yaml 添加注解: + + ```console + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + + 如果无法使用注解的方式,您可以手动在 deployment yaml 添加如下环境变量: + +```yaml +······ +env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: 'http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317' + - name: OTEL_SERVICE_NAME + value: "your depolyment name" # (1)! + - name: OTEL_K8S_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES + value: 'k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)' +······ +``` + +1. 修改此值 + +## 请求路由 + +### OpenTelemetry gin/gonic 增强 + +```golang +# Add one line to your import() stanza depending upon your request router: +middleware "go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin" +``` + +然后注入 OpenTelemetry 中间件: + +```golang +router.Use(middleware.Middleware("my-app")) +``` + +### OpenTelemetry gorillamux 增强 + +```golang +# Add one line to your import() stanza depending upon your request router: +middleware "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" +``` + +然后注入 OpenTelemetry 中间件: + +```golang +router.Use(middleware.Middleware("my-app")) +``` + +### gRPC 增强 + +同样,OpenTelemetry 也可以帮助您自动检测 gRPC 请求。要检测您拥有的任何 gRPC 服务器,请将拦截器添加到服务器的实例化中。 + +```golang +import ( + grpcotel "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" +) +func main() { + [...] + + s := grpc.NewServer( + grpc.UnaryInterceptor(grpcotel.UnaryServerInterceptor()), + grpc.StreamInterceptor(grpcotel.StreamServerInterceptor()), + ) +} +``` + +需要注意的是,如果你的程序里面使用到了 Grpc Client 调用第三方服务,你还需要对 Grpc Client 添加拦截器: + +```golang + [...] + + conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()), + grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()), + ) +``` + +### 如果不使用请求路由 + +```golang +import ( + "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" +) +``` + +在将 http.Handler 传递给 ServeMux 的每个地方,您都将包装处理程序函数。例如,将进行以下替换: + +```golang +- mux.Handle("/path", h) ++ mux.Handle("/path", otelhttp.NewHandler(h, "description of path")) +--- +- mux.Handle("/path", http.HandlerFunc(f)) ++ mux.Handle("/path", otelhttp.NewHandler(http.HandlerFunc(f), "description of path")) +``` + +通过这种方式,您可以确保使用 othttp 包装的每个函数都会自动收集其元数据并启动相应的跟踪。 + +## 数据库访问增强 + +### Golang Gorm + +OpenTelemetry 社区也开发了数据库访问库的中间件,比如 Gorm: +```golang +import ( + "github.com/uptrace/opentelemetry-go-extra/otelgorm" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{}) +if err != nil { + panic(err) +} + +otelPlugin := otelgorm.NewPlugin(otelgorm.WithDBName("mydb"), # 缺失会导致数据库相关拓扑展示不完整 + otelgorm.WithAttributes(semconv.ServerAddress("memory"))) # 缺失会导致数据库相关拓扑展示不完整 +if err := db.Use(otelPlugin); err != nil { + panic(err) +} +``` + +### 自定义 Span + +很多时候,OpenTelemetry 提供的中间件不能帮助我们记录更多内部调用的函数,需要我们自定义 Span 来记录 + +```golang + ······ + _, span := otel.Tracer("GetServiceDetail").Start(ctx, + "spanMetricDao.GetServiceDetail", + trace.WithSpanKind(trace.SpanKindInternal)) + defer span.End() + ······ +``` + +### 向 span 添加自定义属性和事件 + +也可以将自定义属性或标签设置为 Span。要添加自定义属性和事件,请按照以下步骤操作: + +### 导入跟踪和属性库 + +```golang +import ( + ... + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) +``` + +### 从上下文中获取当前 Span + +```golang +span := trace.SpanFromContext(c.Request.Context()) +``` + +### 在当前 Span 中设置属性 + +```golang +span.SetAttributes(attribute.String("controller", "books")) +``` + +### 为当前 Span 添加 Event + +添加 span 事件是使用 span 对象上的 __AddEvent__ 完成的。 + +```golang +span.AddEvent(msg) +``` + +## 记录错误和异常 + +```golang +import "go.opentelemetry.io/otel/codes" + +// 获取当前 span +span := trace.SpanFromContext(ctx) + +// RecordError 会自动将一个错误转换成 span even +span.RecordError(err) + +// 标记这个 span 错误 +span.SetStatus(codes.Error, "internal error") +``` + +## 参考 + +有关 Demo 演示请参考: +- [opentelemetry-demo/productcatalogservice](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice) +- [opentelemetry-collector-contrib/demo](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/examples/demo) diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/golang/meter.md b/docs/zh/docs/end-user/insight/quickstart/otel/golang/meter.md new file mode 100644 index 0000000..633f516 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/golang/meter.md @@ -0,0 +1,255 @@ +# 使用 OTel SDK 为应用程序暴露指标 + +> 本文仅供希望评估或探索正在开发的 OTLP 指标的用户参考。 + +OpenTelemetry 项目要求以必须在 OpenTelemetry 协议 (OTLP) 中发出数据的语言提供 API 和 SDK。 + +## 针对 Golang 应用程序 + +Golang 可以通过 sdk 暴露 runtime 指标,具体来说,在应用中添加以下方法开启 metrics 暴露器: + +### 安装相关依赖 + +切换/进入到应用程序源文件夹后运行以下命令: + +```golang +go get go.opentelemetry.io/otel \ + go.opentelemetry.io/otel/attribute \ + go.opentelemetry.io/otel/exporters/prometheus \ + go.opentelemetry.io/otel/metric/global \ + go.opentelemetry.io/otel/metric/instrument \ + go.opentelemetry.io/otel/sdk/metric +``` + +### 使用 OTel SDK 创建初始化函数 + +```golang +import ( + ..... + + "go.opentelemetry.io/otel/attribute" + otelPrometheus "go.opentelemetry.io/otel/exporters/prometheus" + "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/metric/instrument" + "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" + "go.opentelemetry.io/otel/sdk/metric/export/aggregation" + processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" + selector "go.opentelemetry.io/otel/sdk/metric/selector/simple" +) +func (s *insightServer) initMeter() *otelPrometheus.Exporter { + s.meter = global.Meter("xxx") + + config := otelPrometheus.Config{ + DefaultHistogramBoundaries: []float64{1, 2, 5, 10, 20, 50}, + Gatherer: prometheus.DefaultGatherer, + Registry: prometheus.NewRegistry(), + Registerer: prometheus.DefaultRegisterer, + } + + c := controller.New( + processor.NewFactory( + selector.NewWithHistogramDistribution( + histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries), + ), + aggregation.CumulativeTemporalitySelector(), + processor.WithMemory(true), + ), + ) + + exporter, err := otelPrometheus.New(config, c) + if err != nil { + zap.S().Panicf("failed to initialize prometheus exporter %v", err) + } + + global.SetMeterProvider(exporter.MeterProvider()) + + http.HandleFunc("/metrics", exporter.ServeHTTP) + + go func() { + _ = http.ListenAndServe(fmt.Sprintf(":%d", 8888), nil) + }() + + zap.S().Info("Prometheus server running on ", fmt.Sprintf(":%d", port)) + return exporter +} +``` + +以上方法会为您的应用暴露一个指标接口: http://localhost:8888/metrics + +随后,在 main.go 中对其进行初始化: + +```golang +func main() { +······ + tp := initMeter() +······ +} +``` + +此外,如果想添加自定义指标,可以参考: + +```golang +// exposeClusterMetric expose metric like "insight_logging_count{} 1" +func (s *insightServer) exposeLoggingMetric(lserver *log.LogService) { + s.meter = global.Meter("insight.io/basic") + + var lock sync.Mutex + logCounter, err := s.meter.AsyncFloat64().Counter("insight_log_total") + if err != nil { + zap.S().Panicf("failed to initialize instrument: %v", err) + } + + _ = s.meter.RegisterCallback([]instrument.Asynchronous{logCounter}, func(ctx context.Context) { + lock.Lock() + defer lock.Unlock() + count, err := lserver.Count(ctx) + if err == nil || count != -1 { + logCounter.Observe(ctx, float64(count)) + } + }) +} +``` + +随后,在 main.go 调用该方法: + +```golang +······ +s.exposeLoggingMetric(lservice) +······ +``` + +您可以通过访问 http://localhost:8888/metrics 来检查您的指标是否正常工作。 + +## 针对 Java 应用程序 + +Java 在使用 otel agent 在完成链路的自动接入的基础上,通过添加环境变量: + +```bash +OTEL_METRICS_EXPORTER=prometheus +``` + +就可以直接暴露 JVM 相关指标,您可以通过访问 http://localhost:8888/metrics 来检查您的指标是否正常工作。 + +随后,再配合 prometheus serviceMonitor 即可完成指标的接入。 +如果想暴露自定义指标请参阅 [opentelemetry-java-docs/prometheus](https://github.com/open-telemetry/opentelemetry-java-docs/blob/main/prometheus/README.md)。 + +主要分以下两步: + +- 创建 meter provider,并指定 prometheus 作为 exporter。 + + ```java + /* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + + package io.opentelemetry.example.prometheus; + + import io.opentelemetry.api.metrics.MeterProvider; + import io.opentelemetry.exporter.prometheus.PrometheusHttpServer; + import io.opentelemetry.sdk.metrics.SdkMeterProvider; + import io.opentelemetry.sdk.metrics.export.MetricReader; + + public final class ExampleConfiguration { + + /** + * Initializes the Meter SDK and configures the prometheus collector with all default settings. + * + * @param prometheusPort the port to open up for scraping. + * @return A MeterProvider for use in instrumentation. + */ + static MeterProvider initializeOpenTelemetry(int prometheusPort) { + MetricReader prometheusReader = PrometheusHttpServer.builder().setPort(prometheusPort).build(); + + return SdkMeterProvider.builder().registerMetricReader(prometheusReader).build(); + } + } + + ``` + +- 自定义 meter 并开启 http server + + ```java + package io.opentelemetry.example.prometheus; + + import io.opentelemetry.api.common.Attributes; + import io.opentelemetry.api.metrics.Meter; + import io.opentelemetry.api.metrics.MeterProvider; + import java.util.concurrent.ThreadLocalRandom; + + /** + * Example of using the PrometheusHttpServer to convert OTel metrics to Prometheus format and expose + * these to a Prometheus instance via a HttpServer exporter. + * + *

A Gauge is used to periodically measure how many incoming messages are awaiting processing. + * The Gauge callback gets executed every collection interval. + */ + public final class PrometheusExample { + private long incomingMessageCount; + + public PrometheusExample(MeterProvider meterProvider) { + Meter meter = meterProvider.get("PrometheusExample"); + meter + .gaugeBuilder("incoming.messages") + .setDescription("No of incoming messages awaiting processing") + .setUnit("message") + .buildWithCallback(result -> result.record(incomingMessageCount, Attributes.empty())); + } + + void simulate() { + for (int i = 500; i > 0; i--) { + try { + System.out.println( + i + " Iterations to go, current incomingMessageCount is: " + incomingMessageCount); + incomingMessageCount = ThreadLocalRandom.current().nextLong(100); + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignored here + } + } + } + + public static void main(String[] args) { + int prometheusPort = 8888; + + // it is important to initialize the OpenTelemetry SDK as early as possible in your process. + MeterProvider meterProvider = ExampleConfiguration.initializeOpenTelemetry(prometheusPort); + + PrometheusExample prometheusExample = new PrometheusExample(meterProvider); + + prometheusExample.simulate(); + + System.out.println("Exiting"); + } + } + ``` + +随后,待 java 应用程序运行之后,您可以通过访问 http://localhost:8888/metrics 来检查您的指标是否正常工作。 + +## Insight 采集指标 + +最后重要的是,您已经在应用程序中暴露出了指标,现在需要 Insight 来采集指标。 + +推荐的指标暴露方式是通过 [servicemonitor](https://github.com/prometheus-operator/prometheus-operator/blob/501d079e3d3769b94dca6684cf155034e468829a/Documentation/design.md#servicemonitor) 或者 podmonitor。 + +### 创建 servicemonitor/podmonitor + +添加的 servicemonitor/podmonitor 需要打上 __label:"operator.insight.io/managed-by": "insight"__ 才会被 Operator 识别: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: example-app + labels: + operator.insight.io/managed-by: insight +spec: + selector: + matchLabels: + app: example-app + endpoints: + - port: web + namespaceSelector: + any: true +``` diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/java/index.md b/docs/zh/docs/end-user/insight/quickstart/otel/java/index.md new file mode 100644 index 0000000..ca40861 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/java/index.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 开始监控 Java 应用 + +1. Java 应用链路接入与监控请参考[通过 Operator 实现应用程序无侵入增强](../operator.md) 文档,通过注解实现自动接入链路。 + +2. Java 应用的 JVM 进行监控:已经暴露 JVM 指标和仍未暴露 JVM 指标的 Java 应用如何与可观测性 Insight 对接。 + + - 如果您的 Java 应用未开始暴露 JVM 指标,您可以参考如下文档: + + - [使用 JMX Exporter 暴露 JVM 监控指标](./jvm-monitor/jmx-exporter.md) + - [使用 OpenTelemetry Java Agent 暴露 JVM 监控指标](./jvm-monitor/otel-java-agent.md) + + - 如果您的 Java 应用已经暴露 JVM 指标,您可以参考如下文档: + + - [已有 JVM 指标的 Java 应用对接可观测性](./jvm-monitor/legacy-jvm.md) + +3. [将 TraceId 和 SpanId 写入 Java 应用日志](./mdc.md), 实现链路数据与日志数据关联 diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md b/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md new file mode 100644 index 0000000..24c5ec3 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md @@ -0,0 +1,136 @@ +# 使用 JMX Exporter 暴露 JVM 监控指标 + +JMX-Exporter 提供了两种用法: + +1. 启动独立进程。JVM 启动时指定参数,暴露 JMX 的 RMI 接口,JMX Exporter 调用 RMI 获取 JVM 运行时状态数据, + 转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。 +2. JVM 进程内启动(in-process)。JVM 启动时指定参数,通过 javaagent 的形式运行 JMX-Exporter 的 jar 包, + 进程内读取 JVM 运行时状态数据,转换为 Prometheus metrics 格式,并暴露端口让 Prometheus 采集。 + +!!! note + + 官方不推荐使用第一种方式,一方面配置复杂,另一方面因为它需要一个单独的进程,而这个进程本身的监控又成了新的问题, + 所以本文重点围绕第二种用法讲如何在 Kubernetes 环境下使用 JMX Exporter 暴露 JVM 监控指标。 + +这里使用第二种用法,启动 JVM 时需要指定 JMX Exporter 的 jar 包文件和配置文件。 +jar 包是二进制文件,不好通过 configmap 挂载,配置文件我们几乎不需要修改, +所以建议是直接将 JMX Exporter 的 jar 包和配置文件都打包到业务容器镜像中。 + +其中,第二种方式我们可以选择将 JMX Exporter 的 jar 文件放在业务应用镜像中, +也可以选择在部署的时候挂载进去。这里分别对两种方式做一个介绍: + +## 方式一:将 JMX Exporter JAR 文件构建至业务镜像中 + +prometheus-jmx-config.yaml 内容如下: + +```yaml title="prometheus-jmx-config.yaml" +... +ssl: false +lowercaseOutputName: false +lowercaseOutputLabelNames: false +rules: +- pattern: ".*" +``` + +!!! note + + 更多配置项请参考底部介绍或[Prometheus 官方文档](https://github.com/prometheus/jmx_exporter#configuration)。 + +然后准备 jar 包文件,可以在 [jmx_exporter](https://github.com/prometheus/jmx_exporter) 的 Github 页面找到最新的 jar 包下载地址并参考如下 Dockerfile: + +```shell +FROM openjdk:11.0.15-jre +WORKDIR /app/ +COPY target/my-app.jar ./ +COPY prometheus-jmx-config.yaml ./ +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +ENV JAVA_TOOL_OPTIONS=-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml +EXPOSE 8081 8999 8080 8888 +ENTRYPOINT java $JAVA_OPTS -jar my-app.jar +``` + +注意: + +- 启动参数格式:-javaagent:=: +- 这里使用了 8088 端口暴露 JVM 的监控指标,如果和 Java 应用冲突,可自行更改 + +## 方式二:通过 init container 容器挂载 + +我们需要先将 JMX exporter 做成 Docker 镜像, 以下 Dockerfile 仅供参考: + +```shell +FROM alpine/curl:3.14 +WORKDIR /app/ +# 将前面创建的 config 文件拷贝至镜像 +COPY prometheus-jmx-config.yaml ./ +# 在线下载 jmx prometheus javaagent jar +RUN set -ex; \ + curl -L -O https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar; +``` + +根据上面 Dockerfile 构建镜像: __docker build -t my-jmx-exporter .__ + +在 Java 应用部署 Yaml 中加入如下 init container: + +??? note "点击展开 YAML 文件" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-demo-app + labels: + app: my-demo-app + spec: + selector: + matchLabels: + app: my-demo-app + template: + metadata: + labels: + app: my-demo-app + spec: + imagePullSecrets: + - name: registry-pull + initContainers: + - name: jmx-sidecar + image: my-jmx-exporter + command: ["cp", "-r", "/app/jmx_prometheus_javaagent-0.17.2.jar", "/target/jmx_prometheus_javaagent-0.17.2.jar"] ➊ + volumeMounts: + - name: sidecar + mountPath: /target + containers: + - image: my-demo-app-image + name: my-demo-app + resources: + requests: + memory: "1000Mi" + cpu: "500m" + limits: + memory: "1000Mi" + cpu: "500m" + ports: + - containerPort: 18083 + env: + - name: JAVA_TOOL_OPTIONS + value: "-javaagent:/app/jmx_prometheus_javaagent-0.17.2.jar=8088:/app/prometheus-jmx-config.yaml" ➋ + volumeMounts: + - name: host-time + mountPath: /etc/localtime + readOnly: true + - name: sidecar + mountPath: /sidecar + volumes: + - name: host-time + hostPath: + path: /etc/localtime + - name: sidecar #共享 agent 文件夹 + emptyDir: {} + restartPolicy: Always + ``` + +经过如上的改造之后,示例应用 my-demo-app 具备了暴露 JVM 指标的能力。 +运行服务之后,我们可以通过 `http://lcoalhost:8088` 访问服务暴露出来的 prometheus 格式的指标。 + +接着,您可以参考 [已有 JVM 指标的 Java 应用对接可观测性](./legacy-jvm.md)。 diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md b/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md new file mode 100644 index 0000000..0112bf9 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md @@ -0,0 +1,88 @@ +# 已有 JVM 指标的 Java 应用对接可观测性 + +如果您的 Java 应用通过其他方式(比如 Spring Boot Actuator)暴露了 JVM 的监控指标, +我们需要让监控数据被采集到。您可以通过在工作负载中添加注解(Kubernetes Annotations)的方式让 Insight 来采集已有的 JVM 指标: + +```yaml +annatation: + insight.opentelemetry.io/metric-scrape: "true" # 是否采集 + insight.opentelemetry.io/metric-path: "/" # 采集指标的路径 + insight.opentelemetry.io/metric-port: "9464" # 采集指标的端口 +``` + +例如为 __my-deployment-app__ 添加注解: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment-app +spec: + selector: + matchLabels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + replicas: 1 + template: + metadata: + labels: + app: my-deployment-app + app.kubernetes.io/name: my-deployment-app + annotations: + insight.opentelemetry.io/metric-scrape: "true" # 是否采集 + insight.opentelemetry.io/metric-path: "/" # 采集指标的路径 + insight.opentelemetry.io/metric-port: "9464" # 采集指标的端口 +``` + +以下是完整示例: + +```yaml +--- +apiVersion: v1 +kind: Service +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + type: NodePort + selector: + #app: my-deployment-with-aotu-instrumentation-app + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + port: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spring-boot-actuator-prometheus-metrics-demo +spec: + selector: + matchLabels: + #app: my-deployment-with-aotu-instrumentation-app + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: spring-boot-actuator-prometheus-metrics-demo + annotations: + insight.opentelemetry.io/metric-scrape: "true" # 是否采集 + insight.opentelemetry.io/metric-path: "/actuator/prometheus" # 采集指标的路径 + insight.opentelemetry.io/metric-port: "8080" # 采集指标的端口 + spec: + containers: + - name: myapp + image: docker.m.daocloud.io/wutang/spring-boot-actuator-prometheus-metrics-demo + ports: + - name: http + containerPort: 8080 + resources: + limits: + cpu: 500m + memory: 800Mi + requests: + cpu: 200m + memory: 400Mi +``` + +以上示例中,Insight 会通过 __:8080//actuator/prometheus__ 抓取通过 **Spring Boot Actuator** 暴露出来的 Prometheus 指标。 diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md b/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md new file mode 100644 index 0000000..49f44dd --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md @@ -0,0 +1,23 @@ +# 使用 OpenTelemetry Java Agent 暴露 JVM 监控指标 + +在 Opentelemetry Agent v1.20.0 及以上版本中,Opentelemetry Agent 新增了 JMX Metric Insight 模块,如果你的应用已经集成了 Opentelemetry Agent 去采集应用链路,那么你不再需要另外引入其他 Agent 去为我们的应用暴露 JMX 指标。Opentelemetry Agent 也是通过检测应用程序中本地可用的 MBean 公开的指标,对其进行收集并暴露指标。 + +Opentelemetry Agent 也针对常见的 Java Server 或框架内置了一些监控的样例,请参考[预定义的指标](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/semantic-conventions.md)。 + +使用 OpenTelemetry Java Agent 同样需要考虑如何将 JAR 挂载进容器,除了可以参考上面 JMX Exporter 挂载 JAR 文件的方式外,我们还可以借助 Opentelemetry 提供的 Operator 的能力来实现自动为我们的应用开启 JVM 指标暴露: + +如果你的应用已经集成了 Opentelemetry Agent 去采集应用链路,那么你不再需要另外引入其他 Agent 去为我们的应用暴露 JMX 指标。Opentelemetry Agent 通过检测应用程序中本地可用的 MBean 公开的指标,现在可以本地收集并暴露指标接口。 + +但是,截至目前版本,你仍然需要手动为应用加上相应注解之后,JVM 数据才会被 Insight 采集到,具体注解内容请参考 [已有 JVM 指标的 Java 应用对接可观测性](./legacy-jvm.md)。 + +## 为 Java 中间件暴露指标 + +Opentelemetry Agent 也内置了一些中间件监控的样例,请参考 [预定义指标](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation/jmx-metrics/javaagent/README.md#predefined-metrics)。 + +默认没有指定任何类型,需要通过 __-Dotel.jmx.target.system__ JVM Options 指定,比如 __-Dotel.jmx.target.system=jetty,kafka-broker__ 。 + +## 参考 + +- [Gaining JMX Metric Insights with the OpenTelemetry Java Agent](https://opentelemetry.io/blog/2023/jmx-metric-insight/) + +- [Otel jmx metrics](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/jmx-metrics) diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/java/mdc.md b/docs/zh/docs/end-user/insight/quickstart/otel/java/mdc.md new file mode 100644 index 0000000..d5d0c3f --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/java/mdc.md @@ -0,0 +1,111 @@ +# 将 TraceId 和 SpanId 写入 Java 应用日志 + +本文介绍如何使用 OpenTelemetry 将 TraceId 和 SpanId 自动写入 Java 应用日志。 +TraceId 与 SpanId 写入日志后,您可以将分布式链路数据与日志数据关联起来,实现更高效的故障诊断和性能分析。 + +## 支持的日志库 + +更多信息,请参见 [Logger MDC auto-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/logger-mdc-instrumentation.md)。 + +| 日志框架 | 支持自动埋点的版本 | 手动埋点需要引入的依赖 | +| ------- | --------------- | ------------------ | +| Log4j 1 | 1.2+ | 无| +| Log4j 2 | 2.7+ | [opentelemetry-log4j-context-data-2.17-autoconfigure](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure) | +| Logback | 1.0+ | [opentelemetry-logback-mdc-1.0](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/logback/logback-mdc-1.0/library) | + +## 使用 Logback(SpringBoot 项目) + +Spring Boot 项目内置了日志框架,并且默认使用 Logback 作为其日志实现。如果您的 Java 项目为 SpringBoot 项目,只需少量配置即可将 TraceId 写入日志。 + +在 `application.properties` 中设置 `logging.pattern.level`,添加 `%mdc{trace_id}` 与 `%mdc{span_id}` 到日志中。 + +```bash +logging.pattern.level=trace_id=%mdc{trace_id} span_id=%mdc{span_id} %5p ....省略... +``` + +以下为日志示例: + +```console +2024-06-26 10:56:31.200 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2024-06-26 10:56:31.201 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2024-06-26 10:56:31.209 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms +2024-06-26 10:56:31.296 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=5743699405074f4e INFO 53724 --- [nio-8081-exec-1] com.example.httpserver.ot.OTServer : hello world +``` + +## 使用 Log4j2 + +1. 在 `pom.xml` 中添加 `OpenTelemetry Log4j2` 依赖: + + !!! tip + + 请将 `OPENTELEMETRY_VERSION` 替换为[最新版本](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions) + + ```xml + + + io.opentelemetry.instrumentation + opentelemetry-log4j-context-data-2.17-autoconfigure + OPENTELEMETRY_VERSION + runtime + + + ``` + +1. 修改 `log4j2.xml` 配置,在 `pattern` 中添加 `%X{trace_id}` 与 `%X{span_id}`,可以将 `TraceId` 与 `SpanId` 自动写入日志: + + ```xml + + + + + + + + + + + + + + ``` + +1. 使用 Logback 在 `pom.xml` 中添加 `OpenTelemetry Logback` 依赖。 + + !!! tip + + 请将 `OPENTELEMETRY_VERSION` 替换为[最新版本](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/versions) + + ```xml + + + io.opentelemetry.instrumentation + opentelemetry-logback-mdc-1.0 + OPENTELEMETRY_VERSION + + + ``` + +1. 修改 `log4j2.xml` 配置,在 `pattern` 中添加 `%X{trace_id}` 与 `%X{span_id}`,可以将 `TraceId` 与 `SpanId` 自动写入日志: + + ```xml + + + + + %d{HH:mm:ss.SSS} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %msg%n + + + + + + + + + + + + + + + ``` diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/operator.md b/docs/zh/docs/end-user/insight/quickstart/otel/operator.md new file mode 100644 index 0000000..8f4e071 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/operator.md @@ -0,0 +1,555 @@ +# 通过 Operator 实现应用程序无侵入增强 + +> 目前只有 Java、NodeJs、Python、.Net、Golang 支持 Operator 的方式无侵入接入。 + +## 前提条件 + +请确保 insight-agent 已经就绪。如若没有,请参考[安装 insight-agent 采集数据](../install/install-agent.md)并确保以下三项就绪: + +- 为 insight-agent 开启 trace 功能 +- trace 数据的地址以及端口是否填写正确 +- deployment/insight-agent-opentelemetry-operator 和 + deployment/insight-agent-opentelemetry-collector 对应的 Pod 已经准备就绪 + +## 安装 Instrumentation CR + +!!! tip + + 从 Insight v0.22.0 开始,不再需要手动安装 Instrumentation CR。 + +在 `insight-system` 命名空间下安装,不同版本之间有一些细小的差别。 + +=== "Insight v0.21.x" + + ```bash + K8S_CLUSTER_UID=$(kubectl get namespace kube-system -o jsonpath='{.metadata.uid}') + kubectl apply -f - < language specific env vars -> common env vars -> instrument spec configs' vars + ``` + + 但是需要避免手动覆盖 OTEL_RESOURCE_ATTRIBUTES_NODE_NAME,它在 Operator 内部作为一个 + Pod 是否已经注入探针的标识,如果手动添加了,探针可能无法注入。 + +## 自动注入示例 Demo + +注意这个 `annotations` 是加在 spec.annotations 下的。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-app + labels: + app: my-app +spec: + selector: + matchLabels: + app: my-app + replicas: 1 + template: + metadata: + labels: + app: my-app + annotations: + instrumentation.opentelemetry.io/inject-java: "insight-system/insight-opentelemetry-autoinstrumentation" + spec: + containers: + - name: myapp + image: jaegertracing/vertx-create-span:operator-e2e-tests + ports: + - containerPort: 8080 + protocol: TCP +``` + +最终生成的 YAML 内容如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-deployment-with-sidecar-565bd877dd-nqkk6 + generateName: my-deployment-with-sidecar-565bd877dd- + namespace: default + uid: aa89ca0d-620c-4d20-8bc1-37d67bad4ea4 + resourceVersion: '2668986' + creationTimestamp: '2022-04-08T05:58:48Z' + labels: + app: my-pod-with-sidecar + pod-template-hash: 565bd877dd + annotations: + cni.projectcalico.org/containerID: 234eae5e55ea53db2a4bc2c0384b9a1021ed3908f82a675e4a92a49a7e80dd61 + cni.projectcalico.org/podIP: 192.168.134.133/32 + cni.projectcalico.org/podIPs: 192.168.134.133/32 + instrumentation.opentelemetry.io/inject-java: "insight-system/insight-opentelemetry-autoinstrumentation" +spec: + volumes: + - name: kube-api-access-sp2mz + projected: + sources: + - serviceAccountToken: + expirationSeconds: 3607 + path: token + - configMap: + name: kube-root-ca.crt + items: + - key: ca.crt + path: ca.crt + - downwardAPI: + items: + - path: namespace + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + defaultMode: 420 + - name: opentelemetry-auto-instrumentation + emptyDir: {} + initContainers: + - name: opentelemetry-auto-instrumentation + image: >- + ghcr.m.daocloud.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java + command: + - cp + - /javaagent.jar + - /otel-auto-instrumentation/javaagent.jar + resources: {} + volumeMounts: + - name: opentelemetry-auto-instrumentation + mountPath: /otel-auto-instrumentation + - name: kube-api-access-sp2mz + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + containers: + - name: myapp + image: ghcr.io/pavolloffay/spring-petclinic:latest + env: + - name: OTEL_JAVAAGENT_DEBUG + value: 'true' + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: 'true' + - name: SPLUNK_PROFILER_ENABLED + value: 'false' + - name: JAVA_TOOL_OPTIONS + value: ' -javaagent:/otel-auto-instrumentation/javaagent.jar' + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://insight-agent-opentelemetry-collector.svc.cluster.local:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: '20' + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: '0.85' + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: 'true' + - name: OTEL_SERVICE_NAME + value: my-deployment-with-sidecar + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES_POD_UID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.uid + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES + value: >- + k8s.container.name=myapp,k8s.deployment.name=my-deployment-with-sidecar,k8s.deployment.uid=8de6929d-dda0-436c-bca1-604e9ca7ea4e,k8s.namespace.name=default,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.pod.uid=$(OTEL_RESOURCE_ATTRIBUTES_POD_UID),k8s.replicaset.name=my-deployment-with-sidecar-565bd877dd,k8s.replicaset.uid=190d5f6e-ba7f-4794-b2e6-390b5879a6c4 + - name: OTEL_PROPAGATORS + value: jaeger,b3 + resources: {} + volumeMounts: + - name: kube-api-access-sp2mz + readOnly: true + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + - name: opentelemetry-auto-instrumentation + mountPath: /otel-auto-instrumentation + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: Always + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + nodeName: k8s-master3 + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + schedulerName: default-scheduler + tolerations: + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 300 + priority: 0 + enableServiceLinks: true + preemptionPolicy: PreemptLowerPriority +``` + +## 链路查询 + +如何查询已经接入的服务,参考[链路查询](../../trace/trace.md)。 diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/otel.md b/docs/zh/docs/end-user/insight/quickstart/otel/otel.md new file mode 100644 index 0000000..5e18a38 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/otel.md @@ -0,0 +1,30 @@ +# 使用 OTel 赋予应用可观测性 + +> 增强是使应用程序代码能够生成遥测数据的过程。即一些可以帮助您监视或测量应用程序的性能和状态的东西。 + +OpenTelemetry 是领先的开源项目,为主要编程语言和流行框架提供检测库。它是云原生计算基金会下的一个项目,得到了社区庞大资源的支持。 +它为采集的数据提供标准化的数据格式,无需集成特定的供应商。 + +Insight 支持用于检测应用程序的 OpenTelemetry 来增强您的应用程序。 + +本指南介绍了使用 OpenTelemetry 进行遥测增强的基本概念。 +OpenTelemetry 还有一个由库、插件、集成和其他有用工具组成的生态系统来扩展它。 +您可以在 [Otel Registry](https://opentelemetry.io/registry/) 中找到这些资源。 + +您可以使用任何开放标准库进行遥测增强,并使用 Insight 作为可观察性后端来摄取、分析和可视化数据。 + +为了增强您的代码,您可以使用 OpenTelemetry 为特定语言提供的增强操作: + +Insight 目前提供了使用 OpenTelemetry 增强 .Net NodeJS、Java、Python 和 Golang 应用程序的简单方法。请遵循以下指南。 + +## 链路增强 + +- 链路接入的最佳实践:[通过 Operator 实现应用程序无侵入增强](./operator.md) +- 以 Go 语言为例的手动埋点接入:[使用 OpenTelemetry SDK 增强 Go 应用程序](./golang/golang.md) +- [利用 ebpf 实现 Go 语言无侵入探针](https://github.com/keyval-dev/opentelemetry-go-instrumentation/blob/master/docs/getting-started/README.md)(实验性功能) + + diff --git a/docs/zh/docs/end-user/insight/quickstart/otel/send_tracing_to_insight.md b/docs/zh/docs/end-user/insight/quickstart/otel/send_tracing_to_insight.md new file mode 100644 index 0000000..a8351c9 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/otel/send_tracing_to_insight.md @@ -0,0 +1,99 @@ +# 向 Insight 发送链路数据 + +此文档主要描述客户应用如何自行将链路数据上报给 Insight。主要包含如下两种场景: + +1. 客户应用通过 OTEL Agent/SDK 上报链路给 Insight +2. 通过 Opentelemtry Collector(简称 OTEL COL) 将链路转发给 Insight + +在每个已安装 Insight Agent 的集群中都有 __insight-agent-otel-col__ 组件用于统一接收该集群的链路数据。 +因此,该组件作为用户接入侧的入口,需要先获取该地址。可以通过 AI 算力中心 界面获取该集群 Opentelemtry Collector 的地址, +比如 __insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317__ : + +![image](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/quickstart/images/get_insight_agent_otel_col_svc.png) + +除此之外,针对不同上报方式,有一些细微差别: + +## 客户应用通过 OTel Agent/SDK 上报链路给 Insight Agent Opentelemtry Collector + +为了能够将链路数据正常上报至 Insight 并能够在 Insight 正常展示,需要并建议通过如下环境变量提供 OTLP 所需的元数据 (Resource Attribute),有两种方式可实现: + +- 在部署文件 YAML 中手动添加,例如: + + ```yaml + ... + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://insight-agent-opentelemetry-collector.insight-system.svc.cluster.local:4317" + - name: "OTEL_SERVICE_NAME" + value: my-java-app-name + - name: "OTEL_K8S_NAMESPACE" + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: OTEL_RESOURCE_ATTRIBUTES + value: "k8s.namespace.name=$(OTEL_K8S_NAMESPACE),k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)" + ``` + +- 利用 Insight Agent 自动注入如上元数据 (Resource Attribute) 能力 + + 确保 Insight Agent 正常工作并 [安装 Instrumentation CR](./operator.md#instrumentation-cr) 之后, + 只需要为 Pod 添加如下 Annotation 即可: + + ```console + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + + 举例: + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: my-deployment-with-aotu-instrumentation + spec: + selector: + matchLabels: + app.kubernetes.io/name: my-deployment-with-aotu-instrumentation-kuberntes + replicas: 1 + template: + metadata: + labels: + app.kubernetes.io/name: my-deployment-with-aotu-instrumentation-kuberntes + annotations: + sidecar.opentelemetry.io/inject: "false" + instrumentation.opentelemetry.io/inject-sdk: "insight-system/insight-opentelemetry-autoinstrumentation" + ``` + +## 通过 Opentelemtry Collector 将链路转发给 Insight Agent Opentelemtry Collector + +在保证应用添加了如上元数据之后,只需在客户 Opentelemtry Collector 里面新增一个 OTLP Exporter 将链路数据转发给 +Insight Agent Opentelemtry Collector 即可,如下 Opentelemtry Collector 配置文件所示: + +```yaml +... +exporters: + otlp/insight: + endpoint: insight-opentelemetry-collector.insight-system.svc.cluster.local:4317 +service: +... +pipelines: +... +traces: + exporters: + - otlp/insight +``` + +## 参考 + +- [通过 Operator 实现应用程序无侵入增强](./operator.md) +- [使用 OTel 赋予应用可观测性](./otel.md) diff --git a/docs/zh/docs/end-user/insight/quickstart/other/install-agent-on-ocp.md b/docs/zh/docs/end-user/insight/quickstart/other/install-agent-on-ocp.md new file mode 100644 index 0000000..bfc6782 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/other/install-agent-on-ocp.md @@ -0,0 +1,68 @@ +# OpenShift 安装 Insight Agent + +虽然 OpenShift 系统自带了一套监控系统,因为数据采集约定的一些规则,我们还是会安装 Insight Agent。 + +其中,安除了基础的安装配置之外,helm install 的时候还需要增加如下的参数: + +```bash +## 针对 fluentbit 相关的参数; +--set fluent-bit.ocp.enabled=true \ +--set fluent-bit.serviceAccount.create=false \ +--set fluent-bit.securityContext.runAsUser=0 \ +--set fluent-bit.securityContext.seLinuxOptions.type=spc_t \ +--set fluent-bit.securityContext.readOnlyRootFilesystem=false \ +--set fluent-bit.securityContext.allowPrivilegeEscalation=false \ + +## 启用适配 OpenShift4.x 的 Prometheus(CR) +--set compatibility.openshift.prometheus.enabled=true \ + +## 关闭高版本的 Prometheus 实例 +--set kube-prometheus-stack.prometheus.enabled=false \ +--set kube-prometheus-stack.kubeApiServer.enabled=false \ +--set kube-prometheus-stack.kubelet.enabled=false \ +--set kube-prometheus-stack.kubeControllerManager.enabled=false \ +--set kube-prometheus-stack.coreDns.enabled=false \ +--set kube-prometheus-stack.kubeDns.enabled=false \ +--set kube-prometheus-stack.kubeEtcd.enabled=false \ +--set kube-prometheus-stack.kubeEtcd.enabled=false \ +--set kube-prometheus-stack.kubeScheduler.enabled=false \ +--set kube-prometheus-stack.kubeStateMetrics.enabled=false \ +--set kube-prometheus-stack.nodeExporter.enabled=false \ + +## 限制 PrometheusOperator 处理的 namespace,避免与 OpenShift 自带的 PrometheusOperator 相互竞争 +--set kube-prometheus-stack.prometheusOperator.kubeletService.namespace="insight-system" \ +--set kube-prometheus-stack.prometheusOperator.prometheusInstanceNamespaces="insight-system" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[0]="openshift-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[1]="openshift-user-workload-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[2]="openshift-customer-monitoring" \ +--set kube-prometheus-stack.prometheusOperator.denyNamespaces[3]="openshift-route-monitor-operator" \ +``` + +### 通过 OpenShift 自身机制,将系统监控数据写入 Prometheus 中 + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-monitoring-config + namespace: openshift-monitoring +data: + config.yaml: | + prometheusK8s: + remoteWrite: + - queueConfig: + batchSendDeadline: 60s + maxBackoff: 5s + minBackoff: 30ms + minShards: 1 + capacity: 5000 + maxSamplesPerSend: 1000 + maxShards: 100 + remoteTimeout: 30s + url: http://insight-agent-prometheus.insight-system.svc.cluster.local:9090/api/v1/write + writeRelabelConfigs: + - action: keep + regex: etcd|kubelet|node-exporter|apiserver|kube-state-metrics + sourceLabels: + - job +``` diff --git a/docs/zh/docs/end-user/insight/quickstart/res-plan/index.md b/docs/zh/docs/end-user/insight/quickstart/res-plan/index.md new file mode 100644 index 0000000..9504def --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/res-plan/index.md @@ -0,0 +1,19 @@ +# 部署容量规划 + +默认情况下,可观测性模块为了避免消耗过多资源,已经设置了资源上线(resource limit),可观测系统需要处理大量的数据,如果容量规划不合理,可能会导致系统负载过高,影响稳定性和可靠性。 + +## 观测组件的资源规划 + +可观测性模块包含 Insight 和 Insight Agent。其中,Insight 主要负责观测数据的存储,分析与展示。而 Insight Agent 包含了数据采集、数据处理、数据上传等功能。 + +### 存储组件的容量规划 + +Insight 的存储组件主要包括 ElasticSearch 和 VictoriaMetrics. 其中,ElasticSearch 主要负责存储和查询日志与链路数据,VictoriaMetrics 主要负责存储和查询指标数据。 + +* **VictoriaMetircs**: 其磁盘用量与存储的指标有关,根据 [vmstorage 的磁盘规划](./vms-res-plan.md) 预估容量后 [调整 vmstorage 磁盘](./modify-vms-disk.md)。 + +### 采集器的资源规划 + +Insight Agent 的采集器中包含 Proemtheus,虽然 Prometheus 本身是一个独立的组件,但是在 Insight Agent 中,Prometheus 会被用于采集数据,因此需要对 Prometheus 的资源进行规划。 + +* **Prometheus**:其资源用量与采集的指标量有关,可以参考 [Prometheus 资源规划](./prometheus-res.md) 进行调整。 diff --git a/docs/zh/docs/end-user/insight/quickstart/res-plan/modify-vms-disk.md b/docs/zh/docs/end-user/insight/quickstart/res-plan/modify-vms-disk.md new file mode 100644 index 0000000..0ac83ab --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/res-plan/modify-vms-disk.md @@ -0,0 +1,86 @@ +# vmstorge 磁盘扩容 + +本文描述了 vmstorge 磁盘扩容的方法, +vmstorge 磁盘规范请参考 [vmstorage 磁盘容量规划](../res-plan/vms-res-plan.md)。 + +## 操作步骤 + +### 开启存储池扩容 + +1. 以全局服务集群管理员权限登录 AI 算力中心 平台,点击 __容器管理__ -> __集群列表__ ,点击 __kpanda-global-cluster__ 集群。 + +1. 选择左侧导航 __容器存储__ -> __数据卷声明(PVC)__ ,找到 vmstorage 绑定的数据卷声明。 + + ![找到vmstorage](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk01.png) + +1. 点击某个 vmstorage PVC,进入 vmstorage 的数据卷声明详情,确认该 PVC 绑定的存储池。 + + ![修改磁盘](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk02.png) + +1. 选择左侧导航 __容器存储__ -> __存储池(SC)__ ,找到 __local-path__ ,点击目标右侧的 __┇__ ,在弹出菜单中选择 __编辑__ 。 + + ![编辑存储池](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk03.png) + +1. 开启 __扩容__ 后点击 __确定__ 。 + + ![开启扩容](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk04.png) + +### 更改 vmstorage 的磁盘容量 + +1. 以全局服务集群管理员权限登录 AI 算力中心 平台,进入 __kpanda-global-cluster__ 集群详情。 + +1. 选择左侧导航 __自定义资源__ ,找到 __vmcluster__ 的自定义资源。 + + ![vmcluster](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk05.png) + +1. 点击该 vmcluster 自定义资源进入详情页,切换到 __insight-system__ 命名空间下,从 __insight-victoria-metrics-k8s-stack__ 右侧菜单选择 __编辑 YAML__ 。 + + ![编辑 YAML](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk06.png) + +1. 根据图例修改后点击 __确定__ 。 + + ![修改 YAML](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk07.png) + +1. 再次选择左侧导航 __容器存储__ -> __数据卷声明(PVC)__ ,找到 vmstorage 绑定的数据卷声明确认修改已生效。在某个 PVC 详情页,点击关联存储源 (PV)。 + + ![关联存储源](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk08.png) + +1. 打开数据卷详情页,点击右上角 __更新__ 按钮。 + + ![更新](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk09.png) + +1. 修改 __容量__ 后点击 __确定__ ,稍等片刻等到扩容成功。 + + ![修改容量](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk10.png) + +### 克隆存储卷 + +若存储卷扩容失败,可参考以下方法克隆存储卷。 + +1. 以全局服务集群管理员权限登录 AI 算力中心 平台,进入 __kpanda-global-cluster__ 集群详情。 + +1. 选择左侧导航 __工作负载__ -> __有状态负载__ ,找到 __vmstorage__ 的有状态负载,点击目标右侧的 __┇__ ,在弹出菜单中选择 __状态__ -> __停止__ -> __确定__ 。 + + ![状态停止](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk11.png) + +1. 在命令行中登录 __kpanda-global-cluster__ 集群的 __master__ 节点后,执行以下命令复制 vmstorage 容器中的 vm-data 目录将指标信息存储在本地: + + ```bash + kubectl cp -n insight-system vmstorage-insight-victoria-metrics-k8s-stack-1:vm-data ./vm-data + ``` + +1. 登录 AI 算力中心 平台进入 __kpanda-global-cluster__ 集群详情,选择左侧导航 __容器存储__ -> __数据卷(PV)__ ,点击右上角的 __克隆__ ,并修改数据卷的容量。 + + ![克隆](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk15.png) + + ![修改容量](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk12.png) + +1. 删除之前 vmstorage 的数据卷。 + + ![删除数据卷](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/vmdisk13.png) + +1. 稍等片刻,待存储卷声明跟克隆的数据卷绑定后,执行以下命令将第 3 步中导出的数据导入到对应的容器中,然后开启之前暂停的 __vmstorage__ 。 + + ```bash + kubectl cp -n insight-system ./vm-data vmstorage-insight-victoria-metrics-k8s-stack-1:vm-data + ``` diff --git a/docs/zh/docs/end-user/insight/quickstart/res-plan/prometheus-res.md b/docs/zh/docs/end-user/insight/quickstart/res-plan/prometheus-res.md new file mode 100644 index 0000000..30e2078 --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/res-plan/prometheus-res.md @@ -0,0 +1,49 @@ +# Prometheus 资源规划 + +Prometheus 在实际使用过程中,受到集群容器数量以及开启 Istio 的影响,会导致 Prometheus 的 CPU、内存等资源使用量超出设定的资源。 + +为了保证不同规模集群下 Prometheus 的正常运行,需要根据集群的实际规模对 Prometheus 进行资源调整。 + +## 参考资源规划 + +在未开启网格情况下,测试情况统计出系统 Job 指标量与 Pod 的关系为 **Series 数量 = 800 \* Pod 数量** + +在开启服务网格时,开启功能后 Pod 产生的 Istio 相关指标数量级为 **Series 数量 = 768 \* Pod 数量** + +### 当未开启服务网格时 + +以下资源规划为 **未开启服务网格** 场景下,Prometheus 的资源规划推荐: + +| 集群规模(Pod 数) | 指标量(未开启服务网格) | CPU(core) | 内存(GB) | +| -------------- | ------------------- | ------------------------ | ---------------------------- | +| 100 | 8w | Request: 0.5
Limit:1 | Request:2GB
Limit:4GB | +| 200 | 16w | Request:1
Limit:1.5 | Request:3GB
Limit:6GB | +| 300 | 24w | Request:1
Limit:2 | Request:3GB
Limit:6GB | +| 400 | 32w | Request:1
Limit:2 | Request:4GB
Limit:8GB | +| 500 | 40w | Request:1.5
Limit:3 | Request:5GB
Limit:10GB | +| 800 | 64w | Request:2
Limit:4 | Request:8GB
Limit:16GB | +| 1000 | 80w | Request:2.5
Limit:5 | Request:9GB
Limit:18GB | +| 2000 | 160w | Request:3.5
Limit:7 | Request:20GB
Limit:40GB | +| 3000 | 240w | Request:4
Limit:8 | Request:33GB
Limit:66GB | + +### 当开启服务网格功能时 + +以下资源规划为 **开启服务网格** 场景下,Prometheus 的资源规划推荐: + +| 集群规模(Pod 数) | 指标量(已开启服务网格) | CPU(core) | 内存(GB) | +| -------------- | ------------------- | ----------------------- | ----------------------------- | +| 100 | 15w | Request: 1
Limit:2 | Request:3GB
Limit:6GB | +| 200 | 31w | Request:2
Limit:3 | Request:5GB
Limit:10GB | +| 300 | 46w | Request:2
Limit:4 | Request:6GB
Limit:12GB | +| 400 | 62w | Request:2
Limit:4 | Request:8GB
Limit:16GB | +| 500 | 78w | Request:3
Limit:6 | Request:10GB
Limit:20GB | +| 800 | 125w | Request:4
Limit:8 | Request:15GB
Limit:30GB | +| 1000 | 156w | Request:5
Limit:10 | Request:18GB
Limit:36GB | +| 2000 | 312w | Request:7
Limit:14 | Request:40GB
Limit:80GB | +| 3000 | 468w | Request:8
Limit:16 | Request:65GB
Limit:130GB | + +!!! note + + 1. 表格中的 __Pod 数量__ 指集群中基本稳定运行的 Pod 数量,如出现大量的 Pod 重启,则会造成短时间内指标量的陡增,此时资源需要进行相应上调。 + 2. Prometheus 内存中默认保存两小时数据,且集群中开启了 [Remote Write 功能](https://prometheus.io/docs/practices/remote_write/#memory-usage)时,会占用一定内存,资源超配比建议配置为 2。 + 3. 表格中数据为推荐值,适用于通用情况。如环境有精确的资源要求,建议在集群运行一段时间后,查看对应 Prometheus 的资源占用量进行精确配置。 diff --git a/docs/zh/docs/end-user/insight/quickstart/res-plan/vms-res-plan.md b/docs/zh/docs/end-user/insight/quickstart/res-plan/vms-res-plan.md new file mode 100644 index 0000000..4baa65e --- /dev/null +++ b/docs/zh/docs/end-user/insight/quickstart/res-plan/vms-res-plan.md @@ -0,0 +1,74 @@ +# vmstorage 磁盘容量规划 + +vmstorage 是负责存储可观测性多集群指标。 +为保证 vmstorage 的稳定性,需要根据集群数量及集群规模调整 vmstorage 的磁盘容量。 +更多资料请参考 [vmstorage 保留期与磁盘空间](https://docs.victoriametrics.com/guides/understand-your-setup-size.html?highlight=datapoint#retention-perioddisk-space)。 + +## 测试结果 + +经过 14 天对不同规模的集群的 vmstorage 的磁盘观测, +我们发现 vmstorage 的磁盘用量与其存储的指标量和单个数据点占用磁盘正相关。 + +1. 瞬时存储的指标量 __increase(vm_rows{ type != "indexdb"}[30s])__ 以获取 30s 内增加的指标量 +2. 单个数据点 (datapoint) 的占用磁盘: __sum(vm_data_size_bytes{type!="indexdb"}) / sum(vm_rows{type != "indexdb"})__ + +## 计算方法 + +**磁盘用量** = 瞬时指标量 x 2 x 单个数据点的占用磁盘 x 60 x 24 x 存储时间 (天) + +**参数说明:** + +1. 磁盘用量单位为 __Byte__ 。 +2. __存储时长(天) x 60 x 24__ 将时间(天)换算成分钟以便计算磁盘用量。 +3. Insight Agent 中 Prometheus 默认采集时间为 30s ,故在 1 分钟内产生两倍的指标量。 +4. vmstorage 中默认存储时长为 1 个月,修改配置请参考[修改系统配置](../../system-config/modify-config.md)。 + +!!! warning + + 该公式为通用方案,建议在计算结果上预留冗余磁盘容量以保证 vmstorage 的正常运行。 + +## 参考容量 + +表格中数据是根据默认存储时间为一个月 (30 天),单个数据点 (datapoint) 的占用磁盘取 0.9 计算所得结果。 +多集群场景下,Pod 数量表示多集群 Pod 数量的总和。 + +### 当未开启服务网格时 + +| 集群规模 (Pod 数) | 指标量 | 磁盘容量 | +| ----------------- | ------ | -------- | +| 100 | 8w | 6 GiB | +| 200 | 16w | 12 GiB | +| 300 | 24w | 18 GiB | +| 400 | 32w | 24 GiB | +| 500 | 40w | 30 GiB | +| 800 | 64w | 48 GiB | +| 1000 | 80w | 60 GiB | +| 2000 | 160w | 120 GiB | +| 3000 | 240w | 180 GiB | + +### 当开启服务网格时 + +| 集群规模 (Pod 数) | 指标量 | 磁盘容量 | +| ----------------- | ------ | -------- | +| 100 | 15w | 12 GiB | +| 200 | 31w | 24 GiB | +| 300 | 46w | 36 GiB | +| 400 | 62w | 48 GiB | +| 500 | 78w | 60 GiB | +| 800 | 125w | 94 GiB | +| 1000 | 156w | 120 GiB | +| 2000 | 312w | 235 GiB | +| 3000 | 468w | 350 GiB | + +### 举例说明 + +AI 算力中心 平台中有两个集群,其中全局服务集群(开启服务网格)中运行 500 个 Pod,工作集群(未开启服务网格)运行了 1000 个 Pod,预期指标存 30 天。 + +- 全局服务集群中指标量为 800x500 + 768x500 = 784000 +- 工作集群指标量为 800x1000 = 800000 + +则当前 vmstorage 磁盘用量应设置为 (784000+80000)x2x0.9x60x24x31 = 124384896000 byte = 116 GiB + +!!! note + + 集群中指标量与 Pod 数量的关系可参考 [Prometheus 资源规划](./prometheus-res.md)。 diff --git a/docs/zh/docs/end-user/insight/system-config/modify-config.md b/docs/zh/docs/end-user/insight/system-config/modify-config.md new file mode 100644 index 0000000..65bccdb --- /dev/null +++ b/docs/zh/docs/end-user/insight/system-config/modify-config.md @@ -0,0 +1,190 @@ +# 修改系统配置 + +可观测性会默认持久化保存指标、日志、链路的数据,您可参阅本文修改系统配置。该文档仅适用于内置部署的 Elasticsearch,若使用外部 Elasticsearch 可自行调整。 + +## 如何修改指标数据保留期限 + +先 ssh 登录到对应的节点,参考以下步骤修改指标数据保留期限。 + +1. 执行以下命令: + + ```sh + kubectl edit vmcluster insight-victoria-metrics-k8s-stack -n insight-system + ``` + +2. 在 Yaml 文件中, __retentionPeriod__ 的默认值为 __14__ ,单位为 __天__ 。您可根据需求修改参数。 + + ```Yaml + apiVersion: operator.victoriametrics.com/v1beta1 + kind: VMCluster + metadata: + annotations: + meta.helm.sh/release-name: insight + meta.helm.sh/release-namespace: insight-system + creationTimestamp: "2022-08-25T04:31:02Z" + finalizers: + - apps.victoriametrics.com/finalizer + generation: 2 + labels: + app.kubernetes.io/instance: insight + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: victoria-metrics-k8s-stack + app.kubernetes.io/version: 1.77.2 + helm.sh/chart: victoria-metrics-k8s-stack-0.9.3 + name: insight-victoria-metrics-k8s-stack + namespace: insight-system + resourceVersion: "123007381" + uid: 55cee8d6-c651-404b-b2c9-50603b405b54 + spec: + replicationFactor: 1 + retentionPeriod: "14" + vminsert: + extraArgs: + maxLabelsPerTimeseries: "45" + image: + repository: docker.m.daocloud.io/victoriametrics/vminsert + tag: v1.80.0-cluster + replicaCount: 1 + ``` + +3. 保存修改后,负责存储指标的组件的容器组会自动重启,稍等片刻即可。 + +## 如何修改日志数据存储时长 + +先 ssh 登录到对应的节点,参考以下步骤修改日志数据保留期限: + +### 方法一:修改 Json 文件 + +1. 修改以下文件中 __rollover__ 字段中的 __max_age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。注意需要修改第一行中的 Elastic 用户名和密码、IP 地址和索引。 + + ```json + curl --insecure --location -u"elastic:amyVt4o826e322TUVi13Ezw6" -X PUT "https://172.30.47.112:30468/_ilm/policy/insight-es-k8s-logs-policy?pretty" -H 'Content-Type: application/json' -d' + { + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "set_priority": { + "priority": 100 + }, + "rollover": { + "max_age": "8d", + "max_size": "10gb" + } + } + }, + "warm": { + "min_age": "10d", + "actions": { + "forcemerge": { + "max_num_segments": 1 + } + } + }, + "delete": { + "min_age": "30d", + "actions": { + "delete": {} + } + } + } + } + }' + ``` + +2. 修改完后,执行以上命令。它会打印出如下所示内容,则修改成功。 + + ```json + { + "acknowledged" : true + } + ``` + +### 方法二:从 UI 修改 + +1. 登录 __kibana__ ,选择左侧导航栏 __Stack Management__ 。 + + ![Stack Management](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys01.png) + +2. 选择左侧导航 __Index Lifecycle Polices__ ,并找到索引 __insight-es-k8s-logs-policy__ ,点击进入详情。 + + ![索引](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys02.png) + +3. 展开 __Hot phase__ 配置面板,修改 __Maximum age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。 + + ![保留期限](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys03.png) + +4. 修改完后,点击页面底部的 __Save policy__ 即修改成功。 + + ![保存](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys04.png) + +## 如何修改链路数据存储时长 + +先 ssh 登录到对应的节点,参考以下步骤修改链路数据保留期限: + +### 方法一:修改 Json 文件 + +1. 修改以下文件中 __rollover__ 字段中的 __max_age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。注意需要修改第一行中的 Elastic 用户名和密码、IP 地址和索引。 + + ```json + curl --insecure --location -u"elastic:amyVt4o826e322TUVi13Ezw6" -X PUT "https://172.30.47.112:30468/_ilm/policy/jaeger-ilm-policy?pretty" -H 'Content-Type: application/json' -d' + { + "policy": { + "phases": { + "hot": { + "min_age": "0ms", + "actions": { + "set_priority": { + "priority": 100 + }, + "rollover": { + "max_age": "6d", + "max_size": "10gb" + } + } + }, + "warm": { + "min_age": "10d", + "actions": { + "forcemerge": { + "max_num_segments": 1 + } + } + }, + "delete": { + "min_age": "30d", + "actions": { + "delete": {} + } + } + } + } + }' + ``` + +2. 修改完后,在控制台执行以上命令。它会打印出如下所示内容,则修改成功。 + + ```json + { + "acknowledged" : true + } + ``` + +### 方法二:从 UI 修改 + +1. 登录 __kibana__ ,选择左侧导航栏 __Stack Management__ 。 + + ![Stack Management](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/logsys01.png) + +2. 选择左侧导航 __Index Lifecycle Polices__ ,并找到索引 __jaeger-ilm-policy__ ,点击进入详情。 + + ![索引](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/trace02.png) + +3. 展开 __Hot phase__ 配置面板,修改 __Maximum age__ 参数,并设置保留期限,默认存储时长为 __7d__ 。 + + ![保留期限](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/trace03.png) + +4. 修改完后,点击页面底部的 __Save policy__ 即修改成功。 + + ![保存](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/trace04.png) diff --git a/docs/zh/docs/end-user/insight/system-config/system-component.md b/docs/zh/docs/end-user/insight/system-config/system-component.md new file mode 100644 index 0000000..1aa71ea --- /dev/null +++ b/docs/zh/docs/end-user/insight/system-config/system-component.md @@ -0,0 +1,27 @@ +# 系统组件 + +在系统组件页面可快速的查看可观测性模块中系统组件的运行状态,当系用组件发生故障时,会导致可观测模块中的部分功能不可用。 + +1. 进入 __可观测性__ 产品模块, +2. 在左边导航栏选择 __系统管理 -> 系统组件__ 。 + + ![系统组件](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/system00.png) + +## 组件说明 + +|模块 | 组件名称 | 说明 | +| ----- | --------------- | ----------------------------------------------- | +|指标 | vminsert-insight-victoria-metrics-k8s-stack | 负责将各集群中 Prometheus 采集到的指标数据写入存储组件。该组件异常会导致无法写入工作集群的指标数据。 | +|指标 | vmalert-insight-victoria-metrics-k8s-stack | 负责生效 VM Rule 中配置的 recording 和 Alert 规则,并将触发的告警规则发送给 alertmanager。 | +|指标 | vmalertmanager-insight-victoria-metrics-k8s-stack | 负责在告警触时发送消息。该组件异常会导致无法发送告警信息。 | +|指标 | vmselect-insight-victoria-metrics-k8s-stack | 负责查询指标数据。该组件异常会导致无法查询指标。 | +|指标 | vmstorage-insight-victoria-metrics-k8s-stack | 负责存储多集群的指标数据。 | +|仪表盘 | grafana-deployment | 提供监控面板能力。该组件异常会导致无法查看内置的仪表盘。 | +|链路 | insight-jaeger-collector | 负责接收 opentelemetry-collector 中链路数据并将其进行存储。 | +|链路 | insight-jaeger-query | 负责查询各集群中采集到的链路数据。 | +|链路 | insight-opentelemetry-collector | 负责接收各子集群转发的链路数据 | +|日志 | elasticsearch | 负责存储各集群的日志数据。 | + +!!! note + + 若使用外部 Elasticsearch 可能无法获取部分数据以致于 Elasticsearch 的信息为空。 diff --git a/docs/zh/docs/end-user/insight/system-config/system-config.md b/docs/zh/docs/end-user/insight/system-config/system-config.md new file mode 100644 index 0000000..2b46172 --- /dev/null +++ b/docs/zh/docs/end-user/insight/system-config/system-config.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# 系统配置 + + __系统配置__ 展示指标、日志、链路默认的保存时长以及默认的 Apdex 阈值。 + +1. 点击右侧导航栏,选择 __系统配置__。 + + ![系统配置](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/systemconfig00.png) + +2. 修改历史告警存储时长,点击 __编辑__ 输入目标时长。 + + 当存储时长设置为 "0" 将不清除历史告警。 + + ![系统配置](https://docs.daocloud.io/daocloud-docs-images/docs/insight/images/sysconfig02.png) + +3. 修改拓扑图渲染默认配置,点击 __编辑__ 根据需求定义系统中拓扑图阈值。 + + 阈值设置必须大于 0,前面填写的阈值必须小于后面填写的。且填写的阈值必须在最大和最小的范围之间。 + + ![拓扑配置](../images/map-setting.png) + +!!! note + + 修改其他配置,请点击查看[如何修改系统配置?](modify-config.md) diff --git a/docs/zh/docs/end-user/insight/trace/service.md b/docs/zh/docs/end-user/insight/trace/service.md new file mode 100644 index 0000000..e715a53 --- /dev/null +++ b/docs/zh/docs/end-user/insight/trace/service.md @@ -0,0 +1,56 @@ +# 服务监控 + +在 __可观测性 Insight__ 中服务是指使用 Opentelemtry SDK 接入链路数据,服务监控能够辅助运维过程中观察应用程序的性能和状态。 + +如何使用 OpenTelemetry 请参考[使用 OTel 赋予应用可观测性](../quickstart/otel/otel.md)。 + +## 名词解释 + +- **服务** :服务表示为传入请求提供相同行为的一组工作负载。您可以在使用 OpenTelemetry SDK 时定义服务名称或使用 Istio 中定义的名称。 +- **操作** :操作是指一个服务处理的特定请求或操作,每个 Span 都有一个操作名称。 +- **出口流量** :出口流量是指当前服务发起请求的所有流量。 +- **入口流量** :入口流量是指上游服务对当前服务发起请求的所有流量。 + +## 操作步骤 + +服务列表页面展示了集群中所有已接入链路数据的服务的吞吐率、错误率、请求延时等关键指标。 +您可以根据集群、命名空间对服务进行过滤,也可以按照吞吐率、错误率、请求延时对该列表进行排序。列表中的指标数据默认时间为 1 小时,您可以自定义时间范围。 + +请按照以下步骤查看服务监控指标: + +1. 进入 __可观测性__ 产品模块。 + +2. 在左边导航栏选择 __链路追踪__ -> __服务__ 。 + + ![服务监控](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/service00.png){ width="1000"} + + !!! attention + + 1. 若列表中服务所在的命名空间为 __unknown__ 时,则表示该服务未规范接入,建议重新接入。 + 2. 若接入的服务存在同名且均未正确填写环境变量中的 __命名空间__ 时,列表及服务详情页中展示的监控数据为多个服务的汇总数据。 + +3. 点击服务名 (以 insight-server 为例),点击进入服务详情页,查看服务的详细指标和该服务的操作指标。 + + 1. 在服务拓扑模块中,您可以查看当前所选服务的上下各一层的服务拓扑,鼠标悬浮在节点上时可以查看节点的信息。 + 2. 在流量指标模块,您可查看到该服务默认一小时内全部请求(包含入口流量和出口流量)的监控指标。 + 3. 支持通过右上角的时间选择器快速选择时间范围,或自定义时间范围。 + 4. 在 __关联容器__ 模块点击容器组名称,可跳转至容器组详情页。 + + ![服务监控](../images/service.png){ width="1000"} + +4. 点击 Tab 切换到 __操作指标__ ,可查询多选服务相同操作的聚合起来的流量指标。 + + 1. 支持对操作指标中的吞吐率、错误率、请求延时等指标进行排序。 + 2. 点击单个操作后的图标,可跳转至 __调用链__ 快速查询相关链路。 + + ![服务监控](../images/service-1.png){ width="1000"} + +### 服务指标说明 + +| 参数 | 说明 | +| -------- | ---------------------------------------- | +| 吞吐率 | 单位时间内处理请求的数量。 | +| 错误率 | 查询时间范围内错误请求与请求总数的比值。 | +| P50 请求延时 | 在所有的请求中,有 50% 的请求响应时间小于或等于该值。 | +| P95 请求延时 | 在所有的请求中,有 95% 的请求响应时间小于或等于该值。 | +| P99 请求延时 | 在所有的请求中,有 95% 的请求响应时间小于或等于该值。 | diff --git a/docs/zh/docs/end-user/insight/trace/topology.md b/docs/zh/docs/end-user/insight/trace/topology.md new file mode 100644 index 0000000..3e2d4ce --- /dev/null +++ b/docs/zh/docs/end-user/insight/trace/topology.md @@ -0,0 +1,53 @@ +# 服务拓扑 + +服务拓扑图是对服务之间连接、通信和依赖关系的可视化表示。通过可视化拓扑了解服务间的调用关系, +查看服务在指定时间内的调用及其性能状况。拓扑图的节点之间的联系代表两个服务在查询时间范围内服务之间的存在调用关系。 + +## 前提条件 + +1. 集群中已[安装 insight-agent](../quickstart/install/install-agent.md) 且应用处于 __运行中__ 状态。 +2. 服务已通过 [Operator](../quickstart/otel/operator.md) 或 + [Opentelemetry SDK](../quickstart/otel/golang/golang.md) 的方式接入链路。 + +## 操作步骤 + +1. 进入 __可观测性__ 模块 +2. 在左边导航栏选择 __链路追踪 -> 服务拓扑__ +3. 在拓扑图中,您可按需执行以下操作: + + - 单击 __节点__,从右侧划出服务的详情,可查看服务的请求延时、吞吐率、错误率的指标。点击服务名称可跳转至对应服务的详情页。 + - 鼠标悬浮在连线上时,可查看两个服务之间请求的流量指标。 + - 在 __显示设置__ 模块,可配置拓扑图中的显示元素。 + + ![服务拓扑](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/servicemap00.png){ width="1000"} + +4. 点击右下角 __图例__ ,可通过 __临时配置__ 修改当前的拓扑图定义的渲染阈值,跳出或关闭该页面即会丢失该配置。 + + 阈值设置必须大于 0,前面填写的阈值必须小于后面填写的。且填写的阈值必须在最大和最小的范围之间。 + + ![服务拓扑](../images/servicemap01.png){ width="1000"} + + ![服务拓扑](../images/servicemap02.png){ width="1000"} + +### 其他节点 + +在服务拓扑中会存在游离在集群之外的节点,这些游离在外的节点可分成三类: + +- 数据库 +- 消息队列 +- 虚拟节点 + +1. 若服务发起请求到`数据库`或`消息队列`时,拓扑图中会默认展示这两类节点。 + 而`虚拟服务`表示集群内服务请求了集群外的节点或者未接入链路的服务,拓扑图中默认不会展示 `虚拟服务`。 + +1. 当服务请求到 MySQL、PostgreSQL、Oracle Database 这三种数据库时,在拓扑图中可以看到请求的详细数据库类型。 + + ![数据库细节](../images/service-map.png) + +#### 开启虚拟节点 + +1. 更新 insight-server chart 的 values,找到下图所示参数,将 `false` 改为 `true`。 + + ![拓扑图](../images/servicemap.png) + +2. 在服务拓扑的显示设置中勾选 __虚拟服务__ 。 diff --git a/docs/zh/docs/end-user/insight/trace/trace.md b/docs/zh/docs/end-user/insight/trace/trace.md new file mode 100644 index 0000000..227f6e3 --- /dev/null +++ b/docs/zh/docs/end-user/insight/trace/trace.md @@ -0,0 +1,56 @@ +# 链路查询 + +在链路查询页面,您可以过 TraceID 或精确查询调用链路详细情况或结合多种条件筛选查询调用链路。 + +## 名词解释 + +- TraceID:用于标识一个完整的请求调用链路。 +- 操作:描述 Span 所代表的具体操作或事件。 +- 入口 Span:入口 Span 代表了整个请求的第一个请求。 +- 延时:整个调用链从开始接收请求到完成响应的持续时间。 +- Span:整个链路中包含的 Span 个数。 +- 发生时间:当前链路开始的时间。 +- Tag:一组键值对构成的 Span 标签集合,Tag 是用来对 Span 进行简单的注解和补充,每个 Span 可以有多个简直对形式的 Tag。 + +## 操作步骤 + +请按照以下步骤查询链路: + +1. 进入 __可观测性__ 产品模块, +2. 在左边导航栏选择 __链路追踪__ -> __调用链__。 + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace00.png) + + !!! note + + 列表中支持对 Span 数、延时、发生时间进行排序。 + +3. 点击筛选栏中的 __TraceID 搜索__ 切换使用 TraceID 搜索链路。 + + - 使用 TraceID 搜索请输入完整的 TraceID。 + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace04.png) + +## 其他操作 + +### 查看链路详情 + +1. 点击链路列表中的某一链路的 TraceID,可查看该链路的详情调用情况。 + + ![jaeger](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/insight/images/trace03.png) + +### 查看关联日志 + +1. 点击链路数据右侧的图标,可查询该链路的关联日志。 + + - 默认查询该链路的持续时间及其结束之后一分钟内的日志数据。 + - 查询的日志内容为日志文本中包含该链路的 TraceID 的日志和链路调用过程中相关的容器日志。 + +2. 点击 __查看更多__ 后可带条件跳转到 __日志查询__ 的页面。 +3. 默认搜索全部日志,但可下拉根据链路的 TraceID 或链路调用过程中相关的容器日志进行过滤。 + + ![tracelog](../images/tracelog.png) + + !!! note + + 由于链路会跨集群或跨命名空间,若用户权限不足,则无法查询该链路的关联日志。 diff --git a/docs/zh/docs/end-user/k8s/add-node.md b/docs/zh/docs/end-user/k8s/add-node.md new file mode 100644 index 0000000..b740ffa --- /dev/null +++ b/docs/zh/docs/end-user/k8s/add-node.md @@ -0,0 +1,43 @@ +# 添加工作节点 + +如果节点不够用了,可以添加更多节点到集群中。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 有一个管理员帐号 +- [已创建带 GPU 节点的集群](./create-k8s.md) +- [准备一台云主机](../host/createhost.md) + +## 添加步骤 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. 导航至 **容器管理** -> **集群列表** ,点击目标集群的名称 + + ![clusters](../images/remove01.png) + +1. 进入集群概览页,点击 **节点管理** ,点击右侧的 **接入节点** 按钮 + + ![add](../images/add01.png) + +1. 按照向导,填写各项参数后点击 **确定** + + === "基本信息" + + ![basic](../images/add02.png) + + === "参数配置" + + ![arguments](../images/add03.png) + +1. 在弹窗中点击 **确定** + + ![ok](../images/add04.png) + +1. 返回节点列表,新接入的节点状态为 **接入中** ,等待几分钟后状态变为 **健康** 则表示接入成功。 + + ![success](../images/add05.png) + +!!! tip + + 对于刚接入成功的节点,可能还要等 2-3 分钟才能识别出 GPU。 diff --git a/docs/zh/docs/end-user/k8s/create-k8s.md b/docs/zh/docs/end-user/k8s/create-k8s.md new file mode 100644 index 0000000..16674d7 --- /dev/null +++ b/docs/zh/docs/end-user/k8s/create-k8s.md @@ -0,0 +1,80 @@ +# 创建云上 Kubernetes 集群 + +部署 Kubernetes 集群是为了支持高效的 AI 算力调度和管理,实现弹性伸缩,提供高可用性,从而优化模型训练和推理过程。 + +## 前置条件 + +- 已安装 AI 算力平台已 +- 有一个管理员权限的账号 +- 准备一台带 GPU 的物理机 +- 分配两段 IP 地址(Pod CIDR 18 位、SVC CIDR 18 位,不能与现有网段冲突) + +## 创建步骤 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. [创建并启动 3 台不带 GPU 的云主机](../host/createhost.md)用作集群的 Master 节点 + + - 配置资源,CPU 16 核,内存 32 GB,系统盘 200 GB(ReadWriteOnce) + - 网络模式选择 **Bridge(桥接)** + - 设置 root 密码或添加 SSH 公钥,方便以 SSH 连接 + - 记录好 3 台主机的 IP + +1. 导航至 **容器管理** -> **集群列表** ,点击右侧的 **创建集群** 按钮 +1. 按照向导,配置集群的各项参数 + + === "基本信息" + + ![basic](../images/k8s01.png) + + === "节点配置" + + 配置完节点信息后,点击 **开始检查** , + + ![node](../images/k8s02.png) + ![node](../images/k8s03.png) + + === "网络配置" + + ![network](../images/k8s04.png) + + === "Addon 配置" + + ![addon](../images/k8s05.png) + + === "高级配置" + + 每个节点默认可运行 110 个 Pod(容器组),如果节点配置比较高,可以调整到 200 或 300 个 Pod。 + + ![basic](../images/k8s06.png) + +1. 等待集群创建完成。 + + ![done](../images/k8s08.png) + +1. 在集群列表中,找到刚创建的集群,点击集群名称,导航到 **Helm 应用** -> **Helm 模板** ,在搜索框内搜索 metax-gpu-extensions,点击卡片 + + ![cluster](../images/k8s09.png) + + ![helm](../images/k8s10.png) + +1. 点击右侧的 **安装** 按钮,开始安装 GPU 插件 + + === "应用设置" + + 输入名称,选择命名空间,在 YAMl 中修改镜像地址: + + ![app settings](../images/k8s11.png) + + === "Kubernetes 编排确认" + + ![confirm](../images/k8s12.png) + +1. 自动返回 Helm 应用列表,等待 metax-gpu-extensions 状态变为 **已部署** + + ![deployed](../images/k8s13.png) + +1. 到此集群创建成功,可以去查看集群所包含的节点。你可以去[创建 AI 工作负载并使用 GPU 了](../share/workload.md)。 + + ![nodes](../images/k8s14.png) + +下一步:[创建 AI 工作负载](../share/workload.md) diff --git a/docs/zh/docs/end-user/k8s/remove-node.md b/docs/zh/docs/end-user/k8s/remove-node.md new file mode 100644 index 0000000..5f5bd82 --- /dev/null +++ b/docs/zh/docs/end-user/k8s/remove-node.md @@ -0,0 +1,37 @@ +# 移除 GPU 工作节点 + +GPU 资源的成本相对较高,如果暂时用不到 GPU,可以将带 GPU 的工作节点移除。 +以下步骤也同样适用于移除普通工作节点。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 有一个管理员帐号 +- [已创建带 GPU 节点的集群](./create-k8s.md) + +## 移除步骤 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. 导航至 **容器管理** -> **集群列表** ,点击目标集群的名称 + + ![clusters](../images/remove01.png) + +1. 进入集群概览页,点击 **节点管理** ,找到要移除的节点,点击列表右侧的 __┇__ ,在弹出菜单中选择 **移除节点** + + ![remove](../images/remove02.png) + +1. 在弹框中输入节点名称,确认无误后点击 **删除** + + ![confirm](../images/remove03.png) + +1. 自动返回节点列表,状态为 **移除中** ,几分钟后刷新页面,节点不在了,说明节点被成功移除 + + ![removed](../images/remove04.png) + +1. 从 UI 列表移除节点后,通过 SSH 登录到已移除的节点主机,执行关机命令。 + + ![shutdown](../images/remove05.png) + +!!! tip + + 在 UI 上移除节点并将其关机后,节点上的数据并未被立即删除,节点数据会被保留一段时间。 diff --git a/docs/zh/docs/end-user/kpanda/backup/deployment.md b/docs/zh/docs/end-user/kpanda/backup/deployment.md new file mode 100644 index 0000000..c9eab4b --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/backup/deployment.md @@ -0,0 +1,56 @@ +# 应用备份 + +本文介绍如何在算丰 AI 算力平台中为应用做备份,本教程中使用的演示应用名为 __dao-2048__ ,属于无状态工作负载。 + +## 前提条件 + +在对无状态工作负载进行备份前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../register/index.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- [安装 velero 组件](install-velero.md),且 velero 组件运行正常。 + +- [创建一个无状态工作负载](../workloads/create-deployment.md)(本教程中的负载名为 __dao-2048__ ),并为无状态工作负载打上 __app: dao-2048__ 的标签。 + +## 备份工作负载 + +参考以下步骤,备份无状态工作负载 __dao-2048__ 。 + +1. 在左侧导航栏, 点击 __容器管理__ -> __备份恢复__ 。 + + ![集群列表](../images/backupd20481.png) + +2. 进入 __应用备份__ 列表页面,从集群下拉列表中选择已安装了 velero 和 __dao-2048__ 的集群。 + 点击右侧的 __创建备份计划__ 按钮。 + + ![应用备份](../images/backupd20482.png) + +3. 参考下方说明填写备份配置。 + + ![操作菜单](../images/backupd20483.png) + +4. 参考下方说明设置备份执行频率,然后点击 __下一步__ 。 + + - 备份频率:基于分钟、小时、天、周、月设置任务执行的时间周期。支持用数字和 `*` 自定义 Cron 表达式,**输入表达式后下方会提示当前表达式的含义** 。有关详细的表达式语法规则,可参考 [Cron 时间表语法](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax)。 + - 留存时长(天):设置备份资源保存的时间,默认为 30 天,过期后将会被删除。 + - 备份数据卷(PV):是否备份数据卷(PV)中的数据,支持直接复制和使用 CSI 快照两种方式。 + - 直接复制:直接复制数据卷(PV)中的数据用于备份; + - 使用 CSI 快照:使用 CSI 快照来备份数据卷(PV)。需要集群中有可用于备份的 CSI 快照类型。 + + ![操作菜单](../images/backupd20484.png) + +5. 点击 __确定__ ,页面会自动返回应用备份计划列表。您可以找到新建的 __dao-2048__ 备份计划,在右侧点击 __┇__ ,选择 __立即执行__ 开始备份。 + + ![操作菜单](../../../images/backupd20485.png) + +6. 此时集群的 __上一次执行状态__ 将转变为 __备份中__ 。等待备份完成后可以点击备份计划的名称,查看备份计划详情。 + + ![操作菜单](../../../images/backupd20486.png) + +!!! note + + 如果 Job 类型的工作负载状态为 **执行完成** ,则不支持备份。 diff --git a/docs/zh/docs/end-user/kpanda/backup/etcd-backup.md b/docs/zh/docs/end-user/kpanda/backup/etcd-backup.md new file mode 100644 index 0000000..0775d04 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/backup/etcd-backup.md @@ -0,0 +1,128 @@ +# etcd 备份 + +etcd 备份是以集群数据为核心的备份。在硬件设备损坏,开发测试配置错误等场景中,可以通过 etcd 备份恢复集群数据。 + +本文介绍如何为集群制作 etcd 备份。 + +## 前提条件 + +- [接入](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建[命名空间](../namespaces/createns.md)和[用户](../../register/index.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限。详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +- 准备一个 MinIO 实例。 + +## 创建 etcd 备份 + +参照以下步骤创建 etcd 备份。 + +1. 进入 __容器管理__ -> __备份恢复__ -> __etcd 备份__ ,点击 __备份策略__ 页签,然后在右侧点击 __创建备份策略__ 。 + + ![备份策略列表](../../../images/etcd01.png) + +2. 参考以下说明填写 __基本信息__ 。填写完毕后点击 __下一步__ ,系统将自动校验 etcd 的联通性,校验通过之后可以进行下一步。 + + - 备份集群:选择需要备份哪个集群的 etcd 数据,并在终端登录 + - etcd 地址:格式为 `https://${节点IP}:${端口号}` + + - 在标准 Kubernetes 集群中,etcd 的默认端口号为 __2379__ + - 在公有云托管集群中,需要联系相关开发人员获取 etcd 的端口号。 + 这是因为公有云集群的控制面组件由云服务提供商维护和管理,用户无法直接访问或查看这些组件, + 也无法通过常规命令(如 kubectl)无法获取到控制面的端口等信息。 + + ??? note "获取端口号的方式" + + 1. 在 __kube-system__ 命名空间下查找 etcd Pod + + ```shell + kubectl get po -n kube-system | grep etcd + ``` + + 2. 获取 etcd Pod 的 __listen-client-urls__ 中的端口号 + + ```shell + kubectl get po -n kube-system ${etcd_pod_name} -oyaml | grep listen-client-urls # (1)! + ``` + + 1. 将 __etcd_pod_name__ 替换为实际的 Pod 名称 + + 预期输出结果如下,节点 IP 后的数字即为端口号: + + ```shell + - --listen-client-urls=https://127.0.0.1:2379,https://10.6.229.191:2379 + ``` + + - CA 证书:可通过如下命令查看证书,然后将证书内容复制粘贴到对应位置: + + ```shell + cat /etc/kubernetes/ssl/etcd/ca.crt + ``` + + - Cert 证书:可通过如下命令查看证书,然后将证书内容复制粘贴到对应位置: + + ```shell + cat /etc/kubernetes/ssl/apiserver-etcd-client.crt + ``` + + - Key:可通过如下命令查看证书,然后将证书内容复制粘贴到对应位置: + + ```shell + cat /etc/kubernetes/ssl/apiserver-etcd-client.key + ``` + + ![创建基本信息](../../../images/etcd-get01.png) + + !!! note + + 点击输入框下方的 __如何获取__ 可以在 UI 页面查看获取对应信息的方式。 + +3. 参考以下信息填写 __备份策略__ 。 + + - 备份方式:选择手动备份或定时备份 + + - 手动备份:基于备份配置立即执行一次 etcd 全量数据的备份。 + - 定时备份:按照设置的备份频率对 etcd 数据进行周期性全量备份。 + + - 备份链长度:最多保留多少条备份数据。默认为 30 条。 + - 备份频率:支持小时、日、周、月级别和自定义方式。 + + ![定时备份](../../../images/etcd04.png) + +4. 参考以下信息填写 __存储位置__ 。 + + - 存储供应商:默认选择 S3 存储 + - 对象存储访问地址:MinIO 的访问地址 + - 存储桶:在 MinIO 中创建一个 Bucket,填写 Bucket 的名称 + - 用户名:MinIO 的登录用户名 + - 密码:MinIO 的登录密码 + + ![存储位置](../../../images/etcd05.png) + +5. 点击 __确定__ 后页面自动跳转到备份策略列表,可以查看目前创建好的所有策略。 + + - 在策略右侧点击 __┇__ 操作按钮可以查看日志、查看 YAML、更新策略、停止策略、立即执行策略等。 + - 当备份方式为手动时,可以点击 __立即执行__ 进行备份。 + - 当备份方式为定时备份时,则会根据配置的时间进行备份。 + + ![成功创建](../../../images/etcd07.png) + +## 查看备份策略日志 + +点击 __日志__ 可以查看日志内容,默认展示 100 行。若想查看更多日志信息或者下载日志,可在日志上方根据提示前往可观测性模块。 + +![查看日志](../../../images/etcd06.png) + +## 查看备份策略详情 + +进入 __容器管理__ -> __备份恢复__ -> __etcd 备份__ ,点击 __备份策略__ 页签,接着点击策略名称可以查看策略详情。 + +![备份策略详情](../../../images/etcd09.png) + +## 查看备份点 + +1. 进入 __容器管理__ -> __备份恢复__ -> __etcd 备份__ ,点击 __备份点__ 页签。 +2. 选择目标集群后,可以查看该集群下所有备份信息。 + + 每执行一次备份,对应生成一个备份点,可通过成功状态的备份点快速恢复应用。 + + ![备份点](../../../images/etcd08.png) diff --git a/docs/zh/docs/end-user/kpanda/backup/index.md b/docs/zh/docs/end-user/kpanda/backup/index.md new file mode 100644 index 0000000..b2994ef --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/backup/index.md @@ -0,0 +1,30 @@ +--- +hide: + - toc +--- + +# 备份恢复 + +备份恢复分为备份和恢复两方面,实际应用时需要先备份系统在某一时点的数据,然后安全存储地备份数据。后续如果出现数据损坏、丢失、误删等事故,就可以基于之前的数据备份快速还原系统,**缩短故障时间,减少损失**。 + +- 在真实的生产环境中,服务可能分布式地部署在不同的云、不同区域或可用区,如果某一个基础设施自身出现故障,企业需要在其他可用环境中快速恢复应用。在这种情况下,跨云/跨集群的备份恢复显得非常重要。 +- 在大规模系统中往往有很多角色和用户,权限管理体系复杂,操作者众多,难免有人误操作导致系统故障。在这种情况下,也需要能够通过之前备份的数据快速回滚系统,否则如果依赖人为排查故障、修复故障、恢复系统就会耗费大量时间,系统不可用时间越长,企业的损失越大。 +- 此外,还有网络攻击、自然灾害、设备故障等各种因素也可能导致数据事故 + +因此,备份恢复非常重要,可以视之为维护系统稳定和数据安全的最后一道保险。 + +备份通常分为全量备份、增量备份、差异备份三种。算丰 AI 算力平台目前支持全量备份和增量备份。 + +算丰 AI 算力平台提供的备份恢复可以分为 **应用备份** 和 **ETCD 备份** 两种,支持手动备份,或基于 CronJob 定时自动备份。 + +- 应用备份 + + 应用备份指,备份集群中的某个工作负载的数据,然后将该工作负载的数据恢复到本集群或者其他集群。支持备份整个命名空间下的所有资源,也支持通过标签选择器过滤,仅备份带有特定标签的资源。 + + 应用备份支持跨集群备份有状态应用,具体步骤可参考[MySQL 应用及数据的跨集群备份恢复](../../best-practice/backup-mysql-on-nfs.md)。 + +- ETCD 备份 + + etcd 是 Kubernetes 的数据存储组件,Kubernetes 将自身的组件数据和其中的应用数据都存储在 etcd 中。因此,备份 etcd 就相当于备份整个集群的数据,可以在故障时快速将集群恢复到之前某一时点的状态。 + + 需要注意的是,目前仅支持将 etcd 备份数据恢复到同一集群(原集群)。 diff --git a/docs/zh/docs/end-user/kpanda/backup/install-velero.md b/docs/zh/docs/end-user/kpanda/backup/install-velero.md new file mode 100644 index 0000000..36e1351 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/backup/install-velero.md @@ -0,0 +1,107 @@ +# 安装 velero 插件 + +velero 是一个备份和恢复 Kubernetes 集群资源的开源工具。它可以将 Kubernetes +集群中的资源备份到云存储服务、本地存储或其他位置,并且可以在需要时将这些资源恢复到同一或不同的集群中。 + +本节介绍如何在算丰 AI 算力平台中使用 __Helm 应用__ 部署 velero 插件。 + +## 前提条件 + +安装 __velero__ 插件前,需要满足以下前提条件: + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 创建 __velero__ [命名空间](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +请执行如下步骤为集群安装 __velero__ 插件。 + +1. 在集群列表页面找到需要安装 __velero__ 插件的目标集群,点击集群名称,在左侧导航栏依次点击 __Helm 应用__ -> __Helm 模板__ ,在搜索栏输入 __velero__ 进行搜索。 + + ![备份恢复](../../../images/backup1.png) + +1. 阅读 __velero__ 插件相关介绍,选择版本后点击 __安装__ 按钮。本文将以 __4.0.2__ 版本为例进行安装,推荐安装 __4.0.2__ 或更高版本。 + + ![备份恢复](../../../images/backup2.png) + +1. 填写和配置参数后点击 __下一步__ + + === "基本参数" + + ![备份恢复](../../../images/backup3.png) + + - 名称:必填参数,输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 metrics-server-01。 + - 命名空间:插件安装的命名空间,默认为 __velero__ 命名空间。 + - 版本:插件的版本,此处以 __4.0.2__ 版本为例。 + - 就绪等待:可选参数,启用后,将等待应用下所有关联资源处于就绪状态,才会标记应用安装成功。 + - 失败删除:可选参数,开启后,将默认同步开启就绪等待。如果安装失败,将删除安装相关资源。 + - 详情日志:可选参数,开启后将输出安装过程的详细日志。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要经过较长时间才会被标记为 __运行中__ 状态。 + + === "参数配置" + + - S3 Credentials: + + - __Use secret__ :保持默认配置 __true__ 。 + - __Secret name__ :保持默认配置 __velero-s3-credential__ 。 + - __SecretContents.aws_access_key_id = __ :配置访问对象存储的用户名,替换 ____ 为真实参数。 + - __SecretContents.aws_secret_access_key = __ :配置访问对象存储的密码,替换 ____ 为真实参数。 + + ```config "SecretContents 样例" + [default] + aws_access_key_id = minio + aws_secret_access_key = minio123 + ``` + + - Velero Configuration: + + - __Backupstoragelocation__ :velero 备份数据存储的位置 + - __S3 bucket__ :用于保存备份数据的存储桶名称(需为 minio 已经存在的真实存储桶) + - __Is default BackupStorage__ :保持默认配置 __true__ + - __S3 access mode__ :velero 对数据的访问模式,可以选择 + - __ReadWrite__ :允许 velero 读写备份数据 + - __ReadOnly__ :允许 velero 读取备份数据,不能修改备份数据 + - __WriteOnly__ :只允许 velero 写入备份数据,不能读取备份数据 + - __S3 Configs__ :S3 存储(minio)的详细配置 + - __S3 region__ :云存储的地理区域。默认使用 __us-east-1__ 参数,由系统管理员提供 + - __S3 force path style__ :保持默认配置 __true__ + - __S3 server URL__ :对象存储(minio)的控制台访问地址,minio 一般提供了 UI 访问和控制台访问两个服务,此处请使用控制台访问的地址 + + !!! note + + 请确保 s3 存储服务时间跟备份还原集群时间差在10分钟以内,最好是时间保持同步,否则将无法执行备份操作。 + + - migration plugin configuration:启用之后,将在下一步的 YAML 代码段中新增: + + ```yaml + ... + initContainers: + - image: 'release.daocloud.io/kcoral/velero-plugin-for-migration:v0.3.0' + imagePullPolicy: IfNotPresent + name: velero-plugin-for-migration + volumeMounts: + - mountPath: /target + name: plugins + - image: 'docker.m.daocloud.io/velero/velero-plugin-for-csi:v0.7.0' + imagePullPolicy: IfNotPresent + name: velero-plugin-for-csi + volumeMounts: + - mountPath: /target + name: plugins + - image: 'docker.m.daocloud.io/velero/velero-plugin-for-aws:v1.9.0' + imagePullPolicy: IfNotPresent + name: velero-plugin-for-aws + volumeMounts: + - mountPath: /target + name: plugins + ... + ``` + +1. 确认 YAML 无误后点击 __确定__ ,完成 __velero__ 插件的安装。 + 之后系统将自动跳转至 __Helm 应用__ 列表页面,稍等几分钟后,为页面执行刷新操作,即可看到刚刚安装的应用。 diff --git a/docs/zh/docs/end-user/kpanda/clusterops/cluster-oversold.md b/docs/zh/docs/end-user/kpanda/clusterops/cluster-oversold.md new file mode 100644 index 0000000..58c84f4 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusterops/cluster-oversold.md @@ -0,0 +1,50 @@ +# 集群动态资源超卖 + +目前,许多业务存在峰值和低谷的现象。为了确保服务的性能和稳定性,在部署服务时,通常会根据峰值需求来申请资源。 +然而,峰值期可能非常短暂,导致在非峰值期时资源被浪费。 +**集群资源超卖** 就是将这些申请了而未使用的资源(即申请量与使用量的差值)利用起来,从而提升集群资源利用率,减少资源浪费。 + +本文主要介绍如何使用集群动态资源超卖功能。 + +## 前提条件 + +- 容器管理模块已[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者已[创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已完成一个[命名空间的创建](../namespaces/createns.md),并为用户授予 [Cluster Admin](../permissions/permission-brief.md) , + 详情可参考[集群授权](../permissions/cluster-ns-auth.md)。 + +## 开启集群超卖 + +1. 点击左侧导航栏上的 **集群列表** ,然后点击目标集群的名称,进入 **集群详情** 页面 + + ![集群列表](../images/cluster-oversold-01.png) + +1. 在集群详情页面,点击左侧导航栏的 **集群运维** -> **集群设置** ,然后选择 **高级配置** 页签 + + ![高级设置](../images/cluster-oversold-02.png) + +1. 打开集群超卖,设置超卖比 + + - 若未安装 cro-operator 插件,点击 **立即安装** 按钮,安装流程参考[管理 Helm 应用](../helm/helm-app.md) + - 若已安装 cro-operator 插件,打开集群超卖开关,则可以开始使用集群超卖功能。 + + !!! note + + 需要在集群下对应的 namespace 打上如下标签,集群超卖策略才能生效。 + + ```shell + clusterresourceoverrides.admission.autoscaling.openshift.io/enabled: "true" + ``` + + ![集群超卖](../images/cluster-oversold-03.png) + +## 使用集群超卖 + +设置好集群动态资源超卖比后,会在工作负载运行时生效。下文以 niginx 为例,验证使用资源超卖能力。 + +1. 创建工作负载 nginx 并设置对应的资源限制值,创建流程参考[创建无状态负载(Deployment)](../workloads/create-deployment.md) + + ![创建工作负载](../images/cluster-oversold-04.png) + +1. 查看工作负载的 Pod 资源申请值与限制值的比值是否符合超售比 + + ![查看 Pod 资源](../images/cluster-oversold-05.png) diff --git a/docs/zh/docs/end-user/kpanda/clusterops/cluster-settings.md b/docs/zh/docs/end-user/kpanda/clusterops/cluster-settings.md new file mode 100644 index 0000000..df276c6 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusterops/cluster-settings.md @@ -0,0 +1,18 @@ +--- +hide: + - toc +--- + +# 集群设置 + +集群设置用于为您的集群自定义高级特性设置,包括是否启用 GPU、Helm 仓库刷新周期、Helm 操作记录保留等。 + +- 启用 GPU:需要预先在集群上安装 GPU 卡及对应驱动插件。 + + 点击目标集群的名称,在左侧导航栏点击 __最近操作__ -> __集群设置__ -> __Addon 插件__ 。 + + ![配置gpu](../../../images/settings01.png) + +- Helm 操作基础镜像、仓库刷新周期、操作记录保留条数、是否开启集群删除保护(开启后集群将不能直接卸载) + + ![高级配置](../../../images/Advanced-Configuration.png) diff --git a/docs/zh/docs/end-user/kpanda/clusterops/latest-operations.md b/docs/zh/docs/end-user/kpanda/clusterops/latest-operations.md new file mode 100644 index 0000000..17578c0 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusterops/latest-operations.md @@ -0,0 +1,22 @@ +--- +hide: + - toc +--- + +# 最近操作 + +在该页面可以查看最近的集群操作记录和 Helm 操作记录,以及各项操作的 YAML 文件和日志,也可以删除某一条记录。 + +![操作记录](../../../images/operations01.png) + +设置 Helm 操作的保留条数: + +系统默认保留最近 100 条 Helm 操作记录。若保留条数太多,可能会造成数据冗余,保留条数太少可能会造成您所需要的关键操作记录的缺失。需要根据实际情况设置合理的保留数量。具体步骤如下: + +1. 点击目标集群的名称,在左侧导航栏点击 __最近操作__ -> __Helm 操作__ -> __设置保留条数__ 。 + + ![保留条数](../../../images/operations02.png) + +2. 设置需要保留多少条 Helm 操作记录,并点击 __确定__ 。 + + ![保留条数](../../../images/operations03.png) diff --git a/docs/zh/docs/end-user/kpanda/clusters/access-cluster.md b/docs/zh/docs/end-user/kpanda/clusters/access-cluster.md new file mode 100644 index 0000000..2cb4ba4 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/access-cluster.md @@ -0,0 +1,59 @@ +# 访问集群 + +使用算丰 AI 算力平台容器管理平台接入或创建的集群,不仅可以通过 UI 界面直接访问,也可以通过其他两种方式进行访问控制: + +- 通过 CloudShell 在线访问 +- 下载集群证书后通过 kubectl 进行访问 + +!!! note + + 访问集群时,用户应具有 [Cluster Admin](../permissions/permission-brief.md) 权限或更高权限。 + +## 通过 CloudShell 访问 + +1. 在 __集群列表__ 页选择需要通过 CloudShell 访问的集群,点击右侧的 __┇__ 操作图标并在下拉列表中点击 __控制台__ 。 + + ![调用 CloudShell 控制台](../../../images/access-cloudshell.png) + +2. 在 CloudShell 控制台执行 __kubectl get node__ 命令,验证 CloudShell 与集群的连通性。如图,控制台将返回集群下的节点信息。 + + ![验证连通性](../../../images/access-get-node.png) + +现在,您可以通过 CloudShell 来访问并管理该集群了。 + +## 通过 kubectl 访问 + +通过本地节点访问并管理云端集群时,需要满足以下条件: + +- 本地节点和云端集群的网络互联互通。 +- 已经将集群证书下载到了本地节点。 +- 本地节点已经安装了 kubectl 工具。关于详细的安装方式,请参阅安装 [kubectl](https://kubernetes.io/zh-cn/docs/tasks/tools/)。 + +满足上述条件后,按照下方步骤从本地访问云端集群: + +1. 在 __集群列表__ 页选择需要下载证书的集群,点击右侧的 __┇__ ,并在弹出菜单中点击 __证书获取__ 。 + + ![进入下载证书页面](../../../images/access-get-cert.png) + +2. 选择证书有效期并点击 __下载证书__ 。 + + ![下载证书](../../../images/access-download-cert.png) + +3. 打开下载好的集群证书,将证书内容复制至本地节点的 __config__ 文件。 + + kubectl 工具默认会从本地节点的 __$HOME/.kube__ 目录下查找名为 __config__ 的文件。该文件存储了相关集群的访问凭证,kubectl 可以凭该配置文件连接至集群。 + +4. 在本地节点上执行如下命令验证集群的连通性: + + ```sh + kubectl get pod -n default + ``` + + 预期的输出类似于: + + ```none + NAME READY STATUS RESTARTS AGE + dao-2048-2048-58c7f7fc5-mq7h4 1/1 Running 0 30h + ``` + +现在您可以在本地通过 kubectl 访问并管理该集群了。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/cluster-role.md b/docs/zh/docs/end-user/kpanda/clusters/cluster-role.md new file mode 100644 index 0000000..2f4532b --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/cluster-role.md @@ -0,0 +1,67 @@ +# 集群角色 + +算丰 AI 算力平台基于集群的不同功能定位对集群进行了角色分类,帮助用户更好地管理 IT 基础设施。 + +## 全局服务集群 + +此集群用于运行算丰 AI 算力平台组件,例如容器管理、全局管理、可观测性、镜像仓库等。 +一般不承载业务负载。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 1.22+ | +| 操作系统 | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| 集群全生命周期管理 | 支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | Calico、Cillium、Multus 和其它 CNI | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +## 管理集群 + +此集群用于管理工作集群,一般不承载业务负载。 + +- 经典模式将全局服务集群和管理集群部署在不同的集群,适用于企业多数据中心、多架构的场景。 +- 简约模式将管理集群和全局服务集群部署在同一个集群内。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 1.22+ | +| 操作系统 | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| 集群全生命周期管理 | 支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | Calico、Cillium、Multus 和其它 CNI | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +## 工作集群 + +这是使用容器管理创建的集群,主要用于承载业务负载。该集群由管理集群进行管理。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 支持 K8s 1.22 及以上版本 | +| 操作系统 | RedHat 7.6 x86/ARM, RedHat 7.9 x86, RedHat 8.4 x86/ARM, RedHat 8.6 x86;
Ubuntu 18.04 x86, Ubuntu 20.04 x86;
CentOS 7.6 x86/AMD, CentOS 7.9 x86/AMD | +| 集群全生命周期管理 | 支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | Calico、Cillium、Multus 和其它 CNI | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +## 接入集群 + +此集群用于接入已有的标准 K8s 集群,包括但不限于本地数据中心自建集群、公有云厂商提供的集群、私有云厂商提供的集群、边缘集群、信创集群、异构集群。主要用于承担业务负载。 + +| 支持的功能 | 描述 | +| -------- | ---- | +| K8s 版本 | 1.18+ | +| 支持友商 | Vmware Tanzu、Amazon EKS、Redhat Openshift、SUSE Rancher、阿里 ACK、华为 CCE、腾讯 TKE、标准 K8s 集群、算丰 AI 算力平台 | +| 集群全生命周期管理 | 不支持 | +| K8s 资源管理 | 支持 | +| 云原生存储 | 支持 | +| 云原生网络 | 依赖于接入集群发行版网络模式 | +| 策略管理 | 支持网络策略、配额策略、资源限制、灾备策略、安全策略 | + +!!! note + + 一个集群可以有多个集群角色,例如一个集群既可以是全局服务集群,也可以是管理集群或工作集群。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/cluster-scheduler-plugin.md b/docs/zh/docs/end-user/kpanda/clusters/cluster-scheduler-plugin.md new file mode 100644 index 0000000..6716f2d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/cluster-scheduler-plugin.md @@ -0,0 +1,156 @@ +# 如何在集群中部署第二调度器 scheduler-plugins + +本文介绍如何在集群中部署第二个调度器 scheduler-plugins。 + +## 为什么需要 scheduler-plugins? + +通过平台创建的集群中会安装 K8s 原生的调度器,但是原生的调度器存在很多的局限性: + +- 原生的调度器无法满足调度需求,你可以选择使用 + [CoScheduling](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/pkg/coscheduling)、 + [CapacityScheduling](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master/pkg/capacityscheduling) + 等 scheduler-plugins 插件。 +- 在特殊的场景,需要新的调度器来完成调度任务而不影响原生调度器的流程。 +- 区分不同功能的调度器,通过切换调度器名称来实现不同的调度场景。 + +本文以使用 vgpu 调度器的同时,想结合 scheduler-plugins 的 coscheduling 插件能力的场景为示例,介绍如何安装并使用 scheduler-plugins。 + +## 安装 scheduler-plugins + +### 前置条件 + +- kubean 是在 v0.13.0 版本推出的新功能,选择管理集群时请确保版本不低于此版本。 +- 安装 scheduler-plugins 版本为 v0.27.8,请确保集群版本是否与它兼容。 + 参考文档 [Compatibility Matrix](https://github.com/kubernetes-sigs/scheduler-plugins/tree/master?tab=readme-ov-file#compatibility-matrix)。 + +### 安装流程 + +1. 在 **创建集群** -> **高级配置** -> **自定义参数** 中添加 scheduler-plugins 参数 + + ```yaml + scheduler_plugins_enabled:true + scheduler_plugins_plugin_config: + - name: Coscheduling + args: + permitWaitingTimeSeconds: 10 # default is 60 + ``` + + 参数说明: + + - `scheduler_plugins_enabled` 设置为 true 时,开启 scheduler-plugins 插件能力。 + - 您可以通过设置 `scheduler_plugins_enabled_plugins` 或 `scheduler_plugins_disabled_plugins` 选项来启用或禁用某些插件。 + 参阅 [K8s 官方插件名称](https://github.com/kubernetes-sigs/scheduler-plugins?tab=readme-ov-file#plugins)。 + - 如果需要设置自定义插件的参数请配置 scheduler_plugins_plugin_config,例如:设置 coscheduling 的 permitWaitingTimeoutSeconds 参数。 + 参阅 [K8s 官方插件配置项](https://github.com/kubernetes-sigs/scheduler-plugins/blob/master/manifests/coscheduling/scheduler-config.yaml) + +2. 集群创建成功后系统会自动安装 scheduler-plugins 和 controller 组件负载,可以在对应集群的无状态负载中查看负载状态。 + +## 使用 scheduler-plugins + +以下以使用 vgpu 调度器的同时,想结合 scheduler-plugins 的 coscheduling 插件能力场景为示例,介绍如何使用 scheduler-plugins。 + +1. 在 Helm 模板中安装 vgpu,设置 values.yaml 参数。 + + - `schedulerName: scheduler-plugins-scheduler`,这是 kubean 默认安装的 scheduler-plugins 的 scheduler 名称,目前不能修改。 + - `scheduler.kubeScheduler.enabled: false`,不安装 kube-scheduler,将 vgpu-scheduler 作为单独的 extender。 + +1. 在 scheduler-plugins 上扩展 vgpu-scheduler。 + + ```bash + [root@master01 charts]# kubectl get cm -n scheduler-plugins scheduler-config -ojsonpath="{.data.scheduler-config\.yaml}" + ``` + + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1 + kind: KubeSchedulerConfiguration + leaderElection: + leaderElect: false + profiles: + # Compose all plugins in one profile + - schedulerName: scheduler-plugins-scheduler + plugins: + multiPoint: + enabled: + - name: Coscheduling + - name: CapacityScheduling + - name: NodeResourceTopologyMatch + - name: NodeResourcesAllocatable + disabled: + - name: PrioritySort + pluginConfig: + - args: + permitWaitingTimeSeconds: 10 + name: Coscheduling + ``` + + 修改 scheduler-plugins 的 scheduler-config 的 configmap 参数,如下: + + ```bash + [root@master01 charts]# kubectl get cm -n scheduler-plugins scheduler-config -ojsonpath="{.data.scheduler-config\.yaml}" + ``` + + ```yaml + apiVersion: kubescheduler.config.k8s.io/v1 + kind: KubeSchedulerConfiguration + leaderElection: + leaderElect: false + profiles: + # Compose all plugins in one profile + - schedulerName: scheduler-plugins-scheduler + plugins: + multiPoint: + enabled: + - name: Coscheduling + - name: CapacityScheduling + - name: NodeResourceTopologyMatch + - name: NodeResourcesAllocatable + disabled: + - name: PrioritySort + pluginConfig: + - args: + permitWaitingTimeSeconds: 10 + name: Coscheduling + extenders: + - urlPrefix: "${urlPrefix}" + filterVerb: filter + bindVerb: bind + nodeCacheCapable: true + ignorable: true + httpTimeout: 30s + weight: 1 + enableHTTPS: true + tlsConfig: + insecure: true + managedResources: + - name: nvidia.com/vgpu + ignoredByScheduler: true + - name: nvidia.com/gpumem + ignoredByScheduler: true + - name: nvidia.com/gpucores + ignoredByScheduler: true + - name: nvidia.com/gpumem-percentage + ignoredByScheduler: true + - name: nvidia.com/priority + ignoredByScheduler: true + - name: cambricon.com/mlunum + ignoredByScheduler: true + ``` + +1. 安装完 vgpu-scheduler 后,系统会自动创建 svc,urlPrefix 指定 svc 的 URL。 + + !!! note + + - svc 指 pod 服务负载,您可以到安装了 nvidia-vgpu 插件的命名空间下通过以下命令拿到 443 端口对应的外部访问信息。 + + ```shell + kubectl get svc -n ${namespace} + ``` + + - urlprifix 格式为 `https://${ip 地址}:${端口}` + + +1. 将 scheduler-plugins 的 scheduler Pod 重启,加载新的配置文件。 + + !!! note + + 在创建 vgpu 应用时不需要指定调度器名称,vgpu-scheduler 的 Webhook 会自动将 Scheduler 的名称修改为 scheduler-plugins-scheduler,不用手动指定。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/cluster-status.md b/docs/zh/docs/end-user/kpanda/clusters/cluster-status.md new file mode 100644 index 0000000..161dc2c --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/cluster-status.md @@ -0,0 +1,26 @@ +# 集群状态 + +容器管理模块支持纳管两种类型的集群:接入集群和自建集群。 +关于集群纳管类型的更多信息,请参见[集群角色](cluster-role.md)。 + +这两种集群的状态如下所述。 + +## 接入集群 + +| 状态 | 描述 | +| ---------------------- | ------------------------------------------------------------ | +| 接入中(Joining) | 集群正在接入 | +| 解除接入中(Removing) | 集群正在解除接入 | +| 运行中(Running) | 集群正常运行 | +| 未知(Unknown) | 集群已失联,系统展示数据为失联前缓存数据,不代表真实数据,同时失联状态下执行的任何操作都将不生效,请检查集群网络连通性或主机状态。 | + +## 自建集群 + +| 状态 | 描述 | +| ------------------------------------------ | ------------------------------------------------------------ | +| 创建中(Creating) | 集群正在创建 | +| 更新中(Updating) | 更新集群 Kubernetes 版本 | +| 删除中(Deleting) | 集群正在删除 | +| 运行中(Running) | 集群正常运行 | +| 未知(Unknown) | 集群已失联,系统展示数据为失联前缓存数据,不代表真实数据,同时失联状态下执行的任何操作都将不生效,请检查集群网络连通性或主机状态。 | +| 创建失败(Failed) | 集群创建失败,请查看日志以获取详细失败原因 | diff --git a/docs/zh/docs/end-user/kpanda/clusters/cluster-version.md b/docs/zh/docs/end-user/kpanda/clusters/cluster-version.md new file mode 100644 index 0000000..eac297e --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/cluster-version.md @@ -0,0 +1,49 @@ +# 集群版本支持范围 + +在算丰 AI 算力平台中,[接入型集群](cluster-status.md)和[自建集群](cluster-status.md)采取不同的版本支持机制。 + +本文主要介绍自建集群的版本支持机制。 + +Kubernetes 社区支持 3 个版本范围,如 1.26、1.27、1.28。当社区新版本发布之后,支持的版本范围将会进行递增。 +如社区最新的 1.29 版本已经发布,此时社区支持的版本范围是 1.27、1.28、1.29。 + +例如,社区支持的版本范围是 1.25、1.26、1.27,则在算丰 AI 算力平台中使用界面创建工作集群的版本范围是 1.24、1.25、1.26,并且会为用户推荐一个稳定的版本,如 1.24.7。 + +除此之外,算丰 AI 算力平台中使用界面创建工作集群的版本范围与社区保持高度同步,当社区版本进行递增后,算丰 AI 算力平台中使用界面创建工作集群的版本范围也会同步递增一个版本。 + +## Kubernetes 版本支持范围 + + + + + + + + + + + + + + + + + + + + +
Kubernetes 社区版本范围自建工作集群版本范围自建工作集群推荐版本算丰 AI 算力平台安装器发布时间
+
    +
  • 1.26
  • +
  • 1.27
  • +
  • 1.28
  • +
+
+
    +
  • 1.25
  • +
  • 1.26
  • +
  • 1.27
  • +
+
1.27.5v0.13.02023.11.30
+ +![版本支持机制](../../../images/cluster-version.png) diff --git a/docs/zh/docs/end-user/kpanda/clusters/create-cluster.md b/docs/zh/docs/end-user/kpanda/clusters/create-cluster.md new file mode 100644 index 0000000..eda0c8d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/create-cluster.md @@ -0,0 +1,105 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# 创建工作集群 + +在算丰 AI 算力平台容器管理模块中,[集群角色](cluster-role.md)分四类:全局服务集群、管理集群、工作集群、接入集群。 +其中,接入集群只能从第三方厂商接入,参见[接入集群](./integrate-cluster.md)。 + +本页介绍如何创建工作集群,默认情况下,新建工作集群的工作节点 OS 类型和 CPU 架构需要与全局服务集群保持一致。 +如需使用区别于全局服务集群 OS 或架构的节点创建集群,参阅[在 centos 管理平台上创建 ubuntu 工作集群](../../best-practice/create-ubuntu-on-centos-platform.md)进行创建。 + +推荐使用 [算丰 AI 算力平台支持的操作系统](../../../install/commercial/deploy-requirements.md)来创建集群。 +如您本地节点不在上述支持范围,可参考[在非主流操作系统上创建集群](../../best-practice/use-otherlinux-create-custer.md)进行创建。 + +## 前提条件 + +创建集群之前需要满足一定的前提条件: + +- 根据业务需求准备一定数量的节点,且节点 OS 类型和 CPU 架构一致。 +- 推荐 Kubernetes 版本 1.29.5,具体版本范围,参阅 [算丰 AI 算力平台集群版本支持体系](./cluster-version.md), + 目前算丰 AI 算力平台支持自建工作集群版本范围在 `v1.28.0-v1.30.2`。如需创建低版本的集群,请参考[集群版本支持范围](./cluster-version.md)、[部署与升级 Kubean 向下兼容版本](../../best-practice/kubean-low-version.md)。 +- 目标主机需要允许 IPv4 转发。如果 Pod 和 Service 使用的是 IPv6,则目标服务器需要允许 IPv6 转发。 +- 算丰 AI 算力平台暂不提供对防火墙的管理功能,您需要预先自行定义目标主机防火墙规则。为了避免创建集群的过程中出现问题,建议禁用目标主机的防火墙。 +- 参阅[节点可用性检查](../nodes/node-check.md)。 + +## 操作步骤 + +1. 在 __集群列表__ 页面中,点击 __创建集群__ 按钮。 + + ![创建集群按钮](../../../images/create001.png) + +2. 参考下列要求填写集群基本信息,并点击 __下一步__ 。 + + - 集群名称:名称只包含小写字母、数字和连字符("-"),必须以小写字母或者数字开头和结尾,最长 63 个字符。 + - 被纳管:选择由哪个集群来管理此集群,例如在集群生命周期中创建、升级、节点扩缩容、删除集群等。 + - 运行时:选择集群的运行时环境,目前支持 containerd 和 docker,[如何选择容器运行时](runtime.md)。 + - Kubernetes 版本:支持 3 个版本跨度,具体取决于被纳管集群所支持的版本。 + + ![填写基本信息](../../../images/create002.png) + +3. 填写节点配置信息,并点击 __下一步__ 。 + + - 高可用:开启后需要提供至少 3 个控制器节点。关闭后,只提供 1 个控制器节点即可。 + + > 生产环境中建议使用高可用模式。 + + - 认证方式:选择通过用户名/密码还是公私钥访问节点。 + + > 如果使用公私钥方式访问节点,需要预先配置节点的 SSH 密钥。参阅[使用 SSH 密钥认证节点](../nodes/node-authentication.md)。 + + - 使用统一的密码:开启后集群中所有节点的访问密码都相同,需要在下方输入访问所有节点的统一密码。如果关闭,则可以为每个节点设置单独的用户名和密码。 + + - 节点信息:填写节点名称和 IP 地址。 + - 自定义参数:设置变量控制 Ansible 与远程主机交互。可设置变量参考[连接到主机:行为清单参数](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters) + - NTP 时间同步:开启后会自动同步各个节点上的时间,需要提供 NTP 服务器地址。 + + ![节点配置](../../../images/createnew01.png) + +4. 在页面底部点击节点检查。如果检查通过则继续下一步操作。如果检查未通过,则更新 __节点信息__ 并再次执行检查。 + +5. 填写网络配置信息,并点击 __下一步__ 。 + + - 网络插件:负责为集群内的 Pod 提供网络服务,**创建集群后不可更改网络插件**。支持 cilium 和 calico。选择 __none__ 表示暂不安装网络插件。 + + - 容器网段:集群下容器使用的网段,决定集群下容器的数量上限。创建后不可修改。 + - 服务网段:同一集群下容器互相访问时使用的 Service 资源的网段,决定 Service 资源的上限。创建后不可修改。 + + ![网络配置1](../../../images/creatnew03.png) + + ![网络配置2](../../../images/creatnew04.png) + +6. 填写插件配置信息,并点击 __下一步__ 。 + + ![插件配置](../../../images/creatnew05.png) + +7. 填写高级配置信息,并点击 __确定__ 。 + + - __kubelet_max_pods__ :设置每个节点的最大 Pod 数量,默认为 110 个。 + - __hostname_overide__ :重置主机名,建议使用默认值,采用系统默认生成的名称作为主机名称。 + - __kubernetes_audit__ :Kubernetes 的审计日志,默认开启。 + - __auto_renew_certificate__ :在每月第一个星期一自动更新 Kubernetes 控制平面证书,默认开启。 + - __disable_firewalld&ufw__ :禁用防火墙,避免节点在安装过程中无法被访问。 + - __Insecure_registries__ :私有镜像仓库配置。使用私有镜像仓库创建集群时,为了避免证书问题导致容器引擎拒绝访问,需要在这里填写私有镜像仓库地址,以绕过容器引擎的证书认证而获取镜像。 + - __yum_repos__ :填写 Yum 源仓库地址。离线环境下,默认给出的地址选项仅供参考,请根据实际情况填写。 + + ![高级配置](../../../images/creatnew06.png) + +!!! success + + - 填写正确信息并完成上述步骤后,页面会提示集群正在创建中。 + - 创建集群耗时较长,需要耐心等待。其间,可以点击 __返回集群列表__ 按钮让安装过程后台运行。 + - 如需查看当前状态,可点击 __实时日志__ 。 + + ![查看实时日志](../../../images/create009.png) + +!!! note + + - 当集群出现未知状态时,表示当前集群已失联。 + - 系统展示数据为失联前缓存数据,不代表真实数据。 + - 同时失联状态下执行的任何操作都将不生效,请检查集群网络连通性或主机状态。 + + ![未知状态](../../../images/createnew07.png) diff --git a/docs/zh/docs/end-user/kpanda/clusters/delete-cluster.md b/docs/zh/docs/end-user/kpanda/clusters/delete-cluster.md new file mode 100644 index 0000000..ec0c3d3 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/delete-cluster.md @@ -0,0 +1,57 @@ +--- +hide: + - toc +--- + +# 卸载/解除接入集群 + +通过算丰 AI 算力平台容器管理平台 **创建的集群** 支持 __卸载集群__ 或 __解除接入__ 操作,从其他环境直接 **接入的集群** 仅支持 __解除接入__ 操作。 + +!!! info + + 如果想彻底删除一个接入的集群,需要前往创建该集群的原始平台操作。算丰 AI 算力平台不支持删除接入的集群。 + +在算丰 AI 算力平台中, __卸载集群__ 和 __解除接入__ 的区别在于: + +- __卸载集群__ 操作会销毁该集群,并重置集群下所有节点的数据。所有数据都将被销毁,建议做好备份。后期需要时必须重新创建一个集群。 +- __解除接入__ 操作会将当前集群从平台中移除,不会摧毁集群,也不会销毁数据。 + +## 卸载集群 + +!!! note + + - 当前操作用户应具备 Admin 或 Kpanda Owner 权限才能执行卸载集群的操作。 + - 卸载集群之前,应该先在集群列表中点击某个集群名称,在 __集群运维__ -> __集群设置__ -> __高级配置__ 中关闭 __集群删除保护__ , + 否则不显示 __卸载集群__ 的选项。 + - __全局服务集群__ 不支持卸载或移除操作。 + +1. 在 __集群列表__ 页找到需要卸载集群,点击右侧的 __┇__ 并在下拉列表中点击 __卸载集群__ 。 + +2. 输入集群名称进行确认,然后点击 __删除__ 。 + + 如果提示集群中还有一些残留的资源,则需要按提示删除相关资源后才能执行卸载操作。 + +3. 返回 __集群列表__ 页可以看到该集群的状态已经变成 __删除中__ 。卸载集群可能需要一段时间,请您耐心等候。 + +## 解除接入集群 + +!!! note + + - 当前操作用户应具备 Admin 或 Kpanda Owner 权限才能执行解除接入的操作。 + - __全局服务集群__ 不支持解除接入。 + +1. 在 __集群列表__ 页找到需要卸载集群,点击右侧的 __┇__ 并在下拉列表中点击 __解除接入__ 。 + +2. 输入集群名称进行确认,然后点击 __解除接入__ 。 + + 如果提示集群中还有一些残留的资源,则需要按提示删除相关资源后才能解除接入。 + +## 清理解除接入集群配置数据 + +集群被移除后,集群中原有的管理平台数据不会被自动清除,如需将集群接入至新管理平台则需要手动执行如下操作: + +删除 kpanda-system、insight-system 命名空间 + +```shell +kubectl delete ns kpanda-system insight-system +``` diff --git a/docs/zh/docs/end-user/kpanda/clusters/integrate-cluster.md b/docs/zh/docs/end-user/kpanda/clusters/integrate-cluster.md new file mode 100644 index 0000000..ae3d40e --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/integrate-cluster.md @@ -0,0 +1,42 @@ +--- +hide: + - toc +--- + +# 接入集群 + +通过接入集群操作,能够对众多云服务平台集群和本地私有物理集群进行统一纳管,形成统一治理平台,有效避免了被厂商锁定风险,助力企业业务安全上云。 + +容器管理模块支持接入多种主流的容器集群,例如 Redhat Openshift, SUSE Rancher, VMware Tanzu, Amazon EKS, Aliyun ACK, Huawei CCE, Tencent TKE, 标准 Kubernetes 集群。 + +## 前提条件 + +- 准备一个待接入的集群,确保容器管理集群和待接入集群之间网络通畅,并且集群的 Kubernetes 版本 1.22+。 +- 当前操作用户应具有 [Kpanda Owner](../permissions/permission-brief.md) 或更高权限。 + +## 操作步骤 + +1. 进入 __集群列表__ 页面,点击右上角的 __接入集群__ 按钮。 + + ![接入集群](../../../images/join001.png) + +2. 填写基本信息。 + + - 集群名称:名称应具有唯一性,设置后不可更改。最长 63 个字符,只能包含小写字母、数字及分隔符("-"),且必须以小写字母或数字开头及结尾。 + - 集群别名:可输入任意字符,不超过 60 个字符。 + - 发行版:集群的发行厂商,包括市场主流云厂商和本地私有物理集群。 + +3. 填写目标集群的 KubeConfig,点击 __验证 Config__ ,验证通过后才能成功接入集群。 + + > 如果不知道如何获取集群的 KubeConfig 文件,可以在输入框右上角点击 __如何获取 kubeConfig__ 查看对应步骤。 + + ![接入集群](../../../images/join003.png) + +4. 确认所有参数填写正确,在页面右下角点击 __确定__ 。 + + ![接入集群](../../../images/join002.png) + +!!! note + + - 新接入的集群状态为 __接入中__ ,接入成功后变为 __运行中__ 。 + - 如果集群状态一直处于 __接入中__ ,请确认接入脚本是否在对应集群上执行成功。有关集群状态的更多详情,请参考[集群状态](cluster-status.md)。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/integrate-rancher-cluster.md b/docs/zh/docs/end-user/kpanda/clusters/integrate-rancher-cluster.md new file mode 100644 index 0000000..83e1f74 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/integrate-rancher-cluster.md @@ -0,0 +1,216 @@ +# 接入 rancher 集群 + +本文介绍如何接入 rancher 集群。 + +## 前提条件 + +- 准备一个具有管理员权限的待接入 ranhcer 集群,确保容器管理集群和待接入集群之间网络通畅。 +- 当前操作用户应具有 [Kpanda Owner](../permissions/permission-brief.md) 或更高权限。 + +## 操作步骤 + +### 步骤一:在 rancher 集群创建具有管理员权限的 ServiceAccount 用户 + +1. 使用具有管理员权限的角色进入 rancher 集群,并使用终端新建一个名为 __sa.yaml__ 的文件。 + + ```bash + vi sa.yaml + ``` + + 然后按下 i 键进入插入模式,输入以下内容: + + ```yaml title="sa.yaml" + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: rancher-rke + rules: + - apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' + - nonResourceURLs: + - '*' + verbs: + - '*' + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: rancher-rke + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: rancher-rke + subjects: + - kind: ServiceAccount + name: rancher-rke + namespace: kube-system + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: rancher-rke + namespace: kube-system + ``` + + 按下 __esc__ 键退出插入模式,然后输入 __ :wq__ 保存并退出。 + +2. 在当前路径下执行如下命令,新建名为 __rancher-rke__ 的 ServiceAccount(以下简称为 __SA__ ): + + ```bash + kubectl apply -f sa.yaml + ``` + + 预期输出如下: + + ```console + clusterrole.rbac.authorization.k8s.io/rancher-rke created + clusterrolebinding.rbac.authorization.k8s.io/rancher-rke created + serviceaccount/rancher-rke created + ``` + +3. 创建名为 __rancher-rke-secret__ 的密钥,并将密钥和 __rancher-rke__ SA 绑定。 + + ```bash + kubectl apply -f - < + Annotations: kubernetes.io/service-account.name: rancher-rke + kubernetes.io/service-account.uid: d83df5d9-bd7d-488d-a046-b740618a0174 + + Type: kubernetes.io/service-account-token + + Data + ==== + ca.crt: 570 bytes + namespace: 11 bytes + token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjUtNE9nUWZLRzVpbEJORkZaNmtCQXhqVzRsZHU4MHhHcDBfb0VCaUo0V1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJyYW5jaGVyLXJrZS1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicmFuY2hlci1ya2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkODNkZjVkOS1iZDdkLTQ4OGQtYTA0Ni1iNzQwNjE4YTAxNzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cmFuY2hlci1ya2UifQ.VNsMtPEFOdDDeGt_8VHblcMRvjOwPXMM-79o9UooHx6q-VkHOcIOp3FOT2hnEdNnIsyODZVKCpEdCgyozX-3y5x2cZSZpocnkMcBbQm-qfTyUcUhAY7N5gcYUtHUhvRAsNWJcsDCn6d96gT_qo-ddo_cT8Ri39Lc123FDYOnYG-YGFKSgRQVy7Vyv34HIajZCCjZzy7i--eE_7o4DXeTjNqAFMFstUxxHBOXI3Rdn1zKQKqh5Jhg4ES7X-edSviSUfJUX-QV_LlAw5DuAyGPH7bDH4QaQ5k-p6cIctmpWZE-9wRDlKA4LYRblKE7MJcI6OmM4ldlMM0Jc8N-gCtl4w + ``` + +### 步骤二:在本地使用 rancher-rke SA 的认证信息更新 kubeconfig 文件 + +在任意一台安装了 __kubelet__ 的本地节点执行如下操作: + +1. 配置 kubelet token: + + ```bash + kubectl config set-credentials rancher-rke --token=`rancher-rke-secret` 里面的 token 信息 + ``` + + 例如: + + ``` + kubectl config set-credentials eks-admin --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjUtNE9nUWZLRzVpbEJORkZaNmtCQXhqVzRsZHU4MHhHcDBfb0VCaUo0V1kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJyYW5jaGVyLXJrZS1zZWNyZXQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicmFuY2hlci1ya2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkODNkZjVkOS1iZDdkLTQ4OGQtYTA0Ni1iNzQwNjE4YTAxNzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06cmFuY2hlci1ya2UifQ.VNsMtPEFOdDDeGt_8VHblcMRvjOwPXMM-79o9UooHx6q-VkHOcIOp3FOT2hnEdNnIsyODZVKCpEdCgyozX-3y5x2cZSZpocnkMcBbQm-qfTyUcUhAY7N5gcYUtHUhvRAsNWJcsDCn6d96gT_qo-ddo_cT8Ri39Lc123FDYOnYG-YGFKSgRQVy7Vyv34HIajZCCjZzy7i--eE_7o4DXeTjNqAFMFstUxxHBOXI3Rdn1zKQKqh5Jhg4ES7X-edSviSUfJUX-QV_LlAw5DuAyGPH7bDH4QaQ5k-p6cIctmpWZE-9wRDlKA4LYRblKE7MJcI6OmM4ldlMM0Jc8N-gCtl4w + ``` + +2. 配置 kubelet APIServer 信息: + + ```bash + kubectl config set-cluster {集群名} --insecure-skip-tls-verify=true --server={APIServer} + ``` + + - __{集群名}__ :指 rancher 集群的名称。 + - __{APIServer}__ :指集群的访问地址,一般为集群控制节点 IP + 6443 端口,如 `https://10.X.X.X:6443` + + 例如: + + ```bash + kubectl config set-cluster rancher-rke --insecure-skip-tls-verify=true --server=https://10.X.X.X:6443 + ``` + +3. 配置 kubelet 上下文信息: + + ```bash + kubectl config set-context {上下文名称} --cluster={集群名} --user={SA 用户名} + ``` + + 例如: + + ```bash + kubectl config set-context rancher-rke-context --cluster=rancher-rke --user=rancher-rke + ``` + +4. 在 kubelet 中指定我们刚刚新建的上下文 __rancher-rke-context__ : + + ```bash + kubectl config use-context rancher-rke-context + ``` + +5. 获取上下文 __rancher-rke-context__ 中的 kubeconfig 信息。 + + ```bash + kubectl config view --minify --flatten --raw + ``` + + 预期输出: + + ```yaml + apiVersion: v1 + clusters: + - cluster: + insecure-skip-tls-verify: true + server: https://77C321BCF072682C70C8665ED4BFA10D.gr7.ap-southeast-1.eks.amazonaws.com + name: joincluster + contexts: + - context: + cluster: joincluster + user: eks-admin + name: ekscontext + current-context: ekscontext + kind: Config + preferences: {} + users: + - name: eks-admin + user: + token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImcxTjJwNkktWm5IbmRJU1RFRExvdWY1TGFWVUtGQ3VIejFtNlFQcUNFalEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2V + ``` + +### 步骤三:算丰 AI 算力平台界面接入集群 + +使用刚刚获取的 kubeconfig 文件,参考[接入集群](./integrate-cluster.md)文档,将 rancher 集群接入全局服务集群。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/k8s-cert.md b/docs/zh/docs/end-user/kpanda/clusters/k8s-cert.md new file mode 100644 index 0000000..acabcdb --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/k8s-cert.md @@ -0,0 +1,122 @@ +# Kubernetes 集群证书更新 + +为保证 Kubernetes 各组件之间的通信安全,组件之间的调用会进行 TLS 身份验证,执行验证操作需要配置集群 PKI 证书。 + +集群证书有效期为1年,为避免证书过期导致业务无法使用,请及时更新证书。 + +本文介绍如何手动进行证书更新。 + +## 检查证书是否过期 + +您可以执行以下命令查看证书是否过期: + +```shell +kubeadm certs check-expiration +``` + +输出类似于以下内容: + +```output +CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED +admin.conf Dec 14, 2024 07:26 UTC 204d no +apiserver Dec 14, 2024 07:26 UTC 204d ca no +apiserver-etcd-client Dec 14, 2024 07:26 UTC 204d etcd-ca no +apiserver-kubelet-client Dec 14, 2024 07:26 UTC 204d ca no +controller-manager.conf Dec 14, 2024 07:26 UTC 204d no +etcd-healthcheck-client Dec 14, 2024 07:26 UTC 204d etcd-ca no +etcd-peer Dec 14, 2024 07:26 UTC 204d etcd-ca no +etcd-server Dec 14, 2024 07:26 UTC 204d etcd-ca no +front-proxy-client Dec 14, 2024 07:26 UTC 204d front-proxy-ca no +scheduler.conf Dec 14, 2024 07:26 UTC 204d no + +CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED +ca Dec 12, 2033 07:26 UTC 9y no +etcd-ca Dec 12, 2033 07:26 UTC 9y no +front-proxy-ca Dec 12, 2033 07:26 UTC 9y no +``` + +## 手动更新证书 + +您可以通过以下命令手动更新证书,只需带上合适的命令行选项。更新证书前请先备份当前证书。 + +更新指定证书: + +```shell +kubeadm certs renew +``` + +更新全部证书: + +```shell +kubeadm certs renew all +``` + +更新后的证书可以在 `/etc/kubernetes/pki` 目录下查看,有效期延续 1 年。 +以下对应的几个配置文件也会同步更新: + +- /etc/kubernetes/admin.conf +- /etc/kubernetes/controller-manager.conf +- /etc/kubernetes/scheduler.conf + +!!! note + + - 如果您部署的是一个高可用集群,这个命令需要在所有控制节点上执行。 + - 此命令用 CA(或者 front-proxy-CA )证书和存储在 `/etc/kubernetes/pki` 中的密钥执行更新。 + +## 重启服务 + +执行更新操作之后,你需要重启控制面 Pod。因为动态证书重载目前还不被所有组件和证书支持,所有这项操作是必须的。 + +静态 Pod 是被本地 kubelet 而不是 API 服务器管理,所以 kubectl 不能用来删除或重启他们。 + +要重启静态 Pod,你可以临时将清单文件从 `/etc/kubernetes/manifests/` 移除并等待 20 秒。 +参考 [KubeletConfiguration 结构](https://kubernetes.io/zh-cn/docs/reference/config-api/kubelet-config.v1beta1/)中的 fileCheckFrequency 值。 + +如果 Pod 不在清单目录里,kubelet 将会终止它。 +在另一个 fileCheckFrequency 周期之后你可以将文件移回去,kubelet 可以完成 Pod 的重建,而组件的证书更新操作也得以完成。 + +```shell +mv ./manifests/* ./temp/ +mv ./temp/* ./manifests/ +``` + +!!! note + + 如果容器服务使用的是 Docker,为了让证书生效,可以使用以下命令对涉及到证书使用的几个服务进行重启: + + ```shell + docker ps | grep -E 'k8s_kube-apiserver|k8s_kube-controller-manager|k8s_kube-scheduler|k8s_etcd_etcd' | awk -F ' ' '{print $1}' | xargs docker restart + ``` + +## 更新 KubeConfig + +构建集群时通常会将 **admin.conf** 证书复制到 **$HOME/.kube/config** 中,为了在更新 admin.conf 后更新 $HOME/.kube/config 的内容, 必须运行以下命令: + +```shell +sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config +sudo chown $(id -u):$(id -g) $HOME/.kube/config +``` + +## 为 kubelet 配置证书轮换 + +完成以上操作后,基本完成了集群所有证书的更新,但不包括 kubelet。 + +因为 kubernetes 包含特性 kubelet 证书轮换, 在当前证书即将过期时, 将自动生成新的秘钥,并从 Kubernetes API 申请新的证书。 一旦新的证书可用,它将被用于与 Kubernetes API 间的连接认证。 + +!!! note + + 此特性适用于 Kubernetes 1.8.0 或更高的版本。 + +启用客户端证书轮换,配置参数如下: + +- kubelet 进程接收 --rotate-certificates 参数,该参数决定 kubelet 在当前使用的 证书即将到期时,是否会自动申请新的证书。 + +- kube-controller-manager 进程接收 --cluster-signing-duration 参数 + (在 1.19 版本之前为 --experimental-cluster-signing-duration),用来控制签发证书的有效期限。 + +更多详情参考[为 kubelet 配置证书轮换](https://kubernetes.io/zh-cn/docs/tasks/tls/certificate-rotation/)。 + +## 自动更新证书 + +为了更高效便捷处理已过期或者即将过期的 kubernetes 集群证书,可参考 +[k8s 版本集群证书更新](https://github.com/yuyicai/update-kube-cert/blob/master/README-zh_CN.md)。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/runtime.md b/docs/zh/docs/end-user/kpanda/clusters/runtime.md new file mode 100644 index 0000000..ab5220d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/runtime.md @@ -0,0 +1,22 @@ +# 如何选择容器运行时 + +容器运行时是 kubernetes 中对容器和容器镜像生命周期进行管理的重要组件。 +kubernetes 在 1.19 版本中将 containerd 设为默认的容器运行时,并在 1.24 版本中移除了 Dockershim 组件的支持。 + +因此相较于 Docker 运行时,我们更加 **推荐您使用轻量的 containerd 作为您的容器运行时**,因为这已经成为当前主流的运行时选择。 + +除此之外,一些操作系统发行厂商对 Docker 运行时的兼容也不够友好,不同操作系统对运行时的支持如下表: + +## 不同操作系统和推荐的运行时版本对应关系 + +| 操作系统 | 推荐的 containerd 版本 | 推荐的 Docker 版本 | +|-------------|---------------|------------| +| CentOS | 1.7.5 | 20.10 | +| RedHatOS |1.7.5 | 20.10 | +| KylinOS | 1.7.5 | 19.03(仅 ARM 架构支持 ,在 x86 架构下不支持使用 Docker 作为运行时)| + +更多支持的运行时版本信息,请参考 [RedHatOS 支持的运行时版本](https://github.com/kubernetes-sigs/kubespray/blob/master/roles/container-engine/docker/vars/redhat.yml/) 和 [KylinOS 支持的运行时版本](https://github.com/kubernetes-sigs/kubespray/blob/master/roles/container-engine/docker/vars/kylin.yml) + +!!! note + + 在离线安装模式下,需要提前准备相关操作系统的运行时离线包。 diff --git a/docs/zh/docs/end-user/kpanda/clusters/upgrade-cluster.md b/docs/zh/docs/end-user/kpanda/clusters/upgrade-cluster.md new file mode 100644 index 0000000..61caae5 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/clusters/upgrade-cluster.md @@ -0,0 +1,59 @@ +--- +date: 2022-11-17 +hide: + - toc +--- + +# 集群升级 + +Kubernetes 社区每个季度都会发布一次小版本,每个版本的维护周期大概只有 9 个月。 +版本停止维护后就不会再更新一些重大漏洞或安全漏洞。手动升级集群操作较为繁琐,给管理人员带来了极大的工作负担。 + +本节将介绍如何在通过 Web UI 界面一键式在线升级工作集群 Kubernetes 版本, +如需离线升级工作集群的 kubernetes 版本,请参阅[工作集群离线升级指南](../../best-practice/update-offline-cluster.md)进行升级。 + +!!! danger + + 版本升级后将无法回退到之前的版本,请谨慎操作。 + +!!! note + + - Kubernetes 版本以 __x.y.z__ 表示,其中 __x__ 是主要版本, __y__ 是次要版本, __z__ 是补丁版本。 + - 不允许跨次要版本对集群进行升级,例如不能从 1.23 直接升级到 1.25。 + - __接入集群__ 不支持版本升级。如果左侧导航栏没有 __集群升级__ ,请检查该集群是否为 __接入集群__ 。 + - 全局服务集群只能通过终端进行升级。 + - 升级工作集群时,该工作集群的[管理集群](cluster-role.md#_3)应该已经接入容器管理模块,并且处于正常运行中。 + - 如果需要修改集群参数,可以通过升级相同版本的方式实现,具体操作参考下文。 + +1. 在集群列表中点击目标集群的名称。 + + ![升级集群](../../../images/upgradeclsuter00.png) + +2. 然后在左侧导航栏点击 __集群运维__ -> __集群升级__ ,在页面右上角点击 __版本升级__ 。 + + ![升级集群](../../../images/upgradecluster01.png) + +3. 选择可升级的版本,输入集群名称进行确认。 + + ![可升级版本](../../../images/upgradecluster02.png) + + !!! note + + 如果您是想通过升级方式来修改集群参数,请参考以下步骤: + + 1. 找到集群对应的 ConfigMap,您可以登录控制节点执行如下命令,找到 varsConfRef 中的 ConfigMap 名称。 + + ```shell + kubectl get cluster.kubean.io -o yaml + ``` + 2. 根据需要,修改 ConfigMap 中的参数信息。 + + 3. 在此处选择相同版本进行升级操作,升级完成即可成功更新对应的集群参数。 + +4. 点击 __确定__ 后,可以看到集群的升级进度。 + + ![升级进度](../../../images/upgradecluster03.png) + +5. 集群升级预计需要 30 分钟,可以点击 __实时日志__ 按钮查看集群升级的详细日志。 + + ![实时日志](../../../images/createcluster07.png) diff --git a/docs/zh/docs/end-user/kpanda/configmaps-secrets/configmap-hot-loading.md b/docs/zh/docs/end-user/kpanda/configmaps-secrets/configmap-hot-loading.md new file mode 100644 index 0000000..5266d4f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/configmaps-secrets/configmap-hot-loading.md @@ -0,0 +1,29 @@ +# configmap/secret 热加载 + +configmap/secret 热加载是指将 configmap/secret 作为数据卷挂载在容器中挂载时,当配置发生改变时,容器将自动读取 configmap/secret 更新后的配置,而无需重启 Pod。 + +## 操作步骤 + +1. 参考创建工作负载 - [容器配置](../workloads/create-deployment.md#_4),配置容器数据存储,选择 __Configmap__ 、 __Configmap Key__ 、 __Secret__ 、 __Secret Key__ 作为数据卷挂载至容器。 + + ![使用 config 作为数据卷](../../../images/user_configmap_to_volume.jpg) + + !!! note + + 使用子路径(SubPath)方式挂载的配置文件不支持热加载。 + +2. 进入【配置与密钥】页面,进入配置项详情页面,在【关联资源】中找到对应的 __container__ 资源,点击 __立即加载__ 按钮,进入配置热加载页面。 + + ![使用 config 作为数据卷](../../../images/configmap-hot-loading03.png) + + !!! note + + 如果您的应用支持自动读取 configmap/secret 更新后的配置,则无需手动执行热加载操作。 + +3. 在热加载配置弹窗中,输入进入容器内的 __执行命令__ 并点击 __确定__ 按钮,以重载配置。例如,在 nginx 容器中,以 root 用户权限,执行 __nginx -s reload__ 命令来重载配置。 + + ![使用 config 作为数据卷](../../../images/configmap-hot-loading02.png) + +4. 在界面弹出的 web 终端中查看应用重载情况。 + + ![使用 config 作为数据卷](../../../images/configmap-hot-loading.jpg) diff --git a/docs/zh/docs/end-user/kpanda/configmaps-secrets/create-configmap.md b/docs/zh/docs/end-user/kpanda/configmaps-secrets/create-configmap.md new file mode 100644 index 0000000..24c8a81 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/configmaps-secrets/create-configmap.md @@ -0,0 +1,80 @@ +# 创建配置项 + +配置项(ConfigMap)以键值对的形式存储非机密性数据,实现配置数据和应用代码相互解耦的效果。配置项可用作容器的环境变量、命令行参数或者存储卷中的配置文件。 + +!!! note + + - 在配置项中保存的数据不可超过 1 MiB。如果需要存储体积更大的数据,建议挂载存储卷或者使用独立的数据库或者文件服务。 + + - 配置项不提供保密或者加密功能。如果要存储加密数据,建议使用[密钥](use-secret.md),或者其他第三方工具来保证数据的私密性。 + +支持两种创建方式: + +- 图形化表单创建 +- YAML 创建 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 图形化表单创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_10.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __配置项__ ,点击右上角 __创建配置项__ 按钮。 + + ![创建配置项](../../../images/configmap01.png) + +3. 在 __创建配置项__ 页面中填写配置信息,点击 __确定__ 。 + + !!! note + + 点击 __上传文件__ 可以从本地导入已有的文件,快速创建配置项。 + + ![创建配置项](../../../images/configmap03.png) + +4. 创建完成后在配置项右侧点击更多可以,可以编辑 YAML、更新、导出、删除等操作。 + + ![创建配置项](../../../images/configmap04.png) + +## YAML 创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_10.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __配置项__ ,点击右上角 __YAML 创建__ 按钮。 + + ![创建配置项](../../../images/configmap02.png) + +3. 填写或粘贴事先准备好的配置文件,然后在弹框右下角点击 __确定__ 。 + + !!! note + + - 点击 __导入__ 可以从本地导入已有的文件,快速创建配置项。 + - 填写数据之后点击 __下载__ 可以将配置文件保存在本地。 + + ![创建配置项](../images/create-configmap.png) + +4. 创建完成后在配置项右侧点击更多可以,可以编辑 YAML、更新、导出、删除等操作。 + + ![创建配置项](../../../images/configmap04.png) + +## 配置项 YAML 示例 + + ```yaml + kind: ConfigMap + apiVersion: v1 + metadata: + name: kube-root-ca.crt + namespace: default + annotations: + data: + version: '1.0' + ``` + +[下一步:使用配置项](use-configmap.md){ .md-button .md-button--primary } diff --git a/docs/zh/docs/end-user/kpanda/configmaps-secrets/create-secret.md b/docs/zh/docs/end-user/kpanda/configmaps-secrets/create-secret.md new file mode 100644 index 0000000..a7e5f86 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/configmaps-secrets/create-secret.md @@ -0,0 +1,80 @@ +# 创建密钥 + +密钥是一种用于存储和管理密码、OAuth 令牌、SSH、TLS 凭据等敏感信息的资源对象。使用密钥意味着您不需要在应用程序代码中包含敏感的机密数据。 + +密钥使用场景: + +- 作为容器的环境变量使用,提供容器运行过程中所需的一些必要信息。 +- 使用密钥作为 Pod 的数据卷。 +- 在 kubelet 拉取容器镜像时作为镜像仓库的身份认证凭证。 + +支持两种创建方式: + +- 图形化表单创建 +- YAML 创建 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) ,详情可参考[集群和命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 图形化表单创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_12.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __密钥__ ,点击右上角 __创建密钥__ 按钮。 + + ![创建密钥](../../../images/secret01_1.png) + +3. 在 __创建密钥__ 页面中填写配置信息,点击 __确定__ 。 + + ![创建密钥](../../../images/secret02_1.png) + + 填写配置时需要注意: + + - 密钥的名称在同一个命名空间中必须具有唯一性 + - 密钥类型: + - 默认(Opaque):Kubernetes 默认的密钥类型,支持用户定义的任意数据。 + - TLS (kubernetes.io/tls):用于 TLS 客户端或者服务器端数据访问的凭证。 + - 镜像仓库信息 (kubernetes.io/dockerconfigjson):用于镜像仓库访问的凭证。 + - 用户名和密码(kubernetes.io/basic-auth):用于基本身份认证的凭证。 + - 自定义:用户根据业务需要自定义的类型。 + - 密钥数据:密钥所存储的数据,不同数据需要填写的参数有所不同 + - 当密钥类型为默认(Opaque)/自定义:可以填入多个键值对数据。 + - 当密钥类型为 TLS (kubernetes.io/tls):需要填入证书凭证和私钥数据。证书是自签名或 CA 签名过的凭据,用来进行身份认证。证书请求是对签名的请求,需要使用私钥进行签名。 + - 当密钥类型为镜像仓库信息 (kubernetes.io/dockerconfigjson):需要填入私有镜像仓库的账号和密码。 + - 当密钥类型为用户名和密码(kubernetes.io/basic-auth):需要指定用户名和密码。 + +## YAML 创建 + +1. 在 __集群列表__ 页面点击某个集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_12.png) + +2. 在左侧导航栏,点击 __配置与密钥__ -> __密钥__ ,点击右上角 __YAML 创建__ 按钮。 + + ![YAML 创建](../../../images/secret03_1.png) + +3. 在 __YAML 创建__ 页面中填写 YAML 配置,点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![YAML 创建](../images/secret04.png) + +## 密钥 YAML 示例 + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: secretdemo + type: Opaque + data: + username: ****** + password: ****** + ``` + +[下一步:使用密钥](use-secret.md){ .md-button .md-button--primary } diff --git a/docs/zh/docs/end-user/kpanda/configmaps-secrets/use-configmap.md b/docs/zh/docs/end-user/kpanda/configmaps-secrets/use-configmap.md new file mode 100644 index 0000000..252bf57 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/configmaps-secrets/use-configmap.md @@ -0,0 +1,147 @@ +# 使用配置项 + +配置项(ConfigMap)是 Kubernetes 的一种 API 对象,用来将非机密性的数据保存到键值对中,可以存储其他对象所需要使用的配置。 +使用时, 容器可以将其用作环境变量、命令行参数或者存储卷中的配置文件。通过使用配置项,能够将配置数据和应用程序代码分开,为应用配置的修改提供更加灵活的途径。 + +!!! note + + 配置项并不提供保密或者加密功能。如果要存储的数据是机密的,请使用[密钥](use-secret.md),或者使用其他第三方工具来保证数据的私密性,而不是用配置项。 + 此外在容器里使用配置项时,容器和配置项必须处于同一集群的命名空间中。 + +## 使用场景 + +您可以在 Pod 中使用配置项,有多种使用场景,主要包括: + +- 使用配置项设置容器的环境变量 + +- 使用配置项设置容器的命令行参数 + +- 使用配置项作为容器的数据卷 + +## 设置容器的环境变量 + +您可以通过图形化界面或者终端命令行来使用配置项作为容器的环境变量。 + +!!! note + + 配置项导入是将配置项作为环境变量的值;配置项键值导入是将配置项中某一参数作为环境变量的值。 + +### 图形化界面操作 + +通过镜像创建工作负载时,可以在 __环境变量__ 界面通过选择 __配置项导入__ 或 __配置项键值导入__ 为容器设置环境变量。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面中,在 __容器配置__ 这一步中,选择 __环境变量__ 配置,点击 __添加环境变量__ 按钮。 + + ![添加环境变量](../../../images/config05.png) + +2. 在环境变量类型处选择 __配置项导入__ 或 __配置项键值导入__ 。 + + - 当环境变量类型选择为 __配置项导入__ 时,依次输入 __变量名__ 、 __前缀__ 名称、 __配置项__ 的名称。 + + - 当环境变量类型选择为 __配置项键值导入__ 时,依次输入 __变量名__ 、 __配置项__ 名称、 __键__ 的名称。 + +### 命令行操作 + +您可以在创建工作负载时将配置项设置为环境变量,使用 valueFrom 参数引用 ConfigMap 中的 Key/Value。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod-1 +spec: + containers: + - name: test-container + image: busybox + command: [ "/bin/sh", "-c", "env" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: # (1)! + configMapKeyRef: + name: kpanda-configmap # (2)! + key: SPECIAL_LEVEL # (3)! + restartPolicy: Never +``` + +1. 使用 __valueFrom__ 来指定 env 引用配置项的 value 值 +2. 引用的配置文件名称 +3. 引用的配置项 key + +## 设置容器的命令行参数 + +您可以使用配置项设置容器中的命令或者参数值,使用环境变量替换语法 __$(VAR_NAME)__ 来进行。如下所示。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod-3 +spec: + containers: + - name: test-container + image: busybox + command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] + env: + - name: SPECIAL_LEVEL_KEY + valueFrom: + configMapKeyRef: + name: kpanda-configmap + key: SPECIAL_LEVEL + - name: SPECIAL_TYPE_KEY + valueFrom: + configMapKeyRef: + name: kpanda-configmap + key: SPECIAL_TYPE + restartPolicy: Never +``` + +这个 Pod 运行后,输出如下内容。 + +```none +Hello Kpanda +``` + +## 用作容器数据卷 + +您可以通过图形化界面或者终端命令行来使用配置项作为容器的环境变量。 + +### 图形化操作 + +在通过镜像创建工作负载时,您可以通过在 __数据存储__ 界面选择存储类型为 __配置项__ ,将配置项作为容器的数据卷。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面中,在 __容器配置__ 这一步中,选择 __数据存储__ 配置,在 __节点路径映射__ 列表点击 __添加__ 按钮。 + + ![添加环境变量](../images/config06.png) + +2. 在存储类型处选择 __配置项__ ,并依次输入 __容器路径__ 、 __子路径__ 等信息。 + +### 命令行操作 + +要在一个 Pod 的存储卷中使用 ConfigMap。 + +下面是一个将 ConfigMap 以卷的形式进行挂载的 Pod 示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + configMap: + name: myconfigmap +``` + +如果 Pod 中有多个容器,则每个容器都需要自己的 __volumeMounts__ 块,但针对每个 ConfigMap,您只需要设置一个 __spec.volumes__ 块。 + +!!! note + + 将配置项作为容器挂载的数据卷时,配置项只能作为只读文件进行读取。 diff --git a/docs/zh/docs/end-user/kpanda/configmaps-secrets/use-secret.md b/docs/zh/docs/end-user/kpanda/configmaps-secrets/use-secret.md new file mode 100644 index 0000000..4662828 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/configmaps-secrets/use-secret.md @@ -0,0 +1,141 @@ +# 使用密钥 + +密钥是一种用于存储和管理密码、OAuth 令牌、SSH、TLS 凭据等敏感信息的资源对象。使用密钥意味着您不需要在应用程序代码中包含敏感的机密数据。 + +## 使用场景 + +您可以在 Pod 中使用密钥,有多种使用场景,主要包括: + +- 作为容器的环境变量使用,提供容器运行过程中所需的一些必要信息。 +- 使用密钥作为 Pod 的数据卷。 +- 在 kubelet 拉取容器镜像时用作镜像仓库的身份认证凭证使用。 + +## 使用密钥设置容器的环境变量 + +您可以通过图形化界面或者终端命令行来使用密钥作为容器的环境变量。 + +!!! note + + 密钥导入是将密钥作为环境变量的值;密钥键值导入是将密钥中某一参数作为环境变量的值。 + +### 图形界面操作 + +在通过镜像创建工作负载时,您可以在 __环境变量__ 界面通过选择 __密钥导入__ 或 __密钥键值导入__ 为容器设置环境变量。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面。 + + ![创建 deployment](../../../images/secret05.png) + +2. 在 __容器配置__ 选择 __环境变量__ 配置,点击 __添加环境变量__ 按钮。 + + ![添加环境变量](../../../images/secret06.png) + +3. 在环境变量类型处选择 __密钥导入__ 或 __密钥键值导入__ 。 + + ![密钥导入](../../../images/secret07.png) + + - 当环境变量类型选择为 __密钥导入__ 时,依次输入 __变量名__ 、 __前缀__ 、 __密钥__ 的名称。 + + - 当环境变量类型选择为 __密钥键值导入__ 时,依次输入 __变量名__ 、 __密钥__ 、 __键__ 的名称。 + +### 命令行操作 + +如下例所示,您可以在创建工作负载时将密钥设置为环境变量,使用 __valueFrom__ 参数引用 Secret 中的 Key/Value。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: secret-env-pod +spec: + containers: + - name: mycontainer + image: redis + env: + - name: SECRET_USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + optional: false # (1)! + - name: SECRET_PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + optional: false # (2)! + +``` + +1. 此值为默认值;意味着 "mysecret",必须存在且包含名为 "username" 的主键 +2. 此值为默认值;意味着 "mysecret",必须存在且包含名为 "password" 的主键 + +## 使用密钥作为 Pod 的数据卷 + +### 图形界面操作 + +在通过镜像创建工作负载时,您可以通过在 __数据存储__ 界面选择存储类型为 __密钥__ ,将密钥作为容器的数据卷。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面。 + + ![创建deployment](../../../images/secret05.png) + +2. 在 __容器配置__ 选择 __数据存储__ 配置,在 __节点路径映射__ 列表点击 __添加__ 按钮。 + + ![创建deployment](../images/secret08.png) + +3. 在存储类型处选择 __密钥__ ,并依次输入 __容器路径__ 、 __子路径__ 等信息。 + +### 命令行操作 + +下面是一个通过数据卷来挂载名为 __mysecret__ 的 Secret 的 Pod 示例: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + optional: false # (1)! +``` + +1. 默认设置,意味着 "mysecret" 必须已经存在 + +如果 Pod 中包含多个容器,则每个容器需要自己的 __volumeMounts__ 块,不过针对每个 Secret 而言,只需要一份 `.spec.volumes` 设置。 + +## 在 kubelet 拉取容器镜像时用作镜像仓库的身份认证凭证 + +您可以通过图形化界面或者终端命令行来使用密钥作为镜像仓库身份认证凭证。 + +### 图形化操作 + +在通过镜像创建工作负载时,您可以通过在 __数据存储__ 界面选择存储类型为 __密钥__ ,将密钥作为容器的数据卷。 + +1. 进入[镜像创建工作负载](../workloads/create-deployment.md)页面。 + + ![创建deployment](../../../images/secret05.png) + +2. 在第二步 __容器配置__ 时选择 __基本信息__ 配置,点击 __选择镜像__ 按钮。 + + ![选择镜像](../../../images/secret09.png) + +3. 在弹框的 __镜像仓库__ 下拉选择私有镜像仓库名称。关于私有镜像密钥创建请查看[创建密钥](create-secret.md)了解详情。 + + ![选择镜像](../../../images/secret10.png) + +4. 输入私有仓库内的镜像名称,点击 __确定__ ,完成镜像选择。 + +!!! note + + 创建密钥时,需要确保输入正确的镜像仓库地址、用户名称、密码并选择正确的镜像名称,否则将无法获取镜像仓库中的镜像。 diff --git a/docs/zh/docs/end-user/kpanda/custom-resources/create.md b/docs/zh/docs/end-user/kpanda/custom-resources/create.md new file mode 100644 index 0000000..8a00506 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/custom-resources/create.md @@ -0,0 +1,103 @@ +# 创建自定义资源 (CRD) + +在 Kubernetes 中一切对象都被抽象为资源,如 Pod、Deployment、Service、Volume 等是 Kubernetes 提供的默认资源, +这为我们的日常运维和管理工作提供了重要支撑,但是在一些特殊的场景中,现有的预置资源并不能满足业务的需要, +因此我们希望去扩展 Kubernetes API 的能力,自定义资源(CustomResourceDefinition, CRD)正是基于这样的需求应运而生。 + +容器管理模块支持对自定义资源的界面化管理,主要功能如下: + +- 获取集群下自定义资源列表和详细信息 +- 基于 YAML 创建自定资源 +- 基于 YAML 创建自定义资源示例 CR(Custom Resource) +- 删除自定义资源 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并将用户授权为 [Cluster Admin](../permissions/permission-brief.md#cluster-admin) 角色 ,详情可参考[集群和命名空间授权](../permissions/cluster-ns-auth.md) + +## 通过 YAML 创建自定义资源 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd-cluster-list.png) + +2. 在左侧导航栏,点击 __自定义资源__ ,点击右上角 __YAML 创建__ 按钮。 + + ![点击创建按钮](../images/crd-list-01.png) + +3. 在 __YAML 创建__ 页面中,填写 YAML 语句后,点击 __确定__ 。 + + ![填写 yaml](../../../images/crd03.png) + +4. 返回自定义资源列表页,即可查看刚刚创建的名为 `crontabs.stable.example.com` 的自定义资源。 + + ![查看](../images/crd-list-02.png) + +**自定义资源示例:** + +```yaml title="CRD example" +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + cronSpec: + type: string + image: + type: string + replicas: + type: integer + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct +``` + +## 通过 YAML 创建自定义资源示例 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd-cluster-list.png) + +2. 在左侧导航栏,点击 __自定义资源__ ,进入自定义资源列表页面。 + + ![点击创建按钮](../images/crd-list-03.png) + +3. 点击名为 `crontabs.stable.example.com` 的自定义资源,进入详情,点击右上角 __YAML 创建__ 按钮。 + + ![点击创建按钮](../images/crd-instance-list.png) + +4. 在 __YAML 创建__ 页面中,填写 YAML 语句后,点击 __确定__ 。 + + ![填写 yaml](../../../images/crd06.png) + +5. 返回 `crontabs.stable.example.com` 的详情页面,即可查看刚刚创建的名为 __my-new-cron-object__ 的自定义资源。 + +**CR 示例:** + +```yaml title="CR example" +apiVersion: "stable.example.com/v1" +kind: CronTab +metadata: + name: my-new-cron-object +spec: + cronSpec: "* * * * */5" + image: my-awesome-cron-image +``` diff --git a/docs/zh/docs/end-user/kpanda/gpu/FAQ.md b/docs/zh/docs/end-user/kpanda/gpu/FAQ.md new file mode 100644 index 0000000..be7159f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/FAQ.md @@ -0,0 +1,16 @@ +--- +hide: + - toc +--- + +# GPU 相关 FAQ + +## Pod 内 nvidia-smi 看不到 GPU 进程 + +Q: 在使用 GPU 的 Pod 内执行 `nvidia-smi` 命令看不到使用 GPU 的进程信息,包括整卡模式、vGPU 模式等。 + +A: 因为有 `PID namespace` 隔离,导致在 Pod 内查看不到 GPU 进程,如果要查看 GPU 进程有如下几种方法: + +- 在使用 GPU 的工作负载配置 `hostPID: true`,使其可以查看到宿主机上的 PID +- 在 gpu-operator 的 driver Pod 中执行 `nvidia-smi` 命令查看进程 +- 在宿主机上执行 `chroot /run/nvidia/driver nvidia-smi` 命令查看进程 diff --git a/docs/zh/docs/end-user/kpanda/gpu/Iluvatar_usage.md b/docs/zh/docs/end-user/kpanda/gpu/Iluvatar_usage.md new file mode 100644 index 0000000..a49f737 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/Iluvatar_usage.md @@ -0,0 +1,64 @@ +# App 使用天数智芯(Iluvatar)GPU + +本节介绍如何在算丰 AI 算力平台使用天数智芯虚拟 GPU。 + +## 前提条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 当前集群已安装天数智芯 GPU 驱动,驱动安装请参考[天数智芯官方文档](https://support.iluvatar.com/#/login)。 +- 当前集群内 GPU 卡未进行任何虚拟化操作且未被其它 App 占用。 + +## 操作步骤 + +### 使用界面配置 + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Iluvatar__ 。 + + ![集群设置](../../../images/cluster-setting-iluvatar-gpu.jpg) + +2. 部署工作负载。点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Iluvatar)之后,需要配置 App 使用的 GPU 资源: + + - 物理卡数量(iluvatar.ai/vcuda-core):表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且 **小于等于** 宿主机上的卡数量。 + - 显存使用数量(iluvatar.ai/vcuda-memory):表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值。 + + ![负载使用](../../../images/workload_iluvatargpu_userguide.jpg) + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 + +### 使用 YAML 配置 + +创建工作负载申请 GPU 资源,在资源申请和限制配置中增加`iluvatar.ai/vcuda-core: 1`、`iluvatar.ai/vcuda-memory: 200` 参数,配置 App 使用物理卡的资源。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-iluvatar-gpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-iluvatar-gpu-demo + template: + metadata: + labels: + app: full-iluvatar-gpu-demo + spec: + containers: + - image: nginx:perl + name: container-0 + resources: + limits: + cpu: 250m + iluvatar.ai/vcuda-core: '1' + iluvatar.ai/vcuda-memory: '200' + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + imagePullSecrets: + - name: default-secret +``` diff --git a/docs/zh/docs/end-user/kpanda/gpu/ascend/ascend_driver_install.md b/docs/zh/docs/end-user/kpanda/gpu/ascend/ascend_driver_install.md new file mode 100644 index 0000000..e565b13 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/ascend/ascend_driver_install.md @@ -0,0 +1,161 @@ +# 昇腾 NPU 组件安装 + +本章节提供昇腾 NPU 驱动、Device Plugin、NPU-Exporter 等组件的安装指导。 + +## 前提条件 + +1. 安装前请确认支持的 NPU 型号,详情请参考[昇腾 NPU 矩阵](../gpu_matrix.md) +2. 请确认 对应 NPU 型号所要求的内核版本是否匹配,详情请参考[昇腾 NPU 矩阵](../gpu_matrix.md) +3. 准备 Kubernetes 基础环境 + +## 安装步骤 + +使用 NPU 资源之前,需要完成固件安装、NPU 驱动安装、 Docker Runtime 安装、用户创建、日志目录创建以及 NPU Device Plugin 安装,详情参考如下步骤。 + +### 安装固件 + +1. 安装前请确认内核版本在“二进制安装”安装方式对应的版本范围内,则可以直接安装NPU驱动固件。 +2. 固件与驱动下载请参考[固件下载地址](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=15&cann=6.3.RC2.alpha005&driver=1.0.20.alpha) +3. 固件安装请参考[安装 NPU 驱动固件](https://www.hiascend.com/document/detail/zh/quick-installation/23.0.RC2/quickinstg/800_3000/quickinstg_800_3000_0001.html) + +### 安装 NPU 驱动 + +1. 如驱动未安装,请参考昇腾官方文档进行安装。例如 Ascend910,参考 + [910 驱动安装文档](https://www.hiascend.com/document/detail/zh/Atlas%20200I%20A2/23.0.RC3/EP/installationguide/Install_87.html)。 +2. 运行 __npu-smi info__ 命令,并且能够正常返回 NPU 信息,表示 NPU 驱动与固件已就绪。 + +![昇腾信息](../../../../images/npu-smi-info.png) + +### 安装 Docker Runtime + +1. 下载 Ascend Docker Runtime + + 社区版下载地址:https://www.hiascend.com/zh/software/mindx-dl/community + + ```sh + wget -c https://mindx.obs.cn-south-1.myhuaweicloud.com/OpenSource/MindX/MindX%205.0.RC2/MindX%20DL%205.0.RC2/Ascend-docker-runtime_5.0.RC2_linux-x86_64.run + ``` + + 安装到指定路径下,依次执行以下两条命令,参数为指定的安装路径: + + ```sh + chmod u+x Ascend-docker-runtime_5.0.RC2_linux-x86_64.run + ./Ascend-docker-runtime_{version}_linux-{arch}.run --install --install-path= + ``` + +2. 修改 containerd 配置文件 + + containerd 无默认配置文件时,依次执行以下3条命令,创建配置文件: + + ```bash + mkdir /etc/containerd + containerd config default > /etc/containerd/config.toml + vim /etc/containerd/config.toml + ``` + + containerd 有配置文件时: + + ```bash + vim /etc/containerd/config.toml + ``` + + 根据实际情况修改 runtime 的安装路径,主要修改 runtime 字段: + + ```toml + ... + [plugins."io.containerd.monitor.v1.cgroups"] + no_prometheus = false + [plugins."io.containerd.runtime.v1.linux"] + shim = "containerd-shim" + runtime = "/usr/local/Ascend/Ascend-Docker-Runtime/ascend-docker-runtime" + runtime_root = "" + no_shim = false + shim_debug = false + [plugins."io.containerd.runtime.v2.task"] + platforms = ["linux/amd64"] + ... + ``` + + 执行以下命令,重启 containerd: + + ```bash + systemctl restart containerd + ``` + +### 用户创建 + +在对应组件安装的节点上执行以下命令创建用户。 + +```sh +# Ubuntu 操作系统 +useradd -d /home/hwMindX -u 9000 -m -s /usr/sbin/nologin hwMindX +usermod -a -G HwHiAiUser hwMindX +# Centos 操作系统 +useradd -d /home/hwMindX -u 9000 -m -s /sbin/nologin hwMindX +usermod -a -G HwHiAiUser hwMindX +``` + +### 日志目录创建 + +在对应节点创建组件日志父目录和各组件的日志目录,并设置目录对应属主和权限。执行下述命令,创建组件日志父目录。 + +```bash +mkdir -m 755 /var/log/mindx-dl +chown root:root /var/log/mindx-dl +``` + +执行下述命令,创建 Device Plugin 组件日志目录。 + +```bash +mkdir -m 750 /var/log/mindx-dl/devicePlugin +chown root:root /var/log/mindx-dl/devicePlugin +``` + +!!! note + + 请分别为所需组件创建对应的日志目录,当前案例中只需要 Device Plugin 组件。 + 如果有其他组件需求请参考[官方文档](https://www.hiascend.com/document/detail/zh/mindx-dl/50rc3/clusterscheduling/clusterschedulingig/dlug_installation_016.html) + +### 创建节点 Label + +参考下述命令在对应节点上创建 Label: + +```shell +# 在安装了驱动的计算节点创建此标签 +kubectl label node {nodename} huawei.com.ascend/Driver=installed +kubectl label node {nodename} node-role.kubernetes.io/worker=worker +kubectl label node {nodename} workerselector=dls-worker-node +kubectl label node {nodename} host-arch=huawei-arm //或者host-arch=huawei-x86 ,根据实际情况选择 +kubectl label node {nodename} accelerator=huawei-Ascend910 //根据实际情况进行选择 +# 在控制节点创建此标签 +kubectl label node {nodename} masterselector=dls-master-node +``` + +### 安装 Device Plugin 和 NpuExporter + +功能模块路径: __容器管理__ -> __集群管理__ ,点击目标集群的名称,从左侧导航栏点击 __Helm 应用__ -> __Helm 模板__ -> 搜索 __ascend-mindxdl__ 。 + +![找到 ascend-mindxdl](../images/ascend-mindxdl.png) + +![ascend-mindxdl详情](../images/detail-ascend.png) + +- __DevicePlugin__ :通过提供通用设备插件机制和标准的设备API接口,供Kubernetes使用设备。建议使用默认的镜像及版本。 +- __NpuExporter__ :基于Prometheus/Telegraf生态,该组件提供接口,帮助用户能够关注到昇腾系列AI处理器以及容器级分配状态。建议使用默认的镜像及版本。 +- __ServiceMonitor__ :默认不开启,开启后可前往可观测性模块查看 NPU 相关监控。如需开启,请确保 insight-agent 已安装并处于运行状态,否则将导致 ascend-mindxdl 安装失败。 +- __isVirtualMachine__ :默认不开启,如果 NPU 节点为云主机场景,请开启 isVirtualMachine 参数。 + +安装成功后,对应命名空间下会出现两个组件,如下图: + +![ascend-mindxdl列表](../images/list-ascend-mindxdl.png) + +同时节点信息上也会出现对应 NPU 的信息: + +![节点标签](../images/label-ascend-mindxdl.png) + +一切就绪后,我们通过页面创建工作负载时,就能够选择到对应的 NPU 设备,如下图: + +![使用 NPU](../images/use-ascend-mindxdl.png) + +!!! note + + 有关详细使用步骤,请参照[应用使用昇腾(Ascend)NPU](./ascend_usage.md)。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/ascend/ascend_usage.md b/docs/zh/docs/end-user/kpanda/gpu/ascend/ascend_usage.md new file mode 100644 index 0000000..9647012 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/ascend/ascend_usage.md @@ -0,0 +1,162 @@ +# 应用使用昇腾(Ascend)NPU + +本节介绍如何在算丰 AI 算力平台使用昇腾 GPU。 + +## 前提条件 + +- 当前 NPU 节点已安装昇腾 (Ascend)驱动。 +- 当前 NPU 节点已安装 Ascend-Docker-Runtime 组件。 +- 当前集群已安装 NPU MindX DL 套件。 +- 当前集群内 NPU 卡未进行任何虚拟化操作或被其它应用占用。 + +请参考[昇腾 NPU 组件安装文档](ascend_driver_install.md)安装基础环境。 + +## 快速使用 + +本文使用昇腾示例库中的 [AscentCL 图片分类应用](https://gitee.com/ascend/samples/tree/master/inference/modelInference/sampleResnetQuickStart/python)示例。 + +1. 下载昇腾代码库 + + 运行以下命令下载昇腾 Demo 示例代码库,并且请记住代码存放的位置,后续需要使用。 + + ```git + git clone https://gitee.com/ascend/samples.git + ``` + +2. 准备基础镜像 + + 此例使用 Ascent-pytorch 基础镜像,可访问[昇腾镜像仓库](https://www.hiascend.com/developer/ascendhub)获取。 + +3. 准备 YAML + + ```yaml title="ascend-demo.yaml" + apiVersion: batch/v1 + kind: Job + metadata: + name: resnetinfer1-1-1usoc + spec: + template: + spec: + containers: + - image: ascendhub.huawei.com/public-ascendhub/ascend-pytorch:23.0.RC2-ubuntu18.04 # Inference image name + imagePullPolicy: IfNotPresent + name: resnet50infer + securityContext: + runAsUser: 0 + command: + - "/bin/bash" + - "-c" + - | + source /usr/local/Ascend/ascend-toolkit/set_env.sh && + TEMP_DIR=/root/samples_copy_$(date '+%Y%m%d_%H%M%S_%N') && + cp -r /root/samples "$TEMP_DIR" && + cd "$TEMP_DIR"/inference/modelInference/sampleResnetQuickStart/python/model && + wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/003_Atc_Models/resnet50/resnet50.onnx && + atc --model=resnet50.onnx --framework=5 --output=resnet50 --input_shape="actual_input_1:1,3,224,224" --soc_version=Ascend910 && + cd ../data && + wget https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/models/aclsample/dog1_1024_683.jpg && + cd ../scripts && + bash sample_run.sh + resources: + requests: + huawei.com/Ascend910: 1 # Number of the Ascend 910 Processors + limits: + huawei.com/Ascend910: 1 # The value should be the same as that of requests + volumeMounts: + - name: hiai-driver + mountPath: /usr/local/Ascend/driver + readOnly: true + - name: slog + mountPath: /var/log/npu/conf/slog/slog.conf + - name: localtime # The container time must be the same as the host time + mountPath: /etc/localtime + - name: dmp + mountPath: /var/dmp_daemon + - name: slogd + mountPath: /var/slogd + - name: hbasic + mountPath: /etc/hdcBasic.cfg + - name: sys-version + mountPath: /etc/sys_version.conf + - name: aicpu + mountPath: /usr/lib64/aicpu_kernels + - name: tfso + mountPath: /usr/lib64/libtensorflow.so + - name: sample-path + mountPath: /root/samples + volumes: + - name: hiai-driver + hostPath: + path: /usr/local/Ascend/driver + - name: slog + hostPath: + path: /var/log/npu/conf/slog/slog.conf + - name: localtime + hostPath: + path: /etc/localtime + - name: dmp + hostPath: + path: /var/dmp_daemon + - name: slogd + hostPath: + path: /var/slogd + - name: hbasic + hostPath: + path: /etc/hdcBasic.cfg + - name: sys-version + hostPath: + path: /etc/sys_version.conf + - name: aicpu + hostPath: + path: /usr/lib64/aicpu_kernels + - name: tfso + hostPath: + path: /usr/lib64/libtensorflow.so + - name: sample-path + hostPath: + path: /root/samples + restartPolicy: OnFailure + ``` + + 以上 YAML 中有一些字段需要根据实际情况进行修改: + + 1. __atc ... --soc_version=Ascend910__ 使用的是 __Ascend910__ ,请以实际情况为主 + 您可以使用 __npu-smi info__ 命令查看显卡型号然后加上 Ascend 前缀即可 + 2. __samples-path__ 以实际情况为准 + 3. __resources__ 以实际情况为准 + +4. 部署 Job 并查看结果 + + 使用如下命令创建 Job: + + ```shell + kubectl apply -f ascend-demo.yaml + ``` + + 查看 Pod 运行状态: + + ![昇腾 Pod 状态](../../../../images/ascend-demo-pod-status.png) + + Pod 成功运行后,查看日志结果。在屏幕上的关键提示信息示例如下图,提示信息中的 Label 表示类别标识, + Conf 表示该分类的最大置信度,Class 表示所属类别。这些值可能会根据版本、环境有所不同,请以实际情况为准: + + ![昇腾 demo 运行结果](../../../../images/ascend-demo-pod-result.png) + + 结果图片展示: + + ![昇腾 demo 运行结果图片](../../../../images/ascend-demo-infer-result.png) + +## 界面使用 + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Ascend__ 。 + + ![集群设置](../../../../images/cluster-setting-ascend-gpu.jpg) + +2. 部署工作负载,点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Ascend)之后,需要配置应用使用的物理卡数量: + + **物理卡数量(huawei.com/Ascend910)** :表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且**小于等于**宿主机上的卡数量。 + + ![负载使用](../../../../images/workload_ascendgpu_userguide.jpg) + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/ascend/vnpu.md b/docs/zh/docs/end-user/kpanda/gpu/ascend/vnpu.md new file mode 100644 index 0000000..e26c866 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/ascend/vnpu.md @@ -0,0 +1,78 @@ +# 启用昇腾虚拟化 + +昇腾虚拟化分为动态虚拟化和静态虚拟化,本文介绍如何开启并使用昇腾静态虚拟化能力。 + +## 前提条件 + +- Kubernetes 集群环境搭建。 +- 当前 NPU 节点已安装昇腾 (Ascend)驱动。 +- 当前 NPU 节点已安装 Ascend-Docker-Runtime 组件。 +- 当前集群已安装 NPU MindX DL 套件。 +- 支持的 NPU 卡型号: + + - Ascend 310P,已验证 + - Ascend 910b(20 核),已验证 + - Ascend 910(32 核),官方介绍支持,未实际验证 + - Ascend 910(30 核),官方介绍支持,未实际验证 + + 更多细节参阅[官方虚拟化硬件说明](https://www.hiascend.com/document/detail/zh/mindx-dl/50rc1/AVI/cpaug/cpaug_0005.html)。 + +请参考[昇腾 NPU 组件安装文档](./ascend_driver_install.md)安装基础环境。 + +## 开启虚拟化能力 + +开启虚拟化能力需要手动修改 ascend-device-plugin-daemonset 组件的启动参数,参考下述命令: + +```init +- device-plugin -useAscendDocker=true -volcanoType=false -presetVirtualDevice=true +- logFile=/var/log/mindx-dl/devicePlugin/devicePlugin.log -logLevel=0 +``` + +### 切分 VNPU 实例 + +静态虚拟化需要手动对 VNPU 实例的切分,请参考下述命令: + +``` bash +npu-smi set -t create-vnpu -i 13 -c 0 -f vir02 +``` + +- `i` 指的是 card id +- `c` 指的是 chip id +- `vir02` 指的是切分规格模板 + +关于 card id 和 chip id,可以通过 npu-smi info 查询,切分规格可通过 +[ascend 官方模板](https://www.hiascend.com/document/detail/zh/mindx-dl/500/AVI/cpaug/cpaug_006.html)进行查询。 + +切分实例过后可通过下述命令查询切分结果: + +```bash +npu-smi info -t info-vnpu -i 13 -c 0 +``` + +查询结果如下: + +![vnpu1](../images/vnpu1.png) + +### 重启 ascend-device-plugin-daemonset + +切分实例后手动重启 device-plugin pod,然后使用 `kubectl describe` 命令查看已注册 node 的资源: + +```bash +kubectl describe node {{nodename}} +``` + +![vnpu2](../images/vnpu2.png) + +## 如何使用设备 + +在创建应用时,指定资源 key,参考下述 YAML: + +```yaml +...... +resources: + requests: + huawei.com/Ascend310P-2c: 1 + limits: + huawei.com/Ascend310P-2c: 1 +...... +``` diff --git a/docs/zh/docs/end-user/kpanda/gpu/dynamic-regulation.md b/docs/zh/docs/end-user/kpanda/gpu/dynamic-regulation.md new file mode 100644 index 0000000..b3434cb --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/dynamic-regulation.md @@ -0,0 +1,115 @@ +# GPU 资源动态调节 + +提供 GPU 资源动态调整功能,允许您在无需重新加载、重置或重启整个运行环境的情况下,对已经分配的 vGPU 资源进行实时、动态的调整。 +这一功能旨在最大程度地减少对业务运行的影响,确保您的业务能够持续稳定地运行,同时根据实际需求灵活调整 GPU 资源。 + +## 使用场景 + +- **弹性资源分配** :当业务需求或工作负载发生变化时,可以快速调整 GPU 资源以满足新的性能要求。 +- **即时响应** :在面对突发的高负载或业务需求时,可以迅速增加 GPU 资源而无需中断业务运行,以确保服务的稳定性和性能。 + +## 操作步骤 + +以下是一个具体的操作示例,展示如何在不重启 vGPU Pod 的情况下动态调整 vGPU 的算力和显存资源: + +### 创建一个 vGPU Pod + +首先,我们使用以下 YAML 创建一个 vGPU Pod,其算力初始不限制,显存限制为 200Mb。 + +```yaml +kind: Deployment +apiVersion: apps/v1 +metadata: + name: gpu-burn-test + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: gpu-burn-test + template: + metadata: + creationTimestamp: null + labels: + app: gpu-burn-test + spec: + containers: + - name: container-1 + image: docker.io/chrstnhntschl/gpu_burn:latest + command: + - sleep + - '100000' + resources: + limits: + cpu: 1m + memory: 1Gi + nvidia.com/gpucores: '0' + nvidia.com/gpumem: '200' + nvidia.com/vgpu: '1' +``` + +调整前查看 `Pod` 中的资源 `GPU` 分配资源: + +![gpu-dynamic-regulation-before.png](./images/gpu-dynamic-regulation-before.png) + + +### 动态调整算力 + +如果需要修改算力为 10%,可以按照以下步骤操作: + +1. 进入容器: + + ```bash + kubectl exec -it -- /bin/bash + ``` + +1. 执行: + + ```bash + export CUDA_DEVICE_SM_LIMIT=10 + ``` + +1. 在当前终端直接运行: + + ```bash + ./gpu_burn 60 + ``` + + 程序即可生效。注意,不能退出当前 Bash 终端。 + +### 动态调整显存 + +如果需要修改显存为 300 MB,可以按照以下步骤操作: + +1. 进入容器: + + ```bash + kubectl exec -it -- /bin/bash + ``` + +1. 执行以下命令来设置显存限制: + + ```bash + export CUDA_DEVICE_MEMORY_LIMIT_0=300m + export CUDA_DEVICE_MEMORY_SHARED_CACHE=/usr/local/vgpu/d.cache + ``` + + + !!! note + + 每次修改显存大小时,`d.cache` 这个文件名字都需要修改,比如改为 `a.cache`、`1.cache` 等,以避免缓存冲突。 + +1. 在当前终端直接运行: + + ```bash + ./gpu_burn 60 + ``` + + 程序即可生效。同样地,不能退出当前 Bash 终端。 + +调整后查看 `Pod` 中的资源 `GPU` 分配资源: + +![gpu-dynamic-regulation-after.png](./images/gpu-dynamic-regulation-after.png) + + +通过上述步骤,您可以在不重启 vGPU Pod 的情况下动态地调整其算力和显存资源,从而更灵活地满足业务需求并优化资源利用。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/gpu_matrix.md b/docs/zh/docs/end-user/kpanda/gpu/gpu_matrix.md new file mode 100644 index 0000000..8e1b175 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/gpu_matrix.md @@ -0,0 +1,55 @@ +--- +hide: + - toc +--- + +# GPU 支持矩阵 + +本页说明算丰 AI 算力平台支持的 GPU 及操作系统所对应的矩阵。 + +## NVIDIA GPU + +| GPU 厂商及类型 | 支持 GPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| NVIDIA GPU(整卡/vGPU) | NVIDIA Fermi (2.1) 架构 | CentOS 7 | Kernel 3.10.0-123 ~ 3.10.0-1160内核参考文档建议使用操作系统对应 Kernel 版本 | 操作系统:CentOS 7.9;内核版本: 3.10.0-1160 | GPU Operator 离线安装 | +| | NVIDIA GeForce 400 系列 | CentOS 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | +| | NVIDIA Quadro 4000 系列 | Ubuntu 20.04 | Kernel 5.4 | | | +| | NVIDIA Tesla 20 系列 | Ubuntu 22.04 | Kernel 5.19 | | | +| | NVIDIA Ampere 架构系列(A100;A800;H100) | RHEL 7 | Kernel 3.10.0-123 ~ 3.10.0-1160 | | | +| | | RHEL 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | +| NVIDIA MIG | NVIDIA Ampere 架构系列(A100、A800、H100) | CentOS 7 | Kernel 3.10.0-123 ~ 3.10.0-1160 | 操作系统:CentOS 7.9;内核版本:3.10.0-1160 | GPU Operator 离线安装 | +| | | CentOS 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | +| | | Ubuntu 20.04 | Kernel 5.4 | | | +| | | Ubuntu 22.04 | Kernel 5.19 | | | +| | | RHEL 7 | Kernel 3.10.0-123 ~ 3.10.0-1160 | | | +| | | RHEL 8 | Kernel 4.18.0-80 ~ 4.18.0-348 | | | + +## 昇腾(Ascend)NPU + + | GPU 厂商及类型 | 支持 NPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| 昇腾(Ascend 310) | Ascend 310 | Ubuntu 20.04 | 详情参考:内核版本要求 | 操作系统:CentOS 7.9;内核版本:3.10.0-1160 | 300 和 310P 驱动文档 | +| | Ascend 310P; | CentOS 7.6 | | | | +| | | CentOS 8.2 | | | | +| | | KylinV10SP1 操作系统 | | | | +| | | openEuler 操作系统 | | | | +| 昇腾(Ascend 910) | Ascend 910B | Ubuntu 20.04 | 详情参考内核版本要求 | 操作系统:CentOS 7.9;内核版本:3.10.0-1160 | 910 驱动文档 | +| | | CentOS 7.6 | | | | +| | | CentOS 8.2 | | | | +| | | KylinV10SP1 操作系统 | | | | +| | | openEuler 操作系统 | | | | + +## 天数智芯(Iluvatar)GPU + + | GPU 厂商及类型 | 支持的 GPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| 天数智芯(Iluvatar vGPU) | BI100 | CentOS 7 | Kernel 3.10.0-957.el7.x86_64 ~ 3.10.0-1160.42.2.el7.x86_64 | 操作系统:CentOS 7.9;内核版本: 3.10.0-1160 | 补充中 | +| | MR100; | CentOS 8 | Kernel 4.18.0-80.el8.x86_64 ~ 4.18.0-305.19.1.el8_4.x86_64 | | | +| | | Ubuntu 20.04 | Kernel 4.15.0-20-generic ~ 4.15.0-160-generic Kernel 5.4.0-26-generic ~ 5.4.0-89-generic Kernel 5.8.0-23-generic ~ 5.8.0-63-generic | | | +| | | Ubuntu 21.04 | Kernel 4.15.0-20-generic ~ 4.15.0-160-generic Kernel 5.4.0-26-generic ~ 5.4.0-89-generic Kernel 5.8.0-23-generic ~ 5.8.0-63-generic | | | +| | | openEuler 22.03 LTS | Kernel 版本大于等于 5.1 且小于等于 5.10 | | | + +## 沐曦(Metax)GPU +| GPU 厂商及类型 | 支持的 GPU 型号 | 适配的操作系统(在线) | 推荐内核 | 推荐的操作系统及内核 | 安装文档 | +| :--: | :--: | :--: | :--: | :--: | :--: | +| 沐曦Metax(整卡/vGPU) | 曦云 C500 | | | | [沐曦 GPU 安装使用](./metax/usemetax.md) | diff --git a/docs/zh/docs/end-user/kpanda/gpu/gpu_scheduler_config.md b/docs/zh/docs/end-user/kpanda/gpu/gpu_scheduler_config.md new file mode 100644 index 0000000..4c31d6a --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/gpu_scheduler_config.md @@ -0,0 +1,60 @@ +# GPU 调度配置(Binpack 和 Spread ) + +本文介绍使用 NVIDIA vGPU 时,如何通过 Binpack 和 Spread 的 GPU 调度配置减少 GPU 资源碎片、防止单点故障等,实现 vGPU 的高级调度。 +算丰 AI 算力平台提供了集群和工作负载两种维度的 Binpack 和 Spread 调度策略,分别满足不同场景下的使用需求。 + +## 前置条件 + +- 集群节点上已正确安装 GPU 设备。 +- 集群中已正确安装 [gpu-operator 组件](./nvidia/install_nvidia_driver_of_operator.md) 和 + [Nvidia-vgpu 组件](./nvidia/vgpu/vgpu_addon.md)。 +- 集群节点列表中,GPU 模式下存在 NVIDIA-vGPU 类型。 + +## 使用场景 + +- 基于 GPU 卡维度调度策略 + + - Binpack:优先选择节点的同一张 GPU 卡,适用于提高 GPU 利用率,减少资源碎片。 + - Spread:多个 Pod 会分散在节点的不同 GPU 卡上,适用于高可用场景,避免单卡故障。 + +- 基于节点维度的调度策略 + + - Binpack: 多个 Pod 会优先选择同一个节点,适用于提高 GPU 利用率,减少资源碎片。 + - Spread:多个 Pod 会分散在不同节点上,适用于高可用场景,避免单节点故障。 + +## 集群维度使用 Binpack 和 Spread 调度配置 + +!!! note + + 默认情况下,工作负载会遵循集群级别的 Binpack 和 Spread 调度配置。 + 若工作负载单独设置了与集群不一致的 Binpack 和 Spread 调度策略,则该工作负载优先遵循其本身的调度策略。 + +1. 在 __集群列表__ 页选择需要调整 Binpack 和 Spread 调度策略的集群,点击右侧的 __┇__ 操作图标并在下拉列表中点击 __GPU 调度配置__ 。 + + ![集群列表](images/gpu-scheduler-clusterlist.png) + +2. 根据业务场景调整 GPU 调度配置,并点击 __确定__ 后保存。 + + ![binpack配置](images/gpu-scheduler-clusterrule.png) + +## 工作负载维度使用 Binpack 和 Spread 调度配置 + +!!! note + + 当工作负载维度的 Binpack 和 Spread 调度策略与集群级别的配置冲突时,优先遵循工作负载维度的配置。 + +参考以下步骤,使用镜像创建一个无状态负载,并在工作负载中配置 Binpack 和 Spread 调度策略 。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群list](images/clusterlist1.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __无状态负载__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![创建工作负载](images/gpu-createdeploy.png) + +3. 依次填写[基本信息](../workloads/create-deployment.md#_3)、[容器配置](../workloads/create-deployment.md#_4),并在 __容器配置__ 中启用 GPU 配置,选择 GPU 类型为 NVIDIA vGPU, + 点击 __高级设置__ ,启用 Binpack / Spread 调度策略,根据业务场景调整 GPU 调度配置。配置完成后点击 __下一步__ , + 进入 [服务配置](../workloads/create-deployment.md#_5)、[高级配置](../workloads/create-deployment.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + ![配置binpack](images/gpu-deploybipack.png) \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/ascend-mindxdl.png b/docs/zh/docs/end-user/kpanda/gpu/images/ascend-mindxdl.png new file mode 100644 index 0000000..3ed8510 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/ascend-mindxdl.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/clusterlist1.png b/docs/zh/docs/end-user/kpanda/gpu/images/clusterlist1.png new file mode 100644 index 0000000..6504daa Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/clusterlist1.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/config.png b/docs/zh/docs/end-user/kpanda/gpu/images/config.png new file mode 100644 index 0000000..441d162 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/config.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/create-gpu-alarm.png b/docs/zh/docs/end-user/kpanda/gpu/images/create-gpu-alarm.png new file mode 100644 index 0000000..4836dc1 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/create-gpu-alarm.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/detail-ascend.png b/docs/zh/docs/end-user/kpanda/gpu/images/detail-ascend.png new file mode 100644 index 0000000..df1e75a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/detail-ascend.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/driveimage.png b/docs/zh/docs/end-user/kpanda/gpu/images/driveimage.png new file mode 100644 index 0000000..d858b44 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/driveimage.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/driver.jpg b/docs/zh/docs/end-user/kpanda/gpu/images/driver.jpg new file mode 100644 index 0000000..5b886b9 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/driver.jpg differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-details.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-details.png new file mode 100644 index 0000000..2841326 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-details.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-details2.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-details2.png new file mode 100644 index 0000000..57ccd25 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-details2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-message.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-message.png new file mode 100644 index 0000000..efb1a7c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-message.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-message2.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-message2.png new file mode 100644 index 0000000..f349466 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-alarm-message2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-createdeploy.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-createdeploy.png new file mode 100644 index 0000000..c9d2728 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-createdeploy.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-deploybipack.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-deploybipack.png new file mode 100644 index 0000000..015d8f0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-deploybipack.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-dynamic-regulation-after.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-dynamic-regulation-after.png new file mode 100644 index 0000000..450a773 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-dynamic-regulation-after.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-dynamic-regulation-before.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-dynamic-regulation-before.png new file mode 100644 index 0000000..6f9db7b Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-dynamic-regulation-before.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-operator-mig.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-operator-mig.png new file mode 100644 index 0000000..14493ed Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-operator-mig.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-scheduler-clusterlist.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-scheduler-clusterlist.png new file mode 100644 index 0000000..3fb8947 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-scheduler-clusterlist.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/gpu-scheduler-clusterrule.png b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-scheduler-clusterrule.png new file mode 100644 index 0000000..4506326 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/gpu-scheduler-clusterrule.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/image-1.png b/docs/zh/docs/end-user/kpanda/gpu/images/image-1.png new file mode 100644 index 0000000..d0ad415 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/image-1.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/image-2.png b/docs/zh/docs/end-user/kpanda/gpu/images/image-2.png new file mode 100644 index 0000000..a0ceafc Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/image-2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/image.png b/docs/zh/docs/end-user/kpanda/gpu/images/image.png new file mode 100644 index 0000000..4613049 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/image.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/kubean.png b/docs/zh/docs/end-user/kpanda/gpu/images/kubean.png new file mode 100644 index 0000000..6cc2768 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/kubean.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/label-ascend-mindxdl.png b/docs/zh/docs/end-user/kpanda/gpu/images/label-ascend-mindxdl.png new file mode 100644 index 0000000..2327825 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/label-ascend-mindxdl.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/list-ascend-mindxdl.png b/docs/zh/docs/end-user/kpanda/gpu/images/list-ascend-mindxdl.png new file mode 100644 index 0000000..e52b242 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/list-ascend-mindxdl.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/metax-node.png b/docs/zh/docs/end-user/kpanda/gpu/images/metax-node.png new file mode 100644 index 0000000..86d66ed Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/metax-node.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/metax-node1.png b/docs/zh/docs/end-user/kpanda/gpu/images/metax-node1.png new file mode 100644 index 0000000..ba4fc16 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/metax-node1.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/metax-use.png b/docs/zh/docs/end-user/kpanda/gpu/images/metax-use.png new file mode 100644 index 0000000..2227e78 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/metax-use.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/metax-use2.png b/docs/zh/docs/end-user/kpanda/gpu/images/metax-use2.png new file mode 100644 index 0000000..414b50e Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/metax-use2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/mig-select.png b/docs/zh/docs/end-user/kpanda/gpu/images/mig-select.png new file mode 100644 index 0000000..74f2efa Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/mig-select.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/miggpuoperator.png b/docs/zh/docs/end-user/kpanda/gpu/images/miggpuoperator.png new file mode 100644 index 0000000..197737c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/miggpuoperator.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/migoperator.png b/docs/zh/docs/end-user/kpanda/gpu/images/migoperator.png new file mode 100644 index 0000000..659b262 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/migoperator.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/migpolicy.png b/docs/zh/docs/end-user/kpanda/gpu/images/migpolicy.png new file mode 100644 index 0000000..6c0d9e5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/migpolicy.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/mixed.png b/docs/zh/docs/end-user/kpanda/gpu/images/mixed.png new file mode 100644 index 0000000..f59cd4e Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/mixed.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/mlu1.PNG b/docs/zh/docs/end-user/kpanda/gpu/images/mlu1.PNG new file mode 100644 index 0000000..690b3e9 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/mlu1.PNG differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/mlu2.png b/docs/zh/docs/end-user/kpanda/gpu/images/mlu2.png new file mode 100644 index 0000000..b446e68 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/mlu2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/mlu3.png b/docs/zh/docs/end-user/kpanda/gpu/images/mlu3.png new file mode 100644 index 0000000..a52096b Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/mlu3.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/node-gpu.png b/docs/zh/docs/end-user/kpanda/gpu/images/node-gpu.png new file mode 100644 index 0000000..9c6bf7d Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/node-gpu.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/node-mig.png b/docs/zh/docs/end-user/kpanda/gpu/images/node-mig.png new file mode 100644 index 0000000..7184ab6 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/node-mig.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/nvidia-gpu-driver-tag.jpg b/docs/zh/docs/end-user/kpanda/gpu/images/nvidia-gpu-driver-tag.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/operator-mig.png b/docs/zh/docs/end-user/kpanda/gpu/images/operator-mig.png new file mode 100644 index 0000000..6a5ce29 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/operator-mig.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/pod-mig.png b/docs/zh/docs/end-user/kpanda/gpu/images/pod-mig.png new file mode 100644 index 0000000..5efbbe0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/pod-mig.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/redhat0.12.2.png b/docs/zh/docs/end-user/kpanda/gpu/images/redhat0.12.2.png new file mode 100644 index 0000000..01bbb7c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/redhat0.12.2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/rhel7.9.png b/docs/zh/docs/end-user/kpanda/gpu/images/rhel7.9.png new file mode 100644 index 0000000..f740e56 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/rhel7.9.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/use-ascend-mindxdl.png b/docs/zh/docs/end-user/kpanda/gpu/images/use-ascend-mindxdl.png new file mode 100644 index 0000000..da3c80a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/use-ascend-mindxdl.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/usemig.png b/docs/zh/docs/end-user/kpanda/gpu/images/usemig.png new file mode 100644 index 0000000..47805ca Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/usemig.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/usemig1.png b/docs/zh/docs/end-user/kpanda/gpu/images/usemig1.png new file mode 100644 index 0000000..1e501c1 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/usemig1.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/vgpu-addon.png b/docs/zh/docs/end-user/kpanda/gpu/images/vgpu-addon.png new file mode 100644 index 0000000..3241a80 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/vgpu-addon.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/vgpu-sc.png b/docs/zh/docs/end-user/kpanda/gpu/images/vgpu-sc.png new file mode 100644 index 0000000..a9ef974 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/vgpu-sc.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/vnpu1.png b/docs/zh/docs/end-user/kpanda/gpu/images/vnpu1.png new file mode 100644 index 0000000..d395dda Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/vnpu1.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/vnpu2.png b/docs/zh/docs/end-user/kpanda/gpu/images/vnpu2.png new file mode 100644 index 0000000..5fd547c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/vnpu2.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/volcano-binpack1.png b/docs/zh/docs/end-user/kpanda/gpu/images/volcano-binpack1.png new file mode 100644 index 0000000..461c38d Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/volcano-binpack1.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/images/volcano-binpacknode.png b/docs/zh/docs/end-user/kpanda/gpu/images/volcano-binpacknode.png new file mode 100644 index 0000000..17bbcff Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/gpu/images/volcano-binpacknode.png differ diff --git a/docs/zh/docs/end-user/kpanda/gpu/index.md b/docs/zh/docs/end-user/kpanda/gpu/index.md new file mode 100644 index 0000000..f1746ea --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/index.md @@ -0,0 +1,40 @@ +--- +hide: + - toc +--- + +# GPU 管理概述 + +本文介绍 算丰 AI 算力容器管理平台对 GPU为代表的异构资源统一运维管理能力。 + +## 背景 + +随着 AI 应用、大模型、人工智能、自动驾驶等新兴技术的快速发展,企业面临着越来越多的计算密集型任务和数据处理需求。 +以 CPU 为代表的传统计算架构已无法满足企业日益增长的计算需求。此时,以 GPU 为代表的异构计算因在处理大规模数据、进行复杂计算和实时图形渲染方面具有独特的优势被广泛应用。 + +与此同时,由于缺乏异构资源调度管理等方面的经验和专业的解决方案,导致了 GPU 设备的资源利用率极低,给企业带来了高昂的 AI 生产成本。 +如何降本增效,提高 GPU 等异构资源的利用效率,成为了当前众多企业亟需跨越的一道难题。 + +## GPU 能力介绍 + +算丰 AI 算力容器管理平台支持对 GPU、NPU 等异构资源进行统一调度和运维管理,充分释放 GPU 资源算力,加速企业 AI 等新兴应用发展。GPU 管理能力如下: + +- 支持统一纳管 NVIDIA、华为昇腾、天数等国内外厂商的异构计算资源。 +- 支持同一集群多卡异构调度,并支持集群 GPU 卡自动识别。 +- 支持 NVIDIA GPU、vGPU、MIG 等 GPU 原生管理方案,并提供云原生能力。 +- 支持单块物理卡切分给不同的租户使用,并支持对租户和容器使用 GPU 资源按照算力、显存进行 GPU 资源配额。 +- 支持集群、节点、应用等多维度 GPU 资源监控,帮助运维人员管理 GPU 资源。 +- 兼容 TensorFlow、pytorch 等多种训练框架。 + +## GPU Operator 介绍 + +同普通计算机硬件一样,NVIDIA GPU 卡作为物理硬件,必须安装 NVIDIA GPU 驱动后才能使用。 +为了降低用户在 kuberneets 上使用 GPU 的成本,NVIDIA 官方提供了 NVIDIA GPU Operator 组件来管理使用 NVIDIA GPU 所依赖的各种组件。 +这些组件包括 NVIDIA 驱动程序(用于启用 CUDA)、NVIDIA 容器运行时、GPU 节点标记、基于 DCGM 的监控等。 +理论上来说用户只需要将 GPU 卡插在已经被 kubernetes 所纳管的计算设备上,然后通过 GPU Operator 就能使用 NVIDIA GPU 的所有能力了。 +了解更多 NVIDIA GPU Operator 相关信息,请参考 [NVIDIA 官方文档](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/index.html)。 +如何部署请参考 [GPU Operator 离线安装](nvidia/install_nvidia_driver_of_operator.md) + +NVIDIA GPU Operator 架构图: + +![NVIDIA GPU Operator 架构图](../../../images/nvidia-gpu-operator-image.jpg) diff --git a/docs/zh/docs/end-user/kpanda/gpu/metax/usemetax.md b/docs/zh/docs/end-user/kpanda/gpu/metax/usemetax.md new file mode 100644 index 0000000..5a3d831 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/metax/usemetax.md @@ -0,0 +1,88 @@ +# 沐曦 GPU 组件安装与使用 + +本章节提供沐曦 gpu-extensions、gpu-operator 等组件的安装指导和沐曦 GPU 整卡和 vGPU 两种模式的使用方法。 + +## 前提条件 + +1. 已在[沐曦软件中心](https://sw-download.metax-tech.com/software-list)下载并安装所需的 tar 包, + 本文以 metax-gpu-k8s-package.0.7.10.tar.gz 为例。 +1. 准备 Kubernetes 基础环境 + +## 组件介绍 + +Metax 提供了两个 helm-chart 包,一个是 metax-extensions,一个是 gpu-operator,根据使用场景可选择安装不同的组件。 + +1. Metax-extensions:包含 gpu-device 和 gpu-label 两个组件。在使用 Metax-extensions 方案时,用户的应用容器镜像需要基于 MXMACA® 基础镜像构建。且 Metax-extensions 仅适用于 GPU 整卡使用场景。 +2. gpu-operator:包含 gpu-device、gpu-label、driver-manager、container-runtime、operator-controller 这些组件。 + 使用 gpu-operator 方案时,用户可选择制作不包含 MXMACA® SDK 的应用容器镜像。gpu-operator 适用于 GPU 整卡和 vGPU 场景。 + +## 操作步骤 + +1. 从 `/home/metax/metax-docs/k8s/metax-gpu-k8s-package.0.7.10.tar.gz` 文件中解压出 + + - deploy-gpu-extensions.yaml # 部署yaml + - metax-gpu-extensions-0.7.10.tgz、metax-operator-0.7.10.tgz # helm chart文件 + - metax-k8s-images.0.7.10.run # 离线镜像 + +2. 查看系统是否安装驱动 + + ```bash + $ lsmod | grep metax + metax 1605632 0 + ttm 86016 3 drm_vram_helper,metax,drm_ttm_helper + drm 618496 7 drm_kms_helper,drm_vram_helper,ast,metax,drm_ttm_helper,ttm + ``` + + - 如没有内容显示,就表示没有安装过软件包。如有内容显示,则表示安装过软件包。 + - 使用 metax-opeartor 时,不推荐在工作节点预安装 MXMACA 内核态驱动,若已安装也无需卸载。 + +3. 安装驱动 + +### gpu-extensions + +1. 推送镜像 + + ```bash + tar -xf metax-gpu-k8s-package.0.7.10.tar.gz + ./metax-k8s-images.0.7.10.run push {registry}/metax + ``` + +2. 推送 Helm Chart + + ```bash + helm plugin install https://github.com/chartmuseum/helm-push + helm repo add --username rootuser --password rootpass123 metax http://172.16.16.5:8081 + helm cm-push metax-operator-0.7.10.tgz metax + helm cm-push metax-gpu-extensions-0.7.10.tgz metax + ``` + +3. 在算丰 AI 算力平台上安装 metax-gpu-extensions + + 部署成功之后,可以在节点上查看到资源。 + + ![查看资源](../images/metax-node.png) + + +4. 修改成功之后就可以在节点上看到带有 `Metax GPU` 的标签 + + ![metax节点标签](../images/metax-node1.png) + +### gpu-operator + +安装 `gpu-opeartor` 时的已知问题: + +1. `metax-operator`、`gpu-label`、`gpu-device` 、`container-runtime` 这几个组件镜像要带有 `amd64` 后缀。 + +2. `metax-maca` 组件的镜像不在 `metax-k8s-images.0.7.13.run` 包里面,需要单独下载 `maca-mxc500-2.23.0.23-ubuntu20.04-x86_64.tar.xz` 这类镜像,`load` 之后重新修改 `metax-maca` 组件的镜像。 + +3. `metax-driver` 组件的镜像需要从 `https://pub-docstore.metax-tech.com:7001` 这个网站下载 `k8s-driver-image.2.23.0.25.run` 文件,然后执行 `k8s-driver-image.2.23.0.25.run push {registry}/metax` 命令把镜像推送到镜像仓库。推送之后修改 `metax-driver` 组件的镜像地址。 + +## 使用 GPU + +安装后可在工作负载中[使用沐曦 GPU](../../workloads/create-deployment.md#_5)。注意启用 GPU 后,需选择GPU类型为 Metax GPU + +![使用 GPU](../images/metax-use.png) + +进入容器,执行 mx-smi 可查看 GPU 的使用情况. + +![使用 GPU](../images/metax-use2.png) diff --git a/docs/zh/docs/end-user/kpanda/gpu/mlu/use-mlu.md b/docs/zh/docs/end-user/kpanda/gpu/mlu/use-mlu.md new file mode 100644 index 0000000..fbf49ed --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/mlu/use-mlu.md @@ -0,0 +1,67 @@ +# 使用寒武纪 GPU + +本文介绍如何在算丰 AI 算力平台中使用寒武纪 GPU。 + +## 前置条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 当前集群已安装寒武纪固件、驱动以及DevicePlugin组件,安装详情请参考官方文档: + - [驱动固件安装](https://www.cambricon.com/docs/sdk_1.15.0/driver_5.10.22/user_guide/index.html) + - [DevicePlugin 安装](https://github.com/Cambricon/cambricon-k8s-device-plugin/blob/master/device-plugin/README.md) + +在安装 DevicePlugin 时请关闭 **--enable-device-type** 参数,否则算丰 AI 算力平台将无法正确识别寒武纪 GPU。 + +## 寒武纪 GPU 模式介绍 + +寒武纪 GPU 有以下几种模式: + +- 整卡模式:将寒武纪GPU以整卡的方式注册到集群当中进行使用。 +- Share 模式:可以将一张寒武纪GPU共享给多个 Pod 进行使用,可以通过 virtualization-num 参数进行设置可共享容器的数量。 +- Dynamic smlu 模式:进一步对资源进行了细化,可以控制分配给容器的显存、算力的大小。 +- Mim 模式:可以将寒武纪 GPU 按照固定的规格切分成多张 GPU 进行使用。 + +## 算丰 AI 算力平台使用寒武纪 + +这里以 Dynamic smlu 模式为例: + +1. 在正确安装 DevicePlugin 等组件后,点击对应 **集群** -> **集群运维**-> **集群设置** -> **Addon 插件** ,查看是否已自动启用并自动检测对应 GPU 类型。 + + ![mlu类型](../images/mlu1.PNG) + +1. 点击节点管理页面,查看节点是否已经正确识别到对应的GPU类型。 + + ![节点列表](../images/mlu2.png) + +1. 部署工作负载。点击对应 **集群** -> **工作负载** ,通过镜像方式部署工作负载,选择类型(MLU VGPU)之后,需要配置 App 使用的 GPU 资源: + + - GPU 算力(cambricon.com/mlu.smlu.vcore):表示当前 Pod 需要使用核心的百分比数量。 + - GPU 显存(cambricon.com/mlu.smlu.vmemory):表示当前Pod需要使用显存的大小,单位是MB。 + + ![使用mlu](../images/mlu3.png) + +## 使用 YAML 配置 + +参考 YAML 文件如下: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: pod1 +spec: + restartPolicy: OnFailure + containers: + - image: ubuntu:16.04 + name: pod1-ctr + command: ["sleep"] + args: ["100000"] + resources: + limits: + cambricon.com/mlu: "1" # use this when device type is not enabled, else delete this line. + #cambricon.com/mlu: "1" #uncomment to use when device type is enabled + #cambricon.com/mlu.share: "1" #uncomment to use device with env-share mode + #cambricon.com/mlu.mim-2m.8gb: "1" #uncomment to use device with mim mode + #cambricon.com/mlu.smlu.vcore: "100" #uncomment to use device with mim mode + #cambricon.com/mlu.smlu.vmemory: "1024" #uncomment to use device with mim mode +``` diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/full_gpu_userguide.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/full_gpu_userguide.md new file mode 100644 index 0000000..e370255 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/full_gpu_userguide.md @@ -0,0 +1,67 @@ +# 应用使用 GPU 整卡 + +本节介绍如何在算丰 AI 算力平台将整个 NVIDIA GPU 卡分配给单个应用。 + +## 前提条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 当前集群已离线安装 GPU Operator 并已启用 NVIDIA DevicePlugin ,可参考 [GPU Operator 离线安装](install_nvidia_driver_of_operator.md)。 +- 当前集群内 GPU 卡未进行任何虚拟化操作或被其它应用占用。 + +## 操作步骤 + +### 使用 UI 界面配置 + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Nvidia GPU__ 。 + + ![集群设置](../../../../images/cluster-setting-gpu.jpg) + +2. 部署工作负载,点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Nvidia GPU)之后,需要配置应用使用的物理卡数量: + + **物理卡数量(nvidia.com/gpu)** :表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且 **小于等于** 宿主机上的卡数量。 + + ![集群设置](../../../../images/workload_gpu_userguide.jpg) + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 + +### 使用 YAML 配置 + +创建工作负载申请 GPU 资源,在资源申请和限制配置中增加 __nvidia.com/gpu: 1__ 参数配置应用使用物理卡的数量。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-gpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-gpu-demo + template: + metadata: + labels: + app: full-gpu-demo + spec: + containers: + - image: chrstnhntschl/gpu_burn + name: container-0 + resources: + requests: + cpu: 250m + memory: 512Mi + nvidia.com/gpu: 1 # 申请 GPU 的数量 + limits: + cpu: 250m + memory: 512Mi + nvidia.com/gpu: 1 # GPU 数量的使用上限 + imagePullSecrets: + - name: default-secret +``` + +!!! note + + 使用 __nvidia.com/gpu__ 参数指定 GPU 数量时,requests 和 limits 值需要保持一致。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md new file mode 100644 index 0000000..4af9f2f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md @@ -0,0 +1,65 @@ +# GPU 告警规则 + +本文介绍如何在算丰 AI 算力平台设置 GPU 相关的告警规则。 + +## 前置条件 + +- 集群节点上已正确安装 GPU 设备 +- 集群中已正确安装 [gpu-operator 组件](../install_nvidia_driver_of_operator.md) +- 如果用到了 vGPU 还需要在集群中安装 [Nvidia-vgpu 组件](../vgpu/vgpu_addon.md),并且开启 servicemonitor +- 集群正确安装了 insight-agent 组件 + +## 告警常用 GPU 指标 + +本节介绍 GPU 告警常用的指标,分为两个部分: + +- GPU 卡纬度的指标,主要反应单个 GPU 设备的运行状态。 +- 应用纬度的指标,主要反应 Pod 在 GPU 上的运行状态。 + +### GPU 卡指标 + +| 指标名称 | 指标单位 | 说明 | +| --- | --- | --- | +| DCGM_FI_DEV_GPU_UTIL | % | GPU 利用率 | +| DCGM_FI_DEV_MEM_COPY_UTIL | % | 显存利用率 | +| DCGM_FI_DEV_ENC_UTIL | % | 编码器利用率 | +| DCGM_FI_DEV_DEC_UTIL | % | 解码器利用率 | +| DCGM_FI_DEV_FB_FREE | MB | 表示显存剩余量 | +| DCGM_FI_DEV_FB_USED | MB | 表示显存使用量 | +| DCGM_FI_DEV_GPU_TEMP | 摄氏度 | 表示当前 GPU 的温度度数 | +| DCGM_FI_DEV_POWER_USAGE | W | 设备电源使用情况 | +| DCGM_FI_DEV_XID_ERRORS | - | 表示一段时间内,最后发生的 XID 错误号。XID 提供 GPU 硬件、NVIDIA 软件或应用中的错误类型、错误位置、错误代码等信息,更多 [XID 信息](./gpu-metrics.md#_2) | + +### 应用维度的指标 + +| 指标名称 | 指标单位 | 说明 | +| --- | --- | --- | +| kpanda_gpu_pod_utilization | % | 表示 Pod 对 GPU 的使用率 | +| kpanda_gpu_mem_pod_usage | MB | 表示 Pod 对 GPU 显存的使用量 | +| kpanda_gpu_mem_pod_utilization | % | 表示 Pod 对 GPU 显存的使用率 | + +## 设置告警规则 + +这里会介绍如何设置 GPU 告警规则,使用 GPU 卡利用率指标作为案例,请用户根据实际的业务场景选择指标以及编写 promql。 + +目标:当GPU卡利用率在五秒钟内一直保持 80% 的利用率时发出告警 + +1. 在可观测页面,点击 __告警__ -> __告警策略__ -> __创建告警策略__ + + ![创建告警规则](../../images/create-gpu-alarm.png) + +2. 填写基本信息 + + ![填写告警规则](../../images/gpu-alarm-details.png) + +3. 添加规则 + + ![填写告警规则2](../../images/gpu-alarm-details2.png) + +4. 选择通知方式 + + ![通知方式](../../images/gpu-alarm-message.png) + +5. 设置完成后,当一个 GPU 在 5s 内一直保持 80% 的利用率,会收到如下的告警信息。 + + ![告警信息](../../images/gpu-alarm-message2.png) diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md new file mode 100644 index 0000000..0ee5fd1 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md @@ -0,0 +1,96 @@ +# GPU 监控指标 + +本页列出一些常用的 GPU 监控指标。 + +## 集群维度 + +| 指标名称 | 描述 | +| ------- | ------ | +| GPU 卡数 | 集群下所有的 GPU 卡数量 | +| GPU 平均使用率 | 集群下所有 GPU 卡的平均算力使用率 | +| GPU 平均显存使用率 | 集群下所有 GPU 卡的平均显存使用率 | +| GPU 卡功率 | 集群下所有 GPU 卡的功率 | +| GPU 卡温度 | 集群下所有 GPU 卡的温度 | +| GPU 算力使用率细节 | 24 小时内,集群下所有 GPU 卡的使用率细节(包含 max、avg、current) | +| GPU 显存使用量细节 | 24 小时内,集群下所有 GPU 卡的显存使用量细节(包含 min、max、avg、current) | +| GPU 显存带宽使用率 | 表示内存带宽利用率。以 Nvidia GPU V100 为例,其最大内存带宽为 900 GB/sec,如果当前的内存带宽为 450 GB/sec,则内存带宽利用率为 50% | + +## 节点维度 + +| 指标名称 | 描述 | +| ------- | --- | +| GPU 模式 | 节点上 GPU 卡的使用模式,包含整卡模式、MIG 模式、vGPU 模式 | +| GPU 物理卡数 | 节点上所有的 GPU 卡数量 | +| GPU 虚拟卡数 | 节点上已经被创建出来的 vGPU 设备数量 | +| GPU MIG 实例数 | 节点上已经被创建出来的 MIG 实例数 | +| GPU 显存分配率 | 节点上所有 GPU 卡的显存分配率 | +| GPU 算力平均使用率 | 节点上所有 GPU 卡的算力平均使用率 | +| GPU 显存平均使用率 | 节点上所有 GPU 卡的平均显存使用率 | +| GPU 驱动版本 | 节点上 GPU 卡驱动的版本信息 | +| GPU 算力使用率细节 | 24 小时内,节点上每张 GPU 卡的算力使用率细节(包含 max、avg、current) | +| GPU 显存使用量 | 24 小时内,节点上每张 GPU 卡的显存使用量细节(包含 min、max、avg、current) | + +**根据 XID 状态排查 GPU 相关问题** + +XID 消息是 NVIDIA 驱动程序向操作系统的内核日志或事件日志打印的错误报告。XID 消息用于标识 GPU 错误事件, +提供 GPU 硬件、NVIDIA 软件或应用中的错误类型、错误位置、错误代码等信息。 +如检查项 GPU 节点上的 XID 异常为空,表明无 XID 消息;如有,您可按照下表自助排查并解决问题, +或查看[更多 XID 消息](https://docs.nvidia.com/deploy/xid-errors/index.html#topic_4)。 + +| XID | 消息 | 说明 | +| --- | --- | --- | +| 13 | Graphics Engine Exception. | 通常是数组越界、指令错误,小概率是硬件问题。 | +| 31 | GPU memory page fault. | 通常是应用程序的非法地址访问,极小概率是驱动或者硬件问题。 | +| 32 | Invalid or corrupted push buffer stream. | 事件由 PCIE 总线上管理 NVIDIA 驱动和 GPU 之间通信的 DMA 控制器上报,通常是 PCI 质量问题导致,而非您的程序产生。 | +| 38 | Driver firmware error. | 通常是驱动固件错误而非硬件问题。 | +| 43 | GPU stopped processing. | 通常是您应用自身错误,而非硬件问题。 | +| 45 | Preemptive cleanup, due to previous errors -- Most likely to see when running multiple cuda applications and hitting a DBE. | 通常是您手动退出或者其他故障(硬件、资源限制等)导致的 GPU 应用退出,XID 45 只提供一个结果,具体原因通常需要进一步分析日志。 | +| 48 | Double Bit ECC Error (DBE). | 当 GPU 发生不可纠正的错误时,会上报此事件,该错误也会同时反馈给您的应用程序。通常需要重置 GPU 或重启节点来清除这个错误。 | +| 61 | Internal micro-controller breakpoint/warning. | GPU 内部引擎停止工作,您的业务已经受到影响。 | +| 62 | Internal micro-controller halt. | 与 XID 61 的触发场景类似。 | +| 63 | ECC page retirement or row remapping recording event. | 当应用程序遭遇到 GPU 显存硬件错误时,NVIDIA 自纠错机制会将错误的内存区域 retire 或者 remap,retirement 和 remapped 信息需记录到 infoROM 中才能永久生效。Volt 架构:成功记录 ECC page retirement 事件到 infoROM。Ampere 架构:成功记录 row remapping 事件到 infoROM。 | +| 64 | ECC page retirement or row remapper recording failure. | 与 XID 63 的触发场景类似。但 XID 63 代表 retirement 和 remapped 信息成功记录到了 infoROM,XID 64 代表该记录操作失败。 | +| 68 | NVDEC0 Exception. | 通常是硬件或驱动问题。 | +| 74 | NVLINK Error. | NVLink 硬件错误产生的 XID,表明 GPU 已经出现严重硬件故障,需要下线维修。 | +| 79 | GPU has fallen off the bus. | GPU 硬件检测到掉卡,总线上无法检测该 GPU,表明该 GPU 已经出现严重硬件故障,需要下线维修。 | +| 92 | High single-bit ECC error rate. | 硬件或驱动故障。 | +| 94 | Contained ECC error. | 当应用程序遭遇到 GPU 不可纠正的显存 ECC 错误时,NVIDIA 错误抑制机制会尝试将错误抑制在发生硬件故障的应用程序,避免该错误影响 GPU 节点上运行的其他应用程序。当抑制机制成功抑制错误时,会产生该事件,仅出现不可纠正 ECC 错误的应用程序受到影响。 | +| 95 | Uncontained ECC error. | 与 XID 94 的触发场景类似。但 XID 94 代表抑制成功,而 XID 95 代表抑制失败,表明运行在该 GPU 上的所有应用程序都已受到影响。 | + +## Pod 维度 + +| 分类 | 指标名称 | 描述 | +| --- | ------- | ---- | +| 应用概览 GPU 卡 - 算力 & 显存 | Pod GPU 算力使用率 | 当前 Pod 所使用到的 GPU 卡的算力使用率 | +| | Pod GPU 显存使用率 | 当前 Pod 所使用到的 GPU 卡的显存使用率 | +| | Pod 显存使用量 | 当前 Pod 所使用到的 GPU 卡的显存使用量 | +| | 显存分配量 | 当前 Pod 所使用到的 GPU 卡的显存分配量 | +| | Pod GPU 显存复制使用率 | 当前 Pod 所使用到的 GPU 卡的显存显存复制比率 | +| GPU 卡 - 引擎概览 | GPU 图形引擎活动百分比 | 表示在一个监控周期内,Graphics 或 Compute 引擎处于 Active 的时间占总的时间的比例 | +| | GPU 内存带宽利用率 | 表示内存带宽利用率(Memory BW Utilization)将数据发送到设备内存或从设备内存接收数据的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。较高的值表示设备内存的利用率较高。
该值为 1(100%)表示在整个时间间隔内的每个周期执行一条 DRAM 指令(实际上,峰值约为 0.8 (80%) 是可实现的最大值)。
假设该值为 0.2(20%),表示 20% 的周期在时间间隔内读取或写入设备内存。 | +| | Tensor 核心引擎使用率 | 表示在一个监控周期内,Tensor Core 管道(Pipe)处于 Active 时间占总时间的比例 | +| | FP16 引擎使用率 | 表示在一个监控周期内,FP16 管道处于 Active 的时间占总的时间的比例 | +| | FP32 引擎使用率 | 表示在一个监控周期内,FP32 管道处于 Active 的时间占总的时间的比例 | +| | FP64 引擎使用率 | 表示在一个监控周期内,FP64 管道处于 Active 的时间占总的时间的比例 | +| | GPU 解码使用率 | GPU 卡解码引擎比率 | +| | GPU 编码使用率 | GPU 卡编码引擎比率 | +| GPU 卡 - 温度 & 功耗 | GPU 卡温度 | 集群下所有 GPU 卡的温度 | +| | GPU 卡功率 | 集群下所有 GPU 卡的功率 | +| | GPU 卡 - 总耗能 | GPU 卡总共消耗的能量 | +| GPU 卡 - Clock | GPU 卡内存频率 | 内存频率 | +| | GPU 卡应用SM 时钟频率 | 应用的 SM 时钟频率 | +| | GPU 卡应用内存频率 | 应用内存频率 | +| | GPU 卡视频引擎频率 | 视频引擎频率 | +| | GPU 卡降频原因 | 降频原因 | +| GPU 卡 - 其他细节 | 图形引擎活动 | 图形或计算引擎的任何部分处于活动状态的时间比例。如果图形/计算上下文已绑定且图形/计算管道繁忙,则图形引擎处于活动状态。该值表示时间间隔内的平均值,而不是瞬时值。 | +| | SM活动 | 多处理器上至少一个 Warp 处于活动状态的时间比例,所有多处理器的平均值。请注意,“活动”并不一定意味着 Warp 正在积极计算。例如,等待内存请求的 Warp 被视为活动状态。该值表示时间间隔内的平均值,而不是瞬时值。0.8 或更大的值是有效使用 GPU 的必要条件,但还不够。小于 0.5 的值可能表示 GPU 使用效率低下。给出一个简化的 GPU 架构视图,如果 GPU 有 N 个 SM,则使用 N 个块并在整个时间间隔内运行的内核将对应于活动 1(100%)。使用 N/5 个块并在整个时间间隔内运行的内核将对应于活动 0.2(20%)。使用 N 个块并运行五分之一时间间隔的内核,如果 SM 处于空闲状态,则活动也将为 0.2(20%)。该值与每个块的线程数无关(参见DCGM_FI_PROF_SM_OCCUPANCY)。 | +| | SM 入住率 | 多处理器上驻留 Warp 的比例,相对于多处理器上支持的最大并发 Warp 数。该值表示时间间隔内的平均值,而不是瞬时值。占用率越高并不一定表示 GPU 使用率越高。对于 GPU 内存带宽受限的工作负载(参见DCGM_FI_PROF_DRAM_ACTIVE),占用率越高表明 GPU 使用率越高。但是,如果工作负载是计算受限的(即不受 GPU 内存带宽或延迟限制),则占用率越高并不一定与 GPU 使用率越高相关。计算占用率并不简单,它取决于 GPU 属性、每个块的线程数、每个线程的寄存器以及每个块的共享内存等因素。使用[CUDA 占用率计算器](https://docs.nvidia.com/cuda/cuda-occupancy-calculator/index.html) 探索各种占用率场景。 | +| | 张量活动 | 张量 (HMMA / IMMA) 管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,张量核心的利用率越高。活动 1 (100%) 相当于在整个时间间隔内每隔一个周期发出一个张量指令。活动 0.2 (20%) 可能表示 20% 的 SM 在整个时间段内的利用率为 100%,100% 的 SM 在整个时间段内的利用率为 20%,100% 的 SM 在 20% 的时间段内的利用率为 100%,或者介于两者之间的任何组合(请参阅DCGM_FI_PROF_SM_ACTIVE以帮助消除这些可能性的歧义)。| +| | FP64 引擎活动 |FP64(双精度)管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,FP64 核心的利用率越高。活动量 1(100%)相当于整个时间间隔内 Volta 上[每四个周期的每个 SM](https://docs.nvidia.com/cuda/volta-tuning-guide/index.html#sm-scheduling)上执行一条 FP64 指令 。活动量 0.2(20%)可能表示 20% 的 SM 在整个时间段内利用率为 100%,100% 的 SM 在整个时间段内利用率为 20%,100% 的 SM 在 20% 的时间段内利用率为 100%,或者介于两者之间的任何组合(请参阅 DCGM_FI_PROF_SM_ACTIVE 以帮助消除这些可能性的歧义)。 | +| | FP32 引擎活动 | FMA(FP32(单精度)和整数)管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,FP32 核心的利用率越高。活动量 1(100%)相当于整个时间间隔内每隔一个周期执行一次 FP32 指令。活动量 0.2(20%)可能表示 20% 的 SM 在整个时间段内利用率为 100%,100% 的 SM 在整个时间段内利用率为 20%,100% 的 SM 在 20% 的时间段内利用率为 100%,或者两者之间的任何组合(请参阅DCGM_FI_PROF_SM_ACTIVE以帮助消除这些可能性的歧义)。 | +| | FP16 引擎活动 | FP16(半精度)管道处于活动状态的周期分数。该值表示时间间隔内的平均值,而不是瞬时值。值越高,FP16 核心的利用率越高。活动量 1(100%)相当于整个时间间隔内每隔一个周期执行一次 FP16 指令。活动量 0.2(20%)可能表示 20% 的 SM 在整个时间段内利用率为 100%,100% 的 SM 在整个时间段内利用率为 20%,100% 的 SM 在 20% 的时间段内利用率为 100%,或者介于两者之间的任何组合(请参阅DCGM_FI_PROF_SM_ACTIVE以帮助消除这些可能性的歧义)。 | +| | 内存带宽利用率 | 向设备内存发送数据或从设备内存接收数据的周期比例。该值表示时间间隔内的平均值,而不是瞬时值。值越高,设备内存的利用率越高。活动率为 1 (100%) 相当于整个时间间隔内每个周期执行一条 DRAM 指令(实际上,峰值约为 0.8 (80%) 是可实现的最大值)。活动率为 0.2 (20%) 表示在时间间隔内有 20% 的周期正在读取或写入设备内存。 | +| | NVLink 带宽 | 通过 NVLink 传输/接收的数据速率(不包括协议标头),以每秒字节数为单位。该值表示一段时间内的平均值,而不是瞬时值。速率是一段时间内的平均值。例如,如果 1 秒内传输了 1 GB 的数据,则无论数据是以恒定速率还是突发速率传输,速率都是 1 GB/s。理论上,每个链路每个方向的最大 NVLink Gen2 带宽为 25 GB/s。 | +| | PCIe 带宽 | 通过 PCIe 总线传输/接收的数据速率,包括协议标头和数据有效负载,以字节/秒为单位。该值表示一段时间内的平均值,而不是瞬时值。该速率是一段时间内的平均值。例如,如果 1 秒内传输了 1 GB 的数据,则无论数据是以恒定速率还是突发速率传输,速率都是 1 GB/s。理论上最大 PCIe Gen3 带宽为每通道 985 MB/s。 | +| | PCIe 传输速率 | 节点 GPU 卡通过 PCIe 总线传输的数据速率 | +| | PCIe 接收速率 | 节点 GPU 卡通过 PCIe 总线接收的数据速率 | diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/index.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/index.md new file mode 100644 index 0000000..e2f495a --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/index.md @@ -0,0 +1,45 @@ +# NVIDIA GPU 卡使用模式 + +NVIDIA 作为业内知名的图形计算供应商,为算力的提升提供了诸多软硬件解决方案,其中 NVIDIA 在 GPU 的使用方式上提供了如下三种解决方案: + +#### 整卡(Full GPU) + +整卡是指将整个 NVIDIA GPU 分配给单个用户或应用程序。在这种配置下,应用可以完全占用 GPU 的所有资源, +并获得最大的计算性能。整卡适用于需要大量计算资源和内存的工作负载,如深度学习训练、科学计算等。 + +#### vGPU(Virtual GPU) + +vGPU 是一种虚拟化技术,允许将一个物理 GPU 划分为多个虚拟 GPU,每个虚拟 GPU 分配给不同的云主机或用户。 +vGPU 使多个用户可以共享同一台物理 GPU,并在各自的虚拟环境中独立使用 GPU 资源。 +每个虚拟 GPU 可以获得一定的计算能力和显存容量。vGPU 适用于虚拟化环境和云计算场景,可以提供更高的资源利用率和灵活性。 + +#### MIG(Multi-Instance GPU) + +MIG 是 NVIDIA Ampere 架构引入的一项功能,它允许将一个物理 GPU 划分为多个物理 GPU 实例,每个实例可以独立分配给不同的用户或工作负载。 +每个 MIG 实例具有自己的计算资源、显存和 PCIe 带宽,就像一个独立的虚拟 GPU。 +MIG 提供了更细粒度的 GPU 资源分配和管理,可以根据需求动态调整实例的数量和大小。 +MIG 适用于多租户环境、容器化应用程序和批处理作业等场景。 + +无论是在虚拟化环境中使用 vGPU,还是在物理 GPU 上使用 MIG,NVIDIA 为用户提供了更多的选择和优化 GPU 资源的方式。 +算丰 AI 算力容器管理平台全面兼容了上述 NVIDIA 的能力特性,用户只需通过简单的界面操作,就能够获得全部 NVIDIA GPU 的计算能力,从而提高资源利用率并降低成本。 + +- **Single 模式**,节点仅在其所有 GPU 上公开单一类型的 MIG 设备,节点上的所有 GPU 必须: + - 属于同一个型号(例如 A100-SXM-40GB),只有同一型号 GPU 的 MIG Profile 才是一样的 + - 启用 MIG 配置,需要重启机器才能生效 + - 为在所有产品中公开“完全相同”的 MIG 设备类型,创建相同的GI 和 CI +- **Mixed 模式**,节点在其所有 GPU 上公开混合 MIG 设备类型。请求特定的 MIG 设备类型需要设备类型提供的计算切片数量和内存总量。 + - 节点上的所有 GPU 必须:属于同一产品线(例如 A100-SXM-40GB) + - 每个 GPU 可启用或不启用 MIG,并且可以自由配置任何可用 MIG 设备类型的混合搭配。 + - 在节点上运行的 k8s-device-plugin 将: + - 使用传统的 __nvidia.com/gpu__ 资源类型公开任何不处于 MIG 模式的 GPU + - 使用遵循架构 __nvidia.com/mig-g.gb__ 的资源类型公开各个 MIG 设备 + +开启配置详情参考 [GPU Operator 离线安装](install_nvidia_driver_of_operator.md)。 + +## 如何使用 + +您可以参考以下链接,快速使用算丰 AI 算力平台关于 NVIDIA GPU 卡的管理能力。 + +- **[NVIDIA GPU 整卡使用](full_gpu_userguide.md)** +- **[NVIDIA vGPU 使用](vgpu/vgpu_user.md)** +- **[NVIDIA MIG 使用](mig/mig_usage.md)** diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md new file mode 100644 index 0000000..2f80028 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md @@ -0,0 +1,107 @@ +# GPU Operator 离线安装 + +算丰 AI 算力平台预置了 Ubuntu22.04、Ubuntu20.04、CentOS 7.9 这三个操作系统的 Driver 镜像,驱动版本是 535.104.12; +并且内置了各操作系统所需的 Toolkit 镜像,用户不再需要手动离线 Toolkit 镜像。 + +本文使用 AMD 架构的 CentOS 7.9(3.10.0-1160)进行演示。如需使用 Red Hat 8.4 部署, +请参考[向火种节点仓库上传 Red Hat GPU Opreator 离线镜像](./push_image_to_repo.md)和[构建 Red Hat 8.4 离线 yum 源](./upgrade_yum_source_redhat8_4.md)。 + +## 前提条件 + +- 待部署 gpu-operator 的集群节点内核版本必须完全一致。节点所在的发行版和 GPU 卡型号在 [GPU 支持矩阵](../gpu_matrix.md)的范围内。 +- 安装 gpu-operator 时选择 v23.9.0+2 及以上版本 + +## 操作步骤 + +参考如下步骤为集群安装 gpu-operator 插件。 + +1. 登录平台,进入 __容器管理__ -> __待安装 gpu-operator 的集群__ -> 进入集群详情。 + +2. 在 __Helm 模板__ 页面,选择 __全部仓库__ ,搜索 __gpu-operator__ 。 + +3. 选择 __gpu-operator__ ,点击 __安装__ 。 + +4. 参考下文参数配置,配置 __gpu-operator__ 安装参数,完成 __gpu-operator__ 的安装。 + +## 参数配置 + +- __systemOS__ :选择机器的操作系统,当前内置了 `Ubuntu 22.04`、`Ubuntu20.04`、`Centos7.9` 、`other` 四个选项,请正确的选择操作系统。 + +### 基本参数配置 + +- __名称__ :输入插件名称。 +- __命名空间__ :选择将插件安装的命名空间。 +- __版本__ :插件的版本,此处以 __v23.9.0+2__ 版本为例。 +- __失败删除__ :安装失败,则删除已经安装的关联资源。开启后,将默认同步开启 __就绪等待__ 。 +- __就绪等待__ :启用后,所有关联资源都处于就绪状态,才会标记应用安装成功。 +- __详情日志__ :开启后,将记录安装过程的详细日志。 + +### 高级参数配置 + +#### Operator 参数配置 + +- __InitContainer.image__ :配置 CUDA 镜像,推荐默认镜像: __nvidia/cuda__ +- __InitContainer.repository__ :CUDA 镜像所在的镜像仓库,默认为 __nvcr.m.daocloud.io__ 仓库 +- __InitContainer.version__ : CUDA 镜像的版本,请使用默认参数 + +#### Driver 参数配置 + +- __Driver.enable__ :配置是否在节点上部署 NVIDIA 驱动,默认开启,如果您在使用 GPU Operator 部署前,已经在节点上部署了 NVIDIA 驱动程序,请关闭。(若手动部署驱动程序需要关注 CUDA Toolkit 与 Toolkit Driver Version 的[适配关系](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#id5),通过 GPU operator 安装则无需关注)。 +- __Driver.usePrecompiled__ :启用预编译的GPU驱动 +- __Driver.image__ :配置 GPU 驱动镜像,推荐默认镜像: __nvidia/driver__ 。 +- __Driver.repository__ :GPU 驱动镜像所在的镜像仓库,默认为 nvidia 的 __nvcr.io__ 仓库。 +- __Driver.usePrecompiled__ :开启预编译模式安装驱动。 +- __Driver.version__ :GPU 驱动镜像的版本,离线部署请使用默认参数,仅在线安装时需配置。不同类型操作系统的 Driver 镜像的版本存在如下差异, + 详情可参考:[Nvidia GPU Driver 版本](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags)。 + 如下不同操作系统的 `Driver Version` 示例: + + !!! note + + 使用内置的操作系统版本无需修改镜像版本,其他操作系统版本请参考[向火种节点仓库上传镜像](./push_image_to_repo.md)。 + 注意版本号后无需填写 Ubuntu、CentOS、Red Hat 等操作系统名称,若官方镜像含有操作系统后缀,请手动移除。 + + - Red Hat 系统,例如 `525.105.17` + - Ubuntu 系统,例如 `535-5.15.0-1043-nvidia` + - CentOS 系统,例如 `525.147.05` + +- __Driver.RepoConfig.ConfigMapName__ :用来记录 GPU Operator 的离线 yum 源配置文件名称, + 当使用预置的离线包时,各类型的操作系统请参考如下的文档。 + + - [构建 CentOS 7.9 离线 yum 源](./upgrade_yum_source_centos7_9.md) + - [构建 Red Hat 8.4 离线 yum 源](./upgrade_yum_source_redhat8_4.md) + +#### Toolkit 配置参数 + +__Toolkit.enable__ :默认开启,该组件让 conatainerd/docker 支持运行需要 GPU 的容器。 + +#### MIG 配置参数 + +详细配置方式请参考[开启 MIG 功能](mig/create_mig.md) + +**MigManager.Config.name** :MIG 的切分配置文件名,用于定义 MIG 的(GI, CI)切分策略。 +默认为 __default-mig-parted-config__ 。自定义参数参考[开启 MIG 功能](mig/create_mig.md)。 + +### 下一步操作 + +完成上述相关参数配置和创建后: + +- 如果使用 **整卡模式**,[应用创建时可使用 GPU 资源](full_gpu_userguide.md) + +- 如果使用 **vGPU 模式** ,完成上述相关参数配置和创建后,下一步请完成 [vGPU Addon 安装](vgpu/vgpu_addon.md) + +- 如果使用 **MIG 模式**,并且需要给个别 GPU 节点按照某种切分规格进行使用, + 否则按照 `MigManager.Config` 中的 __default__ 值进行切分。 + + - **single** 模式请给对应节点打上如下 Label: + + ```sh + kubectl label nodes {node} nvidia.com/mig.config="all-1g.10gb" --overwrite + ``` + + - **mixed** 模式请给对应节点打上如下 Label: + + ```sh + kubectl label nodes {node} nvidia.com/mig.config="custom-config" --overwrite + ``` + +​ 切分后,应用可[使用 MIG GPU 资源](mig/mig_usage.md)。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/create_mig.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/create_mig.md new file mode 100644 index 0000000..07d0132 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/create_mig.md @@ -0,0 +1,124 @@ +# 开启 MIG 功能 + +本章节介绍如何开启 NVIDIA MIG 功能方式,NVIDIA 当前提供两种在 Kubernetes 节点上公开 MIG 设备的策略: + +- **Single 模式**,节点仅在其所有 GPU 上公开单一类型的 MIG 设备。 +- **Mixed 模式**,节点在其所有 GPU 上公开混合 MIG 设备类型。 + +详情参考 [NVIDIA GPU 卡使用模式](../index.md)。 + +## 前提条件 + +- 待安装 GPU 驱动节点系统要求请参考:[GPU 支持矩阵](../../gpu_matrix.md) +- 确认集群节点上具有对应型号的 GPU 卡([NVIDIA H100](https://www.nvidia.com/en-us/data-center/h100/)、 + [A100](https://www.nvidia.com/en-us/data-center/a100/) 和 + [A30](https://www.nvidia.com/en-us/data-center/products/a30-gpu/) Tensor Core GPU), + 详情参考 [GPU 支持矩阵](../../gpu_matrix.md)。 +- 节点上的所有 GPU 必须:属于同一产品线(例如 A100-SXM-40GB) + +## 安装 gpu-operator Addon + +### 参数配置 + +[安装 Operator](../install_nvidia_driver_of_operator.md) 时需要对应设置 MigManager Config 参数, +默认为 **default-mig-parted-config** ,同时也可以自定义切分策略配置文件: + +![single](../../images/gpu-operator-mig.png) + +### 自定义切分策略 + +```yaml + ## 自定义切分 GI 实例配置 + all-disabled: + - devices: all + mig-enabled: false + all-enabled: + - devices: all + mig-enabled: true + mig-devices: {} + all-1g.10gb: + - devices: all + mig-enabled: true + mig-devices: + 1g.5gb: 7 + all-1g.10gb.me: + - devices: all + mig-enabled: true + mig-devices: + 1g.10gb+me: 1 + all-1g.20gb: + - devices: all + mig-enabled: true + mig-devices: + 1g.20gb: 4 + all-2g.20gb: + - devices: all + mig-enabled: true + mig-devices: + 2g.20gb: 3 + all-3g.40gb: + - devices: all + mig-enabled: true + mig-devices: + 3g.40gb: 2 + all-4g.40gb: + - devices: all + mig-enabled: true + mig-devices: + 4g.40gb: 1 + all-7g.80gb: + - devices: all + mig-enabled: true + mig-devices: + 7g.80gb: 1 + all-balanced: + - device-filter: ["0x233110DE", "0x232210DE", "0x20B210DE", "0x20B510DE", "0x20F310DE", "0x20F510DE"] + devices: all + mig-enabled: true + mig-devices: + 1g.10gb: 2 + 2g.20gb: 1 + 3g.40gb: 1 + # 设置后会按照设置规格切分 CI 实例 + custom-config: + - devices: all + mig-enabled: true + mig-devices: + 3g.40gb: 2 +``` + +在上述的 **YAML** 中设置 **custom-config** ,设置后会按照规格切分 **CI** 实例。 + +```yaml +custom-config: + - devices: all + mig-enabled: true + mig-devices: + 1c.3g.40gb: 6 +``` + +设置完成后,在确认部署应用时即可[使用 GPU MIG 资源](mig_usage.md)。 + +## 切换节点 GPU 模式 + +!!! note + + 切换 GPU 模式或者修改切分规格后需要重启 nvidia-mig-manager。 + +当我们成功安装 gpu-operator 之后,节点默认是整卡模式,在节点管理页面会有标识,如下图所示: + +![mixed](../../images/node-gpu.png) + +点击节点列表右侧的 __┇__ ,选择 **GPU 模式切换** ,然后选择对应的 MIG 模式以及切分的策略,这里以 MIXED 模式为例: + +![mig](../../images/mig-select.png) + +这里一共有两个配置: + +1. MIg 策略:Mixed 以及 Single 。 +2. 切分策略:这里的策略需要与 **default-mig-parted-config** + (或者用户自定义的切分策略)配置文件中的 key 保持一致。 + +点击 **确定** 按钮后,等待约一分钟左右刷新页面,MIG 模式切换成: + +![切换 mig](../../images/node-mig.png) diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/index.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/index.md new file mode 100644 index 0000000..852b6b6 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/index.md @@ -0,0 +1,95 @@ +# NVIDIA 多实例 GPU(MIG) 概述 + +## MIG 场景 + +- **多租户云环境** + + MIG 允许云服务提供商将一块物理 GPU 划分为多个独立的 GPU 实例,每个实例可以独立分配给不同的租户。这样可以实现资源的隔离和独立性,满足多个租户对 GPU 计算能力的需求。 + +- **容器化应用程序** + + MIG 可以在容器化环境中实现更细粒度的 GPU 资源管理。通过将物理 GPU 划分为多个 MIG 实例,可以为每个容器分配独立的 GPU 计算资源,提供更好的性能隔离和资源利用。 + +- **批处理作业** + + 对于需要大规模并行计算的批处理作业,MIG 可以提供更高的计算性能和更大的显存容量。每个 MIG 实例可以利用物理 GPU 的一部分计算资源,从而加速大规模计算任务的处理。 + +- **AI/机器学习训练** + + MIG 可以在训练大规模深度学习模型时提供更大的计算能力和显存容量。将物理 GPU 划分为多个 MIG 实例,每个实例可以独立进行模型训练,提高训练效率和吞吐量。 + +总体而言,NVIDIA MIG 适用于需要更细粒度的GPU资源分配和管理的场景,可以实现资源的隔离、提高性能利用率,并且满足多个用户或应用程序对 GPU 计算能力的需求。 + +## MIG 概述 + +NVIDIA 多实例 GPU(Multi-Instance GPU,简称 MIG)是 NVIDIA 在 H100,A100,A30 系列 GPU 卡上推出的一项新特性, +旨在将一块物理 GPU 分割为多个 GPU 实例,以提供更细粒度的资源共享和隔离。MIG 最多可将一块 GPU 划分成七个 GPU 实例, +使得一个 物理 GPU 卡可为多个用户提供单独的 GPU 资源,以实现最佳 GPU 利用率。 + +这个功能使得多个应用程序或用户可以同时共享GPU资源,提高了计算资源的利用率,并增加了系统的可扩展性。 + +通过 MIG,每个 GPU 实例的处理器在整个内存系统中具有独立且隔离的路径——芯片上的交叉开关端口、L2 +高速缓存组、内存控制器和 DRAM 地址总线都唯一分配给单个实例。 + +这确保了单个用户的工作负载能够以可预测的吞吐量和延迟运行,并具有相同的二级缓存分配和 DRAM 带宽。 +MIG 可以划分可用的 GPU 计算资源(包括流多处理器或 SM 和 GPU 引擎,如复制引擎或解码器)进行分区, +以便为不同的客户端(如云主机、容器或进程)提供定义的服务质量(QoS)和故障隔离)。 +MIG 使多个 GPU 实例能够在单个物理 GPU 上并行运行。 + +MIG 允许多个 vGPU(以及云主机)在单个 GPU 实例上并行运行,同时保留 vGPU 提供的隔离保证。 +有关使用 vGPU 和 MIG 进行 GPU 分区的详细信息,请参阅 +[NVIDIA Multi-Instance GPU and NVIDIA Virtual Compute Server](https://www.nvidia.com/content/dam/en-zz/Solutions/design-visualization/solutions/resources/documents1/TB-10226-001_v01.pdf)。 + +## MIG 架构 + +如下是一个 MIG 的概述图,可以看出 MIG 将一张物理 GPU 卡虚拟化成了 7 个 GPU 实例,这些 GPU 实例能够可以被多个 User 使用。 + +![img](../../../../../images/mig_overview.png) + +## 重要概念 + +* __SM__ :流式多处理器(Streaming Multiprocessor),GPU 的核心计算单元,负责执行图形渲染和通用计算任务。 + 每个 SM 包含一组 CUDA 核心,以及共享内存、寄存器文件和其他资源,可以同时执行多个线程。 + 每个 MIG 实例都拥有一定数量的 SM 和其他相关资源,以及被划分出来的显存。 +* __GPU Memory Slice__ :GPU 内存切片,GPU 内存切片是 GPU 内存的最小部分,包括相应的内存控制器和缓存。 + GPU 内存切片大约是 GPU 内存资源总量的八分之一,包括容量和带宽。 +* __GPU SM Slice__ :GPU SM 切片是 GPU 上 SM 的最小计算单位。在 MIG 模式下配置时, + GPU SM 切片大约是 GPU 中可用 SMS 总数的七分之一。 +* __GPU Slice__ :GPU 切片是 GPU 中由单个 GPU 内存切片和单个 GPU SM 切片组合在一起的最小部分。 +* __GPU Instance__ :GPU 实例 (GI) 是 GPU 切片和 GPU 引擎(DMA、NVDEC 等)的组合。 + GPU 实例中的任何内容始终共享所有 GPU 内存切片和其他 GPU 引擎,但它的 SM 切片可以进一步细分为计算实例(CI)。 + GPU 实例提供内存 QoS。每个 GPU 切片都包含专用的 GPU 内存资源,这些资源会限制可用容量和带宽,并提供内存 QoS。 + 每个 GPU 内存切片获得总 GPU 内存资源的八分之一,每个 GPU SM 切片获得 SM 总数的七分之一。 +* __Compute Instance__ :GPU 实例的计算切片可以进一步细分为多个计算实例 (CI),其中 CI 共享父 + GI 的引擎和内存,但每个 CI 都有专用的 SM 资源。 + +### GPU 实例(GI) + +本节介绍如何在 GPU 上创建各种分区。将使用 A100-40GB 作为示例演示如何对单个 GPU 物理卡上进行分区。 + +GPU 的分区是使用内存切片进行的,因此可以认为 A100-40GB GPU 具有 8x5GB 内存切片和 7 个 GPU SM 切片,如下图所示,展示了 A100 上可用的内存切片。 + +![img](../../../../../images/mig_7m.png) + +如上所述,创建 GPU 实例 (GI) 需要将一定数量的内存切片与一定数量的计算切片相结合。 +在下图中,一个 5GB 内存切片与 1 个计算切片相结合,以创建 __1g.5gb__ GI 配置文件: + +![img](../../../../../images/mig_1g5gb.png) + +同样,4x5GB 内存切片可以与 4x1 计算切片结合使用以创建 __4g.20gb__ 的 GI 配置文件: + +![img](../../../../../images/mig_4g20gb.png) + +### 计算实例(CI) + +GPU 实例的计算切片(GI)可以进一步细分为多个计算实例(CI),其中 CI 共享父 GI 的引擎和内存, +但每个 CI 都有专用的 SM 资源。使用上面的相同 __4g.20gb__ 示例,可以创建一个 CI 以仅使用第一个计算切片的 __1c.4g.20gb__ 计算配置,如下图蓝色部分所示: + +![img](../../../../../images/mig_1c.4g.20gb.png) + +在这种情况下,可以通过选择任何计算切片来创建 4 个不同的 CI。还可以将两个计算切片组合在一起以创建 __2c.4g.20gb__ 的计算配置): + +![img](../../../../../images/mig2c.4g.20gb.png) + +除此之外,还可以组合 3 个计算切片以创建计算配置文件,或者可以组合所有 4 个计算切片以创建 __3c.4g.20gb__ 、 __4c.4g.20gb__ 计算配置文件。 +合并所有 4 个计算切片时,配置文件简称为 __4g.20gb__ 。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/mig_command.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/mig_command.md new file mode 100644 index 0000000..d42cda7 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/mig_command.md @@ -0,0 +1,25 @@ +# MIG 相关命令 + +GI 相关命名: + +| 子命令 | 说明 | +| --------------------------------------- | ----------------------------- | +| nvidia-smi mig -lgi | 查看创建 GI 实例列表 | +| nvidia-smi mig -dgi -gi {Instance ID} | 删除指定的 GI 实例 | +| nvidia-smi mig -lgip | 查看 GI 的 __profile__ | +| nvidia-smi mig -cgi {profile id} | 通过指定 profile 的 ID 创建 GI | + +CI 相关命令: + +| 子命令 | 说明 | +| ------------------------------------------------------- | ------------------------------------------------------------ | +| nvidia-smi mig -lcip { -gi {gi Instance ID}} | 查看 CI 的 __profile__ ,指定 __-gi__ 可以查看特定 GI 实例可以创建的 CI | +| nvidia-smi mig -lci | 查看创建的 CI 实例列表 | +| nvidia-smi mig -cci {profile id} -gi {gi instance id} | 指定的 GI 创建 CI 实例 | +| nvidia-smi mig -dci -ci {ci instance id} | 删除指定 CI 实例 | + +GI+CI 相关命令: + +| 子命令 | 说明 | +| ------------------------------------------------------------ | -------------------- | +| nvidia-smi mig -i 0 -cgi {gi profile id} -C {ci profile id} | 直接创建 GI + CI 实例 | diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/mig_usage.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/mig_usage.md new file mode 100644 index 0000000..4b00ee6 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/mig/mig_usage.md @@ -0,0 +1,100 @@ +# 使用 MIG GPU 资源 + +本节介绍应用如何使用 MIG GPU 资源。 + +## 前提条件 + +- 已经部署 算丰 AI 算力平台 容器管理平台,且平台运行正常。 +- 容器管理模块[已接入 Kubernetes 集群](../../../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../../../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已安装 [GPU Operator](../install_nvidia_driver_of_operator.md)。 +- 集群节点上具有[对应型号的 GPU 卡](../../gpu_matrix.md) + +## UI 界面使用 MIG GPU + +1. 确认集群是否已识别 GPU 卡类型 + + 进入 __集群详情__ -> __节点管理__ ,查看是否已正确识别为 MIG 模式。 + + ![gpu](../../images/node-mig.png) + +2. 通过镜像部署应用,可选择并使用 NVIDIA MIG 资源。 + + - MIG Single 模式示例(与整卡使用方式相同): + + !!! note + + MIG single 策略允许用户以与 GPU 整卡相同的方式(`nvidia.com/gpu`)请求和使用GPU资源,不同的是这些资源可以是 GPU 的一部分(MIG设备),而不是整个GPU。了解更多 [GPU MIG 模式设计](../../../../../images/edit) + + ![usemig](../../images/usemig.png) + + - MIG Mixed 模式示例: + + ![mig02](../../images/pod-mig.png) + +## YAML 配置使用 MIG + +**MIG Single 模式:** + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mig-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: mig-demo + template: + metadata: + creationTimestamp: null + labels: + app: mig-demo + spec: + containers: + - name: mig-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/gpu: 2 # (1)! + imagePullPolicy: Always + restartPolicy: Always +``` + +1. 申请 MIG GPU 的数量 + +**MIG Mixed 模式:** + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mig-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: mig-demo + template: + metadata: + creationTimestamp: null + labels: + app: mig-demo + spec: + containers: + - name: mig-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/mig-4g.20gb: 1 # (1)! + imagePullPolicy: Always + restartPolicy: Always +``` + +1. 通过 nvidia.com/mig-g.gb 的资源类型公开各个 MIG 设备 + +进入容器后可以查看只使用了一个 MIG 设备。 + +![mig03](../../../../../images/gpu_mig03.png) diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/push_image_to_repo.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/push_image_to_repo.md new file mode 100644 index 0000000..d406b14 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/push_image_to_repo.md @@ -0,0 +1,89 @@ +# 向火种节点仓库上传 Red Hat GPU Opreator 离线镜像 + +本文以 Red Hat 8.4 的 `nvcr.io/nvidia/driver:525.105.17-rhel8.4` 离线驱动镜像为例,介绍如何向火种节点仓库上传离线镜像。 + +## 前提条件 + +1. 火种节点及其组件状态运行正常。 +1. 准备一个能够访问互联网和火种节点的节点,且节点上已经完成 + Docker 的安装。 + +## 操作步骤 + +### 在联网节点获取离线镜像 + +以下操作在联网节点上进行。 + +1. 在联网机器上拉取 `nvcr.io/nvidia/driver:525.105.17-rhel8.4` 离线驱动镜像: + + ```bash + docker pull nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +2. 镜像拉取完成后,打包镜像为 `nvidia-driver.tar` 压缩包: + + ```bash + docker save nvcr.io/nvidia/driver:525.105.17-rhel8.4 > nvidia-driver.tar + ``` + +3. 拷贝 `nvidia-driver.tar` 镜像压缩包到火种节点: + + ```bash + scp nvidia-driver.tar user@ip:/root + ``` + + 例如: + + ```bash + scp nvidia-driver.tar root@10.6.175.10:/root + ``` + +### 推送镜像到火种节点仓库 + +以下操作在火种节点上进行。 + +1. 登录火种节点,将联网节点拷贝的镜像压缩包 `nvidia-driver.tar` 导入本地: + + ```bash + docker load -i nvidia-driver.tar + ``` + +2. 查看刚刚导入的镜像: + + ```bash + docker images -a |grep nvidia + ``` + + 预期输出: + + ```bash + nvcr.io/nvidia/driver e3ed7dee73e9 1 days ago 1.02GB + ``` + +3. 重新标记镜像,使其与远程 Registry 仓库中的目标仓库对应: + + ```bash + docker tag /: + ``` + + - `` 是上一步 nvidia 镜像的名称, + - `` 是火种节点上 Registry 服务的地址, + - `` 是您要推送到的仓库名称, + - `` 是您为镜像指定的标签。 + + 例如: + + ```bash + registry:docker tag nvcr.io/nvidia/driver 10.6.10.5/nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +4. 将镜像推送到火种节点镜像仓库: + + ```bash + docker push {ip}/nvcr.io/nvidia/driver:525.105.17-rhel8.4 + ``` + +## 接下来 + +参考[构建 Red Hat 8.4 离线 yum 源](./upgrade_yum_source_redhat8_4.md)和 +[GPU Operator 离线安装](./install_nvidia_driver_of_operator.md)来为集群部署 GPU Operator。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md new file mode 100644 index 0000000..d0504a2 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md @@ -0,0 +1,861 @@ +# RHEL 9.2 离线安装 gpu-operator 驱动 + +前提条件:已安装 gpu-operator v23.9.0+2 及更高版本 + +RHEL 9.2 驱动镜像不能直接安装,官方的驱动脚本存在一点问题,在官方修复之前,提供如下的步骤来实现离线安装驱动。 + +## 禁用nouveau驱动 + +在 RHEL 9.2 中存在 `nouveau` 非官方的 `Nvidia` 驱动,因此需要先禁用。 + +```shell +# 创建一个新的文件 +sudo vi /etc/modprobe.d/blacklist-nouveau.conf +# 添加以下两行内容: +blacklist nouveau +options nouveau modeset=0 +# 禁用Nouveau +sudo dracut --force +# 重启vm +sudo reboot +# 检查是否已经成功禁用 +lsmod | grep nouveau +``` + +## 自定义驱动镜像 + +先在本地创建 `nvidia-driver` 文件: + +

+点击查看完整的 nvidia-driver 文件内容 + +```shell +#! /bin/bash -x +# Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + +set -eu + +RUN_DIR=/run/nvidia +PID_FILE=${RUN_DIR}/${0##*/}.pid +DRIVER_VERSION=${DRIVER_VERSION:?"Missing DRIVER_VERSION env"} +KERNEL_UPDATE_HOOK=/run/kernel/postinst.d/update-nvidia-driver +NUM_VGPU_DEVICES=0 +NVIDIA_MODULE_PARAMS=() +NVIDIA_UVM_MODULE_PARAMS=() +NVIDIA_MODESET_MODULE_PARAMS=() +NVIDIA_PEERMEM_MODULE_PARAMS=() +TARGETARCH=${TARGETARCH:?"Missing TARGETARCH env"} +USE_HOST_MOFED="${USE_HOST_MOFED:-false}" +DNF_RELEASEVER=${DNF_RELEASEVER:-""} +RHEL_VERSION=${RHEL_VERSION:-""} +RHEL_MAJOR_VERSION=9 + +OPEN_KERNEL_MODULES_ENABLED=${OPEN_KERNEL_MODULES_ENABLED:-false} +[[ "${OPEN_KERNEL_MODULES_ENABLED}" == "true" ]] && KERNEL_TYPE=kernel-open || KERNEL_TYPE=kernel + +DRIVER_ARCH=${TARGETARCH/amd64/x86_64} && DRIVER_ARCH=${DRIVER_ARCH/arm64/aarch64} +echo "DRIVER_ARCH is $DRIVER_ARCH" + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source $SCRIPT_DIR/common.sh + +_update_package_cache() { + if [ "${PACKAGE_TAG:-}" != "builtin" ]; then + echo "Updating the package cache..." + if ! yum -q makecache; then + echo "FATAL: failed to reach RHEL package repositories. "\ + "Ensure that the cluster can access the proper networks." + exit 1 + fi + fi +} + +_cleanup_package_cache() { + if [ "${PACKAGE_TAG:-}" != "builtin" ]; then + echo "Cleaning up the package cache..." + rm -rf /var/cache/yum/* + fi +} + +_get_rhel_version_from_kernel() { + local rhel_version_underscore rhel_version_arr + rhel_version_underscore=$(echo "${KERNEL_VERSION}" | sed 's/.*el\([0-9]\+_[0-9]\+\).*/\1/g') + # For e.g. :- from the kernel version 4.18.0-513.9.1.el8_9, we expect to extract the string "8_9" + if [[ ! ${rhel_version_underscore} =~ ^[0-9]+_[0-9]+$ ]]; then + echo "Unable to resolve RHEL version from kernel version" >&2 + return 1 + fi + IFS='_' read -r -a rhel_version_arr <<< "$rhel_version_underscore" + if [[ ${#rhel_version_arr[@]} -ne 2 ]]; then + echo "Unable to resolve RHEL version from kernel version" >&2 + return 1 + fi + RHEL_VERSION="${rhel_version_arr[0]}.${rhel_version_arr[1]}" + echo "RHEL VERSION successfully resolved from kernel: ${RHEL_VERSION}" + return 0 +} + +_resolve_rhel_version() { + _get_rhel_version_from_kernel || RHEL_VERSION="${RHEL_MAJOR_VERSION}" + # set dnf release version as rhel version by default + if [[ -z "${DNF_RELEASEVER}" ]]; then + DNF_RELEASEVER="${RHEL_VERSION}" + fi + return 0 +} + +# Resolve the kernel version to the form major.minor.patch-revision. +_resolve_kernel_version() { + echo "Resolving Linux kernel version..." + local version=$(yum -q list available --showduplicates kernel-headers | + awk -v arch=$(uname -m) 'NR>1 {print $2"."arch}' | tac | grep -E -m1 "^${KERNEL_VERSION/latest/.*}") + + if [ -z "${version}" ]; then + echo "Could not resolve Linux kernel version" >&2 + return 1 + fi + KERNEL_VERSION="${version}" + echo "Proceeding with Linux kernel version ${KERNEL_VERSION}" + return 0 +} + +# Install the kernel modules header/builtin/order files and generate the kernel version string. +_install_prerequisites() ( + local tmp_dir=$(mktemp -d) + + trap "rm -rf ${tmp_dir}" EXIT + cd ${tmp_dir} + + echo "Installing elfutils..." + if ! dnf install -q -y elfutils-libelf.$DRIVER_ARCH; then + echo "FATAL: failed to install elfutils packages. RHEL entitlement may be improperly deployed." + exit 1 + fi + if ! dnf install -q -y elfutils-libelf-devel.$DRIVER_ARCH; then + echo "FATAL: failed to install elfutils packages. RHEL entitlement may be improperly deployed." + exit 1 + fi + + rm -rf /lib/modules/${KERNEL_VERSION} + mkdir -p /lib/modules/${KERNEL_VERSION}/proc + + echo "Enabling RHOCP and EUS RPM repos..." + if [ -n "${OPENSHIFT_VERSION:-}" ]; then + dnf config-manager --set-enabled rhocp-${OPENSHIFT_VERSION}-for-rhel-9-$DRIVER_ARCH-rpms || true + if ! dnf makecache --releasever=${DNF_RELEASEVER}; then + dnf config-manager --set-disabled rhocp-${OPENSHIFT_VERSION}-for-rhel-9-$DRIVER_ARCH-rpms || true + fi + fi + + dnf config-manager --set-enabled rhel-9-for-$DRIVER_ARCH-baseos-eus-rpms || true + if ! dnf makecache --releasever=${DNF_RELEASEVER}; then + dnf config-manager --set-disabled rhel-9-for-$DRIVER_ARCH-baseos-eus-rpms || true + fi + + # try with EUS disabled, if it does not work, then try just major version + if ! dnf makecache --releasever=${DNF_RELEASEVER}; then + # If pointing to DNF_RELEASEVER does not work, we point to the RHEL_MAJOR_VERSION as a last resort + if ! dnf makecache --releasever=${RHEL_MAJOR_VERSION}; then + echo "FATAL: failed to update the dnf metadata cache after multiple attempts with releasevers ${DNF_RELEASEVER}, ${RHEL_MAJOR_VERSION}" + exit 1 + else + DNF_RELEASEVER=${RHEL_MAJOR_VERSION} + fi + fi + + echo "Installing Linux kernel headers..." + dnf -q -y --releasever=${DNF_RELEASEVER} install kernel-headers-${KERNEL_VERSION} kernel-devel-${KERNEL_VERSION} --allowerasing > /dev/null + ln -s /usr/src/kernels/${KERNEL_VERSION} /lib/modules/${KERNEL_VERSION}/build + + echo "Installing Linux kernel module files..." + dnf -q -y --releasever=${DNF_RELEASEVER} install kernel-core-${KERNEL_VERSION} > /dev/null + + # Prevent depmod from giving a WARNING about missing files + touch /lib/modules/${KERNEL_VERSION}/modules.order + touch /lib/modules/${KERNEL_VERSION}/modules.builtin + + depmod ${KERNEL_VERSION} + + echo "Generating Linux kernel version string..." + if [ "$TARGETARCH" = "arm64" ]; then + gunzip -c /lib/modules/${KERNEL_VERSION}/vmlinuz | strings | grep -E '^Linux version' | sed 's/^\(.*\)\s\+(.*)$/\1/' > version + else + extract-vmlinux /lib/modules/${KERNEL_VERSION}/vmlinuz | strings | grep -E '^Linux version' | sed 's/^\(.*\)\s\+(.*)$/\1/' > version + fi + if [ -z "$(&2 + return 1 + fi + mv version /lib/modules/${KERNEL_VERSION}/proc + + # Parse gcc version + # gcc_version is expected to match x.y.z + # current_gcc is expected to match 'gcc-x.y.z-rel.el8.x86_64 + local gcc_version=$(cat /lib/modules/${KERNEL_VERSION}/proc/version | grep -Eo "gcc \(GCC\) ([0-9\.]+)" | grep -Eo "([0-9\.]+)") + local current_gcc=$(rpm -qa gcc) + echo "kernel requires gcc version: 'gcc-${gcc_version}', current gcc version is '${current_gcc}'" + + if ! [[ "${current_gcc}" =~ "gcc-${gcc_version}"-.* ]]; then + dnf install -q -y --releasever=${DNF_RELEASEVER} "gcc-${gcc_version}" + fi +) + +# Cleanup the prerequisites installed above. +_remove_prerequisites() { + true + if [ "${PACKAGE_TAG:-}" != "builtin" ]; then + dnf -q -y remove kernel-headers-${KERNEL_VERSION} kernel-devel-${KERNEL_VERSION} > /dev/null + # TODO remove module files not matching an existing driver package. + fi +} + +# Check if the kernel version requires a new precompiled driver packages. +_kernel_requires_package() { + local proc_mount_arg="" + + echo "Checking NVIDIA driver packages..." + + [[ ! -d /usr/src/nvidia-${DRIVER_VERSION}/${KERNEL_TYPE} ]] && return 0 + cd /usr/src/nvidia-${DRIVER_VERSION}/${KERNEL_TYPE} + + proc_mount_arg="--proc-mount-point /lib/modules/${KERNEL_VERSION}/proc" + for pkg_name in $(ls -d -1 precompiled/** 2> /dev/null); do + is_match=$(../mkprecompiled --match ${pkg_name} ${proc_mount_arg}) + if [ "${is_match}" == "kernel interface matches." ]; then + echo "Found NVIDIA driver package ${pkg_name##*/}" + return 1 + fi + done + return 0 +} + +# Compile the kernel modules, optionally sign them, and generate a precompiled package for use by the nvidia-installer. +_create_driver_package() ( + local pkg_name="nvidia-modules-${KERNEL_VERSION%%-*}${PACKAGE_TAG:+-${PACKAGE_TAG}}" + local nvidia_sign_args="" + local nvidia_modeset_sign_args="" + local nvidia_uvm_sign_args="" + + trap "make -s -j ${MAX_THREADS} SYSSRC=/lib/modules/${KERNEL_VERSION}/build clean > /dev/null" EXIT + + echo "Compiling NVIDIA driver kernel modules..." + cd /usr/src/nvidia-${DRIVER_VERSION}/${KERNEL_TYPE} + + if _gpu_direct_rdma_enabled; then + ln -s /run/mellanox/drivers/usr/src/ofa_kernel /usr/src/ + # if arch directory exists(MOFED >=5.5) then create a symlink as expected by GPU driver installer + # This is required as currently GPU driver installer doesn't expect headers in x86_64 folder, but only in either default or kernel-version folder. + # ls -ltr /usr/src/ofa_kernel/ + # lrwxrwxrwx 1 root root 36 Dec 8 20:10 default -> /etc/alternatives/ofa_kernel_headers + # drwxr-xr-x 4 root root 4096 Dec 8 20:14 x86_64 + # lrwxrwxrwx 1 root root 44 Dec 9 19:05 5.4.0-90-generic -> /usr/src/ofa_kernel/x86_64/5.4.0-90-generic/ + if [[ -d "/run/mellanox/drivers/usr/src/ofa_kernel/$(uname -m)/$(uname -r)" ]]; then + if [[ ! -e "/usr/src/ofa_kernel/$(uname -r)" ]]; then + ln -s "/run/mellanox/drivers/usr/src/ofa_kernel/$(uname -m)/$(uname -r)" /usr/src/ofa_kernel/ + fi + fi + fi + + make -s -j ${MAX_THREADS} SYSSRC=/lib/modules/${KERNEL_VERSION}/build nv-linux.o nv-modeset-linux.o > /dev/null + + echo "Relinking NVIDIA driver kernel modules..." + rm -f nvidia.ko nvidia-modeset.ko + ld -d -r -o nvidia.ko ./nv-linux.o ./nvidia/nv-kernel.o_binary + ld -d -r -o nvidia-modeset.ko ./nv-modeset-linux.o ./nvidia-modeset/nv-modeset-kernel.o_binary + + if [ -n "${PRIVATE_KEY}" ]; then + echo "Signing NVIDIA driver kernel modules..." + donkey get ${PRIVATE_KEY} sh -c "PATH=${PATH}:/usr/src/linux-headers-${KERNEL_VERSION}/scripts && \ + sign-file sha512 \$DONKEY_FILE pubkey.x509 nvidia.ko nvidia.ko.sign && \ + sign-file sha512 \$DONKEY_FILE pubkey.x509 nvidia-modeset.ko nvidia-modeset.ko.sign && \ + sign-file sha512 \$DONKEY_FILE pubkey.x509 nvidia-uvm.ko" + nvidia_sign_args="--linked-module nvidia.ko --signed-module nvidia.ko.sign" + nvidia_modeset_sign_args="--linked-module nvidia-modeset.ko --signed-module nvidia-modeset.ko.sign" + nvidia_uvm_sign_args="--signed" + fi + + echo "Building NVIDIA driver package ${pkg_name}..." + ../mkprecompiled --pack ${pkg_name} --description ${KERNEL_VERSION} \ + --proc-mount-point /lib/modules/${KERNEL_VERSION}/proc \ + --driver-version ${DRIVER_VERSION} \ + --kernel-interface nv-linux.o \ + --linked-module-name nvidia.ko \ + --core-object-name nvidia/nv-kernel.o_binary \ + ${nvidia_sign_args} \ + --target-directory . \ + --kernel-interface nv-modeset-linux.o \ + --linked-module-name nvidia-modeset.ko \ + --core-object-name nvidia-modeset/nv-modeset-kernel.o_binary \ + ${nvidia_modeset_sign_args} \ + --target-directory . \ + --kernel-module nvidia-uvm.ko \ + ${nvidia_uvm_sign_args} \ + --target-directory . + mkdir -p precompiled + mv ${pkg_name} precompiled +) + +_assert_nvswitch_system() { + [ -d /proc/driver/nvidia-nvswitch ] || return 1 + entries=$(ls -1 /proc/driver/nvidia-nvswitch/devices/*) + if [ -z "${entries}" ]; then + return 1 + fi + return 0 +} + +# For each kernel module configuration file mounted into the container, +# parse the file contents and extract the custom module parameters that +# are to be passed as input to 'modprobe'. +# +# Assumptions: +# - Configuration files are named .conf (i.e. nvidia.conf, nvidia-uvm.conf). +# - Configuration files are mounted inside the container at /drivers. +# - Each line in the file contains at least one parameter, where parameters on the same line +# are space delimited. It is up to the user to properly format the file to ensure +# the correct set of parameters are passed to 'modprobe'. +_get_module_params() { + local base_path="/drivers" + # nvidia + if [ -f "${base_path}/nvidia.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia.conf" + echo "Module parameters provided for nvidia: ${NVIDIA_MODULE_PARAMS[@]}" + fi + # nvidia-uvm + if [ -f "${base_path}/nvidia-uvm.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_UVM_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia-uvm.conf" + echo "Module parameters provided for nvidia-uvm: ${NVIDIA_UVM_MODULE_PARAMS[@]}" + fi + # nvidia-modeset + if [ -f "${base_path}/nvidia-modeset.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_MODESET_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia-modeset.conf" + echo "Module parameters provided for nvidia-modeset: ${NVIDIA_MODESET_MODULE_PARAMS[@]}" + fi + # nvidia-peermem + if [ -f "${base_path}/nvidia-peermem.conf" ]; then + while IFS="" read -r param || [ -n "$param" ]; do + NVIDIA_PEERMEM_MODULE_PARAMS+=("$param") + done <"${base_path}/nvidia-peermem.conf" + echo "Module parameters provided for nvidia-peermem: ${NVIDIA_PEERMEM_MODULE_PARAMS[@]}" + fi +} + +# Load the kernel modules and start persistenced. +_load_driver() { + echo "Parsing kernel module parameters..." + _get_module_params + + local nv_fw_search_path="$RUN_DIR/driver/lib/firmware" + local set_fw_path="true" + local fw_path_config_file="/sys/module/firmware_class/parameters/path" + for param in "${NVIDIA_MODULE_PARAMS[@]}"; do + if [[ "$param" == "NVreg_EnableGpuFirmware=0" ]]; then + set_fw_path="false" + fi + done + + if [[ "$set_fw_path" == "true" ]]; then + echo "Configuring the following firmware search path in '$fw_path_config_file': $nv_fw_search_path" + if [[ ! -z $(grep '[^[:space:]]' $fw_path_config_file) ]]; then + echo "WARNING: A search path is already configured in $fw_path_config_file" + echo " Retaining the current configuration" + else + echo -n "$nv_fw_search_path" > $fw_path_config_file || echo "WARNING: Failed to configure the firmware search path" + fi + fi + + echo "Loading ipmi and i2c_core kernel modules..." + modprobe -a i2c_core ipmi_msghandler ipmi_devintf + + echo "Loading NVIDIA driver kernel modules..." + set -o xtrace +o nounset + modprobe nvidia "${NVIDIA_MODULE_PARAMS[@]}" + modprobe nvidia-uvm "${NVIDIA_UVM_MODULE_PARAMS[@]}" + modprobe nvidia-modeset "${NVIDIA_MODESET_MODULE_PARAMS[@]}" + set +o xtrace -o nounset + + if _gpu_direct_rdma_enabled; then + echo "Loading NVIDIA Peer Memory kernel module..." + set -o xtrace +o nounset + modprobe -a nvidia-peermem "${NVIDIA_PEERMEM_MODULE_PARAMS[@]}" + set +o xtrace -o nounset + fi + + echo "Starting NVIDIA persistence daemon..." + nvidia-persistenced --persistence-mode + + if [ "${DRIVER_TYPE}" = "vgpu" ]; then + echo "Copying gridd.conf..." + cp /drivers/gridd.conf /etc/nvidia/gridd.conf + if [ "${VGPU_LICENSE_SERVER_TYPE}" = "NLS" ]; then + echo "Copying ClientConfigToken..." + mkdir -p /etc/nvidia/ClientConfigToken/ + cp /drivers/ClientConfigToken/* /etc/nvidia/ClientConfigToken/ + fi + + echo "Starting nvidia-gridd.." + LD_LIBRARY_PATH=/usr/lib64/nvidia/gridd nvidia-gridd + + # Start virtual topology daemon + _start_vgpu_topology_daemon + fi + + if _assert_nvswitch_system; then + echo "Starting NVIDIA fabric manager daemon..." + nv-fabricmanager -c /usr/share/nvidia/nvswitch/fabricmanager.cfg + fi +} + +# Stop persistenced and unload the kernel modules if they are currently loaded. +_unload_driver() { + local rmmod_args=() + local nvidia_deps=0 + local nvidia_refs=0 + local nvidia_uvm_refs=0 + local nvidia_modeset_refs=0 + local nvidia_peermem_refs=0 + + echo "Stopping NVIDIA persistence daemon..." + if [ -f /var/run/nvidia-persistenced/nvidia-persistenced.pid ]; then + local pid=$(< /var/run/nvidia-persistenced/nvidia-persistenced.pid) + + kill -SIGTERM "${pid}" + for i in $(seq 1 50); do + kill -0 "${pid}" 2> /dev/null || break + sleep 0.1 + done + if [ $i -eq 50 ]; then + echo "Could not stop NVIDIA persistence daemon" >&2 + return 1 + fi + fi + + if [ -f /var/run/nvidia-gridd/nvidia-gridd.pid ]; then + echo "Stopping NVIDIA grid daemon..." + local pid=$(< /var/run/nvidia-gridd/nvidia-gridd.pid) + + kill -SIGTERM "${pid}" + for i in $(seq 1 10); do + kill -0 "${pid}" 2> /dev/null || break + sleep 0.1 + done + if [ $i -eq 10 ]; then + echo "Could not stop NVIDIA Grid daemon" >&2 + return 1 + fi + fi + + if [ -f /var/run/nvidia-fabricmanager/nv-fabricmanager.pid ]; then + echo "Stopping NVIDIA fabric manager daemon..." + local pid=$(< /var/run/nvidia-fabricmanager/nv-fabricmanager.pid) + + kill -SIGTERM "${pid}" + for i in $(seq 1 50); do + kill -0 "${pid}" 2> /dev/null || break + sleep 0.1 + done + if [ $i -eq 50 ]; then + echo "Could not stop NVIDIA fabric manager daemon" >&2 + return 1 + fi + fi + + echo "Unloading NVIDIA driver kernel modules..." + if [ -f /sys/module/nvidia_modeset/refcnt ]; then + nvidia_modeset_refs=$(< /sys/module/nvidia_modeset/refcnt) + rmmod_args+=("nvidia-modeset") + ((++nvidia_deps)) + fi + if [ -f /sys/module/nvidia_uvm/refcnt ]; then + nvidia_uvm_refs=$(< /sys/module/nvidia_uvm/refcnt) + rmmod_args+=("nvidia-uvm") + ((++nvidia_deps)) + fi + if [ -f /sys/module/nvidia/refcnt ]; then + nvidia_refs=$(< /sys/module/nvidia/refcnt) + rmmod_args+=("nvidia") + fi + if [ -f /sys/module/nvidia_peermem/refcnt ]; then + nvidia_peermem_refs=$(< /sys/module/nvidia_peermem/refcnt) + rmmod_args+=("nvidia-peermem") + ((++nvidia_deps)) + fi + if [ ${nvidia_refs} -gt ${nvidia_deps} ] || [ ${nvidia_uvm_refs} -gt 0 ] || [ ${nvidia_modeset_refs} -gt 0 ] || [ ${nvidia_peermem_refs} -gt 0 ]; then + echo "Could not unload NVIDIA driver kernel modules, driver is in use" >&2 + return 1 + fi + + if [ ${#rmmod_args[@]} -gt 0 ]; then + rmmod ${rmmod_args[@]} + fi + return 0 +} + +# Link and install the kernel modules from a precompiled package using the nvidia-installer. +_install_driver() { + local install_args=() + + echo "Installing NVIDIA driver kernel modules..." + cd /usr/src/nvidia-${DRIVER_VERSION} + rm -rf /lib/modules/${KERNEL_VERSION}/video + + if [ "${ACCEPT_LICENSE}" = "yes" ]; then + install_args+=("--accept-license") + fi + IGNORE_CC_MISMATCH=1 nvidia-installer --kernel-module-only --no-drm --ui=none --no-nouveau-check -m=${KERNEL_TYPE} ${install_args[@]+"${install_args[@]}"} + # May need to add no-cc-check for Rhel, otherwise it complains about cc missing in path + # /proc/version and lib/modules/KERNEL_VERSION/proc are different, by default installer looks at /proc/ so, added the proc-mount-point + # TODO: remove the -a flag. its not needed. in the new driver version, license-acceptance is implicit + #nvidia-installer --kernel-module-only --no-drm --ui=none --no-nouveau-check --no-cc-version-check --proc-mount-point /lib/modules/${KERNEL_VERSION}/proc ${install_args[@]+"${install_args[@]}"} +} + +# Mount the driver rootfs into the run directory with the exception of sysfs. +_mount_rootfs() { + echo "Mounting NVIDIA driver rootfs..." + mount --make-runbindable /sys + mount --make-private /sys + mkdir -p ${RUN_DIR}/driver + mount --rbind / ${RUN_DIR}/driver + + echo "Check SELinux status" + if [ -e /sys/fs/selinux ]; then + echo "SELinux is enabled" + echo "Change device files security context for selinux compatibility" + chcon -R -t container_file_t ${RUN_DIR}/driver/dev + else + echo "SELinux is disabled, skipping..." + fi +} + +# Unmount the driver rootfs from the run directory. +_unmount_rootfs() { + echo "Unmounting NVIDIA driver rootfs..." + if findmnt -r -o TARGET | grep "${RUN_DIR}/driver" > /dev/null; then + umount -l -R ${RUN_DIR}/driver + fi +} + +# Write a kernel postinst.d script to automatically precompile packages on kernel update (similar to DKMS). +_write_kernel_update_hook() { + if [ ! -d ${KERNEL_UPDATE_HOOK%/*} ]; then + return + fi + + echo "Writing kernel update hook..." + cat > ${KERNEL_UPDATE_HOOK} <<'EOF' +#!/bin/bash + +set -eu +trap 'echo "ERROR: Failed to update the NVIDIA driver" >&2; exit 0' ERR + +NVIDIA_DRIVER_PID=$(< /run/nvidia/nvidia-driver.pid) + +export "$(grep -z DRIVER_VERSION /proc/${NVIDIA_DRIVER_PID}/environ)" +nsenter -t "${NVIDIA_DRIVER_PID}" -m -- nvidia-driver update --kernel "$1" +EOF + chmod +x ${KERNEL_UPDATE_HOOK} +} + +_shutdown() { + if _unload_driver; then + _unmount_rootfs + rm -f ${PID_FILE} ${KERNEL_UPDATE_HOOK} + return 0 + fi + return 1 +} + +_find_vgpu_driver_version() { + local count="" + local version="" + local drivers_path="/drivers" + + if [ "${DISABLE_VGPU_VERSION_CHECK}" = "true" ]; then + echo "vgpu version compatibility check is disabled" + return 0 + fi + # check if vgpu devices are present + count=$(vgpu-util count) + if [ $? -ne 0 ]; then + echo "cannot find vgpu devices on host, pleae check /var/log/vgpu-util.log for more details..." + return 0 + fi + NUM_VGPU_DEVICES=$(echo "$count" | awk -F= '{print $2}') + if [ $NUM_VGPU_DEVICES -eq 0 ]; then + # no vgpu devices found, treat as passthrough + return 0 + fi + echo "found $NUM_VGPU_DEVICES vgpu devices on host" + + # find compatible guest driver using driver catalog + if [ -d "/mnt/shared-nvidia-driver-toolkit/drivers" ]; then + drivers_path="/mnt/shared-nvidia-driver-toolkit/drivers" + fi + version=$(vgpu-util match -i "${drivers_path}" -c "${drivers_path}/vgpuDriverCatalog.yaml") + if [ $? -ne 0 ]; then + echo "cannot find match for compatible vgpu driver from available list, please check /var/log/vgpu-util.log for more details..." + return 1 + fi + DRIVER_VERSION=$(echo "$version" | awk -F= '{print $2}') + echo "vgpu driver version selected: ${DRIVER_VERSION}" + return 0 +} + +_start_vgpu_topology_daemon() { + type nvidia-topologyd > /dev/null 2>&1 || return 0 + echo "Starting nvidia-topologyd.." + nvidia-topologyd +} + +_prepare() { + if [ "${DRIVER_TYPE}" = "vgpu" ]; then + _find_vgpu_driver_version || exit 1 + fi + + # Install the userspace components and copy the kernel module sources. + sh NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION.run -x && \ + cd NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION && \ + sh /tmp/install.sh nvinstall && \ + mkdir -p /usr/src/nvidia-$DRIVER_VERSION && \ + mv LICENSE mkprecompiled ${KERNEL_TYPE} /usr/src/nvidia-$DRIVER_VERSION && \ + sed '9,${/^\(kernel\|LICENSE\)/!d}' .manifest > /usr/src/nvidia-$DRIVER_VERSION/.manifest + + echo -e "\n========== NVIDIA Software Installer ==========\n" + echo -e "Starting installation of NVIDIA driver version ${DRIVER_VERSION} for Linux kernel version ${KERNEL_VERSION}\n" +} + +_prepare_exclusive() { + _prepare + + exec 3> ${PID_FILE} + if ! flock -n 3; then + echo "An instance of the NVIDIA driver is already running, aborting" + exit 1 + fi + echo $$ >&3 + + trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM + trap "_shutdown" EXIT + + _unload_driver || exit 1 + _unmount_rootfs +} + +_build() { + # Install dependencies + if _kernel_requires_package; then + _update_package_cache + _install_prerequisites + _create_driver_package + #_remove_prerequisites + _cleanup_package_cache + fi + + # Build the driver + _install_driver +} + +_load() { + _load_driver + _mount_rootfs + _write_kernel_update_hook + + echo "Done, now waiting for signal" + sleep infinity & + trap "echo 'Caught signal'; _shutdown && { kill $!; exit 0; }" HUP INT QUIT PIPE TERM + trap - EXIT + while true; do wait $! || continue; done + exit 0 +} + +init() { + _prepare_exclusive + + _build + + _load +} + +build() { + _prepare + + _build +} + +load() { + _prepare_exclusive + + _load +} + +update() { + exec 3>&2 + if exec 2> /dev/null 4< ${PID_FILE}; then + if ! flock -n 4 && read pid <&4 && kill -0 "${pid}"; then + exec > >(tee -a "/proc/${pid}/fd/1") + exec 2> >(tee -a "/proc/${pid}/fd/2" >&3) + else + exec 2>&3 + fi + exec 4>&- + fi + exec 3>&- + + # vgpu driver version is chosen dynamically during runtime, so pre-compile modules for + # only non-vgpu driver types + if [ "${DRIVER_TYPE}" != "vgpu" ]; then + # Install the userspace components and copy the kernel module sources. + if [ ! -e /usr/src/nvidia-${DRIVER_VERSION}/mkprecompiled ]; then + sh NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION.run -x && \ + cd NVIDIA-Linux-$DRIVER_ARCH-$DRIVER_VERSION && \ + sh /tmp/install.sh nvinstall && \ + mkdir -p /usr/src/nvidia-$DRIVER_VERSION && \ + mv LICENSE mkprecompiled ${KERNEL_TYPE} /usr/src/nvidia-$DRIVER_VERSION && \ + sed '9,${/^\(kernel\|LICENSE\)/!d}' .manifest > /usr/src/nvidia-$DRIVER_VERSION/.manifest + fi + fi + + echo -e "\n========== NVIDIA Software Updater ==========\n" + echo -e "Starting update of NVIDIA driver version ${DRIVER_VERSION} for Linux kernel version ${KERNEL_VERSION}\n" + + trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM + + _update_package_cache + _resolve_kernel_version || exit 1 + _install_prerequisites + if _kernel_requires_package; then + _create_driver_package + fi + _remove_prerequisites + _cleanup_package_cache + + echo "Done" + exit 0 +} + +# Wait for MOFED drivers to be loaded and load nvidia-peermem whenever it gets unloaded during MOFED driver updates +reload_nvidia_peermem() { + if [ "$USE_HOST_MOFED" = "true" ]; then + until lsmod | grep mlx5_core > /dev/null 2>&1 && [ -f /run/nvidia/validations/.driver-ctr-ready ]; + do + echo "waiting for mellanox ofed and nvidia drivers to be installed" + sleep 10 + done + else + # use driver readiness flag created by MOFED container + until [ -f /run/mellanox/drivers/.driver-ready ] && [ -f /run/nvidia/validations/.driver-ctr-ready ]; + do + echo "waiting for mellanox ofed and nvidia drivers to be installed" + sleep 10 + done + fi + # get any parameters provided for nvidia-peermem + _get_module_params && set +o nounset + if chroot /run/nvidia/driver modprobe nvidia-peermem "${NVIDIA_PEERMEM_MODULE_PARAMS[@]}"; then + if [ -f /sys/module/nvidia_peermem/refcnt ]; then + echo "successfully loaded nvidia-peermem module, now waiting for signal" + sleep inf + trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM + fi + fi + echo "failed to load nvidia-peermem module" + exit 1 +} + +# probe by gpu-operator for liveness/startup checks for nvidia-peermem module to be loaded when MOFED drivers are ready +probe_nvidia_peermem() { + if lsmod | grep mlx5_core > /dev/null 2>&1; then + if [ ! -f /sys/module/nvidia_peermem/refcnt ]; then + echo "nvidia-peermem module is not loaded" + return 1 + fi + else + echo "MOFED drivers are not ready, skipping probe to avoid container restarts..." + fi + return 0 +} + +usage() { + cat >&2 < + +使用官方的镜像来二次构建自定义镜像,如下是一个 `Dockerfile` 文件的内容: + +```dockerfile +FROM nvcr.io/nvidia/driver:535.183.06-rhel9.2 +COPY nvidia-driver /usr/local/bin +RUN chmod +x /usr/local/bin/nvidia-driver +CMD ["/bin/bash", "-c"] +``` + +构建命令并推送到火种集群: + +```bash +docker build -t {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535.183.06-01-rhel9.2 -f Dockerfile . +docker push {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535.183.06-01-rhel9.2 +``` + +## 安装驱动 + +1. 安装 gpu-operator addon +2. 设置 `driver.version=535.183.06-01` diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md new file mode 100644 index 0000000..49dee9b --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md @@ -0,0 +1,36 @@ +# Ubuntu22.04 离线安装 gpu-operator 驱动 + +前提条件:已安装 gpu-operator v23.9.0+2 及更高版本 + +## 准备离线镜像 + +1. 查看内核版本 + + ```bash + $ uname -r + 5.15.0-78-generic + ``` + +1. 查看内核对应的 GPU Driver 镜像版本, + `https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags`。 + 使用内核查询镜像版本,通过 `ctr export` 保存镜像。 + + ```bash + ctr i pull nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ctr i export --all-platforms driver.tar.gz nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ``` + +1. 把镜像导入到火种集群的镜像仓库中 + + ```bash + ctr i import driver.tar.gz + ctr i tag nvcr.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 + ctr i push {火种registry}/nvcr.m.daocloud.io/nvidia/driver:535-5.15.0-78-generic-ubuntu22.04 --skip-verify=true + ``` + +## 安装驱动 + +1. 安装 gpu-operator addon +2. 若使用预编译模式,则设置 `driver.usePrecompiled=true`,并设置 `driver.version=535`,这里要注意,写的是 535,不是 535.104.12。(非预编译模式跳过此步,直接安装即可) + +![安装驱动](../images/driver.jpg) diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/upgrade_yum_source_centos7_9.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/upgrade_yum_source_centos7_9.md new file mode 100644 index 0000000..c87f4dd --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/upgrade_yum_source_centos7_9.md @@ -0,0 +1,248 @@ +# 构建 CentOS 7.9 离线 yum 源 + +## 使用场景介绍 + +当工作节点的内核版本与全局服务集群的控制节点内核版本或 OS 类型不一致时,需要用户手动构建离线 yum 源。 + +本文介绍如何构建离线 yum 源, 并在安装 Gpu Operator 时,通过 `RepoConfig.ConfigMapName` 参数来使用。 + +## 前提条件 + +1. 用户已经在平台上安装了 v0.12.0 及以上版本的 addon 离线包。 +1. 准备一个能够和待部署 GPU Operator 的集群网络能够联通的文件服务器,如 nginx 或 minio。 +1. 准备一个能够访问互联网、待部署 GPU Operator 的集群和文件服务器的节点, + 且节点上已经完成 Docker 的安装。 + +## 操作步骤 + +本文以内核版本为 `3.10.0-1160.95.1.el7.x86_64` 的 CentOS 7.9 节点为例,介绍如何构建 GPU operator 离线包的 yum 源。 + +### 检查集群节点的 OS 和内核版本 + +分别在全局服务集群的控制节点和待部署 GPU Operator 的节点执行如下命令,若两个节点的 OS 和内核版本一致则无需构建 yum 源, +可参考[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 文档直接安装;若两个节点的 OS 或内核版本不一致,请执行[下一步](#yum)。 + +1. 执行如下命令,查看集群下待部署 GPU Operator 节点的发行版名称和版本号。 + + ```bash + cat /etc/redhat-release + ``` + + 预期输出如下: + + ```console + CentOS Linux release 7.9 (Core) + ``` + + 输出结果为当前节点内核版本 `CentOS 7.9` 。 + +2. 执行如下命令,查看集群下待部署 GPU Operator 节点的内核版本。 + + ```bash + uname -a + ``` + + 预期输出如下: + + ```console + Linux localhost.localdomain 3.10.0-1160.95.1.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux + ``` + + 输出结果为当前节点内核版本 `3.10.0-1160.el7.x86_64`。 + +### 制作离线 yum 源 + +在一个能够访问互联网和文件服务器的节点上进行操作。 + +1. 在一个能够访问互联网和文件服务器的节点上执行如下命令新建一个名为 __yum.sh__ 的脚本文件。 + + ```bash + vi yum.sh + ``` + + 然后按下 **i** 键进入插入模式,输入以下内容: + + ```bash + export TARGET_KERNEL_VERSION=$1 + + cat >> run.sh << \EOF + #! /bin/bash + echo "start install kernel repo" + echo ${KERNEL_VERSION} + mkdir centos-base + + if [ "$OS" -eq 7 ]; then + yum install --downloadonly --downloaddir=./centos-base perl + yum install --downloadonly --downloaddir=./centos-base elfutils-libelf.x86_64 + yum install --downloadonly --downloaddir=./redhat-base elfutils-libelf-devel.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-headers-${KERNEL_VERSION}.el7.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-devel-${KERNEL_VERSION}.el7.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-${KERNEL_VERSION}.el7.x86_64 + yum install -y --downloadonly --downloaddir=./centos-base groff-base + elif [ "$OS" -eq 8 ]; then + yum install --downloadonly --downloaddir=./centos-base perl + yum install --downloadonly --downloaddir=./centos-base elfutils-libelf.x86_64 + yum install --downloadonly --downloaddir=./redhat-base elfutils-libelf-devel.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-headers-${KERNEL_VERSION}.el8.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-devel-${KERNEL_VERSION}.el8.x86_64 + yum install --downloadonly --downloaddir=./centos-base kernel-${KERNEL_VERSION}.el8.x86_64 + yum install -y --downloadonly --downloaddir=./centos-base groff-base + else + echo "Error os version" + fi + + createrepo centos-base/ + ls -lh centos-base/ + tar -zcf centos-base.tar.gz centos-base/ + echo "end install kernel repo" + EOF + + cat >> Dockerfile << EOF + FROM centos:7 + ENV KERNEL_VERSION="" + ENV OS=7 + RUN yum install -y createrepo + COPY run.sh . + ENTRYPOINT ["/bin/bash","run.sh"] + EOF + + docker build -t test:v1 -f Dockerfile . + docker run -e KERNEL_VERSION=$TARGET_KERNEL_VERSION --name centos7.9 test:v1 + docker cp centos7.9:/centos-base.tar.gz . + tar -xzf centos-base.tar.gz + ``` + + 按下 __esc__ 键退出插入模式,然后输入 __ :wq__ 保存并退出。 + +2. 运行 __yum.sh__ 文件: + + ```bash + bash -x yum.sh TARGET_KERNEL_VERSION + ``` + + `TARGET_KERNEL_VERSION` 参数用于指定集群节点的内核版本,注意:发行版标识符(如 __ .el7.x86_64 __ )无需输入。 + 例如: + + ```bash + bash -x yum.sh 3.10.0-1160.95.1 + ``` + +至此,您已经生成了内核为 __3.10.0-1160.95.1.el7.x86_64__ 的离线的 yum 源: __centos-base__ 。 + +### 上传离线 yum 源到文件服务器 + +在一个能够访问互联网和文件服务器的节点上进行操作。主要用于将上一步中生成的 yum +源上传到可以被待部署 GPU Operator 的集群进行访问的文件服务器中。 +文件服务器可以为 Nginx 、 Minio 或其它支持 Http 协议的文件服务器。 + +本操作示例采用的是算丰 AI 算力平台火种节点内置的 Minio 作为文件服务器,Minio 相关信息如下: + +- 访问地址: `http://10.5.14.200:9000(一般为{火种节点 IP} + {9000 端口})` +- 登录用户名:rootuser +- 登录密码:rootpass123 + +1. 在节点当前路径下,执行如下命令将节点本地 mc 命令行工具和 minio 服务器建立链接。 + + ```bash + mc config host add minio http://10.5.14.200:9000 rootuser rootpass123 + ``` + + 预期输出如下: + + ```bash + Added `minio` successfully. + ``` + + mc 命令行工具是 Minio 文件服务器提供的客户端命令行工具,详情请参考: + [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html)。 + +2. 在节点当前路径下,新建一个名为 __centos-base__ 的存储桶(bucket)。 + + ```bash + mc mb -p minio/centos-base + ``` + + 预期输出如下: + + ```bash + Bucket created successfully __minio/centos-base__ . + ``` + +3. 将存储桶 __centos-base__ 的访问策略设置为允许公开下载。以便在后期安装 GPU-operator 时能够被访问。 + + ```bash + mc anonymous set download minio/centos-base + ``` + + 预期输出如下: + + ```bash + Access permission for `minio/centos-base` is set to `download` + ``` + +4. 在节点当前路径下,将步骤二生成的离线 yum 源文件 __centos-base__ 复制到 minio 服务器的 __minio/centos-base__ 存储桶中。 + + ```bash + mc cp centos-base minio/centos-base --recursive + ``` + +### 在集群创建配置项用来保存 yum 源信息 + +在待部署 GPU Operator 集群的控制节点上进行操作。 + +1. 执行如下命令创建名为 __CentOS-Base.repo__ 的文件,用来指定 yum 源存储的配置信息。 + + ```bash + # 文件名称必须为 CentOS-Base.repo,否则安装 gpu-operator 时无法被识别 + cat > CentOS-Base.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/centos-base/centos-base #步骤三中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/centos-base/centos-base #步骤三中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. 基于创建的 __CentOS-Base.repo__ 文件,在 gpu-operator 命名空间下,创建名为 __local-repo-config__ 的配置文件: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=CentOS-Base.repo=/etc/yum.repos.d/extension.repo + ``` + + 预期输出如下: + + ```console + configmap/local-repo-config created + ``` + + __local-repo-config__ 配置文件用于在安装 gpu-operator 时,提供 `RepoConfig.ConfigMapName` 参数的值,配置文件名称用户可自定义。 + +3. 查看 __local-repo-config__ 的配置文件的内容: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + + 预期输出如下: + + ```yaml + apiVersion: v1 + data: + CentOS-Base.repo: "[extension-0]\nbaseurl = http://10.6.232.5:32618/centos-base#步骤二中,放置 yum 源的文件服务器路径\ngpgcheck = 0\nname = kubean extension 0\n \n[extension-1]\nbaseurl + = http://10.6.232.5:32618/centos-base #步骤二中,放置 yum 源的文件服务器路径\ngpgcheck = 0\nname + = kubean extension 1\n" + kind: ConfigMap + metadata: + creationTimestamp: "2023-10-18T01:59:02Z" + name: local-repo-config + namespace: gpu-operator + resourceVersion: "59445080" + uid: c5f0ebab-046f-442c-b932-f9003e014387 + ``` + +至此,您已成功为待部署 GPU Operator 的集群创建了离线 yum 源配置文件。 +通过在[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 时通过 `RepoConfig.ConfigMapName` 参数来使用。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md new file mode 100644 index 0000000..0294059 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md @@ -0,0 +1,217 @@ +# 构建 Red Hat 8.4 离线 yum 源 + +算丰 AI 算力平台预置了 CentOS 7.9,内核为 3.10.0-1160 的 GPU operator 离线包。其它 OS 类型的节点或内核需要用户手动构建离线 yum 源。 + +本文介绍如何基于全局服务集群任意节点构建 Red Hat 8.4 离线 yum 源包,并在安装 Gpu Operator 时,通过 `RepoConfig.ConfigMapName` 参数来使用。 + +## 前提条件 + +1. 用户已经在平台上安装了 v0.12.0 及以上版本的 addon 离线包。 +2. 待部署 GPU Operator 的集群节点 OS 必须为 Red Hat 8.4,且内核版本完全一致。 +3. 准备一个能够和待部署 GPU Operator 的集群网络能够联通的文件服务器,如 nginx 或 minio。 +4. 准备一个能够访问互联网、待部署 GPU Operator 的集群和文件服务器的节点,且节点上已经完成 + Docker 的安装。 +5. 全局服务集群的节点必须为 Red Hat 8.4 4.18.0-305.el8.x86_64。 + +## 操作步骤 + +本文以 Red Hat 8.4 4.18.0-305.el8.x86_64 节点为例,介绍如何基于全局服务集群任意节点构建 Red Hat 8.4 离线 yum 源包, +并在安装 Gpu Operator 时,通过 `RepoConfig.ConfigMapName` 参数来使用。 + +### 下载火种节点中的 yum 源 + +以下操作在全局服务集群的 master 节点上执行。 + +1. 使用 ssh 或其它方式进入全局服务集群内任一节点执行如下命令: + + ```bash + cat /etc/yum.repos.d/extension.repo #查看 extension.repo 中的内容 + ``` + + 预期输出如下: + + ```ini + [extension-0] + baseurl = http://10.5.14.200:9000/kubean/redhat/$releasever/os/$basearch + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/kubean/redhat-iso/$releasever/os/$basearch/AppStream + gpgcheck = 0 + name = kubean extension 1 + + [extension-2] + baseurl = http://10.5.14.200:9000/kubean/redhat-iso/$releasever/os/$basearch/BaseOS + gpgcheck = 0 + name = kubean extension 2 + ``` + +2. 在 __root__ 路径下新建一个名为 __redhat-base-repo__ 的文件夹 + + ```bash + mkdir redhat-base-repo + ``` + +3. 下载 yum 源中的 rpm 包到本地: + + ```bash + yum install yum-utils + ``` + +4. 下载 extension-1 中的 rpm 包: + + ```bash + reposync -p redhat-base-repo -n --repoid=extension-1 + ``` + +5. 下载 extension-2 中的 rpm 包: + + ```bash + reposync -p redhat-base-repo -n --repoid=extension-2 + ``` + +### 下载 elfutils-libelf-devel-0.187-4.el8.x86_64.rpm 包 + +以下操作在联网节点执行操作,在操作前,您需要保证联网节点和全局服务集群 master 节点间的网络联通性。 + +1. 在联网节点执行如下命令,下载 __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ 包: + + ```bash + wget https://rpmfind.net/linux/centos/8-stream/BaseOS/x86_64/os/Packages/elfutils-libelf-devel-0.187-4.el8.x86_64.rpm + ``` + +2. 在当前目录下将 __elfutils-libelf-devel-0.187-4.el8.x86_64.rpm__ 包传输至步骤一中的节点上: + + ```bash + scp elfutils-libelf-devel-0.187-4.el8.x86_64.rpm user@ip:~/redhat-base-repo/extension-2/Packages/ + ``` + + 例如: + + ```bash + scp elfutils-libelf-devel-0.187-4.el8.x86_64.rpm root@10.6.175.10:~/redhat-base-repo/extension-2/Packages/ + ``` + +### 生成本地 yum repo + +以下操作在步骤一中全局服务集群的 master 节点上执行。 + +1. 进入 yum repo 目录: + + ```bash + cd ~/redhat-base-repo/extension-1/Packages + cd ~/redhat-base-repo/extension-2/Packages + ``` + +2. 生成目录 repo 索引: + + ```bash + yum install createrepo -y # 若已安装 createrepo 可省略此步骤 + createrepo_c ./ + ``` + +至此,您已经生成了内核为 `4.18.0-305.el8.x86_64` 的离线的 yum 源: __redhat-base-repo__ 。 + +### 将本地生成的 yum repo 上传至文件服务器 + +本操作示例采用的是算丰 AI 算力平台火种节点内置的 Minio 作为文件服务器,用户可基于自身情况选择文件服务器。Minio 相关信息如下: + +- 访问地址: `http://10.5.14.200:9000(一般为{火种节点 IP} + {9000 端口})` +- 登录用户名:rootuser +- 登录密码:rootpass123 + +1. 在节点当前路径下,执行如下命令将节点本地 mc 命令行工具和 minio 服务器建立链接。 + + ```bash + mc config host add minio 文件服务器访问地址 用户名 密码 + ``` + + 例如: + + ```bash + mc config host add minio http://10.5.14.200:9000 rootuser rootpass123 + ``` + + 预期输出如下: + + ```console + Added `minio` successfully. + ``` + + mc 命令行工具是 Minio 文件服务器提供的客户端命令行工具,详情请参考: + [MinIO Client](https://min.io/docs/minio/linux/reference/minio-mc.html)。 + +2. 在节点当前路径下,新建一个名为 __redhat-base__ 的存储桶(bucket)。 + + ```bash + mc mb -p minio/redhat-base + ``` + + 预期输出如下: + + ```console + Bucket created successfully `minio/redhat-base`. + ``` + +3. 将存储桶 __redhat-base__ 的访问策略设置为允许公开下载。以便在后期安装 GPU-operator 时能够被访问。 + + ```bash + mc anonymous set download minio/redhat-base + ``` + + 预期输出如下: + + ```console + Access permission for `minio/redhat-base` is set to `download` + ``` + +4. 在节点当前路径下,将步骤二生成的离线 yum 源文件 __redhat-base-repo__ 复制到 minio 服务器的 __minio/redhat-base__ 存储桶中。 + + ```bash + mc cp redhat-base-repo minio/redhat-base --recursive + ``` + +### 在集群创建配置项用来保存 yum 源信息 + +本步骤在待部署 GPU Operator 集群的控制节点上进行操作。 + +1. 执行如下命令创建名为 __redhat.repo__ 的文件,用来指定 yum 源存储的配置信息。 + + ```bash + # 文件名称必须为 redhat.repo,否则安装 gpu-operator 时无法被识别 + cat > redhat.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/redhat-base/redhat-base-repo/Packages #步骤一中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/redhat-base/redhat-base-repo/Packages #步骤一中,放置 yum 源的文件服务器地址 + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. 基于创建的 __redhat.repo__ 文件,在 gpu-operator 命名空间下,创建名为 __local-repo-config__ 的配置文件: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=./redhat.repo + ``` + + 预期输出如下: + + ``` + configmap/local-repo-config created + ``` + + __local-repo-config__ 配置文件用于在安装 gpu-operator 时,提供 `RepoConfig.ConfigMapName` 参数的值,配置文件名称用户可自定义。 + +3. 查看 __local-repo-config__ 的配置文件的内容: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + +至此,您已成功为待部署 GPU Operator 的集群创建了离线 yum 源配置文件。 +通过在[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 时通过 `RepoConfig.ConfigMapName` 参数来使用。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/hami.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/hami.md new file mode 100644 index 0000000..d164395 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/hami.md @@ -0,0 +1,21 @@ +--- +hide: + - toc +--- + +# 构建 vGPU 显存超配镜像 + +[Hami 项目](https://github.com/Project-HAMi/HAMi)中 vGPU 显存超配的功能已经不存在,目前使用有显存超配的 `libvgpu.so` 文件重新构建。 + +```bash title="Dockerfile" +FROM docker.m.daocloud.io/projecthami/hami:v2.3.11 +COPY libvgpu.so /k8s-vgpu/lib/nvidia/ +``` + +执行以下命令构建镜像: + +```bash +docker build -t release.daocloud.io/projecthami/hami:v2.3.11 -f Dockerfile . +``` + +然后把镜像 push 到 `release.daocloud.io` 中。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/vgpu_addon.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/vgpu_addon.md new file mode 100644 index 0000000..72706e8 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/vgpu_addon.md @@ -0,0 +1,42 @@ +# 安装 NVIDIA vGPU Addon + +如需将一张 NVIDIA 虚拟化成多个虚拟 GPU,并将其分配给不同的云主机或用户,您可以使用 NVIDIA 的 vGPU 能力。 +本节介绍如何在算丰 AI 算力平台中安装 vGPU 插件,这是使用 NVIDIA vGPU 能力的前提。 +## 前提条件 + +- 参考 [GPU 支持矩阵](../../gpu_matrix.md) 确认集群节点上具有对应型号的 GPU 卡。 +- 当前集群已通过 Operator 部署 NVIDIA 驱动,具体参考 [GPU Operator 离线安装](../install_nvidia_driver_of_operator.md)。 + +## 操作步骤 + +1. 功能模块路径: __容器管理__ -> __集群管理__ ,点击目标集群的名称,从左侧导航栏点击 __Helm 应用__ -> __Helm 模板__ -> 搜索 __nvidia-vgpu__ 。 + + ![找到 nvidia-vgpu](../../../../../images/vgpu-addon.png) + +2. 在安装 vGPU 的过程中提供了几个基本修改的参数,如果需要修改高级参数点击 YAML 列进行修改: + + - __deviceCoreScaling__ :NVIDIA 装置算力使用比例,预设值是 1。可以大于 1(启用虚拟算力,实验功能)。如果我们配置 __devicePlugin.deviceCoreScaling__ 参数为 S,在部署了我们装置插件的 Kubernetes 集群中,这张 GPU 分出的 vGPU 将总共包含 __S * 100%__ 算力。 + + - __deviceMemoryScaling__ :NVIDIA 装置显存使用比例,预设值是 1。可以大于 1(启用虚拟显存,实验功能)。 + 对于有 M 显存大小的 NVIDIA GPU,如果我们配置 __devicePlugin.deviceMemoryScaling__ 参数为 S, + 在部署了我们装置插件的 Kubernetes 集群中,这张 GPU 分出的 vGPU 将总共包含 __S * M__ 显存。 + + - __deviceSplitCount__ :整数类型,预设值是 10。GPU 的分割数,每一张 GPU 都不能分配超过其配置数目的任务。 + 若其配置为 N 的话,每个 GPU 上最多可以同时存在 N 个任务。 + + - __Resources__ :就是对应 vgpu-device-plugin 和 vgpu-schedule pod 的资源使用量。 + + - __ServiceMonitor__ :默认不开启,开启后可前往可观测性模块查看 vGPU 相关监控。如需开启,请确保 insight-agent 已安装并处于运行状态,否则将导致 NVIDIA vGPU Addon 安装失败。 + + ![修改参数](../../images/vgpu-addon.png) + +3. 安装成功之后会在指定 __Namespace__ 下出现如下两个类型的 Pod,即表示 NVIDIA vGPU 插件已安装成功: + + ![出现两个 Pod](../../../../../images/vgpu-pod.png) + +安装成功后,[部署应用可使用 vGPU 资源](vgpu_user.md)。 + +!!! note + + NVIDIA vGPU Addon 不支持从老版本 v2.0.0 直接升级为最新版 v2.0.0+1; + 如需升级,请卸载老版本后重新安装。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/vgpu_user.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/vgpu_user.md new file mode 100644 index 0000000..fcc8252 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/vgpu/vgpu_user.md @@ -0,0 +1,62 @@ +# 应用使用 Nvidia vGPU + +本节介绍如何在算丰 AI 算力平台使用 vGPU 能力。 + +## 前提条件 + +- 集群节点上具有[对应型号的 GPU 卡](../../gpu_matrix.md) +- 已成功安装 vGPU Addon,详情参考 [GPU Addon 安装 ](vgpu_addon.md) +- 已安装 GPU Operator,并已 __关闭 Nvidia.DevicePlugin__ 能力,可参考 [GPU Operator 离线安装](../install_nvidia_driver_of_operator.md) + +## 操作步骤 + +### 界面使用 vGPU + +1. 确认集群是否已检测 GPU 卡。点击对应 __集群__ -> __集群设置__ -> __Addon 插件__ ,查看是否已自动启用并自动检测对应 GPU 类型。 + 目前集群会自动启用 __GPU__ ,并且设置 __GPU__ 类型为 __Nvidia vGPU__ 。 + + ![安装 vgpu](../../../../../images/vgpu-cluster.png) + +2. 部署工作负载,点击对应 __集群__ -> __工作负载__ ,通过镜像方式部署工作负载,选择类型(Nvidia vGPU)之后,会自动出现如下几个参数需要填写: + + - **物理卡数量(nvidia.com/vgpu)**:表示当前 Pod 需要挂载几张物理卡,输入值必须为整数且 **小于等于** 宿主机上的卡数量。 + - **GPU 算力(nvidia.com/gpucores)**: 表示每张卡占用的 GPU 算力,值范围为 0-100; + 如果配置为 0, 则认为不强制隔离;配置为100,则认为独占整张卡。 + - **GPU 显存(nvidia.com/gpumem)**: 表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值。 + + > 如果上述值配置的有问题则会出现调度失败,资源分配不了的情况。 + + ![部署工作负载](../../../../../images/vgpu-deployment.png) + +### YAML 配置使用 vGPU + +参考如下工作负载配置,在资源申请和限制配置中增加 __nvidia.com/vgpu: '1'__ 参数来配置应用使用物理卡的数量。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: full-vgpu-demo + namespace: default +spec: + replicas: 1 + selector: + matchLabels: + app: full-vgpu-demo + template: + metadata: + creationTimestamp: null + labels: + app: full-vgpu-demo + spec: + containers: + - name: full-vgpu-demo1 + image: chrstnhntschl/gpu_burn + resources: + limits: + nvidia.com/gpucores: '20' # 申请每张卡占用 20% 的 GPU 算力 + nvidia.com/gpumem: '200' # 申请每张卡占用 200MB 的显存 + nvidia.com/vgpu: '1' # 申请GPU的数量 + imagePullPolicy: Always + restartPolicy: Always +``` diff --git a/docs/zh/docs/end-user/kpanda/gpu/nvidia/yum_source_redhat7_9.md b/docs/zh/docs/end-user/kpanda/gpu/nvidia/yum_source_redhat7_9.md new file mode 100644 index 0000000..d8ef38d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/nvidia/yum_source_redhat7_9.md @@ -0,0 +1,112 @@ +# 构建 Red Hat 7.9 离线 yum 源 + +## 使用场景介绍 + +算丰 AI 算力平台预置了 CentOS 7.9,内核为 3.10.0-1160 的 GPU Operator 离线包。其它 OS 类型的节点或内核需要用户手动构建离线 yum 源。 + +本文介绍如何基于全局服务集群任意节点构建 Red Hat 7.9 离线 yum 源包,并在安装 Gpu Operator 时使用 `RepoConfig.ConfigMapName` 参数。 + +## 前提条件 + +1. 待部署 GPU Operator 的集群节点 OS 必须为 Red Hat 7.9,且内核版本完全一致 +1. 准备一个能够与待部署 GPU Operator 的集群网络联通的文件服务器,如 nginx 或 minio +1. 准备一个能够访问互联网、待部署 GPU Operator 的集群和文件服务器的节点, + 且节点上已经完成 Docker 的安装 +1. 全局服务集群的节点必须为 Red Hat 7.9 + +## 操作步骤 + +### 1. 构建相关内核版本的离线 Yum 源 + +1. [下载 rhel7.9 ISO](https://developers.redhat.com/products/rhel/download#assembly-field-downloads-page-content-61451) + + ![下载 rhel7.9 ISO](../images/rhel7.9.png) + +2. 下载与 Kubean 版本对应的的 [rhel7.9 ospackage](https://github.com/kubean-io/kubean/releases) + + 在 **容器管理** 的全局服务集群中找到 **Helm 应用** ,搜索 kubean,可查看 kubean 的版本号。 + + ![kubean](../images/kubean.png) + + 在 [kubean的代码仓库](https://github.com/kubean-io/kubean/releases) 中下载该版本的 rhel7.9 ospackage。 + + ![kubean 的代码仓库](../images/redhat0.12.2.png) + +3. 通过安装器导入离线资源 + + 参考[导入离线资源文档](../../../../install/import.md)。 + +### 2. 下载 Red Hat 7.9 OS 的离线驱动镜像 + +[点击查看下载地址](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/driver/tags)。 + +![driveimage](../images/driveimage.png) + +### 3. 向火种节点仓库上传 Red Hat GPU Opreator 离线镜像 + +参考[向火种节点仓库上传 Red Hat GPU Opreator 离线镜像](./push_image_to_repo.md)。 + +!!! note + + 此参考以 rhel8.4 为例,请注意修改成 rhel7.9。 + +### 4. 在集群创建配置项用来保存 Yum 源信息 + +在待部署 GPU Operator 集群的控制节点上运行以下命令。 + +1. 执行如下命令创建名为 __CentOS-Base.repo__ 的文件,用来指定 yum 源存储的配置信息。 + + ```bash + # 文件名称必须为 CentOS-Base.repo,否则安装 gpu-operator 时无法被识别 + cat > CentOS-Base.repo << EOF + [extension-0] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # 火种节点的的文件服务器地址,一般为{火种节点 IP} + {9000 端口} + gpgcheck = 0 + name = kubean extension 0 + + [extension-1] + baseurl = http://10.5.14.200:9000/centos-base/centos-base # 火种节点的的文件服务器地址,一般为{火种节点 IP} + {9000 端口} + gpgcheck = 0 + name = kubean extension 1 + EOF + ``` + +2. 基于创建的 __CentOS-Base.repo__ 文件,在 gpu-operator 命名空间下,创建名为 __local-repo-config__ 的配置文件: + + ```bash + kubectl create configmap local-repo-config -n gpu-operator --from-file=CentOS-Base.repo=/etc/yum.repos.d/extension.repo + ``` + + 预期输出如下: + + ```console + configmap/local-repo-config created + ``` + + __local-repo-config__ 配置文件用于在安装 gpu-operator 时,提供 `RepoConfig.ConfigMapName` 参数的值,配置文件名称用户可自定义。 + +3. 查看 __local-repo-config__ 的配置文件的内容: + + ```bash + kubectl get configmap local-repo-config -n gpu-operator -oyaml + ``` + + 预期输出如下: + + ```yaml title="local-repo-config.yaml" + apiVersion: v1 + data: + CentOS-Base.repo: "[extension-0]\nbaseurl = http://10.6.232.5:32618/centos-base # 步骤 2 中,放置 yum 源的文件服务器路径 \ngpgcheck = 0\nname = kubean extension 0\n \n[extension-1]\nbaseurl + = http://10.6.232.5:32618/centos-base # 步骤 2 中,放置 yum 源的文件服务器路径 \ngpgcheck = 0\nname + = kubean extension 1\n" + kind: ConfigMap + metadata: + creationTimestamp: "2023-10-18T01:59:02Z" + name: local-repo-config + namespace: gpu-operator + resourceVersion: "59445080" + uid: c5f0ebab-046f-442c-b932-f9003e014387 + ``` + +至此,您已成功为待部署 GPU Operator 的集群创建了离线 yum 源配置文件。 +其中在[离线安装 GPU Operator](./install_nvidia_driver_of_operator.md) 时使用了 `RepoConfig.ConfigMapName` 参数。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/vgpu_quota.md b/docs/zh/docs/end-user/kpanda/gpu/vgpu_quota.md new file mode 100644 index 0000000..c38e823 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/vgpu_quota.md @@ -0,0 +1,23 @@ +# GPU 配额管理 + +本节介绍如何在算丰 AI 算力平台使用 vGPU 能力。 + +## 前提条件 + +当前集群已通过 Operator 或手动方式部署对应类型 GPU 驱动(NVIDIA GPU、NVIDIA MIG、天数、昇腾) + +## 操作步骤 + +1. 进入 Namespaces 中,点击 **配额管理** 可以配置当前 Namespace 可以使用的 GPU 资源。 + + ![配额管理](../../../images/cluster-ns.png) + +2. 当前命名空间配额管理覆盖的卡类型为:NVIDIA vGPU、NVIDIA MIG、天数、昇腾。 + + **NVIDIA vGPU 配额管理** :配置具体可以使用的配额,会创建 ResourcesQuota CR: + + - 物理卡数量(nvidia.com/vgpu):表示当前 POD 需要挂载几张物理卡,并且要 **小于等于** 宿主机上的卡数量。 + - GPU 算力(nvidia.com/gpucores):表示每张卡占用的 GPU 算力,值范围为 0-100;如果配置为 0,则认为不强制隔离;配置为 100,则认为独占整张卡。 + - GPU 显存(nvidia.com/gpumem):表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值。 + + ![卡类型](../../../images/vgpu-quota.png) diff --git a/docs/zh/docs/end-user/kpanda/gpu/volcano/drf.md b/docs/zh/docs/end-user/kpanda/gpu/volcano/drf.md new file mode 100644 index 0000000..6235e63 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/volcano/drf.md @@ -0,0 +1,67 @@ +# DRF(Dominant Resource Fairness) 调度策略 + +DRF 调度策略认为占用资源较少的任务具有更高的优先级。这样能够满足更多的作业,不会因为一个胖业务, +饿死大批小业务。DRF 调度算法能够确保在多种类型资源共存的环境下,尽可能满足分配的公平原则。 + +## 使用方式 + +DRF 调度策略默认已启用,无需任何配置。 + +```shell +kubectl -n volcano-system view configmaps volcano-scheduler-configmap +``` + +## 使用案例 + +在 AI 训练,或大数据计算中,通过有限运行使用资源少的任务,这样可以让集群资源使用率更高,而且还能避免小任务被饿死。 +如下创建两个 Job,一个是小资源需求,一个是大资源需求,可以看出来小资源需求的 Job 优先运行起来。 + +```shell +cat < + + ```yaml + kind: Deployment + apiVersion: apps/v1 + metadata: + name: numa-tset + spec: + replicas: 1 + selector: + matchLabels: + app: numa-tset + template: + metadata: + labels: + app: numa-tset + annotations: + volcano.sh/numa-topology-policy: single-numa-node # set the topology policy + spec: + containers: + - name: container-1 + image: nginx:alpine + resources: + requests: + cpu: 2 # 必须为整数,且需要与limits中一致 + memory: 2048Mi + limits: + cpu: 2 # 必须为整数,且需要与requests中一致 + memory: 2048Mi + imagePullSecrets: + - name: default-secret + ``` + +2. 示例二:创建一个 Volcano Job,并使用 NUMA 亲和性。 + + ```yaml + apiVersion: batch.volcano.sh/v1alpha1 + kind: Job + metadata: + name: vj-test + spec: + schedulerName: volcano + minAvailable: 1 + tasks: + - replicas: 1 + name: "test" + topologyPolicy: best-effort # set the topology policy for task + template: + spec: + containers: + - image: alpine + command: ["/bin/sh", "-c", "sleep 1000"] + imagePullPolicy: IfNotPresent + name: running + resources: + limits: + cpu: 20 + memory: "100Mi" + restartPolicy: OnFailure + ``` + +### NUMA 调度分析 + +假设 NUMA 节点情况如下: + +| 工作节点 | 节点策略拓扑管理器策略 | NUMA 节点 0 上的可分配 CPU | NUMA 节点 1 上的可分配 CPU | +|--------|------------------|---------------------|---------------------| +| node-1 | single-numa-node | 16U | 16U | +| node-2 | best-effort | 16U | 16U | +| node-3 | best-effort | 20U | 20U | + +- [示例一](#eg1)中,Pod 的 CPU 申请值为 2U,设置拓扑策略为“single-numa-node”,因此会被调度到相同策略的 node-1。 +- [示例二](#eg2)中,Pod 的 CPU 申请值为20U,设置拓扑策略为“best-effort”,它将被调度到 node-3, + 因为 node-3 可以在单个 NUMA 节点上分配 Pod 的 CPU 请求,而 node-2 需要在两个 NUMA 节点上执行此操作。 + +### 查看当前节点的 CPU 概况 + +您可以通过 lscpu 命令查看当前节点的 CPU 概况: + +```sh +lscpu +... +CPU(s): 32 +NUMA node(s): 2 +NUMA node0 CPU(s): 0-15 +NUMA node1 CPU(s): 16-31 +``` + +### 查看当前节点的 CPU 分配 + +然后查看 NUMA 节点使用情况: + +```sh +# 查看当前节点的 CPU 分配 +cat /var/lib/kubelet/cpu_manager_state +{"policyName":"static","defaultCpuSet":"0,10-15,25-31","entries":{"777870b5-c64f-42f5-9296-688b9dc212ba":{"container-1":"16-24"},"fb15e10a-b6a5-4aaa-8fcd-76c1aa64e6fd":{"container-1":"1-9"}},"checksum":318470969} +``` + +以上示例中表示,节点上运行了两个容器,一个占用了 NUMA node0 的1-9 核,另一个占用了 NUMA node1 的 16-24 核。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano-gang-scheduler.md b/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano-gang-scheduler.md new file mode 100644 index 0000000..5fc53b6 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano-gang-scheduler.md @@ -0,0 +1,179 @@ +# 使用 Volcano 的 Gang Scheduler + +Gang 调度策略是 volcano-scheduler 的核心调度算法之一,它满足了调度过程中的 “All or nothing” 的调度需求, +避免 Pod 的任意调度导致集群资源的浪费。具体算法是,观察 Job 下的 Pod 已调度数量是否满足了最小运行数量, +当 Job 的最小运行数量得到满足时,为 Job 下的所有 Pod 执行调度动作,否则,不执行。 + +## 使用场景 + +基于容器组概念的 Gang 调度算法十分适合需要多进程协作的场景。AI 场景往往包含复杂的流程, +Data Ingestion、Data Analysts、Data Splitting、Trainer、Serving、Logging 等, +需要一组容器进行协同工作,就很适合基于容器组的 Gang 调度策略。 +MPI 计算框架下的多线程并行计算通信场景,由于需要主从进程协同工作,也非常适合使用 Gang 调度策略。 +容器组下的容器高度相关也可能存在资源争抢,整体调度分配,能够有效解决死锁。 + +在集群资源不足的场景下,Gang 的调度策略对于集群资源的利用率的提升是非常明显的。 +比如集群现在只能容纳 2 个 Pod,现在要求最小调度的 Pod 数为 3。 +那现在这个 Job 的所有的 Pod 都会 pending,直到集群能够容纳 3 个 Pod,Pod 才会被调度。 +有效防止调度部分 Pod,不满足要求又占用了资源,使其他 Job 无法运行的情况。 + +## 概念说明 + +Gang Scheduler 是 Volcano 的核心的调度插件,安装 Volcano 后默认就开启了。 +在创建工作负载时只需要指定调度器的名称为 Volcano 即可。 + +Volcano 是以 PodGroup 为单位进行调度的,在创建工作负载时,并不需要手动创建 PodGroup 资源, +Volcano 会根据工作负载的信息自动创建。下面是一个 PodGroup 的示例: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + name: test + namespace: default +spec: + minMember: 1 # (1)! + minResources: # (2)! + cpu: "3" + memory: "2048Mi" + priorityClassName: high-prority # (3)! + queue: default # (4)! +``` + +1. 表示该 PodGroup 下 **最少** 需要运行的 Pod 或任务数量。 + 如果集群资源不满足 miniMember 数量任务的运行需求,调度器将不会调度任何一个该 PodGroup 内的任务。 +2. 表示运行该 PodGroup 所需要的最少资源。当集群可分配资源不满足 minResources 时,调度器将不会调度任何一个该 PodGroup 内的任务。 +3. 表示该 PodGroup 的优先级,用于调度器为该 queue 中所有 PodGroup 进行调度时进行排序。 + **system-node-critical** 和 **system-cluster-critical** 是 2 个预留的值,表示最高优先级。不特别指定时,默认使用 default 优先级或 zero 优先级。 +4. 表示该 PodGroup 所属的 queue。queue 必须提前已创建且状态为 open。 + +## 使用案例 + +在 MPI 计算框架下的多线程并行计算通信场景中,我们要确保所有的 Pod 都能调度成功才能保证任务正常完成。 +设置 minAvailable 为 4,表示要求 1 个 mpimaster 和 3 个 mpiworker 能运行。 + +```yaml +apiVersion: batch.volcano.sh/v1alpha1 +kind: Job +metadata: + name: lm-mpi-job + labels: + "volcano.sh/job-type": "MPI" +spec: + minAvailable: 4 + schedulerName: volcano + plugins: + ssh: [] + svc: [] + policies: + - event: PodEvicted + action: RestartJob + tasks: + - replicas: 1 + name: mpimaster + policies: + - event: TaskCompleted + action: CompleteJob + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + MPI_HOST=`cat /etc/volcano/mpiworker.host | tr "\n" ","`; + mkdir -p /var/run/sshd; /usr/sbin/sshd; + mpiexec --allow-run-as-root --host ${MPI_HOST} -np 3 mpi_hello_world; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpimaster + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "500m" + limits: + cpu: "500m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret + - replicas: 3 + name: mpiworker + template: + spec: + containers: + - command: + - /bin/sh + - -c + - | + mkdir -p /var/run/sshd; /usr/sbin/sshd -D; + image: docker.m.daocloud.io/volcanosh/example-mpi:0.0.1 + name: mpiworker + ports: + - containerPort: 22 + name: mpijob-port + workingDir: /home + resources: + requests: + cpu: "1000m" + limits: + cpu: "1000m" + restartPolicy: OnFailure + imagePullSecrets: + - name: default-secret +``` + +生成 PodGroup 的资源: + +```yaml +apiVersion: scheduling.volcano.sh/v1beta1 +kind: PodGroup +metadata: + annotations: + creationTimestamp: "2024-05-28T09:18:50Z" + generation: 5 + labels: + volcano.sh/job-type: MPI + name: lm-mpi-job-9c571015-37c7-4a1a-9604-eaa2248613f2 + namespace: default + ownerReferences: + - apiVersion: batch.volcano.sh/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: Job + name: lm-mpi-job + uid: 9c571015-37c7-4a1a-9604-eaa2248613f2 + resourceVersion: "25173454" + uid: 7b04632e-7cff-4884-8e9a-035b7649d33b +spec: + minMember: 4 + minResources: + count/pods: "4" + cpu: 3500m + limits.cpu: 3500m + pods: "4" + requests.cpu: 3500m + minTaskMember: + mpimaster: 1 + mpiworker: 3 + queue: default +status: + conditions: + - lastTransitionTime: "2024-05-28T09:19:01Z" + message: '3/4 tasks in gang unschedulable: pod group is not ready, 1 Succeeded, + 3 Releasing, 4 minAvailable' + reason: NotEnoughResources + status: "True" + transitionID: f875efa5-0358-4363-9300-06cebc0e7466 + type: Unschedulable + - lastTransitionTime: "2024-05-28T09:18:53Z" + reason: tasks in gang are ready to be scheduled + status: "True" + transitionID: 5a7708c8-7d42-4c33-9d97-0581f7c06dab + type: Scheduled + phase: Pending + succeeded: 1 +``` + +从 PodGroup 可以看出,通过 ownerReferences 关联到工作负载,并设置最小运行的 Pod 数为 4。 diff --git a/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano_binpack.md b/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano_binpack.md new file mode 100644 index 0000000..6660046 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano_binpack.md @@ -0,0 +1,160 @@ +# 使用 Volcano Binpack 调度策略 + +Binpack 调度算法的目标是尽量把已被占用的节点填满(尽量不往空白节点分配)。具体实现上,Binpack 调度算法会给投递的节点打分, +分数越高表示节点的资源利用率越高。通过尽可能填满节点,将应用负载靠拢在部分节点,这种调度算法能够尽可能减小节点内的碎片, +在空闲的机器上为申请了更大资源请求的 Pod 预留足够的资源空间,使集群下空闲资源得到最大化的利用。 + +## 前置条件 + +预先在算丰 AI 算力平台上[安装 Volcano 组件](./volcano_user_guide.md)。 + +## Binpack 算法原理 + +Binpack 在对一个节点打分时,会根据 Binpack 插件自身权重和各资源设置的权重值综合打分。 +首先,对 Pod 请求资源中的每类资源依次打分,以 CPU 为例,CPU 资源在待调度节点的得分信息如下: + +``` +CPU.weight * (request + used) / allocatable +``` + +即 CPU 权重值越高,得分越高,节点资源使用量越满,得分越高。Memory、GPU 等资源原理类似。其中: + +- CPU.weight 为用户设置的 CPU 权重 +- request 为当前 Pod 请求的 CPU 资源量 +- used 为当前节点已经分配使用的 CPU 量 +- allocatable 为当前节点 CPU 可用总量 + +通过 Binpack 策略的节点总得分如下: + +``` +binpack.weight - (CPU.score + Memory.score + GPU.score) / (CPU.weight + Memory.weight + GPU.weight) - 100 +``` + +即 Binpack 插件的权重值越大,得分越高,某类资源的权重越大,该资源在打分时的占比越大。其中: + +- binpack.weight 为用户设置的装箱调度策略权重 +- CPU.score 为 CPU 资源得分,CPU.weight 为 CPU 权重 +- Memory.score 为 Memory 资源得分,Memory.weight 为 Memory 权重 +- GPU.score 为 GPU 资源得分,GPU.weight 为 GPU 权重 + +![原理](../images/volcano-binpack1.png) + +如图所示,集群中存在两个节点,分别为 Node1 和 Node 2,在调度 Pod 时,Binpack 策略对两个节点分别打分。 +假设集群中 CPU.weight 配置为 1,Memory.weight 配置为 1,GPU.weight 配置为 2,binpack.weight 配置为 5。 + +1. Binpack 对 Node 1 的资源打分,各资源的计算公式为: + + - CPU Score: + + CPU.weight - (request + used) / allocatable = 1 - (2 + 4) / 8 = 0.75 + + - Memory Score: + + Memory.weight - (request + used) / allocatable = 1 - (4 + 8) / 16 = 0.75 + + - GPU Score: + + GPU.weight - (request + used) / allocatable = 2 - (4 + 4) / 8 = 2 + +1. 节点总得分的计算公式为: + + ``` + binpack.weight - (CPU.score + Memory.score + GPU.score) / (CPU.weight + Memory.weight + GPU.weight) - 100 + ``` + + 假设 binpack.weight 配置为 5,Node 1 在 Binpack 策略下的得分为: + + ``` + 5 - (0.75 + 0.75 + 2) / (1 + 1 + 2) - 100 = 437.5 + ``` + +1. Binpack 对 Node 2 的资源打分: + + - CPU Score: + + CPU.weight - (request + used) / allocatable = 1 - (2 + 6) / 8 = 1 + + - Memory Score: + + Memory.weight - (request + used) / allocatable = 1 - (4 + 8) / 16 = 0.75 + + - GPU Score: + + GPU.weight - (request + used) / allocatable = 2 - (4 + 4) / 8 = 2 + +1. Node 2 在 Binpack 策略下的得分为: + + ``` + 5 - (1 + 0.75 + 2) / (1 + 1 + 2) - 100 = 468.75 + ``` + +综上,Node 2 得分大于 Node 1,按照 Binpack 策略,Pod 将会优先调度至 Node 2。 + +## 使用案例 + +Binpack 调度插件在安装 Volcano 的时候默认就会开启;如果用户没有配置权重,则使用如下默认的配置权重。 + +```yaml +- plugins: + - name: binpack + arguments: + binpack.weight: 1 + binpack.cpu: 1 + binpack.memory: 1 +``` + +默认权重不能体现堆叠特性,因此需要修改为 `binpack.weight: 10`。 + +```shell +kubectl -n volcano-system edit configmaps volcano-scheduler-configmap +``` + +```yaml +- plugins: + - name: binpack + arguments: + binpack.weight: 10 + binpack.cpu: 1 + binpack.memory: 1 + binpack.resources: nvidia.com/gpu, example.com/foo + binpack.resources.nvidia.com/gpu: 2 + binpack.resources.example.com/foo: 3 +``` + +改好之后重启 volcano-scheduler Pod 使其生效。 + +创建如下的 Deployment。 + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: binpack-test + labels: + app: binpack-test +spec: + replicas: 2 + selector: + matchLabels: + app: test + template: + metadata: + labels: + app: test + spec: + schedulerName: volcano + containers: + - name: test + image: busybox + imagePullPolicy: IfNotPresent + command: ["sh", "-c", 'echo "Hello, Kubernetes!" && sleep 3600'] + resources: + requests: + cpu: 500m + limits: + cpu: 500m +``` + +在两个 Node 的集群上可以看到 Pod 被调度到一个 Node 上。 + +![结果](../images/volcano-binpacknode.png) diff --git a/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano_priority.md b/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano_priority.md new file mode 100644 index 0000000..10600b3 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/gpu/volcano/volcano_priority.md @@ -0,0 +1,199 @@ +# 优先级抢占(Preemption scheduling)策略 + +Volcano 通过 Priority 插件实现了优先级抢占策略,即 Preemption scheduling 策略。在集群资源有限且多个 Job 等待调度时, +如果使用 Kubernetes 默认调度器,可能会导致具有更多 Pod 数量的 Job 分得更多资源。而 Volcano-scheduler 提供了算法,支持不同的 Job 以 fair-share 的形式共享集群资源。 + +Priority 插件允许用户自定义 Job 和 Task 的优先级,并根据需求在不同层次上定制调度策略。 +例如,对于金融场景、物联网监控场景等需要较高实时性的应用,Priority 插件能够确保其优先得到调度。 + +## 使用方式 + +优先级的决定基于配置的 PriorityClass 中的 Value 值,值越大优先级越高。默认已启用,无需修改。可通过以下命令确认或修改。 + +```shell +kubectl -n volcano-system edit configmaps volcano-scheduler-configmap +``` + +## 使用案例 + +假设集群中存在两个空闲节点,并有三个优先级不同的工作负载:high-priority、med-priority 和 low-priority。 +当 high-priority 工作负载运行并占满集群资源后,再提交 med-priority 和 low-priority 工作负载。 +由于集群资源全部被更高优先级的工作负载占用,med-priority 和 low-priority 工作负载将处于 pending 状态。 +当 high-priority 工作负载结束后,根据优先级调度原则,med-priority 工作负载将优先被调度。 + +1. 通过 priority.yaml 创建 3 个优先级定义,分别为:high-priority,med-priority,low-priority。 + + ```yaml title="查看 priority.yaml" + cat < **Helm 应用** -> **Helm 模板** 中找到 Volcano 并安装。 + + ![Volcano helm 模板](../../images/volcano-01.png) + + ![安装 Volcano](../../images/volcano-02.png) + +2. 检查并确认 Volcano 是否安装完成,即 volcano-admission、volcano-controllers、volcano-scheduler 组件是否正常运行。 + + ![Volcano 组件](../../images/volcano-03.png) + +通常 Volcano 会和 AI Lab 平台配合使用,以实现数据集、Notebook、任务训练的整个开发、训练流程的有效闭环。 diff --git a/docs/zh/docs/end-user/kpanda/helm/Import-addon.md b/docs/zh/docs/end-user/kpanda/helm/Import-addon.md new file mode 100644 index 0000000..1ecc25e --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/helm/Import-addon.md @@ -0,0 +1,105 @@ +# 将自定义 Helm 应用导入系统内置 Addon + +本文从离线和在线两种环境说明如何将 Helm 应用导入到系统内置的 Addon 中。 + +## 离线环境 + +离线环境指的是无法连通互联网或封闭的私有网络环境。 + +### 前提条件 + +- 存在可以运行的 [charts-syncer](https://github.com/DaoCloud/charts-syncer)。 + 若没有,可[点击下载](https://github.com/DaoCloud/charts-syncer/releases)。 +- Helm Chart 已经完成适配 [charts-syncer](https://github.com/DaoCloud/charts-syncer)。 + 即在 Helm Chart 内添加了 `.relok8s-images.yaml` 文件。该文件需要包含 Chart 中所有使用到镜像, + 也可以包含 Chart 中未直接使用的镜像,类似 Operator 中使用的镜像。 + +!!! note + + - 如何编写 Chart 可参考 [image-hints-file](https://github.com/vmware-tanzu/asset-relocation-tool-for-kubernetes#image-hints-file)。 + 要求镜像的 registry 和 repository 必须分开,因为 load 镜像时需替换或修改 registry/repository。 + - 安装器所在的火种集群已安装 [charts-syncer](https://github.com/DaoCloud/charts-syncer)。 + 若将自定义 Helm 应用导入安装器所在火种集群,可跳过下载直接适配; + 若未安装 [charts-syncer](https://github.com/DaoCloud/charts-syncer)二进制文件, + 可[立即下载](https://github.com/DaoCloud/charts-syncer/releases)。 + +### 同步 Helm Chart + +1. 进入`容器管理` -> `Helm 应用` -> `Helm 仓库`,搜索 addon,获取内置仓库地址和用户名/密码(系统内置仓库默认用户名/密码为 rootuser/rootpass123)。 + + ![helmlist](../../../images/helmlist.png) + + ![helmdetail](../../../images/helmdetail.png) + +1. 同步 Helm Chart 到容器管理内置仓库 Addon + + * 编写如下配置文件,可以根据具体配置修改,并保存为 `sync-dao-2048.yaml`。 + + ```yaml + source: # helm charts 源信息 + repo: + kind: HARBOR # 也可以是任何其他支持的 Helm Chart 仓库类别,比如 CHARTMUSEUM + url: https://release-ci.daocloud.io/chartrepo/community # 需更改为 chart repo url + #auth: # 用户名/密码,若没有设置密码可以不填写 + #username: "admin" + #password: "Harbor12345" + charts: # 需要同步 + - name: dao-2048 # helm charts 信息,若不填写则同步源 helm repo 内所有 charts + versions: + - 1.4.1 + target: # helm charts 目标信息 + containerRegistry: 10.5.14.40 # 镜像仓库 url + repo: + kind: CHARTMUSEUM # 也可以是任何其他支持的 Helm Chart 仓库类别,比如 HARBOR + url: http://10.5.14.40:8081 # 需更改为正确 chart repo url,可以通过 helm repo add $HELM-REPO 验证地址是否正确 + auth: # 用户名/密码,若没有设置密码可以不填写 + username: "rootuser" + password: "rootpass123" + containers: + # kind: HARBOR # 若镜像仓库为 HARBOR 且希望 charts-syncer 自动创建镜像 Repository 则填写该字段 + # auth: # 用户名/密码,若没有设置密码可以不填写 + # username: "admin" + # password: "Harbor12345" + + # leverage .relok8s-images.yaml file inside the Charts to move the container images too + relocateContainerImages: true + ``` + + * 执行 charts-syncer 命令同步 Chart 及其包含的镜像 + + ```sh + charts-syncer sync --config sync-dao-2048.yaml --insecure --auto-create-repository + ``` + + 预期输出为: + + ```console + I1222 15:01:47.119777 8743 sync.go:45] Using config file: "examples/sync-dao-2048.yaml" + W1222 15:01:47.234238 8743 syncer.go:263] Ignoring skipDependencies option as dependency sync is not supported if container image relocation is true or syncing from/to intermediate directory + I1222 15:01:47.234685 8743 sync.go:58] There is 1 chart out of sync! + I1222 15:01:47.234706 8743 sync.go:66] Syncing "dao-2048_1.4.1" chart... + .relok8s-images.yaml hints file found + Computing relocation... + + Relocating dao-2048@1.4.1... + Pushing 10.5.14.40/daocloud/dao-2048:v1.4.1... + Done + Done moving /var/folders/vm/08vw0t3j68z9z_4lcqyhg8nm0000gn/T/charts-syncer869598676/dao-2048-1.4.1.tgz + ``` + +1. 待上一步执行完成后,进入`容器管理` -> `Helm 应用` -> `Helm 仓库`,找到对应 Addon, + 在操作栏点击`同步仓库`,回到 Helm 模板就可以看到上传的 Helm 应用 + + ![helm同步](../../../images/helmsyn.png) + + ![详情2048](../../../images/helm2048.png) + +1. 后续可正常进行安装、升级、卸载 + + ![安装升级](../../../images/Installation-and-upgrade.png) + +## 在线环境 + +在线环境的 Helm Repo 地址为 `release.daocloud.io`。 +如果用户无权限添加 Helm Repo,则无法将自定义 Helm 应用导入系统内置 Addon。 +您可以添加自己搭建的 Helm 仓库,然后按照离线环境中同步 Helm Chart 的步骤将您的 Helm 仓库集成到平台使用。 diff --git a/docs/zh/docs/end-user/kpanda/helm/README.md b/docs/zh/docs/end-user/kpanda/helm/README.md new file mode 100644 index 0000000..69eddfe --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/helm/README.md @@ -0,0 +1,28 @@ +--- +hide: + - toc +--- + +# Helm 模板 + +Helm 是 Kubernetes 的包管理工具,方便用户快速发现、共享和使用 Kubernetes 构建的应用。容器管理模块提供了上百个 Helm 模板,涵盖存储、网络、监控、数据库等主要场景。借助这些模板,您可以通过 UI 界面快速部署、便捷管理 Helm 应用。此外,支持通过[添加 Helm 仓库](helm-repo.md) 添加更多的个性化模板,满足多样需求。 + +![模板](../../../images/helm14.png) + +**关键概念**: + +使用 Helm 时需要了解以下几个关键概念: + +- Chart:一个 Helm 安装包,其中包含了运行一个应用所需要的镜像、依赖和资源定义等,还可能包含 Kubernetes 集群中的服务定义,类似 Homebrew 中的 formula、APT 的 dpkg 或者 Yum 的 rpm 文件。Chart 在算丰 AI 算力平台中称为 __Helm 模板__ 。 + +- Release:在 Kubernetes 集群上运行的一个 Chart 实例。一个 Chart 可以在同一个集群内多次安装,每次安装都会创建一个新的 Release。Release 在算丰 AI 算力平台中称为 __Helm 应用__ 。 + +- Repository:用于发布和存储 Chart 的存储库。Repository 在算丰 AI 算力平台中称为 __Helm 仓库__。 + +更多详细信息,请前往 [Helm 官网](https://helm.sh/)查看。 + +**相关操作**: + +- [上传 Helm 模板](./upload-helm.md),介绍上传 Helm 模板操作。 +- [管理 Helm 应用](helm-app.md),包括安装、更新、卸载 Helm 应用,查看 Helm 操作记录等。 +- [管理 Helm 仓库](helm-repo.md),包括安装、更新、删除 Helm 仓库等。 diff --git a/docs/zh/docs/end-user/kpanda/helm/helm-app.md b/docs/zh/docs/end-user/kpanda/helm/helm-app.md new file mode 100644 index 0000000..6d9a32f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/helm/helm-app.md @@ -0,0 +1,100 @@ +# 管理 Helm 应用 + +容器管理模块支持对 Helm 进行界面化管理,包括使用 Helm 模板创建 Helm 实例、自定义 Helm 实例参数、对 Helm 实例进行全生命周期管理等功能。 + +本节将以 [cert-manager](https://cert-manager.io/docs/) 为例,介绍如何通过容器管理界面创建并管理 Helm 应用。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 安装 Helm 应用 + +参照以下步骤安装 Helm 应用。 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 模板__ ,进入 Helm 模板页面。 + + 在 Helm 模板页面选择名为 __addon__ 的 [Helm 仓库](helm-repo.md),此时界面上将呈现 __addon__ 仓库下所有的 Helm chart 模板。 + 点击名称为 __cert-manager__ 的 Chart。 + + ![找到 chart](../../../images/helm01.png) + +3. 在安装页面,能够看到 Chart 的相关详细信息,在界面右上角选择需要安装的版本,点击 __安装__ 按钮。此处选择 v1.9.1 版本进行安装。 + + ![点击安装](../../../images/helm02.png) + +4. 配置 __名称__ 、 __命名空间__ 及 __版本信息__ ,也可以在下方的 **参数配置** 区域通过修改 YAML 来自定义参数。点击 __确定__ 。 + + ![填写参数](../../../images/helm03.png) + +5. 系统将自动返回 Helm 应用列表,新创建的 Helm 应用状态为 __安装中__ ,等待一段时间后状态变为 __运行中__ 。 + + ![查看状态](../../../images/helm04.png) + +## 更新 Helm 应用 + +当我们通过界面完成一个 Helm 应用的安装后,我们可以对 Helm 应用执行更新操作。注意:只有通过界面安装的 Helm 应用才支持使用界面进行更新操作。 + +参照以下步骤更新 Helm 应用。 + +1. 点击一个集群名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/crd01.png) + +2. 在左侧导航栏,点击 __Helm 应用__ ,进入 Helm 应用列表页面。 + + 在 Helm 应用列表页选择需要更新的 Helm 应用,点击列表右侧的 __┇__ 操作按钮,在下拉选择中选择 __更新__ 操作。 + + ![点击更新](../../../images/helm08.png) + +3. 点击 __更新__ 按钮后,系统将跳转至更新界面,您可以根据需要对 Helm 应用进行更新,此处我们以更新 __dao-2048__ 这个应用的 http 端口为例。 + + ![更新页面](../../../images/helm09.png) + +4. 修改完相应参数后。您可以在参数配置下点击 __变化__ 按钮,对比修改前后的文件,确定无误后,点击底部 __确定__ 按钮,完成 Helm 应用的更新。 + + ![对比变化](../../../images/helm10.png) + +5. 系统将自动返回 Helm 应用列表,右上角弹窗提示 __更新成功__ 。 + + ![更新成功](../../../images/helm11.png) + +## 查看 Helm 操作记录 + +Helm 应用的每次安装、更新、删除都有详细的操作记录和日志可供查看。 + +1. 在左侧导航栏,依次点击 __集群运维__ -> __最近操作__ ,然后在页面上方选择 __Helm 操作__ 标签页。每一条记录对应一次安装/更新/删除操作。 + + ![helm 操作](../../../images/helm05.png) + +2. 如需查看每一次操作的详细日志:在列表右侧点击 __┇__ ,在弹出菜单中选择 __日志__ 。 + + ![选择日志](../../../images/helm06.png) + +3. 此时页面下方将以控制台的形式展示详细的运行日志。 + + ![查看运行日志](../../../images/helm07.png) + +## 删除 Helm 应用 + +参照以下步骤删除 Helm 应用。 + +1. 找到待删除的 Helm 应用所在的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/crd01.png) + +2. 在左侧导航栏,点击 __Helm 应用__ ,进入 Helm 应用列表页面。 + + 在 Helm 应用列表页选择您需要删除的 Helm 应用,点击列表右侧的 __┇__ 操作按钮,在下拉选择中选择 __删除__ 。 + + ![点击删除](../../../images/helm12.png) + +3. 在弹窗内输入 Helm 应用的名称进行确认,然后点击 __删除__ 按钮。 + + ![确认删除](../../../images/helm13.png) diff --git a/docs/zh/docs/end-user/kpanda/helm/helm-repo.md b/docs/zh/docs/end-user/kpanda/helm/helm-repo.md new file mode 100644 index 0000000..822c8bd --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/helm/helm-repo.md @@ -0,0 +1,92 @@ +# 管理 Helm 仓库 + +Helm 仓库是用来存储和发布 Chart 的存储库。Helm 应用模块支持通过 HTTP(s) 协议来访问存储库中的 Chart 包。系统默认内置了下表所示的 4 个 Helm 仓库以满足企业生产过程中的常见需求。 + +| 仓库 | 描述 | 示例 | +| --- | ---- | --- | +| partner | 由生态合作伙伴所提供的各类优质特色 Chart | tidb | +| system | 系统核心功能组件及部分高级功能所必需依赖的 Chart,如必需安装 insight-agent 才能够获取集群的监控信息| Insight | +| addon | 业务场景中常见的 Chart | cert-manager | +| community | Kubernetes 社区较为热门的开源组件 Chart | Istio | + +除上述预置仓库外,您也可以自行添加第三方 Helm 仓库。本文将介绍如何添加、更新第三方 Helm 仓库。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +- 如果使用私有仓库,当前操作用户应拥有对该私有仓库的读写权限。 + +## 引入第三方 Helm 仓库 + +下面以 Kubevela 公开的镜像仓库为例,引入 Helm 仓库并管理。 + +1. 找到需要引入第三方 Helm 仓库的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 仓库__ ,进入 Helm 仓库页面。 + + ![helm仓库](../images/helmrepo01.png) + +3. 在 Helm 仓库页面点击 __创建仓库__ 按钮,进入创建仓库页面,按照下表配置相关参数。 + + - 仓库名称:设置仓库名称。最长 63 个字符,只能包含小写字母、数字及分隔符 __-__ ,且必须以小写字母或数字开头并结尾,例如 kubevela + - 仓库地址:用来指向目标 Helm 仓库的 http(s)地址。例如 + - 跳过 TLS 验证: 如果添加的 Helm 仓库为 https 地址且需跳过 TLS 验证,可以勾选此选项,默认为不勾选 + - 认证方式:连接仓库地址后用来进行身份校验的方式。对于公开仓库,可以选择 __None__ ,私有的仓库需要输入用户名/密码以进行身份校验 + - 标签:为该 Helm 仓库添加标签。例如 key: repo4;value: Kubevela + - 注解:为该 Helm 仓库添加注解。例如 key: repo4;value: Kubevela + - 描述:为该 Helm 仓库添加描述。例如:这是一个 Kubevela 公开 Helm 仓库 + + ![填写参数](../images/helmrepo02.png) + +4. 点击 __确定__ ,完成 Helm 仓库的创建。页面会自动跳转至 Helm 仓库列表。 + + ![确定](../images/helmrepo03.png) + +## 更新 Helm 仓库 + +当 Helm 仓库的地址信息发生变化时,可以更新 Helm 仓库的地址、认证方式、标签、注解及描述信息。 + +1. 找到待更新仓库所在的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 仓库__ ,进入 Helm 仓库列表页面。 + + ![helm仓库](../images/helmrepo01.png) + +3. 在仓库列表页面找到需要更新的 Helm 仓库,在列表右侧点击 __┇__ 按钮,在弹出菜单中点击 __更新__ 。 + + ![点击更新](../images/helmrepo04.png) + +4. 在 __编辑 Helm 仓库__ 页面进行更新,完成后点击 __确定__ 。 + + ![确定](../images/helmrepo05.png) + +5. 返回 Helm 仓库列表,屏幕提示更新成功。 + +## 删除 Helm 仓库 + +除了引入、更新仓库外,您也可以将不需要的仓库删除,包括系统预置仓库和第三方仓库。 + +1. 找到待删除仓库所在的集群,点击集群名称,进入 __集群详情__ 。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏,依次点击 __Helm 应用__ -> __Helm 仓库__ ,进入 Helm 仓库列表页面。 + + ![helm仓库](../images/helmrepo01.png) + +3. 在仓库列表页面找到需要更新的 Helm 仓库,在列表右侧点击 __┇__ 按钮,在弹出菜单中点击 __删除__ 。 + + ![点击删除](../images/helmrepo07.png) + +4. 输入仓库名称进行确认,点击 __删除__ 。 + + ![确认删除](../images/helmrepo08.png) + +5. 返回 Helm 仓库列表,屏幕提示删除成功。 diff --git a/docs/zh/docs/end-user/kpanda/helm/multi-archi-helm.md b/docs/zh/docs/end-user/kpanda/helm/multi-archi-helm.md new file mode 100644 index 0000000..cc0ec9e --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/helm/multi-archi-helm.md @@ -0,0 +1,88 @@ +# Helm 应用多架构和升级导入步骤 + +通常在多架构集群中,也会使用多架构的 Helm 包来部署应用,以解决架构差异带来的部署问题。 +本文将介绍如何将单架构 Helm 应用融合为多架构,以及多架构与多架构 Helm 应用的相互融合。 + +## 导入 + +### 单架构导入 + +准备好待导入的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz` 。 +把路径填写至 __clusterConfig.yml__ 配置文件,例如: + +```yaml +addonPackage: + path: "/home/addon-offline-full-package-v0.9.0-amd64.tar.gz" +``` + +然后执行导入命令: + +```shell +~/dce5-installer cluster-create -c /home/dce5/sample/clusterConfig.yaml -m /home/dce5/sample/manifest.yaml -d -j13 +``` + +### 多架构融合 + +准备好待融合的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz`。 + +以 addon-offline-full-package-v0.9.0-arm64.tar.gz 为例,执行导入命令: + +```shell +~/dce5-installer import-addon -c /home/dce5/sample/clusterConfig.yaml --addon-path=/home/addon-offline-full-package-v0.9.0-arm64.tar.gz +``` + +## 升级 + +### 单架构升级 + +准备好待导入的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz`。 + +把路径填写至 clusterConfig.yml 配置文件,例如: + +```yaml +addonPackage: + path: "/home/addon-offline-full-package-v0.11.0-amd64.tar.gz" +``` + +然后执行导入命令: + +```shell +~/dce5-installer cluster-create -c /home/dce5/sample/clusterConfig.yaml -m /home/dce5/sample/manifest.yaml -d -j13 +``` + +### 多架构融合 + +准备好待融合的离线包 `addon-offline-full-package-${version}-${arch}.tar.gz`。 + +以 addon-offline-full-package-v0.11.0-arm64.tar.gz 为例,执行导入命令: + +```shell +~/dce5-installer import-addon -c /home/dce5/sample/clusterConfig.yaml --addon-path=/home/addon-offline-full-package-v0.11.0-arm64.tar.gz +``` + +## 注意事项 + +### 磁盘空间 + +离线包比较大,且过程中需要解压和 load 镜像,需要预留充足的空间,否则可能在过程中报 “no space left” 而中断。 + +### 失败后重试 + +如果在多架构融合步骤执行失败,重试前需要清理一下残留: + +```shell +rm -rf addon-offline-target-package +``` + +### 镜像空间 + +如果融合的离线包中包含了与导入的离线包不一致的镜像空间,可能会在融合过程中因为镜像空间不存在而报错: + +![helm](../../../images/multi-arch-helm.png) + +解决办法:只需要在融合之前创建好该镜像空间即可,例如上图报错可通过创建镜像空间 localhost 提前避免。 + +### 架构冲突 + +升级至低于 0.12.0 版本的 addon 时,由于目标离线包里的 charts-syncer 没有检查镜像存在则不推送功能,因此会在升级的过程中会重新把多架构冲成单架构。 +例如:在 v0.10 版本将 addon 实现为多架构,此时若升级为 v0.11 版本,则多架构 addon 会被覆盖为单架构;若升级为 0.12.0 及以上版本则仍能够保持多架构。 diff --git a/docs/zh/docs/end-user/kpanda/helm/upload-helm.md b/docs/zh/docs/end-user/kpanda/helm/upload-helm.md new file mode 100644 index 0000000..6f00146 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/helm/upload-helm.md @@ -0,0 +1,63 @@ +--- +hide: + - toc +--- + +# 上传 Helm 模板 + +本文介绍如何上传 Helm 模板,操作步骤见下文。 + +1. 引入 Helm 仓库,操作步骤参考[引入第三方 Helm 仓库](./helm-repo.md)。 + +2. 上传 Helm Chart 到 Helm 仓库。 + + === "客户端上传" + + !!! note + + 此方式适用于 Harbor、ChartMuseum、JFrog 类型仓库。 + + 1. 登录一个可以访问到 Helm 仓库的节点,将 Helm 二进制文件上传到节点,并安装 cm-push 插件(需要连通外网并提前安装 [Git](https://git-scm.com/downloads))。 + + 安装插件流程参考[安装 cm-push 插件](https://github.com/chartmuseum/helm-push)。 + + 2. 推送 Helm Chart 到 Helm 仓库,执行如下命令; + + ```shell + helm cm-push ${charts-dir} ${HELM_REPO_URL} --username ${username} --password ${password} + ``` + + 字段说明: + + - `charts-dir`:Helm Chart 的目录,或者是打包好的 Chart(即 .tgz 文件)。 + - `HELM_REPO_URL`:Helm 仓库的 URL。 + - `username`/`password`:有推送权限的 Helm 仓库用户名和密码。 + - 如果采用 https 访问且需要跳过证书验证,可添加参数 `--insecure` + + === "页面上传" + + !!! note + + 此方式仅适用于 Harbor 类型仓库。 + + 1. 登录网页 Harbor 仓库,请确保登录用户有推送权限; + + 2. 进入到对应项目,选择 __Helm Charts__ 页签,点击页面 __上传__ 按钮,完成 Helm Chart 上传。 + + ![上传 Helm Chart](../images/upload-helm-01.png) + +3. 同步远端仓库数据 + + === "手动同步" + + 默认集群未开启 __Helm 仓库自动刷新__ ,需要执行手动同步操作,大致步骤为: + + 进入 __Helm 应用__ -> __Helm 仓库__ ,点击仓库列表右侧的 __┇__ 按钮,选择 __同步仓库__ ,完成仓库数据同步。 + + ![上传 Helm Chart](../images/upload-helm-02.png) + + === "自动同步" + + 如需开启 Helm 仓库自动同步功能,可进入 __集群运维__ -> __集群设置__ -> __高级配置__ ,开启 Helm 仓库自动刷新开关。 + + ![自动同步](../images/auto-helm.png) diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-01.png b/docs/zh/docs/end-user/kpanda/images/4-5-01.png new file mode 100644 index 0000000..7285bd0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-02.png b/docs/zh/docs/end-user/kpanda/images/4-5-02.png new file mode 100644 index 0000000..e2b079a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-03.png b/docs/zh/docs/end-user/kpanda/images/4-5-03.png new file mode 100644 index 0000000..be727e9 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-backup1.png b/docs/zh/docs/end-user/kpanda/images/4-5-backup1.png new file mode 100644 index 0000000..4f730d5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-backup1.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-backup2.png b/docs/zh/docs/end-user/kpanda/images/4-5-backup2.png new file mode 100644 index 0000000..8e9063f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-backup2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-calico-01.png b/docs/zh/docs/end-user/kpanda/images/4-5-calico-01.png new file mode 100644 index 0000000..1c7ba31 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-calico-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-calico-02.png b/docs/zh/docs/end-user/kpanda/images/4-5-calico-02.png new file mode 100644 index 0000000..9fe81e0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-calico-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-calico-03.png b/docs/zh/docs/end-user/kpanda/images/4-5-calico-03.png new file mode 100644 index 0000000..bd84e73 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-calico-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-registry-01.png b/docs/zh/docs/end-user/kpanda/images/4-5-registry-01.png new file mode 100644 index 0000000..d2907a5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-registry-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-registry-02.png b/docs/zh/docs/end-user/kpanda/images/4-5-registry-02.png new file mode 100644 index 0000000..6103638 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-registry-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-registry-03.png b/docs/zh/docs/end-user/kpanda/images/4-5-registry-03.png new file mode 100644 index 0000000..b27caa8 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-registry-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-registry-04.png b/docs/zh/docs/end-user/kpanda/images/4-5-registry-04.png new file mode 100644 index 0000000..f5308d5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-registry-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-registry-05.png b/docs/zh/docs/end-user/kpanda/images/4-5-registry-05.png new file mode 100644 index 0000000..11b48ed Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-registry-05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-restore1.png b/docs/zh/docs/end-user/kpanda/images/4-5-restore1.png new file mode 100644 index 0000000..475b3a4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-restore1.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-restore2.png b/docs/zh/docs/end-user/kpanda/images/4-5-restore2.png new file mode 100644 index 0000000..8f75735 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-restore2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-01.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-01.png new file mode 100644 index 0000000..543771c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-02.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-02.png new file mode 100644 index 0000000..5bb4954 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-03.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-03.png new file mode 100644 index 0000000..e3d32e7 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-04.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-04.png new file mode 100644 index 0000000..7bf03cf Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-05.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-05.png new file mode 100644 index 0000000..5f553b0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-06.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-06.png new file mode 100644 index 0000000..2e33138 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-06.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-07.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-07.png new file mode 100644 index 0000000..0e26a36 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-07.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-08.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-08.png new file mode 100644 index 0000000..a4abcb0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-08.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/4-5-underlay-09.png b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-09.png new file mode 100644 index 0000000..19811fa Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/4-5-underlay-09.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/access-cluster-100.png b/docs/zh/docs/end-user/kpanda/images/access-cluster-100.png new file mode 100644 index 0000000..47a6799 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/access-cluster-100.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/access-cluster-101.png b/docs/zh/docs/end-user/kpanda/images/access-cluster-101.png new file mode 100644 index 0000000..dabc8b3 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/access-cluster-101.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/access-cluster-102.png b/docs/zh/docs/end-user/kpanda/images/access-cluster-102.png new file mode 100644 index 0000000..581ce56 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/access-cluster-102.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/access-cluster-103.png b/docs/zh/docs/end-user/kpanda/images/access-cluster-103.png new file mode 100644 index 0000000..ae7e31a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/access-cluster-103.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/auto-helm.png b/docs/zh/docs/end-user/kpanda/images/auto-helm.png new file mode 100644 index 0000000..c7ad3bc Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/auto-helm.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/backupd20481.png b/docs/zh/docs/end-user/kpanda/images/backupd20481.png new file mode 100644 index 0000000..e8130b8 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/backupd20481.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/backupd20482.png b/docs/zh/docs/end-user/kpanda/images/backupd20482.png new file mode 100644 index 0000000..b81d1b4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/backupd20482.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/backupd20483.png b/docs/zh/docs/end-user/kpanda/images/backupd20483.png new file mode 100644 index 0000000..a558e54 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/backupd20483.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/backupd20484.png b/docs/zh/docs/end-user/kpanda/images/backupd20484.png new file mode 100644 index 0000000..0f5d372 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/backupd20484.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/best-practice-001.png b/docs/zh/docs/end-user/kpanda/images/best-practice-001.png new file mode 100644 index 0000000..c1beaa9 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/best-practice-001.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-oversold-01.png b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-01.png new file mode 100644 index 0000000..4c516ac Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-oversold-02.png b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-02.png new file mode 100644 index 0000000..9915cc2 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-oversold-03.png b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-03.png new file mode 100644 index 0000000..6cd4e4c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-oversold-04.png b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-04.png new file mode 100644 index 0000000..254aef7 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-oversold-05.png b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-05.png new file mode 100644 index 0000000..800d890 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-oversold-05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-01.png b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-01.png new file mode 100644 index 0000000..25c2188 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-02.png b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-02.png new file mode 100644 index 0000000..d397cf3 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-03.png b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-03.png new file mode 100644 index 0000000..ac925f8 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-04.png b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-04.png new file mode 100644 index 0000000..b98809e Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-scheduler-plugin-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster-setup-001.png b/docs/zh/docs/end-user/kpanda/images/cluster-setup-001.png new file mode 100644 index 0000000..55f23ab Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster-setup-001.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster01.png b/docs/zh/docs/end-user/kpanda/images/cluster01.png new file mode 100644 index 0000000..a778c9e Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster02.png b/docs/zh/docs/end-user/kpanda/images/cluster02.png new file mode 100644 index 0000000..6581988 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster03.png b/docs/zh/docs/end-user/kpanda/images/cluster03.png new file mode 100644 index 0000000..bf1d074 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cluster04.png b/docs/zh/docs/end-user/kpanda/images/cluster04.png new file mode 100644 index 0000000..de986c6 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cluster04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/clusterlist.png b/docs/zh/docs/end-user/kpanda/images/clusterlist.png new file mode 100644 index 0000000..c5b4da7 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/clusterlist.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/config06.png b/docs/zh/docs/end-user/kpanda/images/config06.png new file mode 100644 index 0000000..68f3de2 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/config06.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/crd-cluster-list.png b/docs/zh/docs/end-user/kpanda/images/crd-cluster-list.png new file mode 100644 index 0000000..e7f6347 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/crd-cluster-list.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/crd-instance-list.png b/docs/zh/docs/end-user/kpanda/images/crd-instance-list.png new file mode 100644 index 0000000..8b5ca5c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/crd-instance-list.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/crd-list-01.png b/docs/zh/docs/end-user/kpanda/images/crd-list-01.png new file mode 100644 index 0000000..e0e7fd6 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/crd-list-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/crd-list-02.png b/docs/zh/docs/end-user/kpanda/images/crd-list-02.png new file mode 100644 index 0000000..7f54b4c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/crd-list-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/crd-list-03.png b/docs/zh/docs/end-user/kpanda/images/crd-list-03.png new file mode 100644 index 0000000..b1ce492 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/crd-list-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/crd01.png b/docs/zh/docs/end-user/kpanda/images/crd01.png new file mode 100644 index 0000000..d3c06f0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/crd01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/create-configmap.png b/docs/zh/docs/end-user/kpanda/images/create-configmap.png new file mode 100644 index 0000000..3d7702f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/create-configmap.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/create-depolyment.png b/docs/zh/docs/end-user/kpanda/images/create-depolyment.png new file mode 100644 index 0000000..fe20c7d Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/create-depolyment.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/create004.png b/docs/zh/docs/end-user/kpanda/images/create004.png new file mode 100644 index 0000000..99b8c6d Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/create004.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/create005.png b/docs/zh/docs/end-user/kpanda/images/create005.png new file mode 100644 index 0000000..9c412a8 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/create005.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/create006.png b/docs/zh/docs/end-user/kpanda/images/create006.png new file mode 100644 index 0000000..1cf366e Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/create006.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/create007.png b/docs/zh/docs/end-user/kpanda/images/create007.png new file mode 100644 index 0000000..dca8620 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/create007.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createVpaScale.png b/docs/zh/docs/end-user/kpanda/images/createVpaScale.png new file mode 100644 index 0000000..9a15310 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createVpaScale.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster-ssh01.png b/docs/zh/docs/end-user/kpanda/images/createcluster-ssh01.png new file mode 100644 index 0000000..4e5965c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster-ssh01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster.png b/docs/zh/docs/end-user/kpanda/images/createcluster.png new file mode 100644 index 0000000..7bc0fed Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster01.png b/docs/zh/docs/end-user/kpanda/images/createcluster01.png new file mode 100644 index 0000000..a4e718f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster02.png b/docs/zh/docs/end-user/kpanda/images/createcluster02.png new file mode 100644 index 0000000..af2d2a8 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster03.png b/docs/zh/docs/end-user/kpanda/images/createcluster03.png new file mode 100644 index 0000000..3052fdd Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster04.png b/docs/zh/docs/end-user/kpanda/images/createcluster04.png new file mode 100644 index 0000000..4907d2c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster05.png b/docs/zh/docs/end-user/kpanda/images/createcluster05.png new file mode 100644 index 0000000..5df2b75 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/createcluster06.png b/docs/zh/docs/end-user/kpanda/images/createcluster06.png new file mode 100644 index 0000000..8f5d47f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/createcluster06.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cronjob02.png b/docs/zh/docs/end-user/kpanda/images/cronjob02.png new file mode 100644 index 0000000..7b7b4f4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cronjob02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cronjob03.png b/docs/zh/docs/end-user/kpanda/images/cronjob03.png new file mode 100644 index 0000000..6f07ab5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cronjob03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cronjob04.png b/docs/zh/docs/end-user/kpanda/images/cronjob04.png new file mode 100644 index 0000000..c14a0c4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cronjob04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/cronjob12.png b/docs/zh/docs/end-user/kpanda/images/cronjob12.png new file mode 100644 index 0000000..a387167 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/cronjob12.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/custommetrics.png b/docs/zh/docs/end-user/kpanda/images/custommetrics.png new file mode 100644 index 0000000..312cfdc Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/custommetrics.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/delete001.png b/docs/zh/docs/end-user/kpanda/images/delete001.png new file mode 100644 index 0000000..fe11fac Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/delete001.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/delete002.png b/docs/zh/docs/end-user/kpanda/images/delete002.png new file mode 100644 index 0000000..3396ae0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/delete002.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/delete003.png b/docs/zh/docs/end-user/kpanda/images/delete003.png new file mode 100644 index 0000000..a2bc110 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/delete003.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deletecluster01.png b/docs/zh/docs/end-user/kpanda/images/deletecluster01.png new file mode 100644 index 0000000..77bb5a9 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deletecluster01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deletecluster02.png b/docs/zh/docs/end-user/kpanda/images/deletecluster02.png new file mode 100644 index 0000000..1654220 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deletecluster02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deletecluster03.png b/docs/zh/docs/end-user/kpanda/images/deletecluster03.png new file mode 100644 index 0000000..9d140ca Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deletecluster03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deploy05.png b/docs/zh/docs/end-user/kpanda/images/deploy05.png new file mode 100644 index 0000000..1be8a44 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deploy05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deploy14.png b/docs/zh/docs/end-user/kpanda/images/deploy14.png new file mode 100644 index 0000000..fd4b30b Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deploy14.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deploy15.png b/docs/zh/docs/end-user/kpanda/images/deploy15.png new file mode 100644 index 0000000..5073286 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deploy15.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/deploy16.png b/docs/zh/docs/end-user/kpanda/images/deploy16.png new file mode 100644 index 0000000..d3ba448 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/deploy16.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/faq01.png b/docs/zh/docs/end-user/kpanda/images/faq01.png new file mode 100644 index 0000000..225d370 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/faq01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/faq02.png b/docs/zh/docs/end-user/kpanda/images/faq02.png new file mode 100644 index 0000000..f261535 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/faq02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/faq204.png b/docs/zh/docs/end-user/kpanda/images/faq204.png new file mode 100644 index 0000000..a771fbd Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/faq204.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/gpu_mig04.png b/docs/zh/docs/end-user/kpanda/images/gpu_mig04.png new file mode 100644 index 0000000..a01cdab Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/gpu_mig04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo01.png b/docs/zh/docs/end-user/kpanda/images/helmrepo01.png new file mode 100644 index 0000000..8e11f54 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo02.png b/docs/zh/docs/end-user/kpanda/images/helmrepo02.png new file mode 100644 index 0000000..72df4f5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo03.png b/docs/zh/docs/end-user/kpanda/images/helmrepo03.png new file mode 100644 index 0000000..d822eac Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo04.png b/docs/zh/docs/end-user/kpanda/images/helmrepo04.png new file mode 100644 index 0000000..85046be Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo05.png b/docs/zh/docs/end-user/kpanda/images/helmrepo05.png new file mode 100644 index 0000000..8ba82ef Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo07.png b/docs/zh/docs/end-user/kpanda/images/helmrepo07.png new file mode 100644 index 0000000..cf7c1cc Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo07.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/helmrepo08.png b/docs/zh/docs/end-user/kpanda/images/helmrepo08.png new file mode 100644 index 0000000..047dadd Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/helmrepo08.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/hpa-cronhpa-capability-rule-01.png b/docs/zh/docs/end-user/kpanda/images/hpa-cronhpa-capability-rule-01.png new file mode 100644 index 0000000..30ee0e4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/hpa-cronhpa-capability-rule-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/imagequest.png b/docs/zh/docs/end-user/kpanda/images/imagequest.png new file mode 100644 index 0000000..8a9ccc8 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/imagequest.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-home.png b/docs/zh/docs/end-user/kpanda/images/inspection-home.png new file mode 100644 index 0000000..603832a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-home.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-list-more.png b/docs/zh/docs/end-user/kpanda/images/inspection-list-more.png new file mode 100644 index 0000000..bb22184 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-list-more.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-report-01.png b/docs/zh/docs/end-user/kpanda/images/inspection-report-01.png new file mode 100644 index 0000000..1d88404 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-report-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-report-02.png b/docs/zh/docs/end-user/kpanda/images/inspection-report-02.png new file mode 100644 index 0000000..927d7c2 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-report-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-report-03.png b/docs/zh/docs/end-user/kpanda/images/inspection-report-03.png new file mode 100644 index 0000000..11d621a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-report-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-start-alone.png b/docs/zh/docs/end-user/kpanda/images/inspection-start-alone.png new file mode 100644 index 0000000..35a27f6 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-start-alone.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/inspection-start.png b/docs/zh/docs/end-user/kpanda/images/inspection-start.png new file mode 100644 index 0000000..fb550d1 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/inspection-start.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/join-cluster01.png b/docs/zh/docs/end-user/kpanda/images/join-cluster01.png new file mode 100644 index 0000000..b07542a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/join-cluster01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/join-cluster02.png b/docs/zh/docs/end-user/kpanda/images/join-cluster02.png new file mode 100644 index 0000000..3631364 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/join-cluster02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/knative-install-1.png b/docs/zh/docs/end-user/kpanda/images/knative-install-1.png new file mode 100644 index 0000000..0925c12 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/knative-install-1.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/knative-install-2.png b/docs/zh/docs/end-user/kpanda/images/knative-install-2.png new file mode 100644 index 0000000..c2fa119 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/knative-install-2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/knative-install-3.png b/docs/zh/docs/end-user/kpanda/images/knative-install-3.png new file mode 100644 index 0000000..1e84211 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/knative-install-3.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/knative-request-flow.png b/docs/zh/docs/end-user/kpanda/images/knative-request-flow.png new file mode 100644 index 0000000..dfa6eb4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/knative-request-flow.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-01.png b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-01.png new file mode 100644 index 0000000..a2dc078 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-02.png b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-02.png new file mode 100644 index 0000000..bb4d28f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-03.png b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-03.png new file mode 100644 index 0000000..c7685a4 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-04.png b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-04.png new file mode 100644 index 0000000..968cbbb Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/limit-disk-usage-docker-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/note.svg b/docs/zh/docs/end-user/kpanda/images/note.svg new file mode 100644 index 0000000..5e473ae --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/images/note.svg @@ -0,0 +1,18 @@ + + + + Icon/16/Prompt备份@0.5x + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/images/ns00.png b/docs/zh/docs/end-user/kpanda/images/ns00.png new file mode 100644 index 0000000..7300a9c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/ns00.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/ns01.png b/docs/zh/docs/end-user/kpanda/images/ns01.png new file mode 100644 index 0000000..c199640 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/ns01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/ns02.png b/docs/zh/docs/end-user/kpanda/images/ns02.png new file mode 100644 index 0000000..dad110c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/ns02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/ns03.png b/docs/zh/docs/end-user/kpanda/images/ns03.png new file mode 100644 index 0000000..058390a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/ns03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/ns04.png b/docs/zh/docs/end-user/kpanda/images/ns04.png new file mode 100644 index 0000000..8b8863c Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/ns04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/operator-framework.svg b/docs/zh/docs/end-user/kpanda/images/operator-framework.svg new file mode 100644 index 0000000..d3dc0fa --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/images/operator-framework.svg @@ -0,0 +1 @@ +Operator Framework logo \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/images/permisson02.png b/docs/zh/docs/end-user/kpanda/images/permisson02.png new file mode 100644 index 0000000..4c69bdc Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/permisson02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/remove001.png b/docs/zh/docs/end-user/kpanda/images/remove001.png new file mode 100644 index 0000000..e20f17d Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/remove001.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/rules.png b/docs/zh/docs/end-user/kpanda/images/rules.png new file mode 100644 index 0000000..9cbefbb Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/rules.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/sc01.png b/docs/zh/docs/end-user/kpanda/images/sc01.png new file mode 100644 index 0000000..62d05e0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/sc01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/sc03.png b/docs/zh/docs/end-user/kpanda/images/sc03.png new file mode 100644 index 0000000..0bff950 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/sc03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/sc04 2.png b/docs/zh/docs/end-user/kpanda/images/sc04 2.png new file mode 100644 index 0000000..b96215a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/sc04 2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/sc04.png b/docs/zh/docs/end-user/kpanda/images/sc04.png new file mode 100644 index 0000000..0919834 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/sc04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/sc05.png b/docs/zh/docs/end-user/kpanda/images/sc05.png new file mode 100644 index 0000000..35352a2 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/sc05.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/sc06.png b/docs/zh/docs/end-user/kpanda/images/sc06.png new file mode 100644 index 0000000..1f7dea5 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/sc06.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/secret04.png b/docs/zh/docs/end-user/kpanda/images/secret04.png new file mode 100644 index 0000000..40868ff Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/secret04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/secret08.png b/docs/zh/docs/end-user/kpanda/images/secret08.png new file mode 100644 index 0000000..a986531 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/secret08.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/security08.png b/docs/zh/docs/end-user/kpanda/images/security08.png new file mode 100644 index 0000000..4a1c8ab Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/security08.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/service03.png b/docs/zh/docs/end-user/kpanda/images/service03.png new file mode 100644 index 0000000..338c365 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/service03.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/service04.png b/docs/zh/docs/end-user/kpanda/images/service04.png new file mode 100644 index 0000000..fbd972e Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/service04.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/servicemonitor.png b/docs/zh/docs/end-user/kpanda/images/servicemonitor.png new file mode 100644 index 0000000..fc0f82f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/servicemonitor.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/settings02.png b/docs/zh/docs/end-user/kpanda/images/settings02.png new file mode 100644 index 0000000..e8f301f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/settings02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/success.png b/docs/zh/docs/end-user/kpanda/images/success.png new file mode 100644 index 0000000..79d2a69 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/success.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/update-kpanda.png b/docs/zh/docs/end-user/kpanda/images/update-kpanda.png new file mode 100644 index 0000000..44a204a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/update-kpanda.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/upgrade.png b/docs/zh/docs/end-user/kpanda/images/upgrade.png new file mode 100644 index 0000000..a7566e3 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/upgrade.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/upload-helm-01.png b/docs/zh/docs/end-user/kpanda/images/upload-helm-01.png new file mode 100644 index 0000000..9da7ed6 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/upload-helm-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/upload-helm-02.png b/docs/zh/docs/end-user/kpanda/images/upload-helm-02.png new file mode 100644 index 0000000..9c22ba1 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/upload-helm-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/volcano-01 2.png b/docs/zh/docs/end-user/kpanda/images/volcano-01 2.png new file mode 100644 index 0000000..c176723 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/volcano-01 2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/volcano-01.png b/docs/zh/docs/end-user/kpanda/images/volcano-01.png new file mode 100644 index 0000000..0b03312 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/volcano-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/volcano-02 2.png b/docs/zh/docs/end-user/kpanda/images/volcano-02 2.png new file mode 100644 index 0000000..d79735b Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/volcano-02 2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/volcano-02.png b/docs/zh/docs/end-user/kpanda/images/volcano-02.png new file mode 100644 index 0000000..fbcbf4b Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/volcano-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/volcano-03 2.png b/docs/zh/docs/end-user/kpanda/images/volcano-03 2.png new file mode 100644 index 0000000..5112532 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/volcano-03 2.png differ diff --git a/docs/zh/docs/end-user/kpanda/images/volcano-03.png b/docs/zh/docs/end-user/kpanda/images/volcano-03.png new file mode 100644 index 0000000..97afd08 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/images/volcano-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/inspect/config.md b/docs/zh/docs/end-user/kpanda/inspect/config.md new file mode 100644 index 0000000..0685684 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/inspect/config.md @@ -0,0 +1,52 @@ +--- +hide: + - toc +--- + +# 创建巡检配置 + +算丰 AI 算力平台容器管理模块提供集群巡检功能,支持从集群维度、节点维度、容器组维度进行巡检。 + +- 集群维度:检查集群中系统组件的运行情况,包括集群状态、资源使用情况,以及控制节点特有的巡检项等,例如 __kube-apiserver__ 和 __etcd__ 的状态。 +- 节点维度:包括控制节点和工作节点通用的检查项,例如节点资源使用情况、句柄数、PID 状态、网络状态。 +- 容器组维度:检查 Pod 的 CPU 和内存使用情况、运行状态、PV 和 PVC 的状态等。 + +下面介绍如何创建巡检配置。 + +## 前提条件 + +- 在容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建集群](../clusters/create-cluster.md) +- 所选集群处于 __运行中__ 状态且已经在集群中[安装了 insight 组件](../../../admin/insight/quickstart/install/install-agent.md) + +## 操作步骤 + +1. 在左侧导航栏点击 __集群巡检__ 。 + + ![nav](../../../images/inspect01.png) + +2. 在页面右侧点击 __巡检配置__ 。 + + ![create](../images/inspection-home.png) + +3. 参考以下说明填写巡检配置,然后在页面底部点击 __确定__ 即可。 + + - 集群:下拉选择要对哪些集群进行巡检。**如果选择多个集群,则自动生成多个巡检配置(仅巡检的集群不一致,其他配置都完全一致)** + - 定时巡检:启用后可根据事先设置的巡检频率定期自动执行集群巡检 + - 巡检频率:设置自动巡检的周期,例如每周二上午十点。支持自定义 CronExpression,可参考 [Cron 时间表语法](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax) + - 巡检记录保留条数:累计最多保留多少条巡检记录,包括所有集群的巡检记录 + - 参数配置:参数配置分为集群维度、节点维度、容器组维度三部分,可以根据场景需求启用或禁用某些巡检项。 + + ![basic](../../../images/inspect03.png) + +巡检配置创建完成后,会自动显示在巡检配置列表中。在配置右侧点击更多操作按钮可以立即执行巡检、修改巡检配置、删除巡检配置和巡检记录。 + +- 点击 __巡检__ 可以根据该配置立即执行一次巡检。 +- 点击 __巡检配置__ 可以修改巡检配置。 +- 点击 __删除__ 可以删除该巡检配置和历史的巡检记录 + + ![basic](../images/inspection-list-more.png) + +!!! note + + - 巡检配置创建完成后,如果启用了 __定时巡检__ 配置,则会在指定时间自动执行巡检。 + - 如未启用 __定时巡检__ 配置,则需要手动[触发巡检](inspect.md)。 diff --git a/docs/zh/docs/end-user/kpanda/inspect/index.md b/docs/zh/docs/end-user/kpanda/inspect/index.md new file mode 100644 index 0000000..3dd6e97 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/inspect/index.md @@ -0,0 +1,17 @@ +--- +hide: + - toc +--- + +# 集群巡检 + +集群巡检可以通过自动或手动方式,定期或随时检查集群的整体健康状态,让管理员获得保障集群安全的主动权。 +基于合理的巡检计划,这种主动自发的集群检查可以让管理员随时掌握集群状态,摆脱之前出现故障时只能被动排查问题的困境,做到事先监控、提前防范。 + +算丰 AI 算力平台容器管理模块提供的集群巡检功能,支持从集群、节点、容器组(Pod)三个维度进行自定义巡检项,巡检结束后会自动生成可视化的巡检报告。 + +- 集群维度:检查集群中系统组件的运行情况,包括集群状态、资源使用情况以及控制节点特有的巡检项等,例如 __kube-apiserver__ 和 __etcd__ 的状态。 +- 节点维度:包括控制节点和工作节点通用的检查项,例如节点资源使用情况、句柄数、PID 状态、网络状态。 +- 容器组维度:检查 Pod 的 CPU 和内存使用情况、运行状态、PV 和 PVC 的状态等。 + +如需了解或执行安全方面的巡检,可参考算丰 AI 算力平台支持的[安全扫描类型](../security/index.md)。 diff --git a/docs/zh/docs/end-user/kpanda/inspect/inspect.md b/docs/zh/docs/end-user/kpanda/inspect/inspect.md new file mode 100644 index 0000000..d84c9d5 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/inspect/inspect.md @@ -0,0 +1,40 @@ +--- +hide: + - toc +--- + +# 执行集群巡检 + +巡检配置创建完成后,如果启用了 __定时巡检__ 配置,则会在指定时间自动执行巡检。如未启用 __定时巡检__ 配置,则需要手动触发巡检。 + +此页介绍如何手动执行集群巡检。 + +## 前提条件 + +- 在容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建集群](../clusters/create-cluster.md) +- 已[创建巡检配置](config.md) +- 所选集群处于 __运行中__ 状态且已经在集群中[安装了 insight 组件](../../../admin/insight/quickstart/install/install-agent.md) + +## 操作步骤 + +执行巡检时,支持勾选多个集群进行批量巡检,或者仅对某一个集群进行单独巡检。 + +=== "批量巡检" + + 1. 在容器管理模块的一级导航栏点击 __集群巡检__ ,然后在页面右侧点击 __巡检__ 。 + + ![start](../images/inspection-start.png) + + 2. 勾选需要巡检的集群,然后在页面底部点击 __确定__ 即可。 + + - 若选择多个集群进行同时巡检,系统将根据不同集群的巡检配置进行巡检。 + - 如未设置集群巡检配置,将使用系统默认配置。 + + ![start](../../../images/inspect05.png) + +=== "单独巡检" + + 1. 进入集群巡检页面。 + 2. 在对应巡检配置的右侧点击 __┇__ 更多操作按钮,然后在弹出的菜单中选择 __巡检__ 即可。 + + ![basic](../images/inspection-start-alone.png) diff --git a/docs/zh/docs/end-user/kpanda/inspect/report.md b/docs/zh/docs/end-user/kpanda/inspect/report.md new file mode 100644 index 0000000..7799cb1 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/inspect/report.md @@ -0,0 +1,32 @@ +--- +hide: + - toc +--- + +# 查看巡检报告 + +[巡检执行](inspect.md)完成后,可以查看巡检记录和详细的巡检报告。 + +## 前提条件 + +- 已经[创建了巡检配置](config.md) +- 已经[执行过至少一次巡检](inspect.md) + +## 操作步骤 + +1. 进入集群巡检页面,点击目标巡检集群的名称。 + + ![start](../images/inspection-report-01.png) + +2. 点击想要查看的巡检记录名称。 + + - 每执行一次巡检,就会生成一条巡检记录。 + - 当巡检记录超过[巡检配置](config.md)中设置的最大保留条数时,从执行时间最早的记录开始删除。 + + ![start](../images/inspection-report-02.png) + +3. 查看巡检的详细信息,根据巡检配置可能包括集群资源概览、系统组件的运行情况等。 + + 在页面右上角可以下载巡检报告或删除该项巡检报告。 + + ![start](../images/inspection-report-03.png) diff --git a/docs/zh/docs/end-user/kpanda/namespaces/createns.md b/docs/zh/docs/end-user/kpanda/namespaces/createns.md new file mode 100644 index 0000000..9d46a87 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/namespaces/createns.md @@ -0,0 +1,56 @@ +# 命名空间 + +命名空间是 Kubernetes 中用来进行资源隔离的一种抽象。一个集群下可以包含多个不重名的命名空间,每个命名空间中的资源相互隔离。有关命名空间的详细介绍,可参考[命名空间](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/namespaces/)。 + +本文将介绍命名空间的相关操作。 + +## 创建命名空间 + +支持通过表单轻松创建命名空间,也支持通过编写或导入 YAML 文件快速创建命名空间。 + +!!! note + + - 在创建命名空间之前,需要在容器管理模块[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群。 + - 集群初始化后通常会自动生成默认的命名空间 __default__ 。但对于生产集群而言,为便于管理,建议创建其他的命名空间,而非直接使用 __default__ 命名空间。 + +### 表单创建 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏点击 __命名空间__ ,然后点击页面右侧的 __创建__ 按钮。 + + ![点击创建](../images/ns01.png) + +3. 填写命名空间的名称,配置工作空间和标签(可选设置),然后点击 __确定__ 。 + + !!! info + + - 命名空间绑定工作空间之后,该命名空间的资源就会共享给所绑定的工作空间。有关工作空间的详细说明,可参考[工作空间与层级](../../ghippo/workspace/workspace.md)。 + + - 命名空间创建完成后,仍然可以绑定/解绑工作空间。 + + ![填写表单](../images/ns02.png) + +4. 点击 __确定__ ,完成命名空间的创建。在命名空间列表右侧,点击 __┇__ ,可以从弹出菜单中选择查看 YAML、修改标签、绑定/解绑工作空间、配额管理、删除等更多操作。 + + ![更多操作](../images/ns03.png) + +### YAML 创建 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![集群详情](../images/crd01.png) + +2. 在左侧导航栏点击 __命名空间__ ,然后点击页面右侧的 __YAML 创建__ 按钮。 + + ![点击创建](../images/ns00.png) + +3. 输入或粘贴事先准备好的 YAML 内容,或者从本地直接导入已有的 YAML 文件。 + + > 输入 YAML 内容后,点击 __下载__ 可以将该 YAML 文件保存到本地。 + + ![点击创建](../images/ns04.png) + +4. 最后在弹框右下角点击 __确定__ 即可。 \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/namespaces/exclusive.md b/docs/zh/docs/end-user/kpanda/namespaces/exclusive.md new file mode 100644 index 0000000..a246a8f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/namespaces/exclusive.md @@ -0,0 +1,203 @@ +# 启用命名空间独享节点 + +命名空间独享节点指在 kubernetes 集群中,通过污点和污点容忍的方式实现特定命名空间对一个或多个节点 CPU、内存等资源的独享。为特定命名空间配置独享节点后,其它非此命名空间的应用和服务均不能运行在被独享的节点上。使用独享节点可以让重要应用独享一部分计算资源,从而和其他应用实现物理隔离。 + +!!! note + + 在节点被设置为独享节点前已经运行在此节点上的应用和服务将不会受影响,依然会正常运行在该节点上,仅当这些 Pod 被删除或重建时,才会调度到其它非独享节点上。 + +## 准备工作 + +检查当前集群的 kube-apiserver 是否启用了 __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器。 + +使用命名空间独享节点功能需要用户启用 kube-apiserver 上的 __PodNodeSelector__ 和 __PodTolerationRestriction__ 两个特性准入控制器(Admission Controllers),关于准入控制器更多说明请参阅 [kubernetes Admission Controllers Reference](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)。 + +您可以前往当前集群下任意一个 Master 节点上检查 __kube-apiserver.yaml__ 文件内是否启用了这两个特性,也可以在 Master 节点上执行执行如下命令进行快速检查: + + ```bash + [root@g-master1 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep enable-admission-plugins + + # 预期输出如下: + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +## 在全局服务集群上启用命名空间独享节点 + +由于全局服务集群上运行着 kpanda、ghippo、insight 等平台基础组件,在 Global 启用命名空间独享节点将可能导致当系统组件重启后,系统组件无法调度到被独享的节点上,影响系统的整体高可用能力。因此,**通常情况下,我们不推荐用户在全局服务集群上启用命名空间独享节点特性**。 + +如果您确实需要在全局服务集群上启用命名空间独享节点,请参考以下步骤进行开启: + +1. 为全局服务集群的 kube-apiserver 启用了 __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器 + + !!! note + + 如果集群已启用了上述的两个准入控制器,请跳过此步,直接前往配置系统组件容忍。 + + 前往当前集群下任意一个 Master 节点上修改 __kube-apiserver.yaml__ 配置文件,也可以在 Master 节点上执行执行如下命令进行配置: + + ```bash + [root@g-master1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml + + # 预期输出如下: + apiVersion: v1 + kind: Pod + metadata: + ...... + spec: + containers: + - command: + - kube-apiserver + ...... + - --default-not-ready-toleration-seconds=300 + - --default-unreachable-toleration-seconds=300 + - --enable-admission-plugins=NodeRestriction #启用的准入控制器列表 + - --enable-aggregator-routing=False + - --enable-bootstrap-token-auth=true + - --endpoint-reconciler-type=lease + - --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.crt + ...... + ``` + + 找到 __--enable-admission-plugins__ 参数,加入(以英文逗号分隔的) __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器。参考如下: + + ```bash + # 加入 __ ,PodNodeSelector,PodTolerationRestriction__ + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +2. 为平台组件所在的命名空间添加容忍注解 + + 完成准入控制器的开启后,您需要为平台组件所在的命名空间添加容忍注解,以保证平台组件的高可用。 + + 目前算丰 AI 算力平台的系统组件命名空间如下表: + + | 命名空间 | 所包含的系统组件 | + | ------------------- | ------------------------------------------------------------ | + | kpanda-system | kpanda | + | hwameiStor-system | hwameiStor | + | istio-system | istio | + | metallb-system | metallb | + | cert-manager-system | cert-manager | + | contour-system | contour | + | kubean-system | kubean | + | ghippo-system | ghippo | + | kcoral-system | kcoral | + | kcollie-system | kcollie | + | insight-system | insight、insight-agent: | + | ipavo-system | ipavo | + | kairship-system | kairship | + | karmada-system | karmada | + | amamba-system | amamba、jenkins | + | skoala-system | skoala | + | mspider-system | mspider | + | mcamel-system | mcamel-rabbitmq、mcamel-elasticsearch、mcamel-mysql、mcamel-redis、mcamel-kafka、mcamel-minio、mcamel-postgresql | + | spidernet-system | spidernet | + | kangaroo-system | kangaroo | + | gmagpie-system | gmagpie | + | dowl-system | dowl | + + 检查当前集群中所有命名空间是否存在上述的命名空间,执行如下命令,分别为每个命名空间添加注解: `scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": "NoSchedule", "key": "ExclusiveNamespace"}]'` 。 + + ```bash + kubectl annotate ns scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]' + ``` + 请确保将 `` 替换为要添加注解的平台命名空间名称。 + +3. 使用界面为命名空间设置独享节点 + + 当您确认集群 API 服务器上的 __PodNodeSelector__ 和 __PodTolerationRestriction__ 两个特性准入控制器已经开启后,请参考如下步骤使用算丰 AI 算力平台的 UI 管理界面为命名空间设置独享节点了。 + + 1. 在集群列表页面点击集群名称,然后在左侧导航栏点击 __命名空间__ 。 + + ![命名空间](../../../images/exclusive01.png) + + 2. 点击命名空间名称,然后点击 __独享节点__ 页签,在下方右侧点击 __添加节点__ 。 + + ![添加节点](../../../images/exclusive02.png) + + 3. 在页面左侧选择让该命名空间独享哪些节点,在右侧可以清空或删除某个已选节点,最后在底部点击 __确定__ 。 + + ![确定](../../../images/exclusive03.png) + + 4. 可以在列表中查看此命名空间的已有的独享节点,在节点右侧可以选择 __取消独享__ 。 + + > 取消独享之后,其他命名空间下的 Pod 也可以被调度到该节点上。 + + ![取消独享](../../../images/exclusive04.png) + +## 在 非全局服务集群上启用命名空间独享节点 + +在 非全局服务集群上启用命名空间独享节点,请参考以下步骤进行开启: + +1. 为当前集群的 kube-apiserver 启用了 __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器 + + !!! note + + 如果集群已启用了上述的两个准入控制器,请跳过此步,直接前往界面为命名空间设置独享节点 + + 前往当前集群下任意一个 Master 节点上修改 __kube-apiserver.yaml__ 配置文件,也可以在 Master 节点上执行执行如下命令进行配置: + + ```bash + [root@g-master1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml + + # 预期输出如下: + apiVersion: v1 + kind: Pod + metadata: + ...... + spec: + containers: + - command: + - kube-apiserver + ...... + - --default-not-ready-toleration-seconds=300 + - --default-unreachable-toleration-seconds=300 + - --enable-admission-plugins=NodeRestriction #启用的准入控制器列表 + - --enable-aggregator-routing=False + - --enable-bootstrap-token-auth=true + - --endpoint-reconciler-type=lease + - --etcd-cafile=/etc/kubernetes/ssl/etcd/ca.crt + ...... + ``` + + 找到 __--enable-admission-plugins__ 参数,加入(以英文逗号分隔的) __PodNodeSelector__ 和 __PodTolerationRestriction__ 准入控制器。参考如下: + + ```bash + # 加入 __ ,PodNodeSelector,PodTolerationRestriction__ + - --enable-admission-plugins=NodeRestriction,PodNodeSelector,PodTolerationRestriction + ``` + +2. 使用界面为命名空间设置独享节点 + + 当您确认集群 API 服务器上的 __PodNodeSelector__ 和 __PodTolerationRestriction__ 两个特性准入控制器已经开启后,请参考如下步骤使用算丰 AI 算力平台的 UI 管理界面为命名空间设置独享节点了。 + + 1. 在集群列表页面点击集群名称,然后在左侧导航栏点击 __命名空间__ 。 + + ![命名空间](../../../images/exclusive01.png) + + 2. 点击命名空间名称,然后点击 __独享节点__ 页签,在下方右侧点击 __添加节点__ 。 + + ![添加节点](../../../images/exclusive02.png) + + 3. 在页面左侧选择让该命名空间独享哪些节点,在右侧可以清空或删除某个已选节点,最后在底部点击 __确定__ 。 + + ![确定](../../../images/exclusive03.png) + + 4. 可以在列表中查看此命名空间的已有的独享节点,在节点右侧可以选择 __取消独享__ 。 + + > 取消独享之后,其他命名空间下的 Pod 也可以被调度到该节点上。 + + ![取消独享](../../../images/exclusive04.png) + +3. 为需要高可用的组件所在的命名空间添加容忍注解(可选) + + 执行如下命令,需要高可用的组件所在的命名空间添加注解:`scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]'`。 + + ```bash + kubectl annotate ns scheduler.alpha.kubernetes.io/defaultTolerations: '[{"operator": "Exists", "effect": + "NoSchedule", "key": "ExclusiveNamespace"}]' + ``` + + 请确保将 `` 替换为要添加注解的平台命名空间名称。 diff --git a/docs/zh/docs/end-user/kpanda/namespaces/podsecurity.md b/docs/zh/docs/end-user/kpanda/namespaces/podsecurity.md new file mode 100644 index 0000000..8070eb2 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/namespaces/podsecurity.md @@ -0,0 +1,51 @@ +# 容器组安全策略 + +容器组安全策略指在 kubernetes 集群中,通过为指定命名空间配置不同的等级和模式,实现在安全的各个方面控制 Pod 的行为,只有满足一定的条件的 Pod 才会被系统接受。它设置三个等级和三种模式,用户可以根据自己的需求选择更加合适的方案来设置限制策略。 + +!!! note + + 一条安全模式仅能配置一条安全策略。同时请谨慎为命名空间配置 enforce 的安全模式,违反后将会导致 Pod 无法创建。 + +本节将介绍如何通过容器管理界面为命名空间配置容器组安全策略。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),集群的版本需要在 v1.22 以上,且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并为用户授予 [NS Admin](../permissions/permission-brief.md#ns-admin) 或更高权限,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +## 为命名空间配置容器组安全策略 + +1. 选择需要配置容器组安全策略的命名空间,进入详情页。在 __容器组安全策略__ 页面点击 __配置策略__ ,进入配置页。 + + ![配置策略列表](../../../images/ps01.png) + +2. 在配置页点击 __添加策略__ ,则会出现一条策略,包括安全级别和安全模式,以下是对安全级别和安全策略的详细介绍。 + + | 安全级别 | 描述 | + | ---------- | ------------------------------------------------------------ | + | Privileged | 不受限制的策略,提供最大可能范围的权限许可。此策略允许已知的特权提升。 | + | Baseline | 限制性最弱的策略,禁止已知的策略提升。允许使用默认的(规定最少)Pod 配置。 | + | Restricted | 限制性非常强的策略,遵循当前的保护 Pod 的最佳实践。 | + + | 安全模式 | 描述 | + | -------- | ------------------------------------------------------------ | + | Audit | 违反指定策略会在审计日志中添加新的审计事件,Pod 可以被创建。 | + | Warn | 违反指定策略会返回用户可见的告警信息,Pod 可以被创建。 | + | Enforce | 违反指定策略会导致 Pod 无法创建。 | + + ![添加策略](../../../images/ps02.png) + +3. 不同的安全级别对应不同的检查项,若您不知道该如何为您的命名空间配置,可以点击页面右上角的 __策略配置项说明__ 查看详细信息。 + + ![配置项说明01](../../../images/ps03.png) + + ![配置项说明01](../../../images/ps04.png) + +4. 点击确定,若创建成功,则页面上将出现您配置的安全策略。 + + ![创建成功](../../../images/ps05.png) + +5. 点击 __┇__ 还可以编辑或者删除您配置的安全策略。 + + ![操作](../../../images/ps06.png) \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/network/create-ingress.md b/docs/zh/docs/end-user/kpanda/network/create-ingress.md new file mode 100644 index 0000000..8acbf1e --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/network/create-ingress.md @@ -0,0 +1,90 @@ +# 创建路由(Ingress) + +在 Kubernetes 集群中,[Ingress](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#ingress-v1beta1-networking-k8s-io) 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 +流量路由由 Ingress 资源上定义的规则控制。下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例: + +![ingress-diagram](../../../images/ingress.svg) + +Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 +- 已经完成 Ingress 实例的创建,已[部署应用工作负载](../workloads/create-deployment.md),并且已[创建对应 Service](create-services.md) +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 创建路由 + +1. 以 __NS Editor__ 用户成功登录后,点击左上角的 __集群列表__ 进入 __集群列表__ 页面。在集群列表中,点击一个集群名称。 + + ![集群列表](../../../images/ingress01.png) + +2. 在左侧导航栏中,点击 __容器网络__ -> __路由__ 进入服务列表,点击右上角 __创建路由__ 按钮。 + + ![服务与路由](../../../images/ingress02.png) + + !!! note + + 也可以通过 __YAML 创建__ 一个路由。 + +3. 打开 __创建路由__ 页面,进行配置。可选择两种协议类型,参考以下两个参数表进行配置。 + +### 创建 HTTP 协议路由 + +输入如下参数: + +![创建路由](../../../images/ingress03.png) + +- __路由名称__ :必填,输入新建路由的名称。 +- __命名空间__ :必填,选择新建服务所在的命名空间。关于命名空间更多信息请参考命名空间概述。 +- __设置路由规则__ : + - __域名__ :必填,使用域名对外提供访问服务。默认为集群的域名。 + - __协议__ :必填,指授权入站到达集群服务的协议,支持 HTTP (不需要身份认证)或 HTTPS(需需要配置身份认证) 协议。 + 这里选择 HTTP 协议的路由。 + - __转发策略__ :选填,指定 Ingress 的访问策略 + - __路径__ :指定服务访问的URL路径,默认为根路径 + - __目标服务__ :进行路由的服务名称 + - __目标服务端口__ :服务对外暴露的端口 +- __负载均衡器类型__ :必填,Ingress 实例的使用范围 + - __平台级负载均衡器__ :同一个集群内,共享同一个 Ingress 实例,其中 Pod 都可以接收到由该负载均衡分发的请求 + - __租户级负载均衡器__ :租户负载均衡器,Ingress 实例独属于当前命名空,或者独属于某一工作空间, + 并且设置的工作空间中包含当前命名空间,其中 Pod 都可以接收到由该负载均衡分发的请求 +- __Ingress Class__ :选填,选择对应的 Ingress 实例,选择后将流量导入到指定的 Ingress 实例。 + - 为 None 时使用默认的 DefaultClass,请在创建 Ingress 实例时设置 DefaultClass, + 更多信息请参考 Ingress Class + - 若选择其他实例(如 __ngnix__ ),则会出现高级配置,可设置 __会话保持__ 、 __路径重写__ 、 __重定向__ 和 __流量分发__ 。 +- __会话保持__ :选填,会话保持分为 三种类型: __L4 源地址哈希__ 、 __Cookie Key__ 、 __L7 Header Name__ ,开启后根据对应规则进行会话保持。 + - __L4 源地址哈希__ :开启后默认在 Annotation 中加入如下标签: + `nginx.ingress.kubernetes.io/upstream-hash-by: "$binary_remote_addr"` + - __Cookie Key__ :开启后来自特定客户端的连接将传递至相同 Pod,开启后 默认在 Annotation 中增加如下参数: + `nginx.ingress.kubernetes.io/affinity: "cookie"。nginx.ingress.kubernetes.io/affinity-mode: persistent` + - __L7 Header Name__ :开启后默认在 Annotation 中加入如下标签: + `nginx.ingress.kubernetes.io/upstream-hash-by: "$http_x_forwarded_for"` +- __路径重写__ :选填, __rewrite-target__ ,某些场景中后端服务暴露的URL与Ingress规则中指定的路径不同,如果不进行URL重写配置,访问会出现错误。 +- __重定向__ :选填, __permanent-redirect__ ,永久重定向,输入重写路径后,访问路径重定向至设置的地址。 +- __流量分发__ :选填,开启后并设置后,根据设定条件进行流量分发。 + - __基于权重__ :设定权重后,在创建的 Ingress 添加如下 Annotation: + __nginx.ingress.kubernetes.io/canary-weight: "10"__ + - __基于 Cookie__ :设定 Cookie 规则后,流量根据设定的 Cookie 条件进行流量分发 + - __基于 Header__ : 设定 Header 规则后,流量根据设定的 Header 条件进行流量分发 +- __标签__ :选填,为路由添加标签 +- __注解__ :选填,为路由添加注解 + +### 创建 HTTPS 协议路由 + +输入如下参数: +![创建路由](../../../images/ingress04.png) + +!!! note + + 注意:与 HTTP 协议 __设置路由规则__ 不同,增加密钥选择证书,其他基本一致。 + +- __协议__ :必填指授权入站到达集群服务的协议,支持 HTTP (不需要身份认证)或 HTTPS(需需要配置身份认证) 协议。这里选择 HTTPS 协议的路由。 +- __密钥__ :必填,Https TLS 证书,[创建秘钥](../configmaps-secrets/create-secret.md)。 + +### 完成路由创建 + +配置完所有参数后,点击 __确定__ 按钮,自动返回路由列表。在列表右侧,点击 __┇__ ,可以修改或删除所选路由。 + +![路由列表](../../../images/ingress05.png) diff --git a/docs/zh/docs/end-user/kpanda/network/create-services.md b/docs/zh/docs/end-user/kpanda/network/create-services.md new file mode 100644 index 0000000..0c5d538 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/network/create-services.md @@ -0,0 +1,95 @@ +# 创建服务(Service) + +在 Kubernetes 集群中,每个 Pod 都有一个内部独立的 IP 地址,但是工作负载中的 Pod 可能会被随时创建和删除,直接使用 Pod IP 地址并不能对外提供服务。 + +这就需要创建服务,通过服务您会获得一个固定的 IP 地址,从而实现工作负载前端和后端的解耦,让外部用户能够访问服务。同时,服务还提供了负载均衡(LoadBalancer)功能,使用户能从公网访问到工作负载。 + +## 前提条件 + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并将用户授权为 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色 ,详情可参考[命名空间授权](../permissions/cluster-ns-auth.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 创建服务 + +1. 以 __NS Editor__ 用户成功登录后,点击左上角的 __集群列表__ 进入 __集群列表__ 页面。在集群列表中,点击一个集群名称。 + + ![集群列表](../../../images/service01.png) + +2. 在左侧导航栏中,点击 __容器网络__ -> __服务__ 进入服务列表,点击右上角 __创建服务__ 按钮。 + + ![服务与路由](../../../images/service02.png) + + !!! tip + + 也可以通过 YAML 创建 一个服务。 + +3. 打开 __创建服务__ 页面,选择一种访问类型,参考以下几个参数表进行配置。 + + ![创建服务](../images/service03.png) + +### 创建 ClusterIP 服务 + +点选 __集群内访问(ClusterIP)__ ,这是指通过集群的内部 IP 暴露服务,选择此项的服务只能在集群内部访问。这是默认的服务类型。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | +| ---------------- | :----------------------------------------------------------- | :-------- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择集群内访问(ClusterIP)。 | ClusterIP | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | +| 标签选择器 | 【类型】必填
【含义】添加标签,Service 根据标签选择 Pod,填写后点击“添加”。也可以引用已有工作负载的标签,点击 __引用负载标签__ ,在弹出的窗口中选择负载,系统会默认将所选的负载标签作为选择器。 | app:job01 | +| 端口配置 | 【类型】必填
【含义】为服务添加协议端口,需要先选择端口协议类型,目前支持 TCP、UDP 两种传输协议。
**端口名称**:输入自定义的端口的名称。
**服务端口(port)**:Pod 对外提供服务的访问端口。
**容器端口(targetport)**:工作负载实际监听的容器端口,用来对集群内暴露服务。 | | +| 会话保持 | 【类型】选填
【含义】开启后,相同客户端的请求将转发至同一 Pod | 开启 | +| 会话保持最大时长 | 【类型】选填
【含义】开启会话保持后,保持的最大时长,默认为 30 秒 | 30 秒 | +| 注解 | 【类型】选填
【含义】为服务添加注解
| | + +### 创建 NodePort 服务 + +点选 __节点访问(NodePort)__ ,这是指通过每个节点上的 IP 和静态端口( __NodePort__ )暴露服务。 __NodePort__ 服务会路由到自动创建的 __ClusterIP__ 服务。通过请求 __<节点 IP>:<节点端口>__ ,您可以从集群的外部访问一个 __NodePort__ 服务。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | +| ---------------- | :----------------------------------------------------------- | :------- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择节点访问(NodePort)。 | NodePort | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | +| 标签选择器 | 【类型】必填
【含义】添加标签,Service 根据标签选择 Pod,填写后点击“添加”。也可以引用已有工作负载的标签,点击 __引用负载标签__ ,在弹出的窗口中选择负载,系统会默认将所选的负载标签作为选择器。 | | +| 端口配置 | 【类型】必填
【含义】为服务添加协议端口,需要先选择端口协议类型,目前支持 TCP、UDP 两种传输协议。
**端口名称**:输入自定义的端口的名称。
**服务端口(port)**:Pod 对外提供服务的访问端口。*默认情况下,为了方便起见,服务端口被设置为与容器端口字段相同的值。*
**容器端口(targetport)**:工作负载实际监听的容器端口。
**节点端口(nodeport)**:节点的端口,接收来自 ClusterIP 传输的流量。用来做外部流量访问的入口。 | | +| 会话保持 | 【类型】选填
【含义】开启后,相同客户端的请求将转发至同一 Pod
开启后 Service 的 `.spec.sessionAffinity` 为 __ClientIP__ ,详情请参考:[Service 的会话亲和性](https://kubernetes.io/zh-cn/docs/reference/networking/virtual-ips/#session-affinity) | 开启 | +| 会话保持最大时长 | 【类型】选填
【含义】开启会话保持后,保持的最大时长,默认超时时长为 30 秒
.spec.sessionAffinityConfig.clientIP.timeoutSeconds 默认设置为 30 秒 | 30 秒 | +| 注解 | 【类型】选填
【含义】为服务添加注解
| | + +### 创建 LoadBalancer 服务 + +点选 __负载均衡(LoadBalancer)__ ,这是指使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 __NodePort__ 服务和 __ClusterIP__ 服务上。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | | +| ------------- | :----------------------------------------------------------- | :------- | ---- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择负载均衡(LoadBalancer)。 | LoadBalancer | | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | | +| 外部流量策略 | 【类型】必填
【含义】设置外部流量策略。
**Cluster**:流量可以转发到集群中所有节点上的 Pod。
**Local**:流量只发给本节点上的 Pod。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | | | +| 标签选择器 | 【类型】必填
【含义】添加标签,Service 根据标签选择 Pod,填写后点击“添加”。也可以引用已有工作负载的标签,点击 __引用负载标签__ ,在弹出的窗口中选择负载,系统会默认将所选的负载标签作为选择器。 | | | +| 负载均衡类型 | 【类型】必填
【含义】使用的负载均衡类型,当前支持 MetalLB 和其他。 | | | +| MetalLB IP 池 | 【类型】必填
【含义】选择的 负载均衡类型为 MetalLB 时,LoadBalancer Service默认会从这个池中分配 IP 地址, 并且通过 APR 宣告这个池中的所有 IP 地址 | | | +| 负载均衡地址 | 【类型】必填
【含义】
1.如使用的是公有云 CloudProvider,此处填写的为云厂商提供的负载均衡地址;
2.如果上述负载均衡类型选择为 MetalLB ,默认从上述 IP 池中获取 IP ,如果不填则自动获取。 | | | +| 端口配置 | 【类型】必填
【含义】为服务添加协议端口,需要先选择端口协议类型,目前支持 TCP、UDP 两种传输协议。
**端口名称**:输入自定义的端口的名称。
**服务端口(port)**:Pod 对外提供服务的访问端口。默认情况下,为了方便起见,服务端口被设置为与容器端口字段相同的值。
**容器端口(targetport)**:工作负载实际监听的容器端口。
**节点端口(nodeport)**:节点的端口,接收来自 ClusterIP 传输的流量。用来做外部流量访问的入口。 | | | +| 注解 | 【类型】选填
【含义】为服务添加注解
| | | + +### 创建 ExternalName 服务 + +点选 __外部服务(ExternalName)__ ,这是指通过将服务映射到外部域名来暴露服务。选择此项的服务不会创建典型的 ClusterIP 或 NodePort,而是通过 DNS 名称解析将请求重定向到外部的服务地址。参考下表配置参数。 + +| 参数 | 说明 | 举例值 | | +| ------------- | :----------------------------------------------------------- | :------- | ---- | +| 访问类型 | 【类型】必填
【含义】指定 Pod 服务发现的方式,这里选择外部服务(ExternalName)。 | ExternalName | | +| 服务名称 | 【类型】必填
【含义】输入新建服务的名称。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | Svc-01 | | +| 命名空间 | 【类型】必填
【含义】选择新建服务所在的命名空间。关于命名空间更多信息请参考[命名空间概述](../namespaces/createns.md)。
【注意】请输入 4 到 63 个字符的字符串,可以包含小写英文字母、数字和中划线(-),并以小写英文字母开头,小写英文字母或数字结尾。 | default | | +| 域名 | 【类型】必填
| | | + +### 完成服务创建 + +配置完所有参数后,点击 __确定__ 按钮,自动返回服务列表。在列表右侧,点击 __┇__ ,可以修改或删除所选服务。 + +![服务列表](../images/service04.png) diff --git a/docs/zh/docs/end-user/kpanda/network/network-policy.md b/docs/zh/docs/end-user/kpanda/network/network-policy.md new file mode 100644 index 0000000..7eb40a4 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/network/network-policy.md @@ -0,0 +1,87 @@ +# 网络策略 + +网络策略(NetworkPolicy)可以在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量。容器管理模块目前支持创建基于 Pod 或命名空间的网络策略,支持通过标签选择器来设定哪些流量可以进入或离开带有特定标签的 Pod。 + +有关网络策略的更多详情,可参考 Kubernetes 官方文档[网络策略](https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/)。 + +## 创建网络策略 + +目前支持通过 YAML 和表单两种方式创建网络策略,这两种方式各有优劣,可以满足不同用户的使用需求。 + +通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉网络策略的 YAML 文件配置。 + +通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器网络__ -> __网络策略__ -> __YAML 创建__ 。 + + ![路径](../../../images/networkpolicy01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + ![yaml](../../../images/networkpolicy02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器网络__ -> __网络策略__ -> __创建策略__ 。 + + ![路径](../../../images/networkpolicy03.png) + +2. 填写基本信息。 + + 名称和命名空间在创建之后不可更改。 + + ![基本信息](../../../images/networkpolicy04.png) + +3. 填写策略配置。 + + 策略配置分为入流量策略和出流量策略。如果源 Pod 想要成功连接到目标 Pod,源 Pod 的出流量策略和目标 Pod 的入流量策略都需要允许连接。如果任何一方不允许连接,都会导致连接失败。 + + - 入流量策略:点击 __➕__ 开始配置策略,支持配置多条策略。多条网络策略的效果相互叠加,只有同时满足所有网络策略,才能成功建立连接。 + + ![ingress](../../../images/networkpolicy05.png) + + - 出流量策略 + + ![egress](../../../images/networkpolicy06.png) + +## 查看网络策略 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器网络__ -> __网络策略__ ,点击网络策略的名称。 + + ![路径](../../../images/networkpolicy07.png) + +2. 查看该策略的基本配置、关联实例信息、入流量策略、出流量策略。 + + ![详情](../../../images/networkpolicy08.png) + +!!! info + + 在关联实例页签下,支持查看实例监控、日志、容器列表、YAML 文件、事件等。 + + ![查看实例信息](../../../images/networkpolicy09.png) + +## 更新网络策略 + +有两种途径可以更新网络策略。支持通过表单或 YAML 文件更新网络策略。 + +- 在网络策略列表页面,找到需要更新的策略,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/networkpolicy10.png) + +- 点击网络策略的名称,进入网络策略的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/networkpolicy11.png) + +## 删除网络策略 + +有两种途径可以删除网络策略。支持通过表单或 YAML 文件更新网络策略。 + +- 在网络策略列表页面,找到需要更新的策略,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 删除。 + + ![删除](../../../images/networkpolicy12.png) + +- 点击网络策略的名称,进入网络策略的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 删除。 + + ![删除](../../../images/networkpolicy13.png) diff --git a/docs/zh/docs/end-user/kpanda/nodes/add-node.md b/docs/zh/docs/end-user/kpanda/nodes/add-node.md new file mode 100644 index 0000000..d490f8d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/add-node.md @@ -0,0 +1,37 @@ +--- +hide: + - toc +--- + +# 集群节点扩容 + +随着业务应用不断增长,集群资源日趋紧张,这时可以基于 kubean 对集群节点进行扩容。扩容后,应用可以运行在新增的节点上,缓解资源压力。 + +只有通过容器管理模块[创建的集群](../clusters/create-cluster.md)才支持节点扩缩容,从外部接入的集群不支持此操作。本文主要介绍同种架构下工作集群的 **工作节点** 扩容。 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + 若 __集群角色__ 中带有 __接入集群__ 的标签,则说明该集群不支持节点扩缩容。 + + ![进入集群列表页面](../../../images/addnode01_1.png) + +2. 在左侧导航栏点击 __节点管理__ ,然后在页面右上角点击 __接入节点__ 。 + + ![节点管理](../../../images/addnode02.png) + +3. 输入主机名称和节点 IP 并点击 __确定__ 。 + + 点击 __➕ 添加工作节点__ 可以继续接入更多节点。 + + ![节点管理](../../../images/addnode03.png) + +!!! note + + 接入节点大约需要 20 分钟,请您耐心等待。 + +## 参考文档 + +- [对工作集群的控制节点扩容](../../best-practice/add-master-node.md) +- [为工作集群添加异构节点](../../best-practice/multi-arch.md) +- [为全局服务集群的工作节点扩容](../../best-practice/add-worker-node-on-global.md) +- [替换工作集群的首个控制节点](../../best-practice/replace-first-master-node.md) diff --git a/docs/zh/docs/end-user/kpanda/nodes/delete-node.md b/docs/zh/docs/end-user/kpanda/nodes/delete-node.md new file mode 100644 index 0000000..03d6bd1 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/delete-node.md @@ -0,0 +1,34 @@ +# 集群节点缩容 + +当业务高峰期结束之后,为了节省资源成本,可以缩小集群规模,卸载冗余的节点,即节点缩容。节点卸载后,应用无法继续运行在该节点上。 + +## 前提条件 + +- 当前操作用户具有 [Cluster Admin](../permissions/permission-brief.md) 角色授权 。 +- 只有通过容器管理模块[创建的集群](../clusters/create-cluster.md)才支持节点扩缩容,从外部接入的集群不支持此操作。 +- 卸载节点之前,需要[暂停调度该节点](schedule.md),并且将该节点上的应用都驱逐至其他节点。 +- 驱逐方式:登录控制器节点,通过 kubectl drain 命令驱逐节点上所有 Pod。安全驱逐的方式可以允许容器组里面的容器优雅地中止。 + +## 注意事项 + +1. 集群节点缩容时,只能逐个进行卸载,无法批量卸载。 + +2. 如需卸载集群控制器节点,需要确保最终控制器节点数为 **奇数**。 + +3. 集群节点缩容时不可下线 **第一个控制器** 节点。如果必须执行此操作,请联系售后工程师。 + +## 操作步骤 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + 若 __集群角色__ 中带有 __接入集群__ 的标签,则说明该集群不支持节点扩缩容。 + + ![进入集群列表页面](../../../images/addnode01.png) + +2. 在左侧导航栏点击 __节点管理__ ,找到需要卸载的节点,点击 __┇__ 选择 __移除节点__ 。 + + ![移除节点](../../../images/deletenode01.png) + +3. 输入节点名称,并点击 __删除__ 进行确认。 + + ![移除节点](../../../images/deletenode02.png) diff --git a/docs/zh/docs/end-user/kpanda/nodes/labels-annotations.md b/docs/zh/docs/end-user/kpanda/nodes/labels-annotations.md new file mode 100644 index 0000000..2233929 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/labels-annotations.md @@ -0,0 +1,29 @@ +--- +hide: + - toc +--- + +# 标签与注解 + +标签(Labels)是为 Pod、节点、集群等 Kubernetes 对象添加的标识性键值对,可结合标签选择器查找并筛选满足某些条件的 Kubernetes 对象。每个键对于给定对象必须是唯一的。 + +注解(Annotations)和标签一样,也是键/值对,但不具备标识或筛选功能。 +使用注解可以为节点添加任意的元数据。 +注解的键通常使用的格式为 __前缀(可选)/名称(必填)__ ,例如 __nfd.node.kubernetes.io/extended-resources__ 。 +如果省略前缀,表示该注解键是用户私有的。 + +有关标签和注解的更多信息,可参考 Kubernetes 的官方文档[标签和选择算符](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/)或[注解](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/annotations/)。 + +添加/删除标签与注解的步骤如下: + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![进入集群列表页面](../../../images/schedule01.png) + +2. 在左侧导航栏点击 __节点管理__ ,在节点右侧点击 __┇__ 操作图标,点击 __修改标签__ 或 __修改注解__ 。 + + ![暂停调度](../../../images/labels01.png) + +3. 点击 __➕ 添加__ 可以添加标签或注解,点击 __X__ 可以删除标签或注解,最后点击 __确定__ 。 + + ![节点管理](../../../images/labels02.png) diff --git a/docs/zh/docs/end-user/kpanda/nodes/node-authentication.md b/docs/zh/docs/end-user/kpanda/nodes/node-authentication.md new file mode 100644 index 0000000..ea13bba --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/node-authentication.md @@ -0,0 +1,73 @@ +--- +hide: + - toc +--- + +# 使用 SSH 密钥认证节点 + +如果您选择使用 SSH 密钥作为待创建集群的节点认证方式,您需要按照如下说明配置公私钥。 + +1. 执行如下命令,在 **待建集群的管理集群中的任意节点** 上生成公私钥。 + + ```shell + cd /root/.ssh + ssh-keygen -t rsa + ``` + +2. 执行 __ls__ 命令查看管理集群上的密钥是否创建成功,正确反馈如下: + + ```shell + ls + id_rsa id_rsa.pub known_hosts + ``` + + 其中名为 __id_rsa__ 的文件是私钥,名为 __id_rsa.pub__ 的文件是公钥。 + +3. 执行如下命令,分别将公钥文件 __id_rsa.pub__ 加载到待创建集群的所有节点上。 + + ```shell + ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.0.0 + ``` + + 将上面命令中的 __root@10.0.0.0__ 用户账号和节点 IP 替换为待创建集群的节点用户名和 IP。** 需要在待创建集群的每台节点都执行相同的操作 **。 + +4. 执行如下命令,查看步骤 1 所创建的私钥文件 __id_rsa__ 。 + + ```shell + cat /root/.ssh/id_rsa + ``` + + 输出如下内容: + + ```bash + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEA3UvyKINzY5BFuemQ+uJ6q+GqgfvnWwNC8HzZhpcMSjJy26MM + UtBEBJxy8fMi57XcjYxPibXW/wnd+32ICCycqCwByUmuXeCC1cjlCQDqjcAvXae7 + Y54IXGF7wm2IsMNwf0kjFEXjuS48FLDA0mGRaN3BG+Up5geXcHckg3K5LD8kXFFx + dEmSIjdyw55NaUitmEdHzN7cIdfi6Z56jcV8dcFBgWKUx+ebiyPmZBkXToz6GnMF + rswzzZCl+G6Jb2xTGy7g7ozb4BoZd1IpSD5EhDanRrESVE0C5YuJ5zUAC0CvVd1l + v67AK8Ko6MXToHp01/bcsvlM6cqgwUFXZKVeOwIDAQABAoIBAQCO36GQlo3BEjxy + M2HvGJmqrx+unDxafliRe4nVY2AD515Qf4xNSzke4QM1QoyenMOwf446krQkJPK0 + k+9nl6Xszby5gGCbK4BNFk8I6RaGPjZWeRx6zGUJf8avWJiPxx6yjz2esSC9RiR0 + F0nmiiefVMyAfgv2/5++dK2WUFNNRKLgSRRpP5bRaD5wMzzxtSSXrUon6217HO8p + 3RoWsI51MbVzhdVgpHUNABcoa0rpr9svT6XLKZxY8mxpKFYjM0Wv2JIDABg3kBvh + QbJ7kStCO3naZjKMU9UuSqVJs06cflGYw7Or8/tABR3LErNQKPjkhAQqt0DXw7Iw + 3tKdTAJBAoGBAP687U7JAOqQkcphek2E/A/sbO/d37ix7Z3vNOy065STrA+ZWMZn + pZ6Ui1B/oJpoZssnfvIoz9sn559X0j67TljFALFd2ZGS0Fqh9KVCqDvfk+Vst1dq + +3r/yZdTOyswoccxkJiC/GDwZGK0amJWqvob39JCZhDAKIGLbGMmjdAHAoGBAN5k + m1WGnni1nZ+3dryIwgB6z1hWcnLTamzSET6KhSuo946ET0IRG9xtlheCx6dqICbr + Vk1Y4NtRZjK/p/YGx59rDWf7E3I8ZMgR7mjieOcUZ4lUlA4l7ZIlW/2WZHW+nUXO + Ti20fqJ8qSp4BUvOvuth1pz2GLUHe2/Fxjf7HIstAoGBAPHpPr9r+TfIlPsJeRj2 + 6lzA3G8qWFRQfGRYjv0fjv0pA+RIb1rzgP/I90g5+63G6Z+R4WdcxI/OJJNY1iuG + uw9n/pFxm7U4JC990BPE6nj5iLz+clpNGYckNDBF9VG9vFSrSDLdaYkxoVNvG/xJ + a9Na90H4lm7f3VewrPy310KvAoGAZr+mwNoEh5Kpc6xo8Gxi7aPP/mlaUVD6X7Ki + gvmu02AqmC7rC4QqEiqTaONkaSXwGusqIWxJ3yp5hELmUBYLzszAEeV/s4zRp1oZ + g133LBRSTbHFAdBmNdqK6Nu+KGRb92980UMOKvZbliKDl+W6cbfvVu+gtKrzTc3b + aevb4TUCgYEAnJAxyVYDP1nJf7bjBSHXQu1E/DMwbtrqw7dylRJ8cAzI7IxfSCez + 7BYWq41PqVd9/zrb3Pbh2phiVzKe783igAIMqummcjo/kZyCwFsYBzK77max1jF5 + aPQsLbRS2aDz8kIH6jHPZ/R+15EROmdtLmA7vIJZGerWWQR0dUU+XXA= + ``` + + 将私钥内容复制后填至界面密钥输入框。 + + ![SSH 认证](../../../images/createcluster-ssh01.png) diff --git a/docs/zh/docs/end-user/kpanda/nodes/node-check.md b/docs/zh/docs/end-user/kpanda/nodes/node-check.md new file mode 100644 index 0000000..9b6312c --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/node-check.md @@ -0,0 +1,38 @@ +# 创建集群节点可用性检查 + +在创建集群或为已有集群添加节点时,请参阅下表,检查节点配置,以避免因节点配置错误导致集群创建或扩容失败。 + +| 检查项 | 描述 | +| -------------- | -------------------------------------- | +| 操作系统 | 参考[支持的架构及操作系统](#_2) | +| SELinux | 关闭 | +| 防火墙 | 关闭 | +| 架构一致性 | 节点间 CPU 架构一致(如均为 ARM 或 x86) | +| 主机时间 | 所有主机间同步误差小于 10 秒。 | +| 网络联通性 | 节点及其 SSH 端口能够正常被平台访问。 | +| CPU | 可用 CPU 资源大于 4 Core | +| 内存 | 可用内存资源大于 8 GB | + +## 支持的架构及操作系统 + +| 架构 | 操作系统 | 备注 | +| ---- | ---------------------------------------------------------- | ---- | +| ARM | Kylin Linux Advanced Server release V10 (Sword) SP2 | 推荐 | +| ARM | UOS Linux | | +| ARM | openEuler | | +| x86 | CentOS 7.x | 推荐 | +| x86 | Redhat 7.x | 推荐 | +| x86 | Redhat 8.x | 推荐 | +| x86 | Flatcar Container Linux by Kinvolk | | +| x86 | Debian Bullseye, Buster, Jessie, Stretch | | +| x86 | Ubuntu 16.04, 18.04, 20.04, 22.04 | | +| x86 | Fedora 35, 36 | | +| x86 | Fedora CoreOS | | +| x86 | openSUSE Leap 15.x/Tumbleweed | | +| x86 | Oracle Linux 7, 8, 9 | | +| x86 | Alma Linux 8, 9 | | +| x86 | Rocky Linux 8, 9 | | +| x86 | Amazon Linux 2 | | +| x86 | Kylin Linux Advanced Server release V10 (Sword) - SP2 海光 | | +| x86 | UOS Linux | | +| x86 | openEuler | | diff --git a/docs/zh/docs/end-user/kpanda/nodes/node-details.md b/docs/zh/docs/end-user/kpanda/nodes/node-details.md new file mode 100644 index 0000000..437ec32 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/node-details.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 节点详情 + +接入或创建集群之后,可以查看集群中各个节点的信息,包括节点状态、标签、资源用量、Pod、监控信息等。 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![进入集群列表页面](../../../images/schedule01_2.png) + +2. 在左侧导航栏点击 __节点管理__ ,可以查看节点状态、角色、标签、CPU/内存使用情况、IP 地址、创建时间。 + + ![暂停调度](../../../images/node-details01.png) + +3. 点击节点名称,可以进入节点详情页面查看更多信息,包括概览信息、容器组信息、标签注解信息、事件列表、状态等。 + + ![节点管理](../../../images/node-details02.png) + + 此外,还可以查看节点的 YAML 文件、监控信息、标签和注解等。 + + ![节点管理](../../../images/node-details03.png) diff --git a/docs/zh/docs/end-user/kpanda/nodes/schedule.md b/docs/zh/docs/end-user/kpanda/nodes/schedule.md new file mode 100644 index 0000000..ccc54a0 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/schedule.md @@ -0,0 +1,24 @@ +--- +hide: + - toc +--- + +# 节点调度 + +支持将节点暂停调度或恢复调度。暂停调度指,停止将 Pod 调度到该节点。恢复调度指,可以将 Pod 调度到该节点。 + +1. 在 __集群列表__ 页面点击目标集群的名称。 + + ![进入集群列表页面](../../../images/schedule01_1.png) + +2. 在左侧导航栏点击 __节点管理__ ,在节点右侧点击 __┇__ 操作图标,点击 __暂停调度__ 按钮即可暂停调度该节点。 + + ![暂停调度](../../../images/schedule02.png) + +3. 在节点右侧点击 __┇__ 操作图标,点击 __恢复调度__ 按钮即可恢复调度该节点。 + + ![节点管理](../../../images/schedule03.png) + +节点调度状态可能因网络情况有所延迟,点击搜索框右侧的刷新图标可以刷新节点调度状态。 + +![节点管理](../../../images/schedule04.png) diff --git a/docs/zh/docs/end-user/kpanda/nodes/taints.md b/docs/zh/docs/end-user/kpanda/nodes/taints.md new file mode 100644 index 0000000..7b2708b --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/nodes/taints.md @@ -0,0 +1,36 @@ +# 节点污点管理 + +污点 (Taint) 能够使节点排斥某一类 Pod,避免 Pod 被调度到该节点上。 +每个节点上可以应用一个或多个污点,不能容忍这些污点的 Pod 则不会被调度该节点上。 + +## 注意事项 + +1. 当前操作用户应具备 [NS Editor](../permissions/permission-brief.md#ns-editor) 角色授权或其他更高权限。 +2. 为节点添加污点之后,只有能容忍该污点的 Pod 才能被调度到该节点。 + +## 操作步骤 + +1. 在 __集群列表__ 页找到目标集群,点击集群名称,进入 __集群概览__ 页面。 + + ![点击集群名称](../../../images/taint-click--cluster-name.png) + +2. 在左侧导航栏,点击 __节点管理__ ,找到需要修改污点的节点,点击右侧的 __┇__ 操作图标并点击 __修改污点__ 按钮。 + + ![修改污点](../../../images/taint-change.png) + +3. 在弹框内输入污点的键值信息,选择污点效果,点击 __确定__ 。 + + 点击 __➕ 添加__ 可以为节点添加多个污点,点击污点效果右侧的 __X__ 可以删除污点。 + + 目前支持三种污点效果: + + - `NoSchedule`:新的 Pod 不会被调度到带有此污点的节点上,除非新的 Pod 具有相匹配的容忍度。当前正在节点上运行的 Pod **不会** 被驱逐。 + - `NoExecute`:这会影响已在节点上运行的 Pod: + - 如果 Pod 不能容忍此污点,会马上被驱逐。 + - 如果 Pod 能够容忍此污点,但是在容忍度定义中没有指定 `tolerationSeconds`,则 Pod 还会一直在这个节点上运行。 + - 如果 Pod 能够容忍此污点而且指定了 `tolerationSeconds`,则 Pod 还能在这个节点上继续运行指定的时长。这段时间过去后,再从节点上驱除这些 Pod。 + - `PreferNoSchedule`:这是“软性”的 `NoSchedule`。控制平面将**尝试**避免将不容忍此污点的 Pod 调度到节点上,但不能保证完全避免。所以要尽量避免使用此污点。 + + ![修改污点](../../../images/taint-add-remove.png) + +有关污点的更多详情,请参阅 Kubernetes 官方文档:[污点和容忍度](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)。 diff --git a/docs/zh/docs/end-user/kpanda/olm/import-miniooperator.md b/docs/zh/docs/end-user/kpanda/olm/import-miniooperator.md new file mode 100644 index 0000000..6c40d7a --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/olm/import-miniooperator.md @@ -0,0 +1,167 @@ +--- +hide: + - toc +--- + + +# 导入离线 MinIo Operator + +本文将介绍在离线环境下如何导入 MinIo Operator。 + +## 前提条件 + +- 当前集群已接入容器管理且全局服务集群已经安装 __kolm__ 组件(helm 模板搜索 kolm) +- 当前集群已经安装 __olm__ 组件且版本 >= 0.2.4 (helm 模板搜索 olm) +- 支持执行 Docker 命令 +- 准备一个镜像仓库 + +## 操作步骤 + +1. 在执行环境中设置环境变量并在后续步骤使用,执行命令: + + ```bash + export OPM_IMG=10.5.14.200/quay.m.daocloud.io/operator-framework/opm:v1.29.0 + export BUNDLE_IMG=10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3 + ``` + + 如何获取上述镜像地址: + + 前往 __容器管理__ -> 选择当前集群 -> __helm 应用__ -> 查看 __olm__ 组件 -> __插件设置__ ,找到后续步骤所需 opm,minio,minio bundle,minio operator 的镜像。 + + ![olm](../../../images/olm.png) + + ```bash + 以上诉截图为例,则四个镜像地址如下 + + # opm 镜像 + 10.5.14.200/quay.m.daocloud.io/operator-framework/opm:v1.29.0 + + # minio 镜像 + 10.5.14.200/quay.m.daocloud.io/minio/minio:RELEASE.2023-03-24T21-41-23Z + + # minio bundle 镜像 + 10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3 + + # minio operator 镜像 + 10.5.14.200/quay.m.daocloud.io/minio/operator:v5.0.3 + ``` + +2. 执行 opm 命令获取离线 bundle 镜像包含的 operator。 + + ```bash + # 创建 operator 存放目录 + $ mkdir minio-operator && cd minio-operator + + # 获取 operator yaml + $ docker run --user root -v $PWD/minio-operator:/minio-operator ${OPM_IMG} alpha bundle unpack --skip-tls-verify -v -d ${BUNDLE_IMG} -o ./minio-operator + + # 预期结果 + . + └── minio-operator + ├── manifests + │   ├── console-env_v1_configmap.yaml + │   ├── console-sa-secret_v1_secret.yaml + │   ├── console_v1_service.yaml + │   ├── minio-operator.clusterserviceversion.yaml + │   ├── minio.min.io_tenants.yaml + │   ├── operator_v1_service.yaml + │   ├── sts.min.io_policybindings.yaml + │   └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 3 directories, 9 files + ``` + +3. 替换  minio-operator/manifests/minio-operator.clusterserviceversion.yaml  文件中的所有镜像地址为离线镜像仓库地址镜像。 + + 替换前: + + ![image1](../../../images/csv1.png) + + 替换后: + + ![image2](../../../images/csv2.png) + +4. 生成构建 bundle 镜像的 Dockerfile + + ```bash + $ docker run --user root -v $PWD:/minio-operator -w /minio-operator ${OPM_IMG} alpha bundle generate --channels stable,beta -d /minio-operator/minio-operator/manifests -e stable -p minio-operator   + + # 预期结果 + . + ├── bundle.Dockerfile + └── minio-operator + ├── manifests + │   ├── console-env_v1_configmap.yaml + │   ├── console-sa-secret_v1_secret.yaml + │   ├── console_v1_service.yaml + │   ├── minio-operator.clusterserviceversion.yaml + │   ├── minio.min.io_tenants.yaml + │   ├── operator_v1_service.yaml + │   ├── sts.min.io_policybindings.yaml + │   └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 3 directories, 10 files + ``` + +5. 执行构建命令,构建 bundle 镜像且推送到离线 registry。 + + ```bash + # 设置新的 bundle image + export OFFLINE_BUNDLE_IMG=10.5.14.200/quay.m.daocloud.io/operatorhubio/minio-operator:v5.0.3-offline + + $ docker build . -f bundle.Dockerfile -t ${OFFLINE_BUNDLE_IMG}   + + $ docker push ${OFFLINE_BUNDLE_IMG} + ``` + +6. 生成构建 catalog 镜像的 Dockerfile。 + + ```bash + $ docker run --user root -v $PWD:/minio-operator -w /minio-operator ${OPM_IMG} index add --bundles ${OFFLINE_BUNDLE_IMG} --generate --binary-image ${OPM_IMG} --skip-tls-verify + + # 预期结果 + . + ├── bundle.Dockerfile + ├── database + │   └── index.db + ├── index.Dockerfile + └── minio-operator + ├── manifests + │   ├── console-env_v1_configmap.yaml + │   ├── console-sa-secret_v1_secret.yaml + │   ├── console_v1_service.yaml + │   ├── minio.min.io_tenants.yaml + │   ├── minio-operator.clusterserviceversion.yaml + │   ├── operator_v1_service.yaml + │   ├── sts.min.io_policybindings.yaml + │   └── sts_v1_service.yaml + └── metadata + └── annotations.yaml + + 4 directories, 12 files + ``` + +7. 构建 catalog 镜像 + + ```bash + # 设置新的 catalog image + export OFFLINE_CATALOG_IMG=10.5.14.200/release.daocloud.io/operator-framework/system-operator-index:v0.1.0-offline + + $ docker build . -f index.Dockerfile -t ${OFFLINE_CATALOG_IMG} + + $ docker push ${OFFLINE_CATALOG_IMG} + ``` + +8. 前往容器管理,更新 helm 应用 olm 的内置 catsrc 镜像(填写构建 catalog 镜像指定的 ${catalog-image} 即可) + + ![olm1](../../../images/olm1.png) + + ![olm2](../../../images/olm2.png) + +9. 更新成功后,Operator Hub 中会出现 __minio-operator__ 组件 + + ![olm3](../../../images/olm3.png) diff --git a/docs/zh/docs/end-user/kpanda/permissions/cluster-ns-auth.md b/docs/zh/docs/end-user/kpanda/permissions/cluster-ns-auth.md new file mode 100644 index 0000000..ac2736a --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/permissions/cluster-ns-auth.md @@ -0,0 +1,55 @@ +# 集群和命名空间授权 + +容器管理基于全局权限管理及全局用户/用户组管理实现授权,如需为用户授予容器管理的最高权限(可以创建、管理、删除所有集群)。 + +## 前提条件 + +给用户/用户组授权之前,请完成如下准备: + +- 已在全局管理中创建了待授权的用户/用户组,请参考[用户](../../register/index.md)。 + +- 仅 Kpanda Owner及当前集群的 [Cluster Admin](permission-brief.md) 具备集群授权能力。详情可参考[权限说明](permission-brief.md)。 + +- 仅 Kpanda Owner、当前集群的 [Cluster Admin](permission-brief.md),当前命名空间的 [NS Admin](permission-brief.md) 具备命名空间授权能力。 + +## 集群授权 + +1. 用户登录平台后,点击左侧菜单栏 __容器管理__ 下的 __权限管理__ ,默认位于 __集群权限__ 页签。 + + ![集群权限](../../../images/perm01.png) + +2. 点击 __添加授权__ 按钮。 + + ![添加授权](../../../images/perm02.png) + +3. 在 __添加集群权限__ 页面中,选择目标集群、待授权的用户/用户组后,点击 __确定__ 。 + + 目前仅支持的集群角色为 __Cluster Admin__ ,详情权限可参考[权限说明](permission-brief.md)。如需要给多个用户/用户组同时进行授权, 可点击 __添加用户权限__ 进行多次添加。 + + ![添加集群权限](../../../images/perm03.png) + +4. 返回集群权限管理页面,屏幕出现消息: __添加集群权限成功__ 。 + + ![添加成功](../../../images/perm04.png) + +## 命名空间授权 + +1. 用户登录平台后,点击左侧菜单栏 __容器管理__ 下的 __权限管理__ ,点击 __命名空间权限__ 页签。 + + ![命名空间权限](../../../images/perm05.png) + +2. 点击 __添加授权__ 按钮。在 __添加命名空间权限__ 页面中,选择目标集群、目标命名空间,以及待授权的用户/用户组后,点击 __确定__ 。 + + 目前支持的命名空间角色为 NS Admin、NS Editor、NS Viewer,详情权限可参考[权限说明](permission-brief.md)。如需给多个用户/用户组同时进行授权,可点击 __添加用户权限__ 进行多次添加。点击 __确定__ 完成权限授权。 + + ![添加命名空间权限](../../../images/perm06.png) + +3. 返回命名空间权限管理页面,屏幕出现消息: __添加集群权限成功__ 。 + + ![添加成功](../../../images/perm07.png) + + !!! tip + + 后续如需删除或编辑权限,可点击列表右侧的 __┇__ ,选择 __编辑__ 或 __删除__ 。 + + ![编辑或删除](../../../images/perm08.png) diff --git a/docs/zh/docs/end-user/kpanda/permissions/custom-kpanda-role.md b/docs/zh/docs/end-user/kpanda/permissions/custom-kpanda-role.md new file mode 100644 index 0000000..f74381c --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/permissions/custom-kpanda-role.md @@ -0,0 +1,84 @@ +# 增加 Kpanda 内置角色权限点 + +*[Kpanda]: 容器管理的开发代号 + +过去 Kpanda 内置角色的权限点(rbac rules)都是提前预定义好的且用户无法修改,因为以前修改内置角色的权限点之后也会被 Kpanda 控制器还原成预定义的权限点。 +为了支持更加灵活的权限配置,满足对系统角色的自定义需求,目前 Kpanda 支持为内置系统角色(cluster admin、ns admin、ns editor、ns viewer)修改权限点。 +以下示例演示如何新增 ns-viewer 权限点,尝试增加可以删除 Deployment 的权限。其他权限点操作类似。 + +## 前提条件 + +- 适用于容器管理 v0.27.0 及以上版本。 +- [已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[用户的创建](../../register/index.md),并为用户授予 [NS Viewer](./permission-brief.md#ns-viewer) ,详情可参考[命名空间授权](./cluster-ns-auth.md)。 + +!!! note + + - 只需在 Global Cluster 增加权限点,Kpanda 控制器会把 Global Cluster 增加的权限点同步到所有接入子集群中,同步需一段时间才能完成 + - 只能在 Global Cluster 增加权限点,在子集群新增的权限点会被 Global Cluster 内置角色权限点覆盖 + - 只支持使用固定 Label 的 ClusterRole 追加权限,不支持替换或者删除权限,也不能使用 role 追加权限,内置角色跟用户创建的 ClusterRole Label 对应关系如下 + + ```output + cluster-admin: rbac.kpanda.io/role-template-cluster-admin: "true" + cluster-edit: rbac.kpanda.io/role-template-cluster-edit: "true" + cluster-view: rbac.kpanda.io/role-template-cluster-view: "true" + ns-admin: rbac.kpanda.io/role-template-ns-admin: "true" + ns-edit: rbac.kpanda.io/role-template-ns-edit: "true" + ns-view: rbac.kpanda.io/role-template-ns-view: "true" + ``` + +## 操作步骤 + +1. 使用 admin 或者 cluster admin 权限的用户[创建无状态负载](../workloads/create-deployment.md) + + ![image-20240514112742395](../images/create-depolyment.png) + +1. 授权 ns-viewer,用户有该 namespace ns-view 权限 + + ![image-20240514113009311](../images/permisson02.png) + +1. 切换登录用户为 ns-viewer,打开控制台获取 ns-viewer 用户对应的 token,使用 curl 请求删除上述的 deployment nginx,发现无删除权限 + + ```bash + [root@master-01 ~]# curl -k -X DELETE 'https://${URL}/apis/kpanda.io/v1alpha1/clusters/cluster-member/namespaces/default/deployments/nginx' -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJOU044MG9BclBRMzUwZ2VVU2ZyNy1xMEREVWY4MmEtZmJqR05uRE1sd1lFIn0.eyJleHAiOjE3MTU3NjY1NzksImlhdCI6MTcxNTY4MDE3OSwiYXV0aF90aW1lIjoxNzE1NjgwMTc3LCJqdGkiOiIxZjI3MzJlNC1jYjFhLTQ4OTktYjBiZC1iN2IxZWY1MzAxNDEiLCJpc3MiOiJodHRwczovLzEwLjYuMjAxLjIwMTozMDE0Ny9hdXRoL3JlYWxtcy9naGlwcG8iLCJhdWQiOiJfX2ludGVybmFsLWdoaXBwbyIsInN1YiI6ImMxZmMxM2ViLTAwZGUtNDFiYS05ZTllLWE5OGU2OGM0MmVmMCIsInR5cCI6IklEIiwiYXpwIjoiX19pbnRlcm5hbC1naGlwcG8iLCJzZXNzaW9uX3N0YXRlIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiYXRfaGFzaCI6IlJhTHoyQjlKQ2FNc1RrbGVMR3V6blEiLCJhY3IiOiIwIiwic2lkIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJucy12aWV3ZXIiLCJsb2NhbGUiOiIifQ.As2ipMjfvzvgONAGlc9RnqOd3zMwAj82VXlcqcR74ZK9tAq3Q4ruQ1a6WuIfqiq8Kq4F77ljwwzYUuunfBli2zhU2II8zyxVhLoCEBu4pBVBd_oJyUycXuNa6HfQGnl36E1M7-_QG8b-_T51wFxxVb5b7SEDE1AvIf54NAlAr-rhDmGRdOK1c9CohQcS00ab52MD3IPiFFZ8_Iljnii-RpXKZoTjdcULJVn_uZNk_SzSUK-7MVWmPBK15m6sNktOMSf0pCObKWRqHd15JSe-2aA2PKBo1jBH3tHbOgZyMPdsLI0QdmEnKB5FiiOeMpwn_oHnT6IjT-BZlB18VkW8rA' + {"code":7,"message":"[RBAC] delete resources(deployments: nginx) is forbidden for user(ns-viewer) in cluster(cluster-member)","details":[]}[root@master-01 ~]# + [root@master-01 ~]# + ``` + +1. 在全局服务集群上创建如下 ClusterRole: + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: append-ns-view # (1)! + labels: + rbac.kpanda.io/role-template-ns-view: "true" # (2)! + rules: + - apiGroups: [ "apps" ] + resources: [ "deployments" ] + verbs: [ "delete" ] + ``` + + 1. 此字段值可任意指定,只需不重复且符合 Kubernetes 资源名称规则要求 + 2. 注意给不同的角色添加权限时应打上不同的 label + +1. 等待 Kpanda 控制器添加用户创建权限到内置角色 ns-viewer 中,可查看对应内置角色如是否有上一步新增的权限点 + + ```bash + [root@master-01 ~]# kubectl get clusterrole role-template-ns-view -oyaml|grep deployments -C 10|tail -n 6 + ``` + ```yaml + - apiGroups: + - apps + resources: + - deployments + verbs: + - delete + ``` + +1. 再次使用 curl 请求删除上述的 deployment nginx,这次成功删除了。也就是说,ns-viewer 成功新增了删除 Deployment 的权限。 + + ```bash + [root@master-01 ~]# curl -k -X DELETE 'https://${URL}/apis/kpanda.io/v1alpha1/clusters/cluster-member/namespaces/default/deployments/nginx' -H 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJOU044MG9BclBRMzUwZ2VVU2ZyNy1xMEREVWY4MmEtZmJqR05uRE1sd1lFIn0.eyJleHAiOjE3MTU3NjY1NzksImlhdCI6MTcxNTY4MDE3OSwiYXV0aF90aW1lIjoxNzE1NjgwMTc3LCJqdGkiOiIxZjI3MzJlNC1jYjFhLTQ4OTktYjBiZC1iN2IxZWY1MzAxNDEiLCJpc3MiOiJodHRwczovLzEwLjYuMjAxLjIwMTozMDE0Ny9hdXRoL3JlYWxtcy9naGlwcG8iLCJhdWQiOiJfX2ludGVybmFsLWdoaXBwbyIsInN1YiI6ImMxZmMxM2ViLTAwZGUtNDFiYS05ZTllLWE5OGU2OGM0MmVmMCIsInR5cCI6IklEIiwiYXpwIjoiX19pbnRlcm5hbC1naGlwcG8iLCJzZXNzaW9uX3N0YXRlIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiYXRfaGFzaCI6IlJhTHoyQjlKQ2FNc1RrbGVMR3V6blEiLCJhY3IiOiIwIiwic2lkIjoiMGJjZWRjZTctMTliYS00NmU1LTkwYmUtOTliMWY2MWEyNzI0IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJncm91cHMiOltdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJucy12aWV3ZXIiLCJsb2NhbGUiOiIifQ.As2ipMjfvzvgONAGlc9RnqOd3zMwAj82VXlcqcR74ZK9tAq3Q4ruQ1a6WuIfqiq8Kq4F77ljwwzYUuunfBli2zhU2II8zyxVhLoCEBu4pBVBd_oJyUycXuNa6HfQGnl36E1M7-_QG8b-_T51wFxxVb5b7SEDE1AvIf54NAlAr-rhDmGRdOK1c9CohQcS00ab52MD3IPiFFZ8_Iljnii-RpXKZoTjdcULJVn_uZNk_SzSUK-7MVWmPBK15m6sNktOMSf0pCObKWRqHd15JSe-2aA2PKBo1jBH3tHbOgZyMPdsLI0QdmEnKB5FiiOeMpwn_oHnT6IjT-BZlB18VkW8rA' + ``` diff --git a/docs/zh/docs/end-user/kpanda/permissions/permission-brief.md b/docs/zh/docs/end-user/kpanda/permissions/permission-brief.md new file mode 100644 index 0000000..a5c182e --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/permissions/permission-brief.md @@ -0,0 +1,362 @@ +# 容器管理权限说明 + +容器管理权限基于全局权限管理以及 Kubernetes RBAC 权限管理打造的多维度权限管理体系。 +支持集群级、命名空间级的权限控制,帮助用户便捷灵活地对租户下的 IAM 用户、用户组(用户的集合)设定不同的操作权限。 + +## 集群权限 + +集群权限基于 Kubernetes RBAC 的 ClusterRolebinding 授权,集群权限设置可让用户/用户组具备集群相关权限。 +目前的默认集群角色为 __Cluster Admin__ (不具备集群的创建、删除权限)。 + +### __Cluster Admin__ + +__Cluster Admin__ 具有以下权限: + +- 可管理、编辑、查看对应集群 + +- 管理、编辑、查看 命名空间下的所有工作负载及集群内所有资源 + +- 可授权用户为集群内角色 (Cluster Admin、NS Admin、NS Editor、NS Viewer) + +该集群角色的 YAML 示例如下: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:49Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-cluster-admin + resourceVersion: "15168" + uid: f8f86d42-d5ef-47aa-b284-097615795076 +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +``` + +## 命名空间权限 + +命名空间权限是基于 Kubernetes RBAC 能力的授权,可以实现不同的用户/用户组对命名空间下的资源具有不同的操作权限(包括 Kubernetes API 权限),详情可参考:[Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)。目前容器管理的默认角色为:NS Admin、NS Editor、NS Viewer。 + +### __NS Admin__ + +__NS Admin__ 具有以下权限: + +- 可查看对应命名空间 +- 管理、编辑、查看 命名空间下的所有工作负载,及自定义资源 +- 可授权用户为对应命名空间角色 (NS Editor、NS Viewer) + +该集群角色的 YAML 示例如下: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:49Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-admin + resourceVersion: "15173" + uid: 69f64c7e-70e7-4c7c-a3e0-053f507f2bc3 +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' +``` + +### __NS Editor__ + +__NS Editor__ 具有以下权限: + +- 可查看对应有权限的命名空间 +- 管理、编辑、查看 命名空间下的所有工作负载 + +??? note "点击查看集群角色的 YAML 示例" + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:50Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-edit + resourceVersion: "15175" + uid: ca9e690e-96c0-4978-8915-6e4c00c748fe + rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - persistentvolumeclaims/status + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - services/status + verbs: + - '*' + - apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - '*' + - apiGroups: + - "" + resources: + - namespaces + verbs: + - '*' + - apiGroups: + - apps + resources: + - controllerrevisions + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - replicasets + - replicasets/scale + - replicasets/status + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - horizontalpodautoscalers/status + verbs: + - '*' + - apiGroups: + - batch + resources: + - cronjobs + - cronjobs/status + - jobs + - jobs/status + verbs: + - '*' + - apiGroups: + - extensions + resources: + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - ingresses + - ingresses/status + - networkpolicies + - replicasets + - replicasets/scale + - replicasets/status + - replicationcontrollers/scale + verbs: + - '*' + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - poddisruptionbudgets/status + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: + - '*' + ``` + +### __NS Viewer__ + +__NS Viewer__ 具有以下权限: + +- 可查看对应命名空间 +- 可查看对应命名空间下的所有工作负载,及自定义资源 + +??? note "点击查看集群角色的 YAML 示例" + + ```yaml + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + kpanda.io/creator: system + creationTimestamp: "2022-06-16T09:42:50Z" + labels: + iam.kpanda.io/role-template: "true" + name: role-template-ns-view + resourceVersion: "15183" + uid: 853888fd-6ee8-42ac-b91e-63923918baf8 + rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - persistentvolumeclaims + - persistentvolumeclaims/status + - pods + - replicationcontrollers + - replicationcontrollers/scale + - serviceaccounts + - services + - services/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - bindings + - events + - limitranges + - namespaces/status + - pods/log + - pods/status + - replicationcontrollers/status + - resourcequotas + - resourcequotas/status + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - apps + resources: + - controllerrevisions + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - replicasets + - replicasets/scale + - replicasets/status + - statefulsets + - statefulsets/scale + - statefulsets/status + verbs: + - get + - list + - watch + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + - horizontalpodautoscalers/status + verbs: + - get + - list + - watch + - apiGroups: + - batch + resources: + - cronjobs + - cronjobs/status + - jobs + - jobs/status + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - daemonsets + - daemonsets/status + - deployments + - deployments/scale + - deployments/status + - ingresses + - ingresses/status + - networkpolicies + - replicasets + - replicasets/scale + - replicasets/status + - replicationcontrollers/scale + verbs: + - get + - list + - watch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + - poddisruptionbudgets/status + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingresses/status + - networkpolicies + verbs: + - get + - list + - watch + ``` + +## 权限 FAQ + +1. 全局权限和容器管理权限管理的关系? + + 答:全局权限仅授权为粗粒度权限,可管理所有集群的创建、编辑、删除;而对于细粒度的权限,如单个集群的管理权限,单个命名空间的管理、编辑、删除权限,需要基于 Kubernetes RBAC 的容器管理权限进行实现。 + 一般权限的用户仅需要在容器管理中进行授权即可。 + +2. 目前仅支持四个默认角色,后台自定义角色的 __RoleBinding__ 以及 __ClusterRoleBinding__ (Kubernetes 细粒度的 RBAC)是否也能生效? + + 答:目前自定义权限暂时无法通过图形界面进行管理,但是通过 kubectl 创建的权限规则同样能生效。 diff --git a/docs/zh/docs/end-user/kpanda/scale/create-hpa.md b/docs/zh/docs/end-user/kpanda/scale/create-hpa.md new file mode 100644 index 0000000..b235ade --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/create-hpa.md @@ -0,0 +1,64 @@ +# 基于内置指标创建 HPA + +算丰 AI 算力平台支持 Pod 资源基于指标进行弹性伸缩(Horizontal Pod Autoscaling, HPA)。 +用户可以通过设置 CPU 利用率、内存用量及自定义指标指标来动态调整 Pod 资源的副本数量。 +例如,为工作负载设置基于 CPU 利用率指标弹性伸缩策略后,当 Pod 的 CPU 利用率超过/低于您设置的指标阀值,工作负载控制器将会自动增加/较少 Pod 副本数。 + +本文将介绍如何为工作负载配置基于内置指标的弹性伸缩。 + +!!! note + + 1. HPA 仅适用于 Deployment 和 StatefulSet,每个工作负载只能创建一个 HPA。 + 2. 如果基于 CPU 利用率创建 HPA 策略,必须预先为工作负载设置配置限制(Limit),否则无法计算 CPU 利用率。 + 3. 如果同时使用内置指标和多种自定义指,HPA 会根据多项指标分别计算所需伸缩副本数,取较大值(但不会超过设置 HPA 策略时配置的最大副本数)进行弹性伸缩。 + +## 内置指标弹性伸缩策略 + +系统内置了 CPU 和内存两种弹性伸缩指标以满足用户的基础业务使用场景。 + +### 前提条件 + +在为工作负载配置内置指标弹性伸缩策略之前,需要满足以下前提条件: + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[无状态工作负载的创建](../workloads/create-deployment.md)或[有状态工作负载的创建](../workloads/create-statefulset.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 已完成[ __metrics-server 插件安装__ ](install-metrics-server.md)。 + +### 操作步骤 + +参考以下步骤,为工作负载配置内置指标弹性伸缩策略。 + +1. 点击左侧导航栏上的 __集群列表__ 进入集群列表页面。点击一个集群名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_14.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ 进入工作负载列表后,点击一个负载名称,进入 __工作负载详情__ 页面。 + + ![工作负载](../../../images/createScale.png) + +3. 点击 __弹性伸缩__ 页签,查看当前集群的弹性伸缩配置情况。 + + ![弹性伸缩](../../../images/createScale02.png) + +4. 确认集群已[安装了 __metrics-server__ 插件](install-metrics-server.md),且插件运行状态为正常后,即可点击 __新建伸缩__ 按钮。 + + ![新建伸缩](../../../images/createScale07.png) + +5. 创建自定义指标弹性伸缩策略参数。 + + ![工作负载](../../../images/createScale08.png) + + - 策略名称:输入弹性伸缩策略的名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 hpa-my-dep。 + - 命名空间:负载所在的命名空间。 + - 工作负载:执行弹性伸缩的工作负载对象。 + - 目标 CPU 利用率:工作负载资源下 Pod 的 CPU 使用率。计算方式为:工作负载下所有的 Pod 资源 / 工作负载的请求(request)值。当实际 CPU 用量大于/小于目标值时,系统自动减少/增加 Pod 副本数量。 + - 目标内存用量:工作负载资源下的 Pod 的内存用量。当实际内存用量大于/小于目标值时,系统自动减少/增加 Pod 副本数量。 + - 副本范围:Pod 副本数的弹性伸缩范围。默认区间为为 1 - 10。 + +6. 完成参数配置后,点击 __确定__ 按钮,自动返回弹性伸缩详情页面。点击列表右侧的 __┇__ ,可以执行编辑、删除操作,还可以查看相关事件。 + + ![工作负载](../../../images/createScale09.png) \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/scale/create-vpa.md b/docs/zh/docs/end-user/kpanda/scale/create-vpa.md new file mode 100644 index 0000000..2a28f5d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/create-vpa.md @@ -0,0 +1,67 @@ +# 创建 VPA + +容器垂直扩缩容策略(Vertical Pod Autoscaler, VPA)通过监控 Pod 在一段时间内的资源申请和用量, +计算出对该 Pod 而言最适合的 CPU 和内存请求值。使用 VPA 可以更加合理地为集群下每个 Pod 分配资源,提高集群的整体资源利用率,避免集群资源浪费。 + +算丰 AI 算力平台支持通过容器垂直扩缩容策略(Vertical Pod Autoscaler, VPA),基于此功能可以根据容器资源的使用情况动态调整 Pod 请求值。 +算丰 AI 算力平台支持通过手动和自动两种方式来修改资源请求值,您可以根据实际需要进行配置。 + +本文将介绍如何为工作负载配置 Pod 垂直伸缩。 + +!!! warning + + 使用 VPA 修改 Pod 资源请求会触发 Pod 重启。由于 Kubernetes 本身的限制, Pod 重启后可能会被调度到其它节点上。 + +## 前提条件 + +为工作负载配置垂直伸缩策略之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)、[用户](../../register/index.md)、[无状态工作负载](../workloads/create-deployment.md)或[有状态工作负载](../workloads/create-statefulset.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 当前集群已经安装 [metrics-server](install-metrics-server.md) 和 [VPA](install-vpa.md) 插件。 + +## 操作步骤 + +参考以下步骤,为工作负载配置内置指标弹性伸缩策略。 + +1. 在 __集群列表__ 中找到目前集群,点击目标集群的名称。 + + ![集群详情](images/create-vpa-01.png) + +2. 在左侧导航栏点击 __工作负载__ ,找到需要创建 VPA 的负载,点击该负载的名称。 + + ![工作负载](images/create-vpa-02.png) +3. 点击 __弹性伸缩__ 页签,查看当前集群的弹性伸缩配置,确认已经安装了相关插件并且插件是否运行正常。 + + ![垂直伸缩](images/create-vpa-03.png) + +4. 点击 __新建伸缩__ 按钮,并配置 VPA 垂直伸缩策略参数。 + + ![新建伸缩](images/create-vpa-04.png) + + - 策略名称:输入垂直伸缩策略的名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 vpa-my-dep。 + - 伸缩模式:执行修改 CPU 和内存请求值的方式,目前垂直伸缩支持手动和自动两种伸缩模式。 + - 手动伸缩:垂直伸缩策略计算出推荐的资源配置值后,需用户手动修改应用的资源配额。 + - 自动伸缩:垂直伸缩策略自动计算和修改应用的资源配额。 + - 目标容器:选择需要进行垂直伸缩的容器。 + +5. 完成参数配置后,点击 __确定__ 按钮,自动返回弹性伸缩详情页面。点击列表右侧的 __┇__ ,可以执行编辑、删除操作。 + + ![工作负载](images/create-vpa-05.png) + +!!! note + + 默认情况下,--min-replicas 的值为 2。表示当副本数大于 1 时,VPA 才会生效, + 可以通过修改 updater 的 --min-replicas 参数值来改变这一默认行为。 + + ```yaml + spec: + containers: + - name: updater + args: + - "--min-replicas=2" + ``` diff --git a/docs/zh/docs/end-user/kpanda/scale/custom-hpa.md b/docs/zh/docs/end-user/kpanda/scale/custom-hpa.md new file mode 100644 index 0000000..cf01341 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/custom-hpa.md @@ -0,0 +1,166 @@ +# 基于自定义指标创建 HPA + +当系统内置的 CPU 和内存两种指标不能满足您业务的实际需求时,您可以通过配置 ServiceMonitoring 来添加自定义指标, +并基于自定义指标实现弹性伸缩。本文将介绍如何为工作负载配置基于自定义指标进行弹性伸缩。 + +!!! note + + 1. HPA 仅适用于 Deployment 和 StatefulSet,每个工作负载只能创建一个 HPA。 + 2. 如果同时使用内置指标和多种自定义指,HPA 会根据多项指标分别计算所需伸缩副本数,取较大值(但不会超过设置 HPA 策略时配置的最大副本数)进行弹性伸缩。 + +## 前提条件 + +在为工作负载配置自定义指标弹性伸缩策略之前,需要满足以下前提条件: + +- [已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md), + 且能够访问集群的 UI 界面 +- 已完成一个[命名空间的创建](../namespaces/createns.md)、[无状态工作负载的创建](../workloads/create-deployment.md)或[有状态工作负载的创建](../workloads/create-statefulset.md) +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限, + 详情可参考[命名空间授权](../namespaces/createns.md) +- 已安装 [metrics-server 插件](install-metrics-server.md) +- 已安装 [insight-agent 插件](../../../admin/insight/quickstart/install/install-agent.md) +- 已安装 Prometheus-adapter 插件 + +## 操作步骤 + +参考以下步骤,为工作负载配置指标弹性伸缩策略。 + +1. 点击左侧导航栏上的 __集群列表__ 进入集群列表页面。点击一个集群名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_15.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ 进入工作负载列表后,点击一个负载名称,进入 __工作负载详情__ 页面。 + + ![工作负载](../../../images/createScale_1.png) + +3. 点击 __弹性伸缩__ 页签,查看当前集群的弹性伸缩配置情况。 + + ![弹性伸缩配置](../../../images/createScale02_1.png) + +4. 确认集群已[安装了 __metrics-server__ ](install-metrics-server.md)、Insight、Prometheus-adapter 插件且插件运行状态为正常后,即可点击 __新建伸缩__ 按钮。 + + !!! note + + 如果相关插件未安装或插件处于异常状态,您在页面上将无法看见创建自定义指标弹性伸缩入口。 + + ![新建伸缩](../../../images/createScale07_1.png) + +5. 创建自定义指标弹性伸缩策略参数。 + + ![伸缩策略参数](../../../images/createScale10.png) + + - 策略名称:输入弹性伸缩策略的名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 hpa-my-dep。 + - 命名空间:负载所在的命名空间。 + - 工作负载:执行弹性伸缩的工作负载对象。 + - 资源类型:进行监控的自定义指标类型,包含 Pod 和 Service 两种类型。 + - 指标:使用 ServiceMonitoring 创建的自定义指标名称或系统内置的自定义指标名称。 + - 数据类型:用于计算指标值的方法,包含目标值和目标平均值两种类型,当资源类型为 Pod 时,只支持使用目标平均值。 + +## 操作示例 + +本案例以 Golang 业务程序为例,该示例程序暴露了 `httpserver_requests_total` 指标,并记录 HTTP 的请求,通过该指标可以计算出业务程序的 QPS 值。 + +### 部署业务程序 + +使用 Deployment 部署业务程序: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: httpserver + namespace: httpserver +spec: + replicas: 1 + selector: + matchLabels: + app: httpserver + template: + metadata: + labels: + app: httpserver + spec: + containers: + - name: httpserver + image: registry.imroc.cc/test/httpserver:custom-metrics + imagePullPolicy: Always +--- + +apiVersion: v1 +kind: Service +metadata: + name: httpserver + namespace: httpserver + labels: + app: httpserver + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + prometheus.io/port: "http" +spec: + type: ClusterIP + ports: + - port: 80 + protocol: TCP + name: http + selector: + app: httpserver +``` + +### Prometheus 采集业务监控 + +若已安装 insight-agent,可以通过创建 ServiceMonitor 的 CRD 对象配置 Prometheus。 + +操作步骤:在 **集群详情** -> **自定义资源** 搜索“servicemonitors.monitoring.coreos.com",点击名称进入详情。 +通过创建 YAML,在命名空间 **httpserver** 下创建如下示例的 CRD: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: httpserver + namespace: httpserver + labels: + operator.insight.io/managed-by: insight +spec: + endpoints: + - port: http + interval: 5s + namespaceSelector: + matchNames: + - httpserver + selector: + matchLabels: + app: httpserver +``` + +![servicemonitor](../images/servicemonitor.png) + +!!! note + + 若通过 insight 安装 Prometheus,则 serviceMonitor 上必须打上 `operator.insight.io/managed-by: insight` + 这个 label,通过其他方式安装则无需此 label。 + +### 在 prometheus-adapter 中配置指标规则 + +操作步骤:在 **集群详情** -> **Helm 应用** 搜索 “prometheus-adapter",通过操作栏进入更新页面,在 YAML 中配置自定义指标,示例如下: + +```yaml +rules: + custom: + - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) + name: + as: httpserver_requests_qps + matches: httpserver_requests_total + resources: + template: <<.Resource>> + seriesQuery: httpserver_requests_total +``` + +![rules](../images/rules.png) + +### 创建自定义指标弹性伸缩策略参数 + +按照上述步骤在 Deployment 中找到应用程序 httpserver 并通过自定义指标创建弹性伸缩。 + +![custommetrics](../images/custommetrics.png) diff --git a/docs/zh/docs/end-user/kpanda/scale/hpa-cronhpa-compatibility-rules.md b/docs/zh/docs/end-user/kpanda/scale/hpa-cronhpa-compatibility-rules.md new file mode 100644 index 0000000..488b06f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/hpa-cronhpa-compatibility-rules.md @@ -0,0 +1,37 @@ +# HPA 和 CronHPA 兼容规则 + +HPA 全称为 HorizontalPodAutoscaler,即 Pod 水平自动伸缩。 + +CronHPA 全称为 Cron HorizontalPodAutoscaler,即 Pod 定时的水平自动伸缩。 + +## CronHPA 和 HPA 兼容冲突 + +定时伸缩 CronHPA 通过设置定时的方式触发容器的水平副本伸缩。为了防止突发的流量冲击等状况, +您可能已经配置 HPA 保障应用的正常运行。如果同时检测到了 HPA 和 CronHPA 的存在, +由于 CronHPA 和 HPA 相互独立无法感知,就会出现两个控制器各自工作,后执行的操作会覆盖先执行的操作。 + +对比 CronHPA 和 HPA 的定义模板,可以观察到以下几点: + +- CronHPA 和 HPA 都是通过 scaleTargetRef 字段来获取伸缩对象。 +- CronHPA 通过 jobs 的 crontab 规则定时伸缩副本数。 +- HPA 通过资源利用率判断伸缩情况。 + +!!! note + + 如果同时设置 CronHPA 和 HPA,会出现 CronHPA 和 HPA 同时操作一个 scaleTargetRef 的场景。 + +## CronHPA 和 HPA 兼容方案 + +从上文可知,CronHPA 和 HPA 同时使用会导致后执行的操作覆盖先执行操作的本质原因是两个控制器无法相互感知, +那么只需要让 CronHPA 感知 HPA 的当前状态就能解决冲突问题。 + +系统会将 HPA 作为定时伸缩 CronHPA 的扩缩容对象,从而实现对该 HPA 定义的 Deployment 对象的定时扩缩容。 + +HPA 的定义将 Deployment 配置在 scaleTargetRef 字段下,然后 Deployment 通过自身定义查找 ReplicaSet,最后通过 ReplicaSet 调整真实的副本数目。 + +算丰 AI 算力平台将 CronHPA 中的 scaleTargetRef 设置为 HPA 对象,然后通过 HPA 对象来寻找真实的 scaleTargetRef,从而让 CronHPA 感知 HPA 的当前状态。 + +![CronHPA 和 HPA 兼容方案](../images/hpa-cronhpa-capability-rule-01.png) + +CronHPA 会通过调整 HPA 的方式感知 HPA。CronHPA 通过识别要达到的副本数与当前副本数两者间的较大值, +判断是否需要扩缩容及修改 HPA 的上限;CronHPA 通过识别 CronHPA 要达到的副本数与 HPA 的配置间的较小值,判断是否需要修改 HPA 的下限。 diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-01.png b/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-01.png new file mode 100644 index 0000000..4c359e3 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-02.png b/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-02.png new file mode 100644 index 0000000..4335320 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-03.png b/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-03.png new file mode 100644 index 0000000..c57019a Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-metrics-server-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-01.png b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-01.png new file mode 100644 index 0000000..c509dc0 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-02.png b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-02.png new file mode 100644 index 0000000..446df49 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-03.png b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-03.png new file mode 100644 index 0000000..a76fe33 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-04.png b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-04.png new file mode 100644 index 0000000..c6c1c8f Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-05.png b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-05.png new file mode 100644 index 0000000..27c7f4b Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/create-vpa-05.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-01.png b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-01.png new file mode 100644 index 0000000..9f0b0e9 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-01.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-02.png b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-02.png new file mode 100644 index 0000000..2853242 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-02.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-03.png b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-03.png new file mode 100644 index 0000000..6e6ed16 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-03.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-04.png b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-04.png new file mode 100644 index 0000000..e7a5584 Binary files /dev/null and b/docs/zh/docs/end-user/kpanda/scale/images/install-vpa-04.png differ diff --git a/docs/zh/docs/end-user/kpanda/scale/install-cronhpa.md b/docs/zh/docs/end-user/kpanda/scale/install-cronhpa.md new file mode 100644 index 0000000..c9433ff --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/install-cronhpa.md @@ -0,0 +1,60 @@ +# 安装 kubernetes-cronhpa-controller 插件 + +容器副本定时水平扩缩容策略(CronHPA)能够为周期性高并发应用提供稳定的计算资源保障, __kubernetes-cronhpa-controller__ 则是实现 CronHPA 的关键组件。 + +本节介绍如何安装 __kubernetes-cronhpa-controller__ 插件。 + +!!! note + + 为了使用 CornHPA,不仅需要安装 __kubernetes-cronhpa-controller__ 插件,还要[安装 __metrics-server__ 插件](install-metrics-server.md)。 + +## 前提条件 + +安装 __kubernetes-cronhpa-controller__ 插件之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +参考如下步骤为集群安装 __kubernetes-cronhpa-controller__ 插件。 + +1. 在 __集群列表__ 页面找到需要安装此插件的目标集群,点击该集群的名称,然后在左侧点击 __工作负载__ -> __无状态工作负载__ ,点击目标工作负载的名称。 + +2. 在工作负载详情页面,点击 __弹性伸缩__ 页签,在 __CronHPA__ 右侧点击 __安装__ 。 + + ![工作负载](../../../images/installcronhpa.png) + +3. 阅读该插件的相关介绍,选择版本后点击 __安装__ 按钮。推荐安装 __1.3.0__ 或更高版本。 + + ![工作负载](../../../images/installcronhpa1.png) + +4. 参考以下说明配置参数。 + + ![工作负载](../../../images/installcronhpa2.png) + + - 名称:输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 kubernetes-cronhpa-controller。 + - 命名空间:选择将插件安装在哪个命名空间,此处以 __default__ 为例。 + - 版本:插件的版本,此处以 __1.3.0__ 版本为例。 + - 就绪等待:启用后,将等待应用下的所有关联资源都处于就绪状态,才会标记应用安装成功。 + - 失败删除:如果插件安装失败,则删除已经安装的关联资源。开启后,将默认同步开启 __就绪等待__ 。 + - 详情日志:开启后,将记录安装过程的详细日志。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要较长时间才会被标记为“运行中”状态。 + +5. 在页面右下角点击 __确定__ ,系统将自动跳转至 __Helm 应用__ 列表页面。稍等几分钟后刷新页面作,即可看到刚刚安装的应用。 + + !!! warning + + 如需删除 __kubernetes-cronhpa-controller__ 插件,应在 __Helm 应用__ 列表页面才能将其彻底删除。 + + 如果在工作负载的 __弹性伸缩__ 页签下删除插件,这只是删除了该插件的工作负载副本,插件本身仍未删除,后续重新安装该插件时也会提示错误。 + +6. 回到工作负载详情页面下的 __弹性伸缩__ 页签,可以看到界面显示 __插件已安装__ 。现在可以开始创建 CronHPA 策略了。 + + ![工作负载](../../../images/installcronhpa3.png) diff --git a/docs/zh/docs/end-user/kpanda/scale/install-metrics-server.md b/docs/zh/docs/end-user/kpanda/scale/install-metrics-server.md new file mode 100644 index 0000000..de0480a --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/install-metrics-server.md @@ -0,0 +1,142 @@ +--- +hide: + - toc +--- + +# 安装 metrics-server 插件 + +__metrics-server__ 是 Kubernetes 内置的资源使用指标采集组件。 +您可以通过配置弹性伸缩(HPA)策略来实现工作负载资源自动水平伸缩 Pod 副本。 + +本节介绍如何安装 __metrics-server__ 。 + +## 前提条件 + +安装 __metrics-server__ 插件前,需要满足以下前提条件: + +- 容器管理模块[已接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者[已创建 Kubernetes 集群](../clusters/create-cluster.md),且能够访问集群的 UI 界面。 + +- 已完成一个[命名空间的创建](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +请执行如下步骤为集群安装 __metrics-server__ 插件。 + +1. 在工作负载详情下的弹性伸缩页面,点击 __去安装__ ,进入 __metrics-server__ 插件安装界面。 + + ![工作负载](images/create-metrics-server-02.png) + +2. 阅读 __metrics-server__ 插件相关介绍,选择版本后点击 __安装__ 按钮。本文将以 __3.8.2__ 版本为例进行安装,推荐您安装 __3.8.2__ 及更高版本。 + + ![工作负载](images/create-metrics-server-01.png) + +3. 在安装配置界面配置基本参数。 + + ![工作负载](images/create-metrics-server-03.png) + + - 名称:输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 metrics-server-01。 + - 命名空间:选择插件安装的命名空间,此处以 __default__ 为例。 + - 版本:插件的版本,此处以 __3.8.2__ 版本为例。 + - 就绪等待:启用后,将等待应用下所有关联资源处于就绪状态,才会标记应用安装成功。 + - 失败删除:开启后,将默认同步开启就绪等待。如果安装失败,将删除安装相关资源。 + - 详情日志:开启安装过程日志的详细输出。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要经过较长时间才会被标记为 __运行中__ 状态。 + +4. 高级参数配置 + + - 如果集群网络无法访问 `k8s.gcr.io` 仓库,请尝试修改 `repositort` 参数为 `repository: k8s.m.daocloud.io/metrics-server/metrics-server` + + - 安装 __metrics-server__ 插件还需提供 SSL 证书。如需绕过证书校验,需要在 `defaultArgs:` 处添加 `- --kubelet-insecure-tls` 参数。 + + ??? note "点击查看推荐的 YAML 参数" + + ```yaml + image: + repository: k8s.m.daocloud.io/metrics-server/metrics-server # 将仓库源地址修改为 k8s.m.daocloud.io + tag: '' + pullPolicy: IfNotPresent + imagePullSecrets: [] + nameOverride: '' + fullnameOverride: '' + serviceAccount: + create: true + annotations: {} + name: '' + rbac: + create: true + pspEnabled: false + apiService: + create: true + podLabels: {} + podAnnotations: {} + podSecurityContext: {} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + priorityClassName: system-cluster-critical + containerPort: 4443 + hostNetwork: + enabled: false + replicas: 1 + updateStrategy: {} + podDisruptionBudget: + enabled: false + minAvailable: null + maxUnavailable: null + defaultArgs: + - '--cert-dir=/tmp' + - '--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname' + - '--kubelet-use-node-status-port' + - '--metric-resolution=15s' + - --kubelet-insecure-tls # 绕过证书校验 + args: [] + livenessProbe: + httpGet: + path: /livez + port: https + scheme: HTTPS + initialDelaySeconds: 0 + periodSeconds: 10 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /readyz + port: https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 10 + failureThreshold: 3 + service: + type: ClusterIP + port: 443 + annotations: {} + labels: {} + metrics: + enabled: false + serviceMonitor: + enabled: false + additionalLabels: {} + interval: 1m + scrapeTimeout: 10s + resources: {} + extraVolumeMounts: [] + extraVolumes: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ``` + +5. 点击 __确定__ 按钮,完成 __metrics-server__ 插件的安装,之后系统将自动跳转至 __Helm 应用__ 列表页面, + 稍等几分钟后,为页面执行刷新操作,即可看到刚刚安装的应用。 + +!!! note + + 删除 __metrics-server__ 插件时,在 __Helm 应用__ 列表页面才能彻底删除该插件。如果仅在工作负载页面删除 __metrics-server__ , + 这只是删除了该应用的工作负载副本,应用本身仍未删除,后续重新安装该插件时也会提示错误。 diff --git a/docs/zh/docs/end-user/kpanda/scale/install-vpa.md b/docs/zh/docs/end-user/kpanda/scale/install-vpa.md new file mode 100644 index 0000000..ff74324 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/install-vpa.md @@ -0,0 +1,55 @@ +# 安装 vpa 插件 + +容器垂直扩缩容策略(Vertical Pod Autoscaler, VPA)能够让集群的资源配置更加合理,避免集群资源浪费。 __vpa__ 则是实现容器垂直扩缩容的关键组件。 + +本节介绍如何安装 __vpa__ 插件。 + + 为了使用 VPA 策略,不仅需要安装 __vpa__ 插件,还要[安装 __metrics-server__ 插件](install-metrics-server.md)。 + +## 前提条件 + +安装 __vpa__ 插件之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +## 操作步骤 + +参考如下步骤为集群安装 __vpa__ 插件。 + +1. 在 __集群列表__ 页面找到需要安装此插件的目标集群,点击该集群的名称,然后在左侧点击 __工作负载__ -> __无状态工作负载__ ,点击目标工作负载的名称。 + +2. 在工作负载详情页面,点击 __弹性伸缩__ 页签,在 __VPA__ 右侧点击 __安装__ 。 + + ![工作负载](images/install-vpa-01.png) +3. 阅读该插件的相关介绍,选择版本后点击 __安装__ 按钮。推荐安装 __1.5.0__ 或更高版本。 + + ![工作负载](images/install-vpa-02.png) +4. 查看以下说明配置参数。 + + ![工作负载](images/install-vpa-04.png) + - 名称:输入插件名称,请注意名称最长 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 kubernetes-cronhpa-controller。 + - 命名空间:选择将插件安装在哪个命名空间,此处以 __default__ 为例。 + - 版本:插件的版本,此处以 __4.5.0__ 版本为例。 + - 就绪等待:启用后,将等待应用下的所有关联资源都处于就绪状态,才会标记应用安装成功。 + - 失败删除:如果插件安装失败,则删除已经安装的关联资源。开启后,将默认同步开启 __就绪等待__ 。 + - 详情日志:开启后,将记录安装过程的详细日志。 + + !!! note + + 开启 __就绪等待__ 和/或 __失败删除__ 后,应用需要经过较长时间才会被标记为“运行中”状态。 + +5. 在页面右下角点击 __确定__ ,系统将自动跳转至 __Helm 应用__ 列表页面。稍等几分钟后刷新页面作,即可看到刚刚安装的应用。 + + !!! warning + + 如需删除 __vpa__ 插件,应在 __Helm 应用__ 列表页面才能将其彻底删除。 + + 如果在工作负载的 __弹性伸缩__ 页签下删除插件,这只是删除了该插件的工作负载副本,插件本身仍未删除,后续重新安装该插件时也会提示错误。 + +6. 回到工作负载详情页面下的 __弹性伸缩__ 页签,可以看到界面显示 __插件已安装__ 。现在可以开始[创建 VPA](create-vpa.md) 策略了。 + + ![工作负载.png](images/install-vpa-03.png) diff --git a/docs/zh/docs/end-user/kpanda/scale/knative/install.md b/docs/zh/docs/end-user/kpanda/scale/knative/install.md new file mode 100644 index 0000000..998736c --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/knative/install.md @@ -0,0 +1,21 @@ +# 安装 + +Knative 是一个面向无服务器部署的跨平台解决方案。 + +## 步骤 + +1. 登录集群,点击侧边栏 __Helm 应用__ -> __Helm 模板__ ,在右侧上方搜索框输入 __knative__ ,然后按回车键搜索。 + + ![Install-1](../../images/knative-install-1.png) + +2. 点击搜索出的 __knative-operator__ ,进入安装配置界面。你可以在该界面查看可用版本以及 Helm values 的 Parameters 可选项。 + + ![Install-2](../../images/knative-install-2.png) + +3. 点击安装按钮后,进入安装配置界面。 + + ![Install-3](../../images/knative-install-3.png) + +4. 输入名称,安装租户,建议勾选 __就绪等待__ 和 __详细日志__ 。 + +5. 在下方设置,可以勾选 __Serving__ ,并输入 Knative Serving 组件的安装租户,会在安装后部署 Knative Serving 组件,该组件由 Knative Operator 管理。 diff --git a/docs/zh/docs/end-user/kpanda/scale/knative/knative.md b/docs/zh/docs/end-user/kpanda/scale/knative/knative.md new file mode 100644 index 0000000..d7a4a72 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/knative/knative.md @@ -0,0 +1,57 @@ +# Kantive 介绍 + +Knative 提供了一种更高层次的抽象,简化并加速了在 Kubernetes 上构建、部署和管理应用的过程。它使得开发人员能够更专注于业务逻辑的实现,而将大部分基础设施和运维工作交给 Knative 去处理,从而显著提高生产力。 + +## 组件 + +knative-operator 运行组件如下。 + +```shell +knative-operator knative-operator-58f7d7db5c-7f6r5 1/1 Running 0 6m55s +knative-operator operator-webhook-667dc67bc-qvrv4 1/1 Running 0 6m55s +``` + +knative-serving 组件如下。 + +```shell +knative-serving 3scale-kourier-gateway-d69fbfbd-bd8d8 1/1 Running 0 7m13s +knative-serving activator-7c6fddd698-wdlng 1/1 Running 0 7m3s +knative-serving autoscaler-8f4b876bb-kd25p 1/1 Running 0 7m17s +knative-serving autoscaler-hpa-5f7f74679c-vkc7p 1/1 Running 0 7m15s +knative-serving controller-789c896c46-tfvsv 1/1 Running 0 7m17s +knative-serving net-kourier-controller-7db578c889-7gd5l 1/1 Running 0 7m14s +knative-serving webhook-5c88b94c5-78x7m 1/1 Running 0 7m1s +knative-serving storage-version-migration-serving-serving-1.12.2-t7zvd 0/1 Completed 0 7m15s +``` + +| 组件 | 作用 | +|----------|-------------| +| Activator | 对请求排队(如果一个 Knative Service 已经缩减到零)。调用 autoscaler,将缩减到 0 的服务恢复并转发排队的请求。Activator 还可以充当请求缓冲器,处理突发流量。 | +| Autoscaler | Autoscaler 负责根据配置、指标和进入的请求来缩放 Knative 服务。 | +| Controller | 管理 Knative CR 的状态。它会监视多个对象,管理依赖资源的生命周期,并更新资源状态。 | +| Queue-Proxy | Sidecar 容器,每个 Knative Service 都会注入一个。负责收集流量数据并报告给 Autoscaler,Autoscaler 根据这些数据和预设的规则来发起扩容或缩容请求。 | +| Webhooks | Knative Serving 有几个 Webhooks 负责验证和变更 Knative 资源。 | + +## Ingress 流量入口方案 + +| 方案 | 适用场景 | +|----------|-------------| +| Istio | 如果已经用了 Istio,可以选择 Istio 作为流量入口方案。 | +| Contour | 如果集群中已经启用了 Contour,可以选择 Contour 作为流量入口方案。 | +| Kourier | 如果在没有上述 2 种 Ingress 组件时,可以使用 Knative 基于 Envoy 实现的 Kourier Ingress 作为流量入口。 | + +## Autoscaler 方案对比 + +| Autoscaler 类型 | 是否为 Knative Serving 核心部分 | 默认启用 | Scale to Zero 支持 | 基于 CPU 的 Autoscaling 支持 | +| -------------- | -------------------------- | ------------ | ------------------ | -------------- | +| Knative Pod Autoscaler (KPA) | 是 | 是 | 是 | 否 | +| Horizontal Pod Autoscaler (HPA) | 否 | 需安装 Knative Serving 后启用 | 否 | 是 | + +## CRD + +| 资源类型 | API 名称 | 描述 | +| ------------ | ----------- | --- | +| Services | service.serving.knative.dev | 自动管理 Workload 的整个生命周期,控制其他对象的创建,确保应用具有 Routes、Configurations 以及每次更新时的新 revision。 | +| Routes | route.serving.knative.dev | 将网络端点映射到一个或多个修订版本,支持流量分配和版本路由。 | +| Configurations | configuration.serving.knative.dev | 维护部署的期望状态,提供代码和配置之间的分离,遵循 Twelve-Factor 应用程序方法论,修改配置会创建新的 revision。 | +| Revisions | revision.serving.knative.dev | 每次对工作负载修改的时间点快照,是不可变对象,可根据流量自动扩容和缩容。 | diff --git a/docs/zh/docs/end-user/kpanda/scale/knative/playground.md b/docs/zh/docs/end-user/kpanda/scale/knative/playground.md new file mode 100644 index 0000000..64df7d1 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/knative/playground.md @@ -0,0 +1,145 @@ +# Knative 使用实践 + +在本节中,我们将通过几个实践来深入了解学习 Knative。 + +## case 1 - Hello World + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +可以使用 kubectl 已部署的应用的状态,这个应用由 knative 自动配置了 ingress 和伸缩器。 + +```shell +~ kubectl get service.serving.knative.dev/hello +NAME URL LATESTCREATED LATESTREADY READY REASON +hello http://hello.knative-serving.knative.loulan.me hello-00001 hello-00001 True +``` + +部署出的 Pod YAML 如下,由 2 个 Pod 组成:user-container 和 queue-proxy。 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: hello-00003-deployment-5fcb8ccbf-7qjfk +spec: + containers: + - name: user-container + - name: queue-proxy +``` + +![knative-request-flow](../../images/knative-request-flow.png) + +请求流: + +1. case1 在低流量或零流量时,流量将路由到 activator +2. case2 流量大时,流量大于 target-burst-capacity 时才直接路由到 Pod + 1. 配置为 0,只有从 0 扩容存在 + 2. 配置为 -1,activator 会一直存在请求路径 + 3. 配置为 >0,触发扩缩容之前,系统能够额外处理的并发请求数量。 +3. case3 流量再变小时,流量低于 current_demand + target-burst-capacity > (pods * concurrency-target) 时将再次路由到 activator + + 待处理的请求总数 + 能接受的超过目标并发数的请求数量 > 每个 Pod 的目标并发数 * Pod 数量 + +## case 2 - 基于并发弹性伸缩 + +我们首先在集群应用下面 YAML 定义。 + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "1" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +执行下面命令测试,并可以通过 `kubectl get pods -A -w` 来观察扩容的 Pod。 + +```shell +wrk -t2 -c4 -d6s http://hello.knative-serving.knative.daocloud.io/ +``` + +## case 3 - 基于并发弹性伸缩,达到特定比例提前扩容 + +我们可以很轻松的实现,例如限制每个容器并发为 10,可以通过 `autoscaling.knative.dev/target-utilization-percentage: 70` 来实现,达到 70% 就开始扩容 Pod。 + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "10" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" +        autoscaling.knative.dev/target-utilization-percentage: "70" +        autoscaling.knative.dev/metric: "concurrency" +     spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" +``` + +## case 4 - 灰度发布/流量百分比 + +我们可以通过 `spec.traffic` 实现到每个版本流量的控制。 + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: hello +spec: + template: + metadata: + annotations: + autoscaling.knative.dev/target: "1" + autoscaling.knative.dev/class: "kpa.autoscaling.knative.dev" + spec: + containers: + - image: m.daocloud.io/ghcr.io/knative/helloworld-go:latest + ports: + - containerPort: 8080 + env: + - name: TARGET + value: "World" + traffic: + - latestRevision: true + percent: 50 + - latestRevision: false + percent: 50 + revisionName: hello-00001 +``` diff --git a/docs/zh/docs/end-user/kpanda/scale/knative/scene.md b/docs/zh/docs/end-user/kpanda/scale/knative/scene.md new file mode 100644 index 0000000..f9666d4 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/scale/knative/scene.md @@ -0,0 +1,19 @@ +# 使用场景 + +## 适合的场景 + +* 短连接高并发业务 +* 需要弹性伸缩的业务 +* 大量应用需要缩容到 0 提高资源利用率 +* AI Serving 服务,基于特定指标进行扩容 + +!!! tip + + 短连接高并发业务以及需要弹性伸缩的业务,推荐使用 HPA 和 VPA 能力。 + +## 不适合的场景 + +* 长连接业务 +* 延时敏感业务 +* 基于 cookie 的流量分流 +* 基于 header 的流量分流 diff --git a/docs/zh/docs/end-user/kpanda/security/audit.md b/docs/zh/docs/end-user/kpanda/security/audit.md new file mode 100644 index 0000000..52dd57b --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/security/audit.md @@ -0,0 +1,61 @@ +# 权限扫描 + +为了使用[权限扫描](index.md)功能,需要先创建扫描策略,执行该策略之后会自动生成扫描报告以供查看。 + +## 创建扫描策略 + +1. 在容器管理模块的首页左侧导航栏点击 __安全管理__ 。 + + ![安全管理](../../../images/security01_2.png) + +2. 在左侧导航栏点击 __权限扫描__ ,点击 __扫描策略__ 页签,在右侧点击 __创建扫描策略__ 。 + + ![安全管理](../../../images/security11.png) + +3. 参考下列说明填写配置,最后点击 __确定__ 即可。 + + - 集群:选择需要扫描哪个集群。可选的集群列表来自容器管理模块中接入或创建的集群。如果没有想选的集群,可以去容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建](../clusters/create-cluster.md)集群。 + - 扫描类型: + + - 立即扫描:在扫描策略创建好之后立即执行一次扫描,后续不可以自动/手动再次执行扫描。 + - 定时扫描:通过设置扫描周期,自动按时重复执行扫描。 + + - 扫描报告保留数量:设置最多保留多少扫描报告。超过指定的保留数量时,从最早的报告开始删除。 + + ![安全管理](../../../images/security12.png) + +## 更新/删除扫描策略 + +创建扫描策略之后,可以根据需要更新或删除扫描策略。 + +在 __扫描策略__ 页签下,点击配置右侧的 __┇__ 操作按钮: + +- 对于周期性的扫描策略: + + - 选择 __立即执行__ 意味着,在周期计划之外立即再扫描一次集群 + - 选择 __禁用__ 会中断扫描计划,直到点击 __启用__ 才可以继续根据周期计划执行该扫描策略。 + - 选择 __编辑__ 可以更新配置,支持更新扫描配置、类型、扫描周期、报告保留数量,不可更改配置名称和需要扫描的目标集群。 + - 选择 __删除__ 可以删除该配置 + +- 对于一次性的扫描策略:仅支持 __删除__ 操作。 + + ![创建扫描配置](../../../images/security13.png) + +## 查看扫描报告 + +1. 在 __安全管理__ -> __权限扫描__ -> __扫描报告__ 页签下,点击报告名称 + + > 在报告右侧点击 __删除__ 可以手动删除报告。 + + ![创建扫描配置](../../../images/security14.png) + +2. 查看扫描报告内容,包括: + + - 扫描的目标集群 + - 使用的扫描策略 + - 扫描项总数、警告数、错误数 + - 在周期性扫描策略生成的扫描报告中,还可以查看扫描频率 + - 扫描开始的时间 + - 检查详情,例如被检查的资源、资源类型、扫描结果、错误类型、错误详情 + + ![创建扫描配置](../../../images/security15.png) \ No newline at end of file diff --git a/docs/zh/docs/end-user/kpanda/security/cis/config.md b/docs/zh/docs/end-user/kpanda/security/cis/config.md new file mode 100644 index 0000000..5602891 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/security/cis/config.md @@ -0,0 +1,39 @@ +# 扫描配置 + +使用[合规性扫描](../index.md)的第一步,就是先创建扫描配置。基于扫描配置再创建扫描策略、执行扫描策略,最后查看扫描结果。 + +## 创建扫描配置 + +创建扫描配置的步骤如下: + +1. 在容器管理模块的首页左侧导航栏点击 __安全管理__ 。 + + ![安全管理](../../../../images/security01_3.png) + +2. 默认进入 __合规性扫描__ 页面,点击 __扫描配置__ 页签,然后在右上角点击 __创建扫描配置__ 。 + + ![安全管理](../../../../images/security02.png) + +3. 填写配置名称、选择配置模板、按需勾选扫描项,最后点击 __确定__ 。 + + 扫描模板:目前提供了两个模板。 __kubeadm__ 模板适用于一般情况下的 Kubernetes 集群。 + 我们在 __kubeadm__ 模板基础上,结合算丰 AI 算力平台的平台设计忽略了不适用于算丰 AI 算力平台的扫描项。 + + ![安全管理](../../../../images/security03.png) + +## 查看扫描配置 + +在扫描配置页签下,点击扫描配置的名称,可以查看该配置的类型、扫描项数量、创建时间、配置模板,以及该配置启用的具体扫描项。 + +![安全管理](../../../../images/security04.png) + +## 更新/删除扫描配置 + +扫描配置创建成功之后,可以根据需求更新配置或删除该配置。 + +在扫描配置页签下,点击配置右侧的 __┇__ 操作按钮: + +- 选择 __编辑__ 可以更新配置,支持更新描述、模板和扫描项。不可更改配置名称。 +- 选择 __删除__ 可以删除该配置。 + + ![安全管理](../../../../images/security04.png) diff --git a/docs/zh/docs/end-user/kpanda/security/cis/policy.md b/docs/zh/docs/end-user/kpanda/security/cis/policy.md new file mode 100644 index 0000000..5afed68 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/security/cis/policy.md @@ -0,0 +1,39 @@ +# 扫描策略 + +## 创建扫描策略 + +[创建扫描配置](config.md)之后,可以基于配置创建扫描策略。 + +1. 在 __安全管理__ -> __合规性扫描__ 页面的 __扫描策略__ 页签下,在右侧点击创建扫描策略。 + + ![创建扫描配置](../../../../images/security05.png) + +2. 参考下列说明填写配置后,点击 __确定__ 。 + + - 集群:选择需要扫描哪个集群。可选的集群列表来自容器管理模块中接入或创建的集群。如果没有想选的集群,可以去容器管理模块中[接入](../../clusters/integrate-cluster.md)或[创建](../../clusters/create-cluster.md)集群。 + - 扫描配置:选择事先创建好的扫描配置。扫描配置规定了需要执行哪些具体的扫描项。 + - 扫描类型: + + - 立即扫描:在扫描策略创建好之后立即执行一次扫描,后续不可以自动/手动再次执行扫描。 + - 定时扫描:通过设置扫描周期,自动按时重复执行扫描。 + + - 扫描报告保留数量:设置最多保留多少扫描报告。超过指定的保留数量时,从最早的报告开始删除。 + + ![创建扫描配置](../../../../images/security06.png) + +## 更新/删除扫描策略 + +创建扫描策略之后,可以根据需要更新或删除扫描策略。 + +在 __扫描策略__ 页签下,点击配置右侧的 __┇__ 操作按钮: + +- 对于周期性的扫描策略: + + - 选择 __立即执行__ 意味着,在周期计划之外立即再扫描一次集群 + - 选择 __禁用__ 会中断扫描计划,直到点击 __启用__ 才可以继续根据周期计划执行该扫描策略。 + - 选择 __编辑__ 可以更新配置,支持更新扫描配置、类型、扫描周期、报告保留数量,不可更改配置名称和需要扫描的目标集群。 + - 选择 __删除__ 可以删除该配置 + +- 对于一次性的扫描策略:仅支持 __删除__ 操作。 + + ![创建扫描配置](../../../../images/security07.png) diff --git a/docs/zh/docs/end-user/kpanda/security/cis/report.md b/docs/zh/docs/end-user/kpanda/security/cis/report.md new file mode 100644 index 0000000..6024862 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/security/cis/report.md @@ -0,0 +1,27 @@ +--- +hide: + - toc +--- + +# 扫描报告 + +执行扫描策略之后会自动生成扫描报告。您可以在线查看扫描报告或将其下载到本地查看。 + +- 下载查看扫描报告 + + __安全管理__ -> __合规性扫描__ 页面的 __扫描报告__ 页签点击报告右侧的 __┇__ 操作按钮选择 __下载__ 。 + + ![报告列表截图](../../../../images/security09.png) + +- 在线查看扫描报告 + + 点击某个报告的名称,您可以在线查看 CIS 合规性扫描的报告内容。具体包括: + + - 扫描的目标集群 + - 使用的扫描策略和扫描配置 + - 扫描开始时间 + - 扫描项总数、通过数与未通过数 + - 对于未通过的扫描项给出对应的修复建议 + - 对于通过的扫描项给出更安全的操作建议 + + ![报告列表截图](../../../../images/security10.png) diff --git a/docs/zh/docs/end-user/kpanda/security/hunter.md b/docs/zh/docs/end-user/kpanda/security/hunter.md new file mode 100644 index 0000000..d741eb8 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/security/hunter.md @@ -0,0 +1,61 @@ +# 漏洞扫描 + +为了使用[漏洞扫描](index.md)功能,需要先创建扫描策略,执行该策略之后会自动生成扫描报告以供查看。 + +## 创建扫描策略 + +1. 在容器管理模块的首页左侧导航栏点击 __安全管理__ 。 + + ![安全管理](../../../images/security01_1.png) + +2. 在左侧导航栏点击 __漏洞扫描__ ,点击 __扫描策略__ 页签,在右侧点击 __创建扫描策略__ 。 + + ![安全管理](../../../images/security16.png) + +3. 参考下列说明填写配置,最后点击 __确定__ 即可。 + + - 集群:选择需要扫描哪个集群。可选的集群列表来自容器管理模块中接入或创建的集群。如果没有想选的集群,可以去容器管理模块中[接入](../clusters/integrate-cluster.md)或[创建](../clusters/create-cluster.md)集群。 + - 扫描类型: + + - 立即扫描:在扫描策略创建好之后立即执行一次扫描,后续不可以自动/手动再次执行扫描。 + - 定时扫描:通过设置扫描周期,自动按时重复执行扫描。 + + - 扫描报告保留数量:设置最多保留多少扫描报告。超过指定的保留数量时,从最早的报告开始删除。 + + ![安全管理](../../../images/security17.png) + +## 更新/删除扫描策略 + +创建扫描策略之后,可以根据需要更新或删除扫描策略。 + +在 __扫描策略__ 页签下,点击配置右侧的 __┇__ 操作按钮: + +- 对于周期性的扫描策略: + + - 选择 __立即执行__ 意味着,在周期计划之外立即再扫描一次集群 + - 选择 __禁用__ 会中断扫描计划,直到点击 __启用__ 才可以继续根据周期计划执行该扫描策略。 + - 选择 __编辑__ 可以更新配置,支持更新扫描配置、类型、扫描周期、报告保留数量,不可更改配置名称和需要扫描的目标集群。 + - 选择 __删除__ 可以删除该配置 + +- 对于一次性的扫描策略:仅支持 __删除__ 操作。 + + ![创建扫描配置](../../../images/security18.png) + +## 查看扫描报告 + +1. 在 __安全管理__ -> __权限扫描__ -> __扫描报告__ 页签下,点击报告名称 + + > 在报告右侧点击 __删除__ 可以手动删除报告。 + + ![创建扫描配置](../../../images/security19.png) + +2. 查看扫描报告内容,包括: + + - 扫描的目标集群 + - 使用的扫描策略 + - 扫描频率 + - 风险总数、高风险数、中风险数、低风险数 + - 扫描时间 + - 检查详情,例如漏洞 ID、漏洞类型、漏洞名称、漏洞描述等 + + ![创建扫描配置](../../../images/security20.png) diff --git a/docs/zh/docs/end-user/kpanda/security/index.md b/docs/zh/docs/end-user/kpanda/security/index.md new file mode 100644 index 0000000..76a6c7d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/security/index.md @@ -0,0 +1,63 @@ +# 安全扫描类型 + +在Kubernetes(简称K8s)环境中,安全扫描是确保集群安全性的关键措施之一。其中,合规性扫描(基于CIS Benchmark)、权限扫描(基于kube-audit审计功能)、漏洞扫描(基于 kube-hunter)是三种常见且重要的安全扫描手段: + +- 合规性扫描:基于 [CIS Benchmark](https://github.com/aquasecurity/kube-bench/tree/main/cfg) 对集群节点进行安全扫描。CIS Benchmark 是一套全球公认的最佳实践标准,为 Kubernetes 集群提供了详细的安全配置指南和自动化检查工具(如Kube-Bench),帮助组织确保其K8s集群符合安全基线要求,保护系统和数据免受威胁。 + +- 权限扫描:基于kube-audit审计功能。权限扫描主要解决集群访问控制和操作透明度的问题。通过审计日志,集群管理员能够追溯集群资源的访问历史,识别异常行为,如未经授权的访问、敏感数据的泄露、有安全漏洞的操作记录等。这对于故障排查、安全事件响应以及满足合规性要求至关重要。此外,权限扫描还可以帮助组织发现潜在的权限滥用问题,及时采取措施防止安全事件的发生。 + +- 漏洞扫描:基于 kube-hunter,主要解决 Kubernetes 集群中存在的已知漏洞和配置错误问题。kube-hunter 通过模拟攻击行为,能够识别集群中可被恶意利用的漏洞,如未授权访问、暴露的服务和API端点、配置错误的角色和绑定策略等。特别地,kube-hunter能够识别并报告 CVE 漏洞,这些漏洞如果被恶意利用,可能导致数据泄露、服务中断等严重后果。[CVE 漏洞](https://www.mitre.org/)是由国际知名的安全组织如MITRE所定义和维护的,CVE数据库为软件和固件中的已知漏洞提供了唯一标识符,成为全球安全社区共同遵循的标准。kube-hunter 通过利用 CVE 数据库中的信息,能够帮助用户快速识别并响应Kubernetes集群中的安全威胁。 + +## 合规性扫描 + +合规性扫描的对象是集群节点。扫描结果中会列出扫描项以及扫描结果,并针对未通过的扫描项给出修复建议。有关扫描时用到的具体安全规则,可参考 [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes) + +检查不同类型的节点时,扫描的侧重点有所不同。 + +- 扫描控制平面节点(Controller) + + - 关注 __API Server__ 、 __controller-manager__ 、 __scheduler__ 、 __kubelet__ 等系统组件的安全性 + - 检查 Etcd 数据库的安全配置 + - 检查集群身份验证机制、授权策略和网络安全配置是否符合安全标准 + +- 扫描工作节点(Worker) + + - 检查 kubelet、Docker等容器运行时的配置否符合安全标准 + - 检查容器镜像是否经过信任验证 + - 检查节点的网络安全配置否符合安全标准 + +!!! tip + + 使用合规性扫描时,需要先创建[扫描配置](cis/config.md),然后基于该配置创建[扫描策略](cis/policy.md)。执行扫描策略之后,可以[查看扫描报告](cis/report.md)。 + +## 权限扫描 + +权限扫描侧重于权限问题引发的安全漏洞。权限扫描可以帮助用户识别 Kubernetes 集群中的安全威胁,标识哪些资源需要进行进一步的审查和保护措施。通过执行这些检查项,用户可以更清楚、更全面地了解自己的 Kubernetes 环境,确保集群环境符合 Kubernetes 的最佳实践和安全标准。 + +具体而言,权限扫描支持以下操作: + +- 扫描集群中的所有节点的健康状态。 + +- 扫描集群组件的运行状况,如 __kube-apiserver__ 、 __kube-controller-manager__ 、 __kube-scheduler__ 等。 + +- 扫描安全配置:检查 Kubernetes 的安全配置 + + - API 安全:启用了不安全的 API 版本,是否设置了适当的 RBAC 角色和权限限制等 + - 容器安全:是否使用了不安全的 Image、是否开放了特权模式,是否设置了合适的安全上下文等 + - 网络安全:是否启用了合适的网络策略来限制流量,是否使用了 TLS 加密等 + - 存储安全:是否启用了适当的加密、访问控制等。 + - 应用程序安全:是否设置了必要的安全措施,例如密码管理、跨站脚本攻击防御等。 + +- 提供警告和建议:建议集群管理员执行的安全最佳实践,例如定期轮换证书、使用强密码、限制网络访问等。 + +!!! tip + + 使用合规性扫描时,需要先创建扫描策略。执行扫描策略之后,可以查看扫描报告。详情可参考[安全扫描](audit.md)。 + +## 漏洞扫描 + +漏洞扫描侧重于扫描潜在的恶意攻击和安全漏洞,例如远程代码执行、SQL 注入、XSS 攻击等,以及一些针对 Kubernetes 特定的攻击。最终的扫描报告会列出集群中存在的安全漏洞,并提出修复建议。 + +!!! tip + + 使用合规性扫描时,需要先创建扫描策略。执行扫描策略之后,可以查看扫描报告。详情可参考[漏洞扫描](hunter.md)。 diff --git a/docs/zh/docs/end-user/kpanda/storage/pv.md b/docs/zh/docs/end-user/kpanda/storage/pv.md new file mode 100644 index 0000000..9be2a5f --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/storage/pv.md @@ -0,0 +1,112 @@ +# 数据卷(PV) + +数据卷(PersistentVolume,PV)是集群中的一块存储,可由管理员事先制备,或使用存储类(Storage Class)来动态制备。PV 是集群资源,但拥有独立的生命周期,不会随着 Pod 进程结束而被删除。将 PV 挂载到工作负载可以实现工作负载的数据持久化。PV 中保存了可被 Pod 中容器访问的数据目录。 + +## 创建数据卷 + +目前支持通过 YAML 和表单两种方式创建数据卷,这两种方式各有优劣,可以满足不同用户的使用需求。 + +- 通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉数据卷的 YAML 文件配置。 + +- 通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷(PV)__ -> __YAML 创建__ 。 + + ![路径](../../../images/pv01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![yaml](../../../images/pv02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷(PV)__ -> __创建数据卷(PV)__ 。 + + ![路径](../../../images/pv03.png) + +2. 填写基本信息。 + + - 数据卷名称、数据卷类型、挂载路径、卷模式、节点亲和性在创建之后不可更改。 + - 数据卷类型:有关卷类型的详细介绍,可参考 Kubernetes 官方文档[卷](https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/)。 + + - Local:将 Node 节点的本地存储包装成 PVC 接口,容器直接使用 PVC 而无需关注底层的存储类型。Local 卷不支持动态配置数据卷,但支持配置节点亲和性,可以限制能从哪些节点上访问该数据卷。 + - HostPath:使用 Node 节点的文件系统上的文件或目录作为数据卷,不支持基于节点亲和性的 Pod 调度。 + + - 挂载路径:将数据卷挂载到容器中的某个具体目录下。 + - 访问模式: + + - ReadWriteOnce:数据卷可以被一个节点以读写方式挂载。 + - ReadWriteMany:数据卷可以被多个节点以读写方式挂载。 + - ReadOnlyMany:数据卷可以被多个节点以只读方式挂载。 + - ReadWriteOncePod:数据卷可以被单个 Pod 以读写方式挂载。 + + - 回收策略: + + - Retain:不删除 PV,仅将其状态变为 __released__ ,需要用户手动回收。有关如何手动回收,可参考[持久卷](https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/#retain)。 + - Recycle:保留 PV 但清空其中的数据,执行基本的擦除操作( __rm -rf /thevolume/*__ )。 + - Delete:删除 PV 时及其中的数据。 + + - 卷模式: + + - 文件系统:数据卷将被 Pod 挂载到某个目录。如果数据卷的存储来自某块设备而该设备目前为空,第一次挂载卷之前会在设备上创建文件系统。 + - 块:将数据卷作为原始块设备来使用。这类卷以块设备的方式交给 Pod 使用,其上没有任何文件系统,可以让 Pod 更快地访问数据卷。 + + - 节点亲和性: + + ![基本信息](../../../images/pv04.png) + +## 查看数据卷 + +在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷(PV)__ 。 + +- 该页面可以查看当前集群中的所有数据卷,以及各个数据卷的状态、容量、命名空间等信息。 + +- 支持按照数据卷的名称、状态、命名空间、创建时间进行顺序或逆序排序。 + + ![详情](../../../images/pv06.png) + +- 点击数据卷的名称,可以查看该数据卷的基本配置、存储池信息、标签、注解等信息。 + + ![详情](../../../images/pv05.png) + +## 克隆数据卷 + +通过克隆数据卷,可以基于被克隆数据卷的配置,重新创建一个新的数据卷。 + +1. 进入克隆页面 + + - 在数据卷列表页面,找到需要克隆的数据卷,在右侧的操作栏下选择 __克隆__ 。 + + > 也可以点击数据卷的名称,在详情页面的右上角点击操作按钮选择 __克隆__ 。 + + ![克隆](../../../images/pv11.png) + +2. 直接使用原配置,或者按需进行修改,然后在页面底部点击 __确定__ 。 + +## 更新数据卷 + +有两种途径可以更新数据卷。支持通过表单或 YAML 文件更新数据卷。 + +!!! note + + 仅支持更新数据卷的别名、容量、访问模式、回收策略、标签和注解。 + +- 在数据卷列表页面,找到需要更新的数据卷,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pv07.png) + +- 点击数据卷的名称,进入数据卷的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pv08.png) + +## 删除数据卷 + +在数据卷列表页面,找到需要删除的数据,在右侧的操作栏下选择 __删除__ 。 + +> 也可以点击数据卷的名称,在详情页面的右上角点击操作按钮选择 __删除__ 。 + +![删除](../../../images/pv09.png) diff --git a/docs/zh/docs/end-user/kpanda/storage/pvc.md b/docs/zh/docs/end-user/kpanda/storage/pvc.md new file mode 100644 index 0000000..e723647 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/storage/pvc.md @@ -0,0 +1,127 @@ +# 数据卷声明(PVC) + +持久卷声明(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。PVC 消耗 PV 资源,申领使用特定大小、特定访问模式的数据卷,例如要求 PV 卷以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 等模式来挂载。 + +## 创建数据卷声明 + +目前支持通过 YAML 和表单两种方式创建数据卷声明,这两种方式各有优劣,可以满足不同用户的使用需求。 + +- 通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉数据卷声明的 YAML 文件配置。 + +- 通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷声明 (PVC)__ -> __YAML 创建__ 。 + + ![路径](../../../images/pvc01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![yaml](../../../images/pvc02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷声明 (PVC)__ -> __创建数据卷声明 (PVC)__ 。 + + ![路径](../../../images/pvc03.png) + +2. 填写基本信息。 + + - 数据卷声明的名称、命名空间、创建方式、数据卷、容量、访问模式在创建之后不可更改。 + - 创建方式:在已有的存储池或者数据卷中动态创建新的数据卷声明,或者基于数据卷声明的快照创建新的数据卷声明。 + + > 基于快照创建时无法修改数据卷声明的容量,可以在创建完成后再进行修改。 + + - 选择创建方式之后,在下拉列表中选择想要使用的存储池/数据卷/快照。 + - 访问模式: + + - ReadWriteOnce,数据卷声明可以被一个节点以读写方式挂载。 + - ReadWriteMany,数据卷声明可以被多个节点以读写方式挂载。 + - ReadOnlyMany,数据卷声明可以被多个节点以只读方式挂载。 + - ReadWriteOncePod,数据卷声明可以被单个 Pod 以读写方式挂载。 + + ![基本信息](../../../images/pvc04.png) + +## 查看数据卷声明 + +在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __数据卷声明(PVC)__ 。 + +- 该页面可以查看当前集群中的所有数据卷声明,以及各个数据卷声明的状态、容量、命名空间等信息。 + +- 支持按照数据卷声明的名称、状态、命名空间、创建时间进行顺序或逆序排序。 + + ![详情](../../../images/pvc06.png) + +- 点击数据卷声明的名称,可以查看该数据卷声明的基本配置、存储池信息、标签、注解等信息。 + + ![详情](../../../images/pvc05.png) + +## 扩容数据卷声明 + +1. 在左侧导航栏点击 __容器存储__ -> __数据卷声明(PVC)__ ,找到想要调整容量的数据卷声明。 + + ![扩容](../../../images/pvc14.png) + +2. 点击数据卷声明的名称,然后在页面右上角点击操作按钮选择 __扩容__ 。 + + ![扩容](../../../images/pvc15.png) + +3. 输入目标容量,然后点击 __确定__ 。 + + ![克隆](../../../images/pvc16.png) + +## 克隆数据卷声明 + +通过克隆数据卷声明,可以基于被克隆数据卷声明的配置,重新创建一个新的数据卷声明。 + +1. 进入克隆页面 + + - 在数据卷声明列表页面,找到需要克隆的数据卷声明,在右侧的操作栏下选择 __克隆__ 。 + + > 也可以点击数据卷声明的名称,在详情页面的右上角点击操作按钮选择 __克隆__ 。 + + ![克隆](../../../images/pvc11.png) + +2. 直接使用原配置,或者按需进行修改,然后在页面底部点击 __确定__ 。 + + ![克隆](../../../images/pvc12.png) + +## 更新数据卷声明 + +有两种途径可以更新数据卷声明。支持通过表单或 YAML 文件更新数据卷声明。 + +!!! note + + 仅支持更新数据卷声明的别名、标签和注解。 + +- 在数据卷列表页面,找到需要更新的数据卷声明,在右侧的操作栏下选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pvc07.png) + +- 点击数据卷声明的名称,进入数据卷声明的详情页面后,在页面右上角选择 __更新__ 即可通过表单更新,选择 __编辑 YAML__ 即可通过 YAML 更新。 + + ![更新](../../../images/pvc08.png) + +## 删除数据卷声明 + +在数据卷声明列表页面,找到需要删除的数据,在右侧的操作栏下选择 __删除__ 。 + +> 也可以点击数据卷声明的名称,在详情页面的右上角点击操作按钮选择 __删除__ 。 + +![删除](../../../images/pvc09.png) + +## 常见问题 + +1. 如果列表中没有可选的存储池或数据卷,可以[创建存储池](sc.md)或[创建数据卷](pv.md)。 + +2. 如果列表中没有可选的快照,可以进入数据卷声明的详情页,在右上角制作快照。 + + ![制作快照](../../../images/pvc17.png) + +3. 如果数据卷声明所使用的存储池 (SC) 没有启用快照,则无法制作快照,页面不会显示“制作快照”选项。 +4. 如果数据卷声明所使用的存储池 (SC) 没有开启扩容功能,则该数据卷不支持扩容,页面不会显示扩容选项。 + + ![开启快照](../../../images/pvc18.png) diff --git a/docs/zh/docs/end-user/kpanda/storage/sc-share.md b/docs/zh/docs/end-user/kpanda/storage/sc-share.md new file mode 100644 index 0000000..ff881e4 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/storage/sc-share.md @@ -0,0 +1,14 @@ +# 共享存储池 + +算丰 AI 算力平台容器管理模块支持将一个存储池共享给多个命名空间使用,以便提高资源利用效率。 + +1. 在存储池列表中找到需要共享的存储池,在右侧操作栏下点击 __授权命名空间__ 。 + + ![授权](../../../images/sc-share01.png) + +2. 点击 __自定义命名空间__ 可以逐一选择需要将此存储池共享到哪些命名空间。 + + - 点击 __授权所有命名空间__ 可以一次性将此存储池共享到当前集群下的所有命名空间。 + - 在列表右侧的操作栏下方点击 __移除授权__ ,可以解除授权,停止将此存储池共享到该命名空间。 + + ![授权](../../../images/sc-share02.png) diff --git a/docs/zh/docs/end-user/kpanda/storage/sc.md b/docs/zh/docs/end-user/kpanda/storage/sc.md new file mode 100644 index 0000000..53f0c5d --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/storage/sc.md @@ -0,0 +1,73 @@ +# 存储池(SC) + +存储池指将许多物理磁盘组成一个大型存储资源池,本平台支持接入各类存储厂商后创建块存储池、本地存储池、自定义存储池,然后为工作负载动态配置数据卷。 + +## 创建存储池(SC) + +目前支持通过 YAML 和表单两种方式创建存储池,这两种方式各有优劣,可以满足不同用户的使用需求。 + +- 通过 YAML 创建步骤更少、更高效,但门槛要求较高,需要熟悉存储池的 YAML 文件配置。 + +- 通过表单创建更直观更简单,根据提示填写对应的值即可,但步骤更加繁琐。 + +### YAML 创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __存储池(SC)__ -> __YAML 创建__ 。 + + ![路径](../images/sc01.png) + +2. 在弹框中输入或粘贴事先准备好的 YAML 文件,然后在弹框底部点击 __确定__ 。 + + > 支持从本地导入 YAML 文件或将填写好的文件下载保存到本地。 + + ![yaml](../../../images/sc02.png) + +### 表单创建 + +1. 在集群列表中点击目标集群的名称,然后在左侧导航栏点击 __容器存储__ -> __存储池(SC)__ -> __创建存储池(SC)__ 。 + + ![路径](../images/sc03.png) + +2. 填写基本信息,然后在底部点击 __确定__ 。 + + **自定义存储系统** + + - 存储池名称、驱动、回收策略在创建后不可修改。 + - CSI 存储驱动:基于标准 Kubernetes 的容器存储接口插件,需遵守存储厂商规定的格式,例如 __rancher.io/local-path__ 。 + + - 有关如何填写不同厂商提供的 CSI 驱动,可参考 Kubernetes 官方文档[存储类](https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#provisioner)。 + - 回收策略:删除数据卷时,保留数据卷中的数据或者删除其中的数据。 + - 快照/扩容:开启后,基于该存储池的数据卷/数据卷声明才能支持扩容和快照功能,但 **前提是底层使用的存储驱动支持快照和扩容功能**。 + + **HwameiStor 存储系统** + + - 存储池名称、驱动、回收策略在创建后不可修改。 + - 存储系统:HwameiStor 存储系统。 + - 存储类型:支持 LVM,裸磁盘类型 + - __LVM 类型__ :HwameiStor 推荐使用此方式,可使用高可用数据卷,对应的的 CSI 存储驱动为 `lvm.hwameistor.io`。 + - __裸磁盘数据卷__ : 适用于非高可用场景,无高可用能力,对应的 CSI 驱动为 `hdd.hwameistor.io` + - 高可用模式:使用高可用能力之前请确认 __DRBD 组件__ 已安装。开启高可用模式后,可将数据卷副本数设置为 1 和 2。 如需要可将数据卷副本从 1 Convert 成 1 + - 回收策略:删除数据卷时,保留数据卷中的数据或者删除其中的数据。 + - 快照/扩容:开启后,基于该存储池的数据卷/数据卷声明才能支持扩容和快照功能,但 **前提是底层使用的存储驱动支持快照和扩容功能**。 + + !!! note + + 目前 HwameiStor xfs、ext4 两种文件系统,其中默认使用的是 xfs 文件系统,如果想要替换为 ext4,可以在自定义参数添加 __csi.storage.k8s.io/fstype: ext4__ + + ![基本信息](../images/sc04.png) + +## 更新存储池(SC) + +在存储池列表页面,找到需要更新的存储池,在右侧的操作栏下选择 __编辑__ 即可通过更新存储池。 + +![更新](../images/sc05.png) + +!!! info + + 选择 __查看 YAML__ 可以查看该存储池的 YAML 文件,但不支持编辑。 + +## 删除存储池(SC) + +在存储池列表页面,找到需要删除的存储池,在右侧的操作栏下选择 __删除__ 。 + +![删除](../images/sc06.png) diff --git a/docs/zh/docs/end-user/kpanda/workloads/create-cronjob.md b/docs/zh/docs/end-user/kpanda/workloads/create-cronjob.md new file mode 100644 index 0000000..fb19df6 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/create-cronjob.md @@ -0,0 +1,223 @@ +# 创建定时任务(CronJob) + +本文介绍如何通过镜像和 YAML 文件两种方式创建定时任务(CronJob)。 + +定时任务(CronJob)适用于于执行周期性的操作,例如备份、报告生成等。这些任务可以配置为周期性重复的(例如:每天/每周/每月一次),可以定义任务开始执行的时间间隔。 + +## 前提条件 + +创建定时任务(CronJob)之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../register/index.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个定时任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_6.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __定时任务__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/cronjob01.png) + +3. 依次填写[基本信息](create-cronjob.md#_3)、[容器配置](create-cronjob.md#_4)、[定时任务配置](create-cronjob.md#_5)、[高级配置](create-cronjob.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __定时任务__ 列表。点击列表右侧的 __┇__ ,可以对定时任务执行执行更新、删除、重启等操作。 + + ![操作菜单](../../../images/cronjob06.png) + +### 基本信息 + +在 __创建定时任务__ 页面中,根据下表输入信息后,点击 __下一步__ 。 + +![基本信息](../images/cronjob02.png) + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的定时任务部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 描述:输入工作负载的描述信息,内容自定义。字符数量应不超过 512 个。 + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../images/cronjob03.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_3.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_3.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_3.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_3.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_3.png) + +### 定时任务配置 + +![定时任务配置](../images/cronjob04.png) + +- 并发策略:是否允许多个 Job 任务并行执行。 + + - __Allow__ :可以在前一个任务未完成时就创建新的定时任务,而且多个任务可以并行。任务太多可能抢占集群资源。 + - __Forbid__ :在前一个任务完成之前,不能创建新任务,如果新任务的执行时间到了而之前的任务仍未执行完,CronJob 会忽略新任务的执行。 + - __Replace__ :如果新任务的执行时间到了,但前一个任务还未完成,新的任务会取代前一个任务。 + + > 上述规则仅适用于同一个 CronJob 创建的多个任务。多个 CronJob 创建的多个任务总是允许并发执行。 + +- 定时规则:基于分钟、小时、天、周、月设置任务执行的时间周期。支持用数字和 `*` 自定义 Cron 表达式,**输入表达式后下方会提示当前表达式的含义**。有关详细的表达式语法规则,可参考 [Cron 时间表语法](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/cron-jobs/#cron-schedule-syntax)。 +- 任务记录:设定保留多少条任务执行成功或失败的记录。 __0__ 表示不保留。 +- 超时时间:超出该时间时,任务就会被标识为执行失败,任务下的所有 Pod 都会被删除。为空时表示不设置超时时间。默认值为 360 s。 +- 重试次数:任务可重试次数,默认值为 6。 +- 重启策略:设置任务失败时是否重启 Pod。 + +### 服务配置 + +为有状态负载配置[服务(Service)](../network/create-services.md),使有状态负载能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../images/cronjob12.png) + +2. 参考[创建服务](../network/create-services.md),配置服务参数。 + + ![创建服务](../../../images/deploy13_2.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +定时任务的高级配置主要涉及标签与注解。 + +可以点击 __添加__ 按钮为工作负载实例 Pod 添加标签和注解。 + +![定时任务配置](../../../images/cronjob05.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建定时任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_6.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __定时任务__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/cronjob07.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/cronjob08_1.png) + +??? note "点击查看创建定时任务的 YAML 示例" + + ```yaml + apiVersion: batch/v1 + kind: CronJob + metadata: + creationTimestamp: '2022-12-26T09:45:47Z' + generation: 1 + name: demo + namespace: default + resourceVersion: '92726617' + uid: d030d8d7-a405-4dcd-b09a-176942ef36c9 + spec: + concurrencyPolicy: Allow + failedJobsHistoryLimit: 1 + jobTemplate: + metadata: + creationTimestamp: null + spec: + activeDeadlineSeconds: 360 + backoffLimit: 6 + template: + metadata: + creationTimestamp: null + spec: + containers: + - image: nginx + imagePullPolicy: IfNotPresent + lifecycle: {} + name: container-3 + resources: + limits: + cpu: 250m + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + securityContext: + privileged: false + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Never + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 + schedule: 0 0 13 * 5 + successfulJobsHistoryLimit: 3 + suspend: false + status: {} + ``` diff --git a/docs/zh/docs/end-user/kpanda/workloads/create-daemonset.md b/docs/zh/docs/end-user/kpanda/workloads/create-daemonset.md new file mode 100644 index 0000000..c6339e0 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/create-daemonset.md @@ -0,0 +1,391 @@ +# 创建守护进程(DaemonSet) + +本文介绍如何通过镜像和 YAML 文件两种方式创建守护进程(DaemonSet)。 + +守护进程(DaemonSet)通过[节点亲和性](https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)与[污点](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)功能确保在全部或部分节点上运行一个 Pod 的副本。对于新加入集群的节点,DaemonSet 自动在新节点上部署相应的 Pod,并跟踪 Pod 的运行状态。当节点被移除时,DaemonSet 则删除其创建的所有 Pod。 + +守护进程的常见用例包括: + +- 在每个节点上运行集群守护进程。 + +- 在每个节点上运行日志收集守护进程。 + +- 在每个节点上运行监控守护进程。 + +简单起见,可以在每个节点上为每种类型的守护进程都启动一个 DaemonSet。如需更精细、更高级地管理守护进程,也可以为同一种守护进程部署多个 DaemonSet。每个 DaemonSet 具有不同的标志,并且对不同硬件类型具有不同的内存、CPU 要求。 + +## 前提条件 + +创建 DaemonSet 之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../register/index.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个守护进程。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_2.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __守护进程__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/daemon01.png) + +3. 依次填写[基本信息](create-daemonset.md#_3)、[容器配置](create-daemonset.md#_4)、[服务配置](create-daemonset.md#_5)、[高级配置](create-daemonset.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __守护进程__ 列表。点击列表右侧的 __┇__ ,可以对守护进程执行执行更新、删除、重启等操作。 + + ![操作菜单](../../../images/daemon05.png) + +### 基本信息 + +在 __创建守护进程__ 页面中,根据下表输入信息后,点击 __下一步__ 。 + +![基本信息](../../../images/daemon02.png) + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的守护进程部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 描述:输入工作负载的描述信息,内容自定义。字符数量应不超过 512 个。 + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../../../images/daemon06.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_1.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_1.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_1.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_1.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_1.png) + +### 服务配置 + +为守护进程创建[服务(Service)](../network/create-services.md),使守护进程能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../../../images/daemon03.png) + +2. 配置服务参数,详情请参考[创建服务](../network/create-services.md)。 + + ![创建服务](../../../images/deploy13.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +高级配置包括负载的网络配置、升级策略、调度策略、标签与注解四部分,可点击下方的页签查看各部分的配置要求。 + +=== "网络配置" + + 应用在某些场景下会出现冗余的 DNS 查询。Kubernetes 为应用提供了与 DNS 相关的配置选项,能够在某些场景下有效地减少冗余的 DNS 查询,提升业务并发量。 + + ![DNS 配置](../../../images/deploy17.png) + + - DNS 策略 + + - Default:使容器使用 kubelet 的 __--resolv-conf__ 参数指向的域名解析文件。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的 DNS 查询。 + - ClusterFirstWithHostNet:应用对接主机的域名文件。 + - ClusterFirst:应用对接 Kube-DNS/CoreDNS。 + - None:Kubernetes v1.9(Beta in v1.10)中引入的新选项值。设置为 None 之后,必须设置 dnsConfig,此时容器的域名解析文件将完全通过 dnsConfig 的配置来生成。 + + - 域名服务器:填写域名服务器的地址,例如 __10.6.175.20__ 。 + - 搜索域:域名查询时的 DNS 搜索域列表。指定后,提供的搜索域列表将合并到基于 dnsPolicy 生成的域名解析文件的 search 字段中,并删除重复的域名。Kubernetes 最多允许 6 个搜索域。 + - Options:DNS 的配置选项,其中每个对象可以具有 name 属性(必需)和 value 属性(可选)。该字段中的内容将合并到基于 dnsPolicy 生成的域名解析文件的 options 字段中,dnsConfig 的 options 的某些选项如果与基于 dnsPolicy 生成的域名解析文件的选项冲突,则会被 dnsConfig 所覆盖。 + - 主机别名:为主机设置的别名。 + +=== "升级策略" + + ![升级策略](../../../images/deploy14.png) + + - 升级方式: __滚动升级__ 指逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。 __重建升级__ 指先删除老版本的负载实例,再安装指定的新版本,升级过程中业务会中断。 + - 最大无效 Pod 数:指定负载更新过程中不可用 Pod 的最大值或比率,默认 25%。如果等于实例数有服务中断的风险。 + - 最大浪涌:更新 Pod 的过程中 Pod 总数超过 Pod 期望副本数部分的最大值或比率。默认 25%。 + - 最大保留版本数:设置版本回滚时保留的旧版本数量。默认 10。 + - Pod 可用最短时间:Pod 就绪的最短时间,只有超出这个时间 Pod 才被认为可用,默认 0 秒。 + - 升级最大持续时间:如果超过所设置的时间仍未部署成功,则将该负载标记为失败。默认 600 秒。 + - 缩容时间窗:负载停止前命令的执行时间窗(0-9,999秒),默认 30 秒。 + +=== "调度策略" + + ![调度策略](../../../images/deploy15.png) + + - 容忍时间:负载实例所在的节点不可用时,将负载实例重新调度到其它可用节点的时间,默认为 300 秒。 + - 节点亲和性:根据节点上的标签来约束 Pod 可以调度到哪些节点上。 + - 工作负载亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到哪些节点。 + - 工作负载反亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 不可以调度到哪些节点。 + - 拓扑域:即 topologyKey,用于指定可以调度的一组节点。例如, __kubernetes.io/os__ 表示只要某个操作系统的节点满足 labelSelector 的条件就可以调度到该节点。 + + > 具体详情请参考[调度策略](pod-config/scheduling-policy.md)。 + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载和容器组添加标签和注解。 + + ![标签与注解](../../../images/deploy16.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建守护进程。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_2.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __守护进程__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/daemon07.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/daemon08.png) + +??? note "点击查看创建守护进程的 YAML 示例" + + ```yaml + kind: DaemonSet + apiVersion: apps/v1 + metadata: + name: hwameistor-local-disk-manager + namespace: hwameistor + uid: ccbdc098-7de3-4a8a-96dd-d1cee159c92b + resourceVersion: '90999552' + generation: 1 + creationTimestamp: '2022-12-15T09:03:44Z' + labels: + app.kubernetes.io/managed-by: Helm + annotations: + deprecated.daemonset.template.generation: '1' + meta.helm.sh/release-name: hwameistor + meta.helm.sh/release-namespace: hwameistor + spec: + selector: + matchLabels: + app: hwameistor-local-disk-manager + template: + metadata: + creationTimestamp: null + labels: + app: hwameistor-local-disk-manager + spec: + volumes: + - name: udev + hostPath: + path: /run/udev + type: Directory + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + hostPath: + path: /dev + type: Directory + - name: socket-dir + hostPath: + path: /var/lib/kubelet/plugins/disk.hwameistor.io + type: DirectoryOrCreate + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: /var/lib/kubelet/pods + type: DirectoryOrCreate + containers: + - name: registrar + image: k8s-gcr.m.daocloud.io/sig-storage/csi-node-driver-registrar:v2.5.0 + args: + - '--v=5' + - '--csi-address=/csi/csi.sock' + - >- + --kubelet-registration-path=/var/lib/kubelet/plugins/disk.hwameistor.io/csi.sock + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + resources: {} + volumeMounts: + - name: socket-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + lifecycle: + preStop: + exec: + command: + - /bin/sh + - '-c' + - >- + rm -rf /registration/disk.hwameistor.io + /registration/disk.hwameistor.io-reg.sock + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: manager + image: ghcr.m.daocloud.io/hwameistor/local-disk-manager:v0.6.1 + command: + - /local-disk-manager + args: + - '--endpoint=$(CSI_ENDPOINT)' + - '--nodeid=$(NODENAME)' + - '--csi-enable=true' + env: + - name: CSI_ENDPOINT + value: unix://var/lib/kubelet/plugins/disk.hwameistor.io/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: NODENAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: OPERATOR_NAME + value: local-disk-manager + resources: {} + volumeMounts: + - name: udev + mountPath: /run/udev + - name: procmount + readOnly: true + mountPath: /host/proc + - name: devmount + mountPath: /dev + - name: registration-dir + mountPath: /var/lib/kubelet/plugins_registry + - name: plugin-dir + mountPath: /var/lib/kubelet/plugins + mountPropagation: Bidirectional + - name: pods-mount-dir + mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + privileged: true + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: hwameistor-admin + serviceAccount: hwameistor-admin + hostNetwork: true + hostPID: true + securityContext: {} + schedulerName: default-scheduler + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - key: node.kubernetes.io/not-ready + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + - key: node.cloudprovider.kubernetes.io/uninitialized + operator: Exists + effect: NoSchedule + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 + revisionHistoryLimit: 10 + status: + currentNumberScheduled: 4 + numberMisscheduled: 0 + desiredNumberScheduled: 4 + numberReady: 4 + observedGeneration: 1 + updatedNumberScheduled: 4 + numberAvailable: 4 + ``` diff --git a/docs/zh/docs/end-user/kpanda/workloads/create-deployment.md b/docs/zh/docs/end-user/kpanda/workloads/create-deployment.md new file mode 100644 index 0000000..8f41a37 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/create-deployment.md @@ -0,0 +1,223 @@ +# 创建无状态负载(Deployment) + +本文介绍如何通过镜像和 YAML 文件两种方式创建无状态负载。 + +[无状态负载(Deployment)](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/)是 Kubernetes 中的一种常见资源,主要为 [Pod](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/) 和 [ReplicaSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/) 提供声明式更新,支持弹性伸缩、滚动升级、版本回退等功能。在 Deployment 中声明期望的 Pod 状态,Deployment Controller 会通过 ReplicaSet 修改当前状态,使其达到预先声明的期望状态。Deployment 是无状态的,不支持数据持久化,适用于部署无状态的、不需要保存数据、随时可以重启回滚的应用。 + +通过算丰 AI 算力平台的容器管理模块,可以基于相应的角色权限轻松管理多云多集群上的工作负载,包括对无状态负载的创建、更新、删除、弹性扩缩、重启、版本回退等全生命周期管理。 + +## 前提条件 + +在使用镜像创建无状态负载之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../register/index.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个无状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_4.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __无状态负载__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/deploy02.png) + +3. 依次填写[基本信息](create-deployment.md#_3)、[容器配置](create-deployment.md#_4)、[服务配置](create-deployment.md#_5)、[高级配置](create-deployment.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __无状态负载__ 列表。点击列表右侧的 __┇__ ,可以对负载执行执行更新、删除、弹性扩缩、重启、版本回退等操作。如果负载状态出现异常,请查看具体异常信息,可参考[工作负载状态](../workloads/pod-config/workload-status.md)。 + + ![操作菜单](../../../images/deploy18.png) + +### 基本信息 + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 deployment-01。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的负载部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 实例数:输入负载的 Pod 实例数量,默认创建 1 个 Pod 实例。 +- 描述:输入负载的描述信息,内容自定义。字符数不超过 512。 + + ![基本信息](../../../images/deploy04.png) + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../images/deploy05.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 安装算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_2.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_2.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_2.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_2.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_2.png) + +### 服务配置 + +为无状态负载配置[服务(Service)](../network/create-services.md),使无状态负载能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../../../images/deploy12.png) + +2. 参考[创建服务](../network/create-services.md),配置服务参数。 + + ![创建服务](../../../images/deploy13_1.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +高级配置包括负载的网络配置、升级策略、调度策略、标签与注解四部分,可点击下方的页签查看各部分的配置要求。 + +=== "网络配置" + + - 如在集群中部署了 SpiderPool 和 Multus 组件,则可以在网络配置中配置容器网卡。 + + - DNS 配置:应用在某些场景下会出现冗余的 DNS 查询。Kubernetes 为应用提供了与 DNS 相关的配置选项,能够在某些场景下有效地减少冗余的 DNS 查询,提升业务并发量。 + + - DNS 策略 + + - Default:使容器使用 kubelet 的 __--resolv-conf__ 参数指向的域名解析文件。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的 DNS 查询。 + - ClusterFirstWithHostNet:应用对接主机的域名文件。 + - ClusterFirst:应用对接 Kube-DNS/CoreDNS。 + - None:Kubernetes v1.9(Beta in v1.10)中引入的新选项值。设置为 None 之后,必须设置 dnsConfig,此时容器的域名解析文件将完全通过 dnsConfig 的配置来生成。 + + - 域名服务器:填写域名服务器的地址,例如 __10.6.175.20__ 。 + - 搜索域:域名查询时的 DNS 搜索域列表。指定后,提供的搜索域列表将合并到基于 dnsPolicy 生成的域名解析文件的 search 字段中,并删除重复的域名。Kubernetes 最多允许 6 个搜索域。 + - Options:DNS 的配置选项,其中每个对象可以具有 name 属性(必需)和 value 属性(可选)。该字段中的内容将合并到基于 dnsPolicy 生成的域名解析文件的 options 字段中,dnsConfig 的 options 的某些选项如果与基于 dnsPolicy 生成的域名解析文件的选项冲突,则会被 dnsConfig 所覆盖。 + - 主机别名:为主机设置的别名。 + + ![DNS 配置](../../../images/deploy17_1.png) + +=== "升级策略" + + - 升级方式: __滚动升级__ 指逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。 __重建升级__ 指先删除老版本的负载实例,再安装指定的新版本,升级过程中业务会中断。 + - 最大不可用:指定负载更新过程中不可用 Pod 的最大值或比率,默认 25%。如果等于实例数有服务中断的风险。 + - 最大峰值:更新 Pod 的过程中 Pod 总数超过 Pod 期望副本数部分的最大值或比率。默认 25%。 + - 最大保留版本数:设置版本回滚时保留的旧版本数量。默认 10。 + - Pod 可用最短时间:Pod 就绪的最短时间,只有超出这个时间 Pod 才被认为可用,默认 0 秒。 + - 升级最大持续时间:如果超过所设置的时间仍未部署成功,则将该负载标记为失败。默认 600 秒。 + - 缩容时间窗:负载停止前命令的执行时间窗(0-9,999秒),默认 30 秒。 + + ![升级策略](../images/deploy14.png) + +=== "调度策略" + + - 容忍时间:负载实例所在的节点不可用时,将负载实例重新调度到其它可用节点的时间,默认为 300 秒。 + - 节点亲和性:根据节点上的标签来约束 Pod 可以调度到哪些节点上。 + - 工作负载亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到哪些节点。 + - 工作负载反亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 不可以调度到哪些节点。 + + > 具体详情请参考[调度策略](pod-config/scheduling-policy.md)。 + + ![调度策略](../images/deploy15.png) + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载和容器组添加标签和注解。 + + ![标签与注解](../images/deploy16.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建无状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_4.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __无状态负载__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/deploy02Yaml.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/deploy03yaml.png) + +??? note "点击查看创建无状态负载的 YAML 示例" + + ```yaml + apiVersion: apps/v1 + kind: Deployment + metadata: + name: nginx-deployment + spec: + selector: + matchLabels: + app: nginx + replicas: 2 # 告知 Deployment 运行 2 个与该模板匹配的 Pod + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + ``` diff --git a/docs/zh/docs/end-user/kpanda/workloads/create-job.md b/docs/zh/docs/end-user/kpanda/workloads/create-job.md new file mode 100644 index 0000000..823eb64 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/create-job.md @@ -0,0 +1,209 @@ +# 创建任务(Job) + +本文介绍如何通过镜像和 YAML 文件两种方式创建任务(Job)。 + +任务(Job)适用于执行一次性任务。Job 会创建一个或多个 Pod,Job 会一直重新尝试执行 Pod,直到成功终止的 Pod 达到一定数量。成功终止的 Pod 达到指定的数量后,Job 也随之结束。删除 Job 时会一同清除该 Job 创建的所有 Pod。暂停 Job 时删除该 Job 中的所有活跃 Pod,直到 Job 被继续执行。有关任务(Job)的更多介绍,可参考[Job](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/job/)。 + +## 前提条件 + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../register/index.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __任务__ ,然后点击页面右上角的 __镜像创建__ 按钮。 + + ![工作负载](../../../images/job01.png) + +3. 依次填写[基本信息](create-job.md#_3)、[容器配置](create-job.md#_4)、服务配置、[高级配置](create-job.md#_5)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __任务__ 列表。点击列表右侧的 __┇__ ,可以对任务执行执行更新、删除、重启等操作。 + + ![操作菜单](../../../images/job08.png) + +### 基本信息 + +在 __创建任务__ 页面中,根据下表输入基本信息后,点击 __下一步__ 。 + +![创建任务](../../../images/job02.png) + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的任务部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 实例数:输入工作负载的 Pod 实例数量。默认创建 1 个 Pod 实例。 +- 描述:输入工作负载的描述信息,内容自定义。字符数量应不超过 512 个。 + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../../../images/job02-1.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态,有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10.png) + +### 高级配置 + +高级配置包括任务设置、标签与注解两部分。 + +=== "任务设置" + + ![任务设置](../../../images/job03.png) + + - 并行数:任务执行过程中允许同时创建的最大 Pod 数,并行数应不大于 Pod 总数。默认为 1。 + - 超时时间:超出该时间时,任务会被标识为执行失败,任务下的所有 Pod 都会被删除。为空时表示不设置超时时间。 + - 重启策略:设置失败时是否重启 Pod。 + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载实例 Pod 添加标签和注解。 + + ![标签与注解](../../../images/job04.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建任务。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __任务__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/job09.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/cronjob08.png) + +??? note "点击查看创建任务的 YAML 示例" + + ```yaml + kind: Job + apiVersion: batch/v1 + metadata: + name: demo + namespace: default + uid: a9708239-0358-4aa1-87d3-a092c080836e + resourceVersion: '92751876' + generation: 1 + creationTimestamp: '2022-12-26T10:52:22Z' + labels: + app: demo + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + job-name: demo + annotations: + revisions: >- + {"1":{"status":"running","uid":"a9708239-0358-4aa1-87d3-a092c080836e","start-time":"2022-12-26T10:52:22Z","completion-time":"0001-01-01T00:00:00Z"}} + spec: + parallelism: 1 + backoffLimit: 6 + selector: + matchLabels: + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + template: + metadata: + creationTimestamp: null + labels: + app: demo + controller-uid: a9708239-0358-4aa1-87d3-a092c080836e + job-name: demo + spec: + containers: + - name: container-4 + image: nginx + resources: + limits: + cpu: 250m + memory: 512Mi + requests: + cpu: 250m + memory: 512Mi + lifecycle: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + securityContext: + privileged: false + restartPolicy: Never + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: {} + schedulerName: default-scheduler + completionMode: NonIndexed + suspend: false + status: + startTime: '2022-12-26T10:52:22Z' + active: 1 + ``` diff --git a/docs/zh/docs/end-user/kpanda/workloads/create-statefulset.md b/docs/zh/docs/end-user/kpanda/workloads/create-statefulset.md new file mode 100644 index 0000000..a623ce4 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/create-statefulset.md @@ -0,0 +1,670 @@ +# 创建有状态负载(StatefulSet) + +本文介绍如何通过镜像和 YAML 文件两种方式创建有状态负载(StatefulSet)。 + +[有状态负载(StatefulSet)](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/)是 Kubernetes 中的一种常见资源,和[无状态负载(Deployment)](create-deployment.md)类似,主要用于管理 Pod 集合的部署和伸缩。二者的主要区别在于,Deployment 是无状态的,不保存数据,而 StatefulSet 是有状态的,主要用于管理有状态应用。此外,StatefulSet 中的 Pod 具有永久不变的 ID,便于在匹配存储卷时识别对应的 Pod。 + +通过算丰 AI 算力平台的容器管理模块,可以基于相应的角色权限轻松管理多云多集群上的工作负载,包括对有状态工作负载的创建、更新、删除、弹性扩缩、重启、版本回退等全生命周期管理。 + +## 前提条件 + +在使用镜像创建有状态负载之前,需要满足以下前提条件: + +- 在容器管理模块中[接入 Kubernetes 集群](../clusters/integrate-cluster.md)或者管理员已为用户创建了集群,且能够访问集群的 UI 界面。 + +- 创建一个[命名空间](../namespaces/createns.md)和[用户](../../register/index.md)。 + +- 当前操作用户应具有 [NS Editor](../permissions/permission-brief.md#ns-editor) 或更高权限,详情可参考[命名空间授权](../namespaces/createns.md)。 + +- 单个实例中有多个容器时,请确保容器使用的端口不冲突,否则部署会失效。 + +## 镜像创建 + +参考以下步骤,使用镜像创建一个有状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 。 + + ![集群详情](../../../images/deploy01_8.png) + +2. 点击左侧导航栏的 __工作负载__ -> __有状态负载__ ,然后点击右上角 __镜像创建__ 按钮。 + + ![工作负载](../../../images/state02.png) + +3. 依次填写[基本信息](create-statefulset.md#_3)、[容器配置](create-statefulset.md#_4)、[服务配置](create-statefulset.md#_5)、[高级配置](create-statefulset.md#_6)后,在页面右下角点击 __确定__ 完成创建。 + + 系统将自动返回 __有状态工作负载__ 列表,等待工作负载状态变为 __运行中__ 。如果工作负载状态出现异常,请查看具体异常信息,可参考[工作负载状态](../workloads/pod-config/workload-status.md)。 + + 点击新建工作负载列右侧的 __┇__ ,可以对工作负载执行执行更新、删除、弹性扩缩、重启、版本回退等操作。 + + ![操作菜单](../../../images/state10.png) + +### 基本信息 + +- 负载名称:最多包含 63 个字符,只能包含小写字母、数字及分隔符(“-”),且必须以小写字母或数字开头及结尾,例如 deployment-01。同一命名空间内同一类型工作负载的名称不得重复,而且负载名称在工作负载创建好之后不可更改。 +- 命名空间:选择将新建的负载部署在哪个命名空间,默认使用 default 命名空间。找不到所需的命名空间时可以根据页面提示去[创建新的命名空间](../namespaces/createns.md)。 +- 实例数:输入负载的 Pod 实例数量,默认创建 1 个 Pod 实例。 +- 描述:输入负载的描述信息,内容自定义。字符数不超过 512。 + + ![基本信息](../../../images/state01.png) + +### 容器配置 + +容器配置分为基本信息、生命周期、健康检查、环境变量、数据存储、安全设置六部分,点击下方的相应页签可查看各部分的配置要求。 + +> 容器配置仅针对单个容器进行配置,如需在一个容器组中添加多个容器,可点击右侧的 __+__ 添加多个容器。 + +=== "基本信息(必填)" + + 在配置容器相关参数时,必须正确填写容器的名称、镜像参数,否则将无法进入下一步。参考以下要求填写配置后,点击 __确认__ 。 + + ![基本信息](../../../images/state11.png) + + - 容器类型:默认为`工作容器`。有关初始化容器,参见 [k8s 官方文档](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/)。 + - 容器名称:最多包含 63 个字符,支持小写字母、数字及分隔符(“-”)。必须以小写字母或数字开头及结尾,例如 nginx-01。 + - 镜像: + - 容器镜像:从列表中选择一个合适的镜像。输入镜像名称时,默认从官方的 [DockerHub](https://hub.docker.com/) 拉取镜像。 + 接入算丰 AI 算力平台的镜像仓库模块后,可以点击右侧的 __选择镜像__ 按钮来选择镜像。 + - 镜像版本:从下拉列表选择一个合适的版本。 + - 镜像拉取策略:勾选 __总是拉取镜像__ 后,负载每次重启/升级时都会从仓库重新拉取镜像。 + 如果不勾选,则只拉取本地镜像,只有当镜像在本地不存在时才从镜像仓库重新拉取。 + 更多详情可参考[镜像拉取策略](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#image-pull-policy)。 + - 镜像仓库密钥:可选。如果目标仓库需要 Secret 才能访问,需要先去[创建一个密钥](../configmaps-secrets/create-secret.md)。 + - 特权容器:容器默认不可以访问宿主机上的任何设备,开启特权容器后,容器即可访问宿主机上的所有设备,享有宿主机上的运行进程的所有权限。 + - CPU/内存配额:CPU/内存资源的请求值(需要使用的最小资源)和限制值(允许使用的最大资源)。请根据需要为容器配置资源,避免资源浪费和因容器资源超额导致系统故障。默认值如图所示。 + - GPU 配置:为容器配置 GPU 用量, 仅支持输入正整数。 + - 整卡模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量。配置后,容器将占用整张物理 GPU卡。同时物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - 虚拟化模式: + - 物理卡数量:容器能够使用的物理 GPU 卡数量, 物理卡数量需要 ≤ 单节点插入的最大 GPU 卡数。 + - GPU 算力:每张物理 GPU 卡上需要使用的算力百分比,最多为100%。 + - 显存:每张物理卡上需要使用的显存数量。 + - 调度策略(Binpack / Spread):支持基于 GPU 卡和基于节点的两种维度的调度策略。Binpack 是集中式调度策略,优先将容器调度到同一个节点的同一张 GPU 卡上;Spread 是分散式调度策略,优先将容器调度到不同节点的不同 GPU 卡上,根据实际场景可组合使用。(当工作负载级别的 Binpack / Spread 调度策略与集群级别的 Binpack / Spread 调度策略冲突时,系统优先使用工作负载级别的调度策略)。 + - 任务优先级:GPU 算力会优先供给高优先级任务使用,普通任务会减少甚至暂停使用 GPU 算力,直到高优先级任务结束,普通任务会重新继续使用 GPU 算力,常用于在离线混部场景。 + - 指定型号:将工作负载调度到指定型号的 GPU 卡上,适用于对 GPU 型号有特殊要求的场景。 + - Mig 模式 + - 规格:切分后的物理 GPU 卡规格。 + - 数量:使用该规格的数量。 + + > 设置 GPU 之前,需要管理员预先在集群上安装 [GPU Operator](../gpu/nvidia/install_nvidia_driver_of_operator.md) 和 [nvidia-vgpu](../gpu/nvidia/vgpu/vgpu_addon.md)(仅 vGPU 模式需要安装),并在[集群设置](../clusterops/cluster-settings.md)中开启 GPU 特性。 + +=== "生命周期(选填)" + + 设置容器启动时、启动后、停止前需要执行的命令。详情可参考[容器生命周期配置](pod-config/lifecycle.md)。 + + ![生命周期](../../../images/deploy06_4.png) + +=== "健康检查(选填)" + + 用于判断容器和应用的健康状态。有助于提高应用的可用性。详情可参考[容器健康检查配置](pod-config/health-check.md)。 + + ![健康检查](../../../images/deploy07_4.png) + +=== "环境变量(选填)" + + 配置 Pod 内的容器参数,为 Pod 添加环境变量或传递配置等。详情可参考[容器环境变量配置](pod-config/env-variables.md)。 + + ![环境变量](../../../images/deploy08_4.png) + +=== "数据存储(选填)" + + 配置容器挂载数据卷和数据持久化的设置。详情可参考[容器数据存储配置](pod-config/env-variables.md)。 + + ![数据存储](../../../images/deploy09_4.png) + +=== "安全设置(选填)" + + 通过 Linux 内置的账号权限隔离机制来对容器进行安全隔离。您可以通过使用不同权限的账号 UID(数字身份标记)来限制容器的权限。例如,输入 __0__ 表示使用 root 账号的权限。 + + ![安全设置](../../../images/deploy10_4.png) + +### 服务配置 + +为有状态负载配置[服务(Service)](../network/create-services.md),使有状态负载能够被外部访问。 + +1. 点击 __创建服务__ 按钮。 + + ![服务配置](../../../images/state12.png) + +2. 参考[创建服务](../network/create-services.md),配置服务参数。 + + ![创建服务](../../../images/deploy13_3.png) + +3. 点击 __确定__ ,点击 __下一步__ 。 + +### 高级配置 + +高级配置包括负载的网络配置、升级策略、调度策略、标签与注解四部分,可点击下方的页签查看各部分的配置要求。 + +=== "网络配置" + + - 如在集群中部署了 SpiderPool 和 Multus 组件,则可以在网络配置中配置容器网卡。 + + - DNS 配置:应用在某些场景下会出现冗余的 DNS 查询。Kubernetes 为应用提供了与 DNS 相关的配置选项,能够在某些场景下有效地减少冗余的 DNS 查询,提升业务并发量。 + + - DNS 策略 + + - Default:使容器使用 kubelet 的 __--resolv-conf__ 参数指向的域名解析文件。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的 DNS 查询。 + - ClusterFirstWithHostNet:应用对接主机的域名文件。 + - ClusterFirst:应用对接 Kube-DNS/CoreDNS。 + - None:Kubernetes v1.9(Beta in v1.10)中引入的新选项值。设置为 None 之后,必须设置 dnsConfig,此时容器的域名解析文件将完全通过 dnsConfig 的配置来生成。 + + - 域名服务器:填写域名服务器的地址,例如 __10.6.175.20__ 。 + - 搜索域:域名查询时的 DNS 搜索域列表。指定后,提供的搜索域列表将合并到基于 dnsPolicy 生成的域名解析文件的 search 字段中,并删除重复的域名。Kubernetes 最多允许 6 个搜索域。 + - Options:DNS 的配置选项,其中每个对象可以具有 name 属性(必需)和 value 属性(可选)。该字段中的内容将合并到基于 dnsPolicy 生成的域名解析文件的 options 字段中,dnsConfig 的 options 的某些选项如果与基于 dnsPolicy 生成的域名解析文件的选项冲突,则会被 dnsConfig 所覆盖。 + - 主机别名:为主机设置的别名。 + + ![DNS 配置](../../../images/deploy17_2.png) + +=== "升级策略" + + - 升级方式: __滚动升级__ 指逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。 __重建升级__ 指先删除老版本的负载实例,再安装指定的新版本,升级过程中业务会中断。 + - 最大保留版本数:设置版本回滚时保留的旧版本数量。默认 10。 + - 缩容时间窗:负载停止前命令的执行时间窗(0-9,999秒),默认 30 秒。 + + ![升级策略](../../../images/deploy14_1.png) + +=== "容器管理策略" + + Kubernetes v1.7 及其之后的版本可以通过 __.spec.podManagementPolicy__ 设置 Pod 的管理策略,支持以下两种方式: + + - __按序策略(OrderedReady)__ :默认的 Pod 管理策略,表示按顺序部署 Pod,只有前一个 Pod 部署 成功完成后,有状态负载才会开始部署下一个 Pod。删除 Pod 时则采用逆序,最后创建的最先被删除。 + + - __并行策略(Parallel)__ :并行创建或删除容器,和 Deployment 类型的 Pod 一样。StatefulSet 控制器并行地启动或终止所有的容器。启动或者终止其他 Pod 前,无需等待 Pod 进入 Running 和 ready 或者完全停止状态。 这个选项只会影响扩缩操作的行为,不影响更新时的顺序。 + + ![容器管理策略](../../../images/state05.png) + +=== "调度策略" + + - 容忍时间:负载实例所在的节点不可用时,将负载实例重新调度到其它可用节点的时间,默认为 300 秒。 + - 节点亲和性:根据节点上的标签来约束 Pod 可以调度到哪些节点上。 + - 工作负载亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 可以调度到哪些节点。 + - 工作负载反亲和性:基于已经在节点上运行的 Pod 的标签来约束 Pod 不可以调度到哪些节点。 + - 拓扑域:即 topologyKey,用于指定可以调度的一组节点。例如, __kubernetes.io/os__ 表示只要某个操作系统的节点满足 labelSelector 的条件就可以调度到该节点。 + + > 具体详情请参考[调度策略](pod-config/scheduling-policy.md)。 + + ![调度策略](../../../images/deploy15_1.png) + +=== "标签与注解" + + 可以点击 __添加__ 按钮为工作负载和容器组添加标签和注解。 + + ![标签与注解](../../../images/deploy16_1.png) + +## YAML 创建 + +除了通过镜像方式外,还可以通过 YAML 文件更快速地创建创建有状态负载。 + +1. 点击左侧导航栏上的 __集群列表__ ,然后点击目标集群的名称,进入 __集群详情__ 页面。 + + ![集群详情](../../../images/deploy01_8.png) + +2. 在集群详情页面,点击左侧导航栏的 __工作负载__ -> __有状态负载__ ,然后点击页面右上角的 __YAML 创建__ 按钮。 + + ![工作负载](../../../images/deploy02Yaml_1.png) + +3. 输入或粘贴事先准备好的 YAML 文件,点击 __确定__ 即可完成创建。 + + ![工作负载](../../../images/state03yaml.png) + +??? note "点击查看创建有状态负载的 YAML 示例" + + ```yaml + kind: StatefulSet + apiVersion: apps/v1 + metadata: + name: test-mysql-123-mysql + namespace: default + uid: d3f45527-a0ab-4b22-9013-5842a06f4e0e + resourceVersion: '20504385' + generation: 1 + creationTimestamp: '2022-09-22T09:34:10Z' + ownerReferences: + - apiVersion: mysql.presslabs.org/v1alpha1 + kind: MysqlCluster + name: test-mysql-123 + uid: 5e877cc3-5167-49da-904e-820940cf1a6d + controller: true + blockOwnerDeletion: true + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + mysql.presslabs.org/cluster: test-mysql-123 + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: test-mysql-123 + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + app.kubernetes.io/version: 5.7.31 + mysql.presslabs.org/cluster: test-mysql-123 + annotations: + config_rev: '13941099' + prometheus.io/port: '9125' + prometheus.io/scrape: 'true' + secret_rev: '13941101' + spec: + volumes: + - name: conf + emptyDir: {} + - name: init-scripts + emptyDir: {} + - name: config-map + configMap: + name: test-mysql-123-mysql + defaultMode: 420 + - name: data + persistentVolumeClaim: + claimName: data + initContainers: + - name: init + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - clone-and-init + envFrom: + - secretRef: + name: test-mysql-123-mysql-operated + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: BACKUP_USER + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: BACKUP_USER + optional: true + - name: BACKUP_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: BACKUP_PASSWORD + optional: true + resources: {} + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: config-map + mountPath: /mnt/conf + - name: data + mountPath: /var/lib/mysql + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + containers: + - name: mysql + image: docker.m.daocloud.io/mysql:5.7.31 + ports: + - name: mysql + containerPort: 3306 + protocol: TCP + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: ORCH_CLUSTER_ALIAS + value: test-mysql-123.default + - name: ORCH_HTTP_API + value: http://mysql-operator.mcamel-system/api + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: ROOT_PASSWORD + optional: false + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: USER + optional: true + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: PASSWORD + optional: true + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: test-mysql-123-secret + key: DATABASE + optional: true + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 100m + memory: 512Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: data + mountPath: /var/lib/mysql + livenessProbe: + exec: + command: + - mysqladmin + - '--defaults-file=/etc/mysql/client.conf' + - ping + initialDelaySeconds: 60 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + exec: + command: + - /bin/sh + - '-c' + - >- + test $(mysql --defaults-file=/etc/mysql/client.conf -NB -e + 'SELECT COUNT(*) FROM sys_operator.status WHERE + name="configured" AND value="1"') -eq 1 + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 2 + successThreshold: 1 + failureThreshold: 3 + lifecycle: + preStop: + exec: + command: + - bash + - /etc/mysql/pre-shutdown-ha.sh + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: sidecar + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - config-and-serve + ports: + - name: sidecar-http + containerPort: 8080 + protocol: TCP + envFrom: + - secretRef: + name: test-mysql-123-mysql-operated + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: XTRABACKUP_TARGET_DIR + value: /tmp/xtrabackup_backupfiles/ + resources: + limits: + cpu: '1' + memory: 1Gi + requests: + cpu: 10m + memory: 64Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + - name: data + mountPath: /var/lib/mysql + readinessProbe: + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: metrics-exporter + image: prom/mysqld-exporter:v0.13.0 + args: + - '--web.listen-address=0.0.0.0:9125' + - '--web.telemetry-path=/metrics' + - '--collect.heartbeat' + - '--collect.heartbeat.database=sys_operator' + ports: + - name: prometheus + containerPort: 9125 + protocol: TCP + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + - name: USER + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: METRICS_EXPORTER_USER + optional: false + - name: PASSWORD + valueFrom: + secretKeyRef: + name: test-mysql-123-mysql-operated + key: METRICS_EXPORTER_PASSWORD + optional: false + - name: DATA_SOURCE_NAME + value: $(USER):$(PASSWORD)@(127.0.0.1:3306)/ + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 32Mi + livenessProbe: + httpGet: + path: /metrics + port: 9125 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 30 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + - name: pt-heartbeat + image: docker.m.daocloud.io/bitpoke/mysql-operator-sidecar-5.7:v0.6.1 + args: + - pt-heartbeat + - '--update' + - '--replace' + - '--check-read-only' + - '--create-table' + - '--database' + - sys_operator + - '--table' + - heartbeat + - '--utc' + - '--defaults-file' + - /etc/mysql/heartbeat.conf + - '--fail-successive-errors=20' + env: + - name: MY_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: MY_POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: MY_SERVICE_NAME + value: mysql + - name: MY_CLUSTER_NAME + value: test-mysql-123 + - name: MY_FQDN + value: $(MY_POD_NAME).$(MY_SERVICE_NAME).$(MY_NAMESPACE) + - name: MY_MYSQL_VERSION + value: 5.7.31 + resources: + limits: + cpu: 100m + memory: 64Mi + requests: + cpu: 10m + memory: 32Mi + volumeMounts: + - name: conf + mountPath: /etc/mysql + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + imagePullPolicy: IfNotPresent + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: + runAsUser: 999 + fsGroup: 999 + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/component: database + app.kubernetes.io/instance: test-mysql-123 + app.kubernetes.io/managed-by: mysql.presslabs.org + app.kubernetes.io/name: mysql + app.kubernetes.io/version: 5.7.31 + mysql.presslabs.org/cluster: test-mysql-123 + topologyKey: kubernetes.io/hostname + schedulerName: default-scheduler + volumeClaimTemplates: + - kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: data + creationTimestamp: null + ownerReferences: + - apiVersion: mysql.presslabs.org/v1alpha1 + kind: MysqlCluster + name: test-mysql-123 + uid: 5e877cc3-5167-49da-904e-820940cf1a6d + controller: true + spec: + accessModes: + - ReadWriteOnce + resources: + limits: + storage: 1Gi + requests: + storage: 1Gi + storageClassName: local-path + volumeMode: Filesystem + status: + phase: Pending + serviceName: mysql + podManagementPolicy: OrderedReady + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: 0 + revisionHistoryLimit: 10 + status: + observedGeneration: 1 + replicas: 1 + readyReplicas: 1 + currentReplicas: 1 + updatedReplicas: 1 + currentRevision: test-mysql-123-mysql-6b8f5577c7 + updateRevision: test-mysql-123-mysql-6b8f5577c7 + collisionCount: 0 + availableReplicas: 1 + ``` diff --git a/docs/zh/docs/end-user/kpanda/workloads/pod-config/env-variables.md b/docs/zh/docs/end-user/kpanda/workloads/pod-config/env-variables.md new file mode 100644 index 0000000..dc0bc60 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/pod-config/env-variables.md @@ -0,0 +1,18 @@ +--- +hide: + - toc +--- + +# 配置环境变量 + +环境变量是指容器运行环境中设定的一个变量,用于给 Pod 添加环境标志或传递配置等,支持通过键值对的形式为 Pod 配置环境变量。 + +算丰 AI 算力平台容器管理在原生 Kubernetes 的基础上增加了图形化界面为 Pod 配置环境变量,支持以下几种配置方式: + +- **键值对**(Key/Value Pair):将自定义的键值对作为容器的环境变量 +- **资源引用**(Resource):将 Container 定义的字段作为环境变量的值,例如容器的内存限制、副本数等 +- **变量/变量引用**(Pod Field):将 Pod 字段作为环境变量的值,例如 Pod 的名称 +- **配置项键值导入**(ConfigMap key):导入配置项中某个键的值作为某个环境变量的值 +- **密钥键值导入**(Secret Key):使用来自 Secret 中的数据定义环境变量的值 +- **密钥导入**(Secret):将 Secret 中的所有键值都导入为环境变量 +- **配置项导入**(ConfigMap):将配置项中所有键值都导入为环境变量 diff --git a/docs/zh/docs/end-user/kpanda/workloads/pod-config/health-check.md b/docs/zh/docs/end-user/kpanda/workloads/pod-config/health-check.md new file mode 100644 index 0000000..474ef59 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/pod-config/health-check.md @@ -0,0 +1,159 @@ +# 容器的健康检查 + +容器健康检查根据用户需求,检查容器的健康状况。配置后,容器内的应用程序入如果异常,容器会自动进行重启恢复。Kubernetes 提供了存活(Liveness)检查、就绪(Readiness)检查和启动(Startup)检查。 + +- **存活检查(LivenessProbe)** 可探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。 + +- **就绪检查(ReadinessProbe)** 可探知容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。 + +- **启动检查(StartupProbe)** 可以了解应用容器何时启动,配置后,可控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探测器不会影响应用的启动。 启动探测可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。 + +## 存活和就绪检查 + +存活检查(LivenessProbe)的配置和就绪检查(ReadinessProbe)的配置参数相似, 唯一区别是要使用 __readinessProbe__ 字段,而不是 __livenessProbe__ 字段。 + +**HTTP GET 参数说明:** + +| 参数 | 参数说明 | +| -------------------------------- | ------------------------------------------------------------ | +| 路径( Path) | 访问的请求路径。如: 示例中的 /healthz 路径 | +| 端口(Port) | 服务监听端口。 如: 示例中的 8080 端口 | +| 协议 | 访问协议,Http 或者Https | +| 延迟时间(initialDelaySeconds) | 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。 | +| 超时时间(timeoutSeconds) | 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 | +| 超时时间(timeoutSeconds) | 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 | +| 成功阈值(successThreshold) | 探测失败后,被视为成功的最小连续成功数。默认值是 1,最小值是 1。存活和启动探测的这个值必须是 1。 | +| 最大失败次数(failureThreshold) | 当探测失败时重试的次数。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。 | + +### 使用 HTTP GET 请求检查 + +**YAML 示例:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-http +spec: + containers: + - name: liveness + image: k8s.gcr.io/liveness + args: + - /server + livenessProbe: + httpGet: + path: /healthz # 访问的请求路径 + port: 8080 # 服务监听端口 + httpHeaders: + - name: Custom-Header + value: Awesome + initialDelaySeconds: 3 # kubelet 在执行第一次探测前应该等待 3 秒 + periodSeconds: 3 # kubelet 每隔 3 秒执行一次存活探测 +``` + +按照设定的规则,ubelet 向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 __/healthz__ 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。 如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。返回大于或等于 200 并且小于 400 的任何代码都标示成功,其它返回代码都标示失败。 容器存活期间的最开始 10 秒中, __/healthz__ 处理程序返回 200 的状态码。 之后处理程序返回 500 的状态码。 + +### 使用 TCP 端口检查 + +**TCP 端口参数说明:** + +| 参数 | 参数说明 | +| ------------------------------- | ------------------------------------------------------------ | +| 端口(Port) | 服务监听端口。 如: 示例中的 8080 端口 | +| 延迟时间(initialDelaySeconds) | 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。 | +| 超时时间(timeoutSeconds) | 超时时间,单位为秒。例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 | + +对于提供TCP通信服务的容器,基于此配置,按照设定规则集群对该容器建立TCP连接,如果连接成功,则证明探测成功,否则探测失败。选择TCP端口探测方式,必须指定容器监听的端口。 + +**YAML 示例:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: goproxy + labels: + app: goproxy +spec: + containers: + - name: goproxy + image: k8s.gcr.io/goproxy:0.1 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 + +``` + +此示例同时使用就绪和存活探针。kubelet 在容器启动 5 秒后发送第一个就绪探测。 尝试连接 __goproxy__ 容器的 8080 端口, 如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。 + +除了就绪探测,这个配置包括了一个存活探测。 kubelet 会在容器启动 15 秒后进行第一次存活探测。 就绪探测会尝试连接 __goproxy__ 容器的 8080 端口。 如果存活探测失败,容器会被重新启动。 + +### 执行命令检查 + +**YAML 示例:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-exec +spec: + containers: + - name: liveness + image: k8s.gcr.io/busybox + args: + - /bin/sh + - -c + - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600 + livenessProbe: + exec: + command: + - cat + - /tmp/healthy + initialDelaySeconds: 5 # kubelet 在执行第一次探测前等待 5 秒 + periodSeconds: 5 #kubelet 每 5 秒执行一次存活探测 +``` + + __periodSeconds__ 字段指定了 kubelet 每 5 秒执行一次存活探测, __initialDelaySeconds__ 字段指定 kubelet 在执行第一次探测前等待 5 秒。按照设定规则,集群周期性的通过 kubelet 在容器内执行命令 __cat /tmp/healthy__ 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。 + +### 使用启动前检查保护慢启动容器 + +有些应用在启动时需要较长的初始化时间,需要使用相同的命令来设置启动探测,针对 HTTP 或 TCP 检测,可以通过将 __failureThreshold * periodSeconds__ 参数设置为足够长的时间来应对启动需要较长时间的场景。 + +**YAML 示例:** + +```yaml +ports: +- name: liveness-port + containerPort: 8080 + hostPort: 8080 + +livenessProbe: + httpGet: + path: /healthz + port: liveness-port + failureThreshold: 1 + periodSeconds: 10 + +startupProbe: + httpGet: + path: /healthz + port: liveness-port + failureThreshold: 30 + periodSeconds: 10 +``` + +如上设置,应用将有最多 5 分钟(30 * 10 = 300s)的时间来完成启动过程, 一旦启动探测成功,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应。 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 __restartPolicy__ 来 执行进一步处置。 diff --git a/docs/zh/docs/end-user/kpanda/workloads/pod-config/job-parameters.md b/docs/zh/docs/end-user/kpanda/workloads/pod-config/job-parameters.md new file mode 100644 index 0000000..7b95386 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/pod-config/job-parameters.md @@ -0,0 +1,51 @@ +--- +hide: + - toc +--- + +# 任务参数说明 + +根据 __.spec.completions__ 和 __.spec.Parallelism__ 的设置,可以将任务(Job)划分为以下几种类型: + +| Job 类型 | 说明 | +| -------------------------- | ------------------------------------------------------------ | +| 非并行 Job | 创建一个 Pod 直至其 Job 成功结束 | +| 具有确定完成计数的并行 Job | 当成功的 Pod 个数达到 __.spec.completions__ 时,Job 被视为完成 | +| 并行 Job | 创建一个或多个 Pod 直至有一个成功结束 | + +**参数说明** + +| RestartPolicy | 创建一个 Pod 直至其成功结束 | +| --------------------------- | ------------------------------------------------------------ | +| .spec.completions | 表示 Job 结束需要成功运行的 Pod 个数,默认为 1 | +| .spec.parallelism | 表示并行运行的 Pod 的个数,默认为 1 | +| spec.backoffLimit | 表示失败 Pod 的重试最大次数,超过这个次数不会继续重试。 | +| .spec.activeDeadlineSeconds | 表示 Pod 运行时间,一旦达到这个时间,Job 即其所有的 Pod 都会停止。且activeDeadlineSeconds 优先级高于 backoffLimit,即到达 activeDeadlineSeconds 的 Job 会忽略backoffLimit 的设置。 | + +以下是一个 Job 配置示例,保存在 myjob.yaml 中,其计算 π 到 2000 位并打印输出。 + +```yaml +apiVersion: batch/v1 +kind: Job # 当前资源的类型 +metadata: + name: myjob +spec: + completions: 50 # Job结束需要运行50个Pod,这个示例中就是打印π 50次 + parallelism: 5 # 并行5个Pod + backoffLimit: 5 # 最多重试5次 + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never #重启策略 +``` + +**相关命令** + +```bash +kubectl apply -f myjob.yaml #启动 job +kubectl get job #查看这个job +kubectl logs myjob-1122dswzs 查看Job Pod 的日志 +``` diff --git a/docs/zh/docs/end-user/kpanda/workloads/pod-config/lifecycle.md b/docs/zh/docs/end-user/kpanda/workloads/pod-config/lifecycle.md new file mode 100644 index 0000000..1dc8962 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/pod-config/lifecycle.md @@ -0,0 +1,55 @@ +# 配置容器生命周期 + +Pod 遵循一个预定义的生命周期,起始于 __Pending__ 阶段,如果 Pod 内至少有一个容器正常启动,则进入 __Running__ 状态。如果 Pod 中有容器以失败状态结束,则状态变为 __Failed__ 。以下 __phase__ 字段值表明了一个 Pod 处于生命周期的哪个阶段。 + +值 | 描述 +:-----|:----------- +__Pending__
(悬决)| Pod 已被系统接受,但有一个或者多个容器尚未创建亦未运行。这个阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 +__Running__
(运行中) | Pod 已经绑定到了某个节点,Pod 中的所有容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 +__Succeeded__
(成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 +__Failed__
(失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败而终止。也就是说,容器以非 0 状态退出或者被系统终止。 +__Unknown__
(未知) | 因为某些原因无法取得 Pod 的状态,这种情况通常是因为与 Pod 所在主机通信失败所致。 + +在算丰 AI 算力平台容器管理中创建一个工作负载时,通常使用镜像来指定容器中的运行环境。默认情况下,在构建镜像时,可以通过 __Entrypoint__ 和 __CMD__ 两个字段来定义容器运行时执行的命令和参数。如果需要更改容器镜像启动前、启动后、停止前的命令和参数,可以通过设置容器的生命周期事件命令和参数,来覆盖镜像中默认的命令和参数。 + +## 生命周期配置 + +根据业务需要对容器的启动命令、启动后命令、停止前命令进行配置。 + +| 参数 | 说明 | 举例值 | +| :-- | :--- | :---- | +| 启动命令 | 【类型】选填
【含义】容器将按照启动命令进行启动。 | | +| 启动后命令 | 【类型】选填
【含义】容器启动后出发的命令
| | +| 停止前命令 | 【类型】选填
【含义】容器在收到停止命令后执行的命令。确保升级或实例删除时可提前将实例中运行的业务排水。 | | + +### 启动命令 + +根据下表对启动命令进行配置。 + +| 参数 | 说明 | 举例值 | +| :-- | :--- | :---- | +| 运行命令 | 【类型】必填
【含义】输入可执行的命令,多个命令之间用空格进行分割,如命令本身带空格,则需要加(“”)。
【含义】多命令时,运行命令建议用/bin/sh或其他的shell,其他全部命令作为参数来传入。 | /run/server | +| 运行参数 | 【类型】选填
【含义】输入控制容器运行命令参数。
| port=8080 | + +### 启动后命令 + +算丰 AI 算力平台提供命令行脚本和 HTTP 请求两种处理类型对启动后命令进行配置。您可以根据下表选择适合您的配置方式。 + +**命令行脚本配置** + +| 参数 | 说明 | 举例值 | +| :-- | :--- | :---- | +| 运行命令 | 【类型】选填
【含义】输入可执行的命令,多个命令之间用空格进行分割,如命令本身带空格,则需要加(“”)。
【含义】多命令时,运行命令建议用/bin/sh或其他的shell,其他全部命令作为参数来传入。 | /run/server | +| 运行参数 | 【类型】选填
【含义】输入控制容器运行命令参数。
| port=8080 | + +### 停止前命令 + +算丰 AI 算力平台提供命令行脚本和 HTTP 请求两种处理类型对停止前命令进行配置。您可以根据下表选择适合您的配置方式。 + +**HTTP 请求配置** + +| 参数 | 说明 | 举例值 | +| :-- | :--- | :---- | +| URL 路径 | 【类型】选填
【含义】请求的URL路径。
【含义】多命令时,运行命令建议用/bin/sh或其他的shell,其他全部命令作为参数来传入。 | /run/server | +| 端口 | 【类型】必填
【含义】请求的端口。
| port=8080 | +| 节点地址 | 【类型】选填
【含义】请求的 IP 地址,默认是容器所在的节点 IP。
| | diff --git a/docs/zh/docs/end-user/kpanda/workloads/pod-config/scheduling-policy.md b/docs/zh/docs/end-user/kpanda/workloads/pod-config/scheduling-policy.md new file mode 100644 index 0000000..7e032f8 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/pod-config/scheduling-policy.md @@ -0,0 +1,98 @@ +# 调度策略 + +在 Kubernetes 集群中,节点也有[标签](https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/labels/)。您可以[手动添加标签](https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/assign-pods-nodes/#add-a-label-to-a-node)。 Kubernetes 也会为集群中所有节点添加一些标准的标签。参见[常用的标签、注解和污点](https://kubernetes.io/zh-cn/docs/reference/labels-annotations-taints/)以了解常见的节点标签。通过为节点添加标签,您可以让 Pod 调度到特定节点或节点组上。您可以使用这个功能来确保特定的 Pod 只能运行在具有一定隔离性,安全性或监管属性的节点上。 + +__nodeSelector__ 是节点选择约束的最简单推荐形式。您可以将 __nodeSelector__ 字段添加到 Pod 的规约中设置您希望目标节点所具有的[节点标签](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#built-in-node-labels)。Kubernetes 只会将 Pod 调度到拥有指定每个标签的节点上。 __nodeSelector__ 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。亲和性和反亲和性扩展了您可以定义的约束类型。使用亲和性与反亲和性的一些好处有: + +- 亲和性、反亲和性语言的表达能力更强。 __nodeSelector__ 只能选择拥有所有指定标签的节点。亲和性、反亲和性为您提供对选择逻辑的更强控制能力。 + +- 您可以标明某规则是“软需求”或者“偏好”,这样调度器在无法找到匹配节点时,会忽略亲和性/反亲和性规则,确保 Pod 调度成功。 + +- 您可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束,而不是只能使用节点本身的标签。这个能力让您能够定义规则允许哪些 Pod 可以被放置在一起。 + +您可以通过设置亲和(affinity)与反亲和(anti-affinity)来选择 Pod 要部署的节点。 + +## 容忍时间 + +当工作负载实例所在的节点不可用时,系统将实例重新调度到其它可用节点的时间窗。默认为 300 秒。 + +## 节点亲和性(nodeAffinity) + +节点亲和性概念上类似于 __nodeSelector__ , 它使您可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种: + +- **必须满足:( __requiredDuringSchedulingIgnoredDuringExecution__ )** 调度器只有在规则被满足的时候才能执行调度。此功能类似于 __nodeSelector__ , 但其语法表达能力更强。您可以定义多条硬约束规则,但只需满足其中一条。 + +- **尽量满足:( __preferredDuringSchedulingIgnoredDuringExecution__ )** 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。同时您还可以定义多条硬约束规则,但只需满足其中一条。 + +#### 标签名 + +对应节点的标签,可以使用默认的标签也可以用户自定义标签。 + +#### 操作符 + +- In:标签值需要在 values 的列表中 +- NotIn:标签的值不在某个列表中 +- Exists:判断某个标签是存在,无需设置标签值 +- DoesNotExist:判断某个标签是不存在,无需设置标签值 +- Gt:标签的值大于某个值(字符串比较) +- Lt:标签的值小于某个值(字符串比较) + +#### 权重 + +仅支持在“尽量满足”策略中添加,可以理解为调度的优先级,权重大的会被优先调度。取值范围是 1 到 100。 + +## 工作负载亲和性 + +与节点亲和性类似,工作负载的亲和性也有两种类型: + +- **必须满足:( __requiredDuringSchedulingIgnoredDuringExecution__ )** 调度器只有在规则被满足的时候才能执行调度。此功能类似于 __nodeSelector__ , 但其语法表达能力更强。您可以定义多条硬约束规则,但只需满足其中一条。 +- **尽量满足:( __preferredDuringSchedulingIgnoredDuringExecution__ )** 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。同时您还可以定义多条硬约束规则,但只需满足其中一条。 + +工作负载的亲和性主要用来决定工作负载的 Pod 可以和哪些 Pod部 署在同一拓扑域。例如,对于相互通信的服务,可通过应用亲和性调度,将其部署到同一拓扑域(如同一可用区)中,减少它们之间的网络延迟。 + +#### 标签名 + +对应节点的标签,可以使用默认的标签也可以用户自定义标签。 + +#### 命名空间 + +指定调度策略生效的命名空间。 + +#### 操作符 + +- In:标签值需要在 values 的列表中 +- NotIn:标签的值不在某个列表中 +- Exists:判断某个标签是存在,无需设置标签值 +- DoesNotExist:判断某个标签是不存在,无需设置标签值 + +#### 拓扑域 + +指定调度时的影响范围。例如,如果指定为 __kubernetes.io/Clustername__ 表示以 Node 节点为区分范围。 + +## 工作负载反亲和性 + +与节点亲和性类似,工作负载的反亲和性也有两种类型: + +- **必须满足:( __requiredDuringSchedulingIgnoredDuringExecution__ )** 调度器只有在规则被满足的时候才能执行调度。此功能类似于 __nodeSelector__ , 但其语法表达能力更强。您可以定义多条硬约束规则,但只需满足其中一条。 +- **尽量满足:( __preferredDuringSchedulingIgnoredDuringExecution__ )** 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。您还可为软约束规则设定权重,具体调度时,若存在多个符合条件的节点,权重最大的节点会被优先调度。同时您还可以定义多条硬约束规则,但只需满足其中一条。 + +工作负载的反亲和性主要用来决定工作负载的 Pod 不可以和哪些 Pod 部署在同一拓扑域。例如,将一个负载的相同 Pod 分散部署到不同的拓扑域(例如不同主机)中,提高负载本身的稳定性。 + +#### 标签名 + +对应节点的标签,可以使用默认的标签也可以用户自定义标签。 + +#### 命名空间 + +指定调度策略生效的命名空间。 + +#### 操作符 + +- In:标签值需要在 values 的列表中 +- NotIn:标签的值不在某个列表中 +- Exists:判断某个标签是存在,无需设置标签值 +- DoesNotExist:判断某个标签是不存在,无需设置标签值 + +#### 拓扑域 + +指定调度时的影响范围。例如,如果指定为 __kubernetes.io/Clustername__ 表示以 Node 节点为区分范围。 diff --git a/docs/zh/docs/end-user/kpanda/workloads/pod-config/workload-status.md b/docs/zh/docs/end-user/kpanda/workloads/pod-config/workload-status.md new file mode 100644 index 0000000..d56eab3 --- /dev/null +++ b/docs/zh/docs/end-user/kpanda/workloads/pod-config/workload-status.md @@ -0,0 +1,53 @@ +# 工作负载状态 + +工作负载是运行在 Kubernetes 上的一个应用程序,在 Kubernetes 中,无论您的应用程序是由单个同一组件或是由多个不同的组件构成,都可以使用一组 Pod 来运行它。Kubernetes 提供了五种内置的工作负载资源来管理 Pod: + +- [无状态工作负载](../create-deployment.md) +- [有状态工作负载](../create-statefulset.md) +- [守护进程](../create-daemonset.md) +- [任务](../create-job.md) +- [定时任务](../create-cronjob.md) + +您也可以通过设置[自定义资源 CRD](../../custom-resources/create.md) 来实现对工作负载资源的扩展。在第五代容器管理中,支持对工作负载进行创建、更新、扩容、监控、日志、删除、版本管理等全生命周期管理。 + +## Pod 状态 + +Pod 是 Kuberneters 中创建和管理的、最小的计算单元,即一组容器的集合。这些容器共享存储、网络以及管理控制容器运行方式的策略。 +Pod 通常不由用户直接创建,而是通过工作负载资源来创建。 +Pod 遵循一个预定义的生命周期,起始于 __Pending__ [阶段](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase),如果至少其中有一个主要容器正常启动,则进入 __Running__ ,之后取决于 Pod 中是否有容器以失败状态结束而进入 __Succeeded__ 或者 __Failed__ 阶段。 + +## 工作负载状态 + +第五代容器管理模块依据 Pod 的状态、副本数等因素,设计了一种内置的工作负载生命周期的状态集,以让用户能够更加真实的感知工作负载运行情况。 +由于不同的工作负载类型(比如无状态工作负载和任务)对 Pod 的管理机制不一致,因此,不同的工作负载在运行过程中会呈现不同的生命周期状态,具体如下表: + +### 无状态负载、有状态负载、守护进程状态 + +| 状态 | 描述 | +| :---------------------- | :----------------------------------------------------------- | +| 等待中 | 1. 工作负载创建正在进行中,工作负载处于此状态。
2. 触发升级或者回滚动作后,工作负载处于此状态。
3. 触发暂停/扩缩容等操作,工作负载处在此状态。 | +| 运行中 | 负载下的所有实例都在运行中且副本数与用户预定义的数量一致时处于此状态。 | +| 删除中 | 执行删除操作时,负载处于此状态,直到删除完成。 | +| 异常 | 因为某些原因无法取得工作负载的状态。这种情况通常是因为与 Pod 所在主机通信失败。 | +| 未就绪 | 容器处于异常,pending 状态时,因未知错误导致负载无法启动时显示此状态 | + +### 任务状态 + +| 状态 | 描述 | +| :------- | :----------------------------------------------------------- | +| 等待中 | 任务创建正在进行中,工作负载处于此状态。 | +| 执行中 | 任务正在执行中,工作负载处于此状态。 | +| 执行完成 | 任务执行完成,工作负载处于此状态。 | +| 删除中 | 触发删除操作,工作负载处在此状态。 | +| 异常 | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 | + +### 定时任务状态 + +| 状态 | 描述 | +| :----- | :----------------------------------------------------------- | +| 等待中 | 定时任务创建正在进行中,定时任务处于此状态。 | +| 已启动 | 创建定时任务成功后,正常运行或将已暂停的任务启动时定时任务处于此状态。 | +| 已停止 | 执行停止任务操作时,定时任务处于此状态。 | +| 删除中 | 触发删除操作,定时任务处在此状态。 | + +当工作负载处于异常或未就绪状态时,您可以通过将鼠标移动到负载的状态值上,系统将通过提示框展示更加详细的错误信息。您也可以通过查看[日志](../../../../insight/data-query/log.mdlog.md)或事件来获取工作负载的相关运行信息。 diff --git a/docs/zh/docs/end-user/register/index.md b/docs/zh/docs/end-user/register/index.md new file mode 100644 index 0000000..2b0c71f --- /dev/null +++ b/docs/zh/docs/end-user/register/index.md @@ -0,0 +1,31 @@ +# 用户注册 + +新用户首次使用 AI 算力平台需要进行注册。 + +## 前置条件 + +- 已安装 AI 算力平台 +- 已开启邮箱注册功能 +- 有一个可用的邮箱 + +## 邮箱注册步骤 + +1. 打开 AI 算力平台首页 ,点击 **注册** + + ![home](../../images/regis01.PNG) + +1. 键入用户名、密码、邮箱后点击 **注册** + + ![to register](../../images/regis02.PNG) + +1. 系统提示发送了一封邮件到您的邮箱。 + + ![to register](../../images/regis03.PNG) + +1. 登录自己的邮箱,找到邮件,点击链接。 + + ![email](../../images/regis04.PNG) + +1. 恭喜,您成功进入了 AI 算力平台,现在可以开始您的 AI 之旅了。 + + ![verify](../../images/regis05.PNG) diff --git a/docs/zh/docs/end-user/share/notebook.md b/docs/zh/docs/end-user/share/notebook.md new file mode 100644 index 0000000..4cbc010 --- /dev/null +++ b/docs/zh/docs/end-user/share/notebook.md @@ -0,0 +1,85 @@ +# 使用 Notebook + +Notebook 通常指的是 Jupyter Notebook 或类似的交互式计算环境。 +这是一种非常流行的工具,广泛用于数据科学、机器学习和深度学习等领域。 +本页说明如何在算丰 AI 算力平台中使用 Notebook。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](../register/index.md) +- 管理员为用户分配了工作空间 +- 已准备好数据集(代码、数据等) + +## 创建和使用 Notebook 实例 + +1. 以 **管理员身份** 登录 AI 算力平台 +1. 导航至 **AI Lab** -> **运维管理** -> **队列管理** ,点击右侧的 **创建** 按钮 + + ![create queue](../images/notebook01.png) + +1. 键入名称,选择集群、工作空间和配额后,点击 **确定** + + ![ok](../images/notebook02.png) + +1. 以 **用户身份** 登录 AI 算力平台,导航至 **AI Lab** -> **Notebook** ,点击右侧的 **创建** 按钮 + + ![create notebook](../images/notebook03.png) + +1. 配置各项参数后点击 **确定** + + === "基本信息" + + 键入名称,选择集群、命名空间,选择刚创建的队列,点击 **一键初始化** + + ![basic](../images/notebook04.png) + + === "资源配置" + + 选择 Notebook 类型,配置内存、CPU,开启 GPU,创建和配置 PVC: + + ![resource](../images/notebook05.png) + + === "高级配置" + + 开启 SSH 外网访问: + + ![advanced](../images/notebook06.png) + +1. 自动跳转到 Notebook 实例列表,点击实例名称 + + ![click name](../images/notebook07.png) + +1. 进入 Notebook 实例详情页,点击右上角的 **打开** 按钮 + + ![open](../images/notebook08.png) + +1. 进入了 Notebook 开发环境,比如在 `/home/jovyan` 目录挂载了持久卷,可以通过 git 克隆代码,通过 SSH 连接后上传数据等。 + + ![notebook](../images/notebook09.png) + +## 通过 SSH 访问 Notebook 实例 + +1. 在自己的电脑上生成 SSH 密钥对 + + 在自己电脑上打开命令行,比如在 Windows 上打开 git bash,输入 `ssh-keygen.exe -t rsa`,然后一路回车。 + + ![generate](../images/ssh01.png) + +1. 通过 `cat ~/.ssh/id_rsa.pub` 等命令查看并复制公钥 + + ![copy key](../images/ssh02.png) + +1. 以用户身份登录 AI 算力平台,在右上角点击 **个人中心** -> **SSH 公钥** -> **导入 SSH 公钥** + + ![import](../images/ssh03.png) + +1. 进入 Notebook 实例的详情页,复制 SSH 的链接 + + ![copy link](../images/ssh04.png) + +1. 在客户端使用 SSH 访问 Notebook 实例 + + ![ssh](../images/ssh05.png) + +下一步:[创建训练任务](../../admin/baize/developer/jobs/create.md) diff --git a/docs/zh/docs/end-user/share/workload.md b/docs/zh/docs/end-user/share/workload.md new file mode 100644 index 0000000..2a5517e --- /dev/null +++ b/docs/zh/docs/end-user/share/workload.md @@ -0,0 +1,51 @@ +# 创建 AI 负载使用 GPU 资源 + +管理员为工作空间分配资源配额后,用户就可以创建 AI 工作负载来使用 GPU 算力资源。 + +## 前置条件 + +- 已安装 AI 算力平台 +- [用户已成功注册](../register/index.md) +- 管理员为用户分配了工作空间 +- 管理员为工作空间设置了资源配额 +- 管理员已经为用户分配了一个集群 + +## 创建 AI 负载步骤 + +1. 以用户身份登录 AI 算力平台 +1. 导航至 **容器管理** ,选择一个命名空间,点击 **工作负载** -> **无状态负载** , + 点击右侧的 **镜像创建** 按钮 + + ![button](../images/workload01.png) + +1. 配置各项参数后点击 **确定** + + === "基本信息" + + 选择自己的命名空间。 + + ![basic](../images/workload02.png) + + === "容器配置" + + 设置镜像,配置 CPU、内存、GPU 等资源,设置启动命令。 + + ![container](../images/workload03.png) + + === "其他" + + 服务配置和高级配置可以使用默认配置。 + +1. 自动返回无状态负载列表,点击负载名称 + + ![click name](../images/workload04.png) + +1. 进入详情页,可以看到 GPU 配额 + + ![check gpu](../images/workload05.png) + +1. 你还可以进入控制台,运行 `mx-smi` 命令查看 GPU 资源 + + ![check gpu](../images/workload06.png) + +下一步:[使用 Notebook](./notebook.md) diff --git a/docs/zh/docs/images/Advanced-Configuration.png b/docs/zh/docs/images/Advanced-Configuration.png new file mode 100644 index 0000000..f261564 Binary files /dev/null and b/docs/zh/docs/images/Advanced-Configuration.png differ diff --git a/docs/zh/docs/images/DaoCloud.png b/docs/zh/docs/images/DaoCloud.png new file mode 100644 index 0000000..de4ee32 Binary files /dev/null and b/docs/zh/docs/images/DaoCloud.png differ diff --git a/docs/zh/docs/images/Installation-and-upgrade.png b/docs/zh/docs/images/Installation-and-upgrade.png new file mode 100644 index 0000000..3bc24dd Binary files /dev/null and b/docs/zh/docs/images/Installation-and-upgrade.png differ diff --git a/docs/zh/docs/images/about02.png b/docs/zh/docs/images/about02.png new file mode 100644 index 0000000..357e47e Binary files /dev/null and b/docs/zh/docs/images/about02.png differ diff --git a/docs/zh/docs/images/about03.png b/docs/zh/docs/images/about03.png new file mode 100644 index 0000000..7b18a08 Binary files /dev/null and b/docs/zh/docs/images/about03.png differ diff --git a/docs/zh/docs/images/access-cloudshell.png b/docs/zh/docs/images/access-cloudshell.png new file mode 100644 index 0000000..00297fb Binary files /dev/null and b/docs/zh/docs/images/access-cloudshell.png differ diff --git a/docs/zh/docs/images/access-download-cert.png b/docs/zh/docs/images/access-download-cert.png new file mode 100644 index 0000000..d529ae0 Binary files /dev/null and b/docs/zh/docs/images/access-download-cert.png differ diff --git a/docs/zh/docs/images/access-get-cert.png b/docs/zh/docs/images/access-get-cert.png new file mode 100644 index 0000000..fa2abb9 Binary files /dev/null and b/docs/zh/docs/images/access-get-cert.png differ diff --git a/docs/zh/docs/images/access-get-node.png b/docs/zh/docs/images/access-get-node.png new file mode 100644 index 0000000..cab7d9d Binary files /dev/null and b/docs/zh/docs/images/access-get-node.png differ diff --git a/docs/zh/docs/images/addnode01.png b/docs/zh/docs/images/addnode01.png new file mode 100644 index 0000000..6834e02 Binary files /dev/null and b/docs/zh/docs/images/addnode01.png differ diff --git a/docs/zh/docs/images/addnode01_1.png b/docs/zh/docs/images/addnode01_1.png new file mode 100644 index 0000000..6834e02 Binary files /dev/null and b/docs/zh/docs/images/addnode01_1.png differ diff --git a/docs/zh/docs/images/addnode02.png b/docs/zh/docs/images/addnode02.png new file mode 100644 index 0000000..6cdd8ae Binary files /dev/null and b/docs/zh/docs/images/addnode02.png differ diff --git a/docs/zh/docs/images/addnode03.png b/docs/zh/docs/images/addnode03.png new file mode 100644 index 0000000..e2b749e Binary files /dev/null and b/docs/zh/docs/images/addnode03.png differ diff --git a/docs/zh/docs/images/appear05.png b/docs/zh/docs/images/appear05.png new file mode 100644 index 0000000..f53a5d8 Binary files /dev/null and b/docs/zh/docs/images/appear05.png differ diff --git a/docs/zh/docs/images/ascend-demo-infer-result.png b/docs/zh/docs/images/ascend-demo-infer-result.png new file mode 100644 index 0000000..b0638b0 Binary files /dev/null and b/docs/zh/docs/images/ascend-demo-infer-result.png differ diff --git a/docs/zh/docs/images/ascend-demo-pod-result.png b/docs/zh/docs/images/ascend-demo-pod-result.png new file mode 100644 index 0000000..6083b53 Binary files /dev/null and b/docs/zh/docs/images/ascend-demo-pod-result.png differ diff --git a/docs/zh/docs/images/ascend-demo-pod-status.png b/docs/zh/docs/images/ascend-demo-pod-status.png new file mode 100644 index 0000000..0ade4b5 Binary files /dev/null and b/docs/zh/docs/images/ascend-demo-pod-status.png differ diff --git a/docs/zh/docs/images/audit01.png b/docs/zh/docs/images/audit01.png new file mode 100644 index 0000000..27060b0 Binary files /dev/null and b/docs/zh/docs/images/audit01.png differ diff --git a/docs/zh/docs/images/audit02.png b/docs/zh/docs/images/audit02.png new file mode 100644 index 0000000..7121a0c Binary files /dev/null and b/docs/zh/docs/images/audit02.png differ diff --git a/docs/zh/docs/images/audit03.png b/docs/zh/docs/images/audit03.png new file mode 100644 index 0000000..0e29cf6 Binary files /dev/null and b/docs/zh/docs/images/audit03.png differ diff --git a/docs/zh/docs/images/audit04.png b/docs/zh/docs/images/audit04.png new file mode 100644 index 0000000..301df9d Binary files /dev/null and b/docs/zh/docs/images/audit04.png differ diff --git a/docs/zh/docs/images/audit05.png b/docs/zh/docs/images/audit05.png new file mode 100644 index 0000000..d989987 Binary files /dev/null and b/docs/zh/docs/images/audit05.png differ diff --git a/docs/zh/docs/images/audit06.png b/docs/zh/docs/images/audit06.png new file mode 100644 index 0000000..f066de4 Binary files /dev/null and b/docs/zh/docs/images/audit06.png differ diff --git a/docs/zh/docs/images/audit07.png b/docs/zh/docs/images/audit07.png new file mode 100644 index 0000000..e43cb6c Binary files /dev/null and b/docs/zh/docs/images/audit07.png differ diff --git a/docs/zh/docs/images/authorize01.png b/docs/zh/docs/images/authorize01.png new file mode 100644 index 0000000..c0cf0bf Binary files /dev/null and b/docs/zh/docs/images/authorize01.png differ diff --git a/docs/zh/docs/images/authorize02.png b/docs/zh/docs/images/authorize02.png new file mode 100644 index 0000000..a41bb60 Binary files /dev/null and b/docs/zh/docs/images/authorize02.png differ diff --git a/docs/zh/docs/images/backup1.png b/docs/zh/docs/images/backup1.png new file mode 100644 index 0000000..6ec51f3 Binary files /dev/null and b/docs/zh/docs/images/backup1.png differ diff --git a/docs/zh/docs/images/backup2.png b/docs/zh/docs/images/backup2.png new file mode 100644 index 0000000..1714966 Binary files /dev/null and b/docs/zh/docs/images/backup2.png differ diff --git a/docs/zh/docs/images/backup3.png b/docs/zh/docs/images/backup3.png new file mode 100644 index 0000000..bd3d185 Binary files /dev/null and b/docs/zh/docs/images/backup3.png differ diff --git a/docs/zh/docs/images/backupd20485.png b/docs/zh/docs/images/backupd20485.png new file mode 100644 index 0000000..aef150c Binary files /dev/null and b/docs/zh/docs/images/backupd20485.png differ diff --git a/docs/zh/docs/images/backupd20486.png b/docs/zh/docs/images/backupd20486.png new file mode 100644 index 0000000..9e3382d Binary files /dev/null and b/docs/zh/docs/images/backupd20486.png differ diff --git a/docs/zh/docs/images/cluster-ns.png b/docs/zh/docs/images/cluster-ns.png new file mode 100644 index 0000000..df28002 Binary files /dev/null and b/docs/zh/docs/images/cluster-ns.png differ diff --git a/docs/zh/docs/images/cluster-setting-ascend-gpu.jpg b/docs/zh/docs/images/cluster-setting-ascend-gpu.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/cluster-setting-gpu.jpg b/docs/zh/docs/images/cluster-setting-gpu.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/cluster-setting-iluvatar-gpu.jpg b/docs/zh/docs/images/cluster-setting-iluvatar-gpu.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/cluster-version.png b/docs/zh/docs/images/cluster-version.png new file mode 100644 index 0000000..2392ce9 Binary files /dev/null and b/docs/zh/docs/images/cluster-version.png differ diff --git a/docs/zh/docs/images/config05.png b/docs/zh/docs/images/config05.png new file mode 100644 index 0000000..a9c71a3 Binary files /dev/null and b/docs/zh/docs/images/config05.png differ diff --git a/docs/zh/docs/images/configmap-hot-loading.jpg b/docs/zh/docs/images/configmap-hot-loading.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/configmap-hot-loading02.png b/docs/zh/docs/images/configmap-hot-loading02.png new file mode 100644 index 0000000..93d3daf Binary files /dev/null and b/docs/zh/docs/images/configmap-hot-loading02.png differ diff --git a/docs/zh/docs/images/configmap-hot-loading03.png b/docs/zh/docs/images/configmap-hot-loading03.png new file mode 100644 index 0000000..89604af Binary files /dev/null and b/docs/zh/docs/images/configmap-hot-loading03.png differ diff --git a/docs/zh/docs/images/configmap01.png b/docs/zh/docs/images/configmap01.png new file mode 100644 index 0000000..7bf0c54 Binary files /dev/null and b/docs/zh/docs/images/configmap01.png differ diff --git a/docs/zh/docs/images/configmap02.png b/docs/zh/docs/images/configmap02.png new file mode 100644 index 0000000..39723be Binary files /dev/null and b/docs/zh/docs/images/configmap02.png differ diff --git a/docs/zh/docs/images/configmap03.png b/docs/zh/docs/images/configmap03.png new file mode 100644 index 0000000..b7109d3 Binary files /dev/null and b/docs/zh/docs/images/configmap03.png differ diff --git a/docs/zh/docs/images/configmap04.png b/docs/zh/docs/images/configmap04.png new file mode 100644 index 0000000..62d8b09 Binary files /dev/null and b/docs/zh/docs/images/configmap04.png differ diff --git a/docs/zh/docs/images/configmap04_1.png b/docs/zh/docs/images/configmap04_1.png new file mode 100644 index 0000000..62d8b09 Binary files /dev/null and b/docs/zh/docs/images/configmap04_1.png differ diff --git a/docs/zh/docs/images/console01.png b/docs/zh/docs/images/console01.png new file mode 100644 index 0000000..ccbcf0a Binary files /dev/null and b/docs/zh/docs/images/console01.png differ diff --git a/docs/zh/docs/images/console02.png b/docs/zh/docs/images/console02.png new file mode 100644 index 0000000..2f5702a Binary files /dev/null and b/docs/zh/docs/images/console02.png differ diff --git a/docs/zh/docs/images/crd01.png b/docs/zh/docs/images/crd01.png new file mode 100644 index 0000000..8f53b7f Binary files /dev/null and b/docs/zh/docs/images/crd01.png differ diff --git a/docs/zh/docs/images/crd01_1.png b/docs/zh/docs/images/crd01_1.png new file mode 100644 index 0000000..8f53b7f Binary files /dev/null and b/docs/zh/docs/images/crd01_1.png differ diff --git a/docs/zh/docs/images/crd01_2.png b/docs/zh/docs/images/crd01_2.png new file mode 100644 index 0000000..8f53b7f Binary files /dev/null and b/docs/zh/docs/images/crd01_2.png differ diff --git a/docs/zh/docs/images/crd03.png b/docs/zh/docs/images/crd03.png new file mode 100644 index 0000000..d9a1134 Binary files /dev/null and b/docs/zh/docs/images/crd03.png differ diff --git a/docs/zh/docs/images/crd06.png b/docs/zh/docs/images/crd06.png new file mode 100644 index 0000000..48666ba Binary files /dev/null and b/docs/zh/docs/images/crd06.png differ diff --git a/docs/zh/docs/images/create-tep01.png b/docs/zh/docs/images/create-tep01.png new file mode 100644 index 0000000..80f2f3d Binary files /dev/null and b/docs/zh/docs/images/create-tep01.png differ diff --git a/docs/zh/docs/images/create-tep02.png b/docs/zh/docs/images/create-tep02.png new file mode 100644 index 0000000..23fb0da Binary files /dev/null and b/docs/zh/docs/images/create-tep02.png differ diff --git a/docs/zh/docs/images/create-tep03.png b/docs/zh/docs/images/create-tep03.png new file mode 100644 index 0000000..b584338 Binary files /dev/null and b/docs/zh/docs/images/create-tep03.png differ diff --git a/docs/zh/docs/images/create-tep04.png b/docs/zh/docs/images/create-tep04.png new file mode 100644 index 0000000..965cb1a Binary files /dev/null and b/docs/zh/docs/images/create-tep04.png differ diff --git a/docs/zh/docs/images/create-tep05.png b/docs/zh/docs/images/create-tep05.png new file mode 100644 index 0000000..54ff24c Binary files /dev/null and b/docs/zh/docs/images/create-tep05.png differ diff --git a/docs/zh/docs/images/create-tep06.png b/docs/zh/docs/images/create-tep06.png new file mode 100644 index 0000000..d21911b Binary files /dev/null and b/docs/zh/docs/images/create-tep06.png differ diff --git a/docs/zh/docs/images/create-tep07.png b/docs/zh/docs/images/create-tep07.png new file mode 100644 index 0000000..aae99c9 Binary files /dev/null and b/docs/zh/docs/images/create-tep07.png differ diff --git a/docs/zh/docs/images/create-tep08.png b/docs/zh/docs/images/create-tep08.png new file mode 100644 index 0000000..30a5d14 Binary files /dev/null and b/docs/zh/docs/images/create-tep08.png differ diff --git a/docs/zh/docs/images/create001.png b/docs/zh/docs/images/create001.png new file mode 100644 index 0000000..718a759 Binary files /dev/null and b/docs/zh/docs/images/create001.png differ diff --git a/docs/zh/docs/images/create002.png b/docs/zh/docs/images/create002.png new file mode 100644 index 0000000..046e50b Binary files /dev/null and b/docs/zh/docs/images/create002.png differ diff --git a/docs/zh/docs/images/create009.png b/docs/zh/docs/images/create009.png new file mode 100644 index 0000000..cf183b7 Binary files /dev/null and b/docs/zh/docs/images/create009.png differ diff --git a/docs/zh/docs/images/createScale.png b/docs/zh/docs/images/createScale.png new file mode 100644 index 0000000..29f523e Binary files /dev/null and b/docs/zh/docs/images/createScale.png differ diff --git a/docs/zh/docs/images/createScale02.png b/docs/zh/docs/images/createScale02.png new file mode 100644 index 0000000..da69f41 Binary files /dev/null and b/docs/zh/docs/images/createScale02.png differ diff --git a/docs/zh/docs/images/createScale02_1.png b/docs/zh/docs/images/createScale02_1.png new file mode 100644 index 0000000..da69f41 Binary files /dev/null and b/docs/zh/docs/images/createScale02_1.png differ diff --git a/docs/zh/docs/images/createScale07.png b/docs/zh/docs/images/createScale07.png new file mode 100644 index 0000000..e437599 Binary files /dev/null and b/docs/zh/docs/images/createScale07.png differ diff --git a/docs/zh/docs/images/createScale07_1.png b/docs/zh/docs/images/createScale07_1.png new file mode 100644 index 0000000..e437599 Binary files /dev/null and b/docs/zh/docs/images/createScale07_1.png differ diff --git a/docs/zh/docs/images/createScale08.png b/docs/zh/docs/images/createScale08.png new file mode 100644 index 0000000..b140e9f Binary files /dev/null and b/docs/zh/docs/images/createScale08.png differ diff --git a/docs/zh/docs/images/createScale09.png b/docs/zh/docs/images/createScale09.png new file mode 100644 index 0000000..491507d Binary files /dev/null and b/docs/zh/docs/images/createScale09.png differ diff --git a/docs/zh/docs/images/createScale10.png b/docs/zh/docs/images/createScale10.png new file mode 100644 index 0000000..cea2060 Binary files /dev/null and b/docs/zh/docs/images/createScale10.png differ diff --git a/docs/zh/docs/images/createScale_1.png b/docs/zh/docs/images/createScale_1.png new file mode 100644 index 0000000..29f523e Binary files /dev/null and b/docs/zh/docs/images/createScale_1.png differ diff --git a/docs/zh/docs/images/createcluster-ssh01.png b/docs/zh/docs/images/createcluster-ssh01.png new file mode 100644 index 0000000..fb104dc Binary files /dev/null and b/docs/zh/docs/images/createcluster-ssh01.png differ diff --git a/docs/zh/docs/images/createcluster07.png b/docs/zh/docs/images/createcluster07.png new file mode 100644 index 0000000..e3a7b9b Binary files /dev/null and b/docs/zh/docs/images/createcluster07.png differ diff --git a/docs/zh/docs/images/createnew01.png b/docs/zh/docs/images/createnew01.png new file mode 100644 index 0000000..d3c0199 Binary files /dev/null and b/docs/zh/docs/images/createnew01.png differ diff --git a/docs/zh/docs/images/createnew07.png b/docs/zh/docs/images/createnew07.png new file mode 100644 index 0000000..2fc5900 Binary files /dev/null and b/docs/zh/docs/images/createnew07.png differ diff --git a/docs/zh/docs/images/createuser01.png b/docs/zh/docs/images/createuser01.png new file mode 100644 index 0000000..26242f2 Binary files /dev/null and b/docs/zh/docs/images/createuser01.png differ diff --git a/docs/zh/docs/images/createuser02.png b/docs/zh/docs/images/createuser02.png new file mode 100644 index 0000000..46b3b9c Binary files /dev/null and b/docs/zh/docs/images/createuser02.png differ diff --git a/docs/zh/docs/images/createuser03.png b/docs/zh/docs/images/createuser03.png new file mode 100644 index 0000000..709f103 Binary files /dev/null and b/docs/zh/docs/images/createuser03.png differ diff --git a/docs/zh/docs/images/createvm02.png b/docs/zh/docs/images/createvm02.png new file mode 100644 index 0000000..23a1c91 Binary files /dev/null and b/docs/zh/docs/images/createvm02.png differ diff --git a/docs/zh/docs/images/createvm05.png b/docs/zh/docs/images/createvm05.png new file mode 100644 index 0000000..ffe7bd6 Binary files /dev/null and b/docs/zh/docs/images/createvm05.png differ diff --git a/docs/zh/docs/images/createvm07.png b/docs/zh/docs/images/createvm07.png new file mode 100644 index 0000000..4e48c1e Binary files /dev/null and b/docs/zh/docs/images/createvm07.png differ diff --git a/docs/zh/docs/images/createvm08.png b/docs/zh/docs/images/createvm08.png new file mode 100644 index 0000000..e1e0d62 Binary files /dev/null and b/docs/zh/docs/images/createvm08.png differ diff --git a/docs/zh/docs/images/createvm08_1.png b/docs/zh/docs/images/createvm08_1.png new file mode 100644 index 0000000..e1e0d62 Binary files /dev/null and b/docs/zh/docs/images/createvm08_1.png differ diff --git a/docs/zh/docs/images/creatnew03.png b/docs/zh/docs/images/creatnew03.png new file mode 100644 index 0000000..f34b710 Binary files /dev/null and b/docs/zh/docs/images/creatnew03.png differ diff --git a/docs/zh/docs/images/creatnew04.png b/docs/zh/docs/images/creatnew04.png new file mode 100644 index 0000000..6feac19 Binary files /dev/null and b/docs/zh/docs/images/creatnew04.png differ diff --git a/docs/zh/docs/images/creatnew05.png b/docs/zh/docs/images/creatnew05.png new file mode 100644 index 0000000..1bdeb28 Binary files /dev/null and b/docs/zh/docs/images/creatnew05.png differ diff --git a/docs/zh/docs/images/creatnew06.png b/docs/zh/docs/images/creatnew06.png new file mode 100644 index 0000000..8329c2c Binary files /dev/null and b/docs/zh/docs/images/creatnew06.png differ diff --git a/docs/zh/docs/images/cronjob01.png b/docs/zh/docs/images/cronjob01.png new file mode 100644 index 0000000..ad4881b Binary files /dev/null and b/docs/zh/docs/images/cronjob01.png differ diff --git a/docs/zh/docs/images/cronjob05.png b/docs/zh/docs/images/cronjob05.png new file mode 100644 index 0000000..1b20b32 Binary files /dev/null and b/docs/zh/docs/images/cronjob05.png differ diff --git a/docs/zh/docs/images/cronjob06.png b/docs/zh/docs/images/cronjob06.png new file mode 100644 index 0000000..3d414be Binary files /dev/null and b/docs/zh/docs/images/cronjob06.png differ diff --git a/docs/zh/docs/images/cronjob07.png b/docs/zh/docs/images/cronjob07.png new file mode 100644 index 0000000..4786ce9 Binary files /dev/null and b/docs/zh/docs/images/cronjob07.png differ diff --git a/docs/zh/docs/images/cronjob08.png b/docs/zh/docs/images/cronjob08.png new file mode 100644 index 0000000..6d3ea21 Binary files /dev/null and b/docs/zh/docs/images/cronjob08.png differ diff --git a/docs/zh/docs/images/cronjob08_1.png b/docs/zh/docs/images/cronjob08_1.png new file mode 100644 index 0000000..6d3ea21 Binary files /dev/null and b/docs/zh/docs/images/cronjob08_1.png differ diff --git a/docs/zh/docs/images/csv1.png b/docs/zh/docs/images/csv1.png new file mode 100644 index 0000000..facf3b9 Binary files /dev/null and b/docs/zh/docs/images/csv1.png differ diff --git a/docs/zh/docs/images/csv2.png b/docs/zh/docs/images/csv2.png new file mode 100644 index 0000000..f478bfb Binary files /dev/null and b/docs/zh/docs/images/csv2.png differ diff --git a/docs/zh/docs/images/custom01.png b/docs/zh/docs/images/custom01.png new file mode 100644 index 0000000..907de78 Binary files /dev/null and b/docs/zh/docs/images/custom01.png differ diff --git a/docs/zh/docs/images/custom01_1.png b/docs/zh/docs/images/custom01_1.png new file mode 100644 index 0000000..907de78 Binary files /dev/null and b/docs/zh/docs/images/custom01_1.png differ diff --git a/docs/zh/docs/images/custom01_2.png b/docs/zh/docs/images/custom01_2.png new file mode 100644 index 0000000..907de78 Binary files /dev/null and b/docs/zh/docs/images/custom01_2.png differ diff --git a/docs/zh/docs/images/custom02.png b/docs/zh/docs/images/custom02.png new file mode 100644 index 0000000..672382e Binary files /dev/null and b/docs/zh/docs/images/custom02.png differ diff --git a/docs/zh/docs/images/custom03.png b/docs/zh/docs/images/custom03.png new file mode 100644 index 0000000..44f7f87 Binary files /dev/null and b/docs/zh/docs/images/custom03.png differ diff --git a/docs/zh/docs/images/custom04.png b/docs/zh/docs/images/custom04.png new file mode 100644 index 0000000..57cbbcf Binary files /dev/null and b/docs/zh/docs/images/custom04.png differ diff --git a/docs/zh/docs/images/custom05.png b/docs/zh/docs/images/custom05.png new file mode 100644 index 0000000..fdd6aff Binary files /dev/null and b/docs/zh/docs/images/custom05.png differ diff --git a/docs/zh/docs/images/custom06.png b/docs/zh/docs/images/custom06.png new file mode 100644 index 0000000..70918be Binary files /dev/null and b/docs/zh/docs/images/custom06.png differ diff --git a/docs/zh/docs/images/custom07.png b/docs/zh/docs/images/custom07.png new file mode 100644 index 0000000..a5b1755 Binary files /dev/null and b/docs/zh/docs/images/custom07.png differ diff --git a/docs/zh/docs/images/daemon01.png b/docs/zh/docs/images/daemon01.png new file mode 100644 index 0000000..7b0c007 Binary files /dev/null and b/docs/zh/docs/images/daemon01.png differ diff --git a/docs/zh/docs/images/daemon02.png b/docs/zh/docs/images/daemon02.png new file mode 100644 index 0000000..d4161e8 Binary files /dev/null and b/docs/zh/docs/images/daemon02.png differ diff --git a/docs/zh/docs/images/daemon03.png b/docs/zh/docs/images/daemon03.png new file mode 100644 index 0000000..cb9ba4b Binary files /dev/null and b/docs/zh/docs/images/daemon03.png differ diff --git a/docs/zh/docs/images/daemon05.png b/docs/zh/docs/images/daemon05.png new file mode 100644 index 0000000..9cbc281 Binary files /dev/null and b/docs/zh/docs/images/daemon05.png differ diff --git a/docs/zh/docs/images/daemon06.png b/docs/zh/docs/images/daemon06.png new file mode 100644 index 0000000..beb4438 Binary files /dev/null and b/docs/zh/docs/images/daemon06.png differ diff --git a/docs/zh/docs/images/daemon07.png b/docs/zh/docs/images/daemon07.png new file mode 100644 index 0000000..89d029b Binary files /dev/null and b/docs/zh/docs/images/daemon07.png differ diff --git a/docs/zh/docs/images/daemon08.png b/docs/zh/docs/images/daemon08.png new file mode 100644 index 0000000..2635498 Binary files /dev/null and b/docs/zh/docs/images/daemon08.png differ diff --git a/docs/zh/docs/images/delete004.png b/docs/zh/docs/images/delete004.png new file mode 100644 index 0000000..e663c09 Binary files /dev/null and b/docs/zh/docs/images/delete004.png differ diff --git a/docs/zh/docs/images/deletegroup01.png b/docs/zh/docs/images/deletegroup01.png new file mode 100644 index 0000000..d74c820 Binary files /dev/null and b/docs/zh/docs/images/deletegroup01.png differ diff --git a/docs/zh/docs/images/deletegroup02.png b/docs/zh/docs/images/deletegroup02.png new file mode 100644 index 0000000..c419b49 Binary files /dev/null and b/docs/zh/docs/images/deletegroup02.png differ diff --git a/docs/zh/docs/images/deletegroup03.png b/docs/zh/docs/images/deletegroup03.png new file mode 100644 index 0000000..fafda4a Binary files /dev/null and b/docs/zh/docs/images/deletegroup03.png differ diff --git a/docs/zh/docs/images/deletenode01.png b/docs/zh/docs/images/deletenode01.png new file mode 100644 index 0000000..ddd9908 Binary files /dev/null and b/docs/zh/docs/images/deletenode01.png differ diff --git a/docs/zh/docs/images/deletenode02.png b/docs/zh/docs/images/deletenode02.png new file mode 100644 index 0000000..26b32e7 Binary files /dev/null and b/docs/zh/docs/images/deletenode02.png differ diff --git a/docs/zh/docs/images/deleteuser01.png b/docs/zh/docs/images/deleteuser01.png new file mode 100644 index 0000000..834d17e Binary files /dev/null and b/docs/zh/docs/images/deleteuser01.png differ diff --git a/docs/zh/docs/images/deleteuser02.png b/docs/zh/docs/images/deleteuser02.png new file mode 100644 index 0000000..71e5992 Binary files /dev/null and b/docs/zh/docs/images/deleteuser02.png differ diff --git a/docs/zh/docs/images/deploy01.png b/docs/zh/docs/images/deploy01.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01.png differ diff --git a/docs/zh/docs/images/deploy01_1.png b/docs/zh/docs/images/deploy01_1.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_1.png differ diff --git a/docs/zh/docs/images/deploy01_10.png b/docs/zh/docs/images/deploy01_10.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_10.png differ diff --git a/docs/zh/docs/images/deploy01_11.png b/docs/zh/docs/images/deploy01_11.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_11.png differ diff --git a/docs/zh/docs/images/deploy01_12.png b/docs/zh/docs/images/deploy01_12.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_12.png differ diff --git a/docs/zh/docs/images/deploy01_13.png b/docs/zh/docs/images/deploy01_13.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_13.png differ diff --git a/docs/zh/docs/images/deploy01_14.png b/docs/zh/docs/images/deploy01_14.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_14.png differ diff --git a/docs/zh/docs/images/deploy01_15.png b/docs/zh/docs/images/deploy01_15.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_15.png differ diff --git a/docs/zh/docs/images/deploy01_2.png b/docs/zh/docs/images/deploy01_2.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_2.png differ diff --git a/docs/zh/docs/images/deploy01_3.png b/docs/zh/docs/images/deploy01_3.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_3.png differ diff --git a/docs/zh/docs/images/deploy01_4.png b/docs/zh/docs/images/deploy01_4.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_4.png differ diff --git a/docs/zh/docs/images/deploy01_5.png b/docs/zh/docs/images/deploy01_5.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_5.png differ diff --git a/docs/zh/docs/images/deploy01_6.png b/docs/zh/docs/images/deploy01_6.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_6.png differ diff --git a/docs/zh/docs/images/deploy01_7.png b/docs/zh/docs/images/deploy01_7.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_7.png differ diff --git a/docs/zh/docs/images/deploy01_8.png b/docs/zh/docs/images/deploy01_8.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_8.png differ diff --git a/docs/zh/docs/images/deploy01_9.png b/docs/zh/docs/images/deploy01_9.png new file mode 100644 index 0000000..604133f Binary files /dev/null and b/docs/zh/docs/images/deploy01_9.png differ diff --git a/docs/zh/docs/images/deploy02.png b/docs/zh/docs/images/deploy02.png new file mode 100644 index 0000000..8cee240 Binary files /dev/null and b/docs/zh/docs/images/deploy02.png differ diff --git a/docs/zh/docs/images/deploy02Yaml.png b/docs/zh/docs/images/deploy02Yaml.png new file mode 100644 index 0000000..6fc8d79 Binary files /dev/null and b/docs/zh/docs/images/deploy02Yaml.png differ diff --git a/docs/zh/docs/images/deploy02Yaml_1.png b/docs/zh/docs/images/deploy02Yaml_1.png new file mode 100644 index 0000000..6fc8d79 Binary files /dev/null and b/docs/zh/docs/images/deploy02Yaml_1.png differ diff --git a/docs/zh/docs/images/deploy03yaml.png b/docs/zh/docs/images/deploy03yaml.png new file mode 100644 index 0000000..ba322a7 Binary files /dev/null and b/docs/zh/docs/images/deploy03yaml.png differ diff --git a/docs/zh/docs/images/deploy04.png b/docs/zh/docs/images/deploy04.png new file mode 100644 index 0000000..c95184d Binary files /dev/null and b/docs/zh/docs/images/deploy04.png differ diff --git a/docs/zh/docs/images/deploy06.png b/docs/zh/docs/images/deploy06.png new file mode 100644 index 0000000..8463bf7 Binary files /dev/null and b/docs/zh/docs/images/deploy06.png differ diff --git a/docs/zh/docs/images/deploy06_1.png b/docs/zh/docs/images/deploy06_1.png new file mode 100644 index 0000000..8463bf7 Binary files /dev/null and b/docs/zh/docs/images/deploy06_1.png differ diff --git a/docs/zh/docs/images/deploy06_2.png b/docs/zh/docs/images/deploy06_2.png new file mode 100644 index 0000000..8463bf7 Binary files /dev/null and b/docs/zh/docs/images/deploy06_2.png differ diff --git a/docs/zh/docs/images/deploy06_3.png b/docs/zh/docs/images/deploy06_3.png new file mode 100644 index 0000000..8463bf7 Binary files /dev/null and b/docs/zh/docs/images/deploy06_3.png differ diff --git a/docs/zh/docs/images/deploy06_4.png b/docs/zh/docs/images/deploy06_4.png new file mode 100644 index 0000000..8463bf7 Binary files /dev/null and b/docs/zh/docs/images/deploy06_4.png differ diff --git a/docs/zh/docs/images/deploy07.png b/docs/zh/docs/images/deploy07.png new file mode 100644 index 0000000..8bab4e9 Binary files /dev/null and b/docs/zh/docs/images/deploy07.png differ diff --git a/docs/zh/docs/images/deploy07_1.png b/docs/zh/docs/images/deploy07_1.png new file mode 100644 index 0000000..8bab4e9 Binary files /dev/null and b/docs/zh/docs/images/deploy07_1.png differ diff --git a/docs/zh/docs/images/deploy07_2.png b/docs/zh/docs/images/deploy07_2.png new file mode 100644 index 0000000..8bab4e9 Binary files /dev/null and b/docs/zh/docs/images/deploy07_2.png differ diff --git a/docs/zh/docs/images/deploy07_3.png b/docs/zh/docs/images/deploy07_3.png new file mode 100644 index 0000000..8bab4e9 Binary files /dev/null and b/docs/zh/docs/images/deploy07_3.png differ diff --git a/docs/zh/docs/images/deploy07_4.png b/docs/zh/docs/images/deploy07_4.png new file mode 100644 index 0000000..8bab4e9 Binary files /dev/null and b/docs/zh/docs/images/deploy07_4.png differ diff --git a/docs/zh/docs/images/deploy08.png b/docs/zh/docs/images/deploy08.png new file mode 100644 index 0000000..9a00da4 Binary files /dev/null and b/docs/zh/docs/images/deploy08.png differ diff --git a/docs/zh/docs/images/deploy08_1.png b/docs/zh/docs/images/deploy08_1.png new file mode 100644 index 0000000..9a00da4 Binary files /dev/null and b/docs/zh/docs/images/deploy08_1.png differ diff --git a/docs/zh/docs/images/deploy08_2.png b/docs/zh/docs/images/deploy08_2.png new file mode 100644 index 0000000..9a00da4 Binary files /dev/null and b/docs/zh/docs/images/deploy08_2.png differ diff --git a/docs/zh/docs/images/deploy08_3.png b/docs/zh/docs/images/deploy08_3.png new file mode 100644 index 0000000..9a00da4 Binary files /dev/null and b/docs/zh/docs/images/deploy08_3.png differ diff --git a/docs/zh/docs/images/deploy08_4.png b/docs/zh/docs/images/deploy08_4.png new file mode 100644 index 0000000..9a00da4 Binary files /dev/null and b/docs/zh/docs/images/deploy08_4.png differ diff --git a/docs/zh/docs/images/deploy09.png b/docs/zh/docs/images/deploy09.png new file mode 100644 index 0000000..7bee4d8 Binary files /dev/null and b/docs/zh/docs/images/deploy09.png differ diff --git a/docs/zh/docs/images/deploy09_1.png b/docs/zh/docs/images/deploy09_1.png new file mode 100644 index 0000000..7bee4d8 Binary files /dev/null and b/docs/zh/docs/images/deploy09_1.png differ diff --git a/docs/zh/docs/images/deploy09_2.png b/docs/zh/docs/images/deploy09_2.png new file mode 100644 index 0000000..7bee4d8 Binary files /dev/null and b/docs/zh/docs/images/deploy09_2.png differ diff --git a/docs/zh/docs/images/deploy09_3.png b/docs/zh/docs/images/deploy09_3.png new file mode 100644 index 0000000..7bee4d8 Binary files /dev/null and b/docs/zh/docs/images/deploy09_3.png differ diff --git a/docs/zh/docs/images/deploy09_4.png b/docs/zh/docs/images/deploy09_4.png new file mode 100644 index 0000000..7bee4d8 Binary files /dev/null and b/docs/zh/docs/images/deploy09_4.png differ diff --git a/docs/zh/docs/images/deploy10.png b/docs/zh/docs/images/deploy10.png new file mode 100644 index 0000000..eed1841 Binary files /dev/null and b/docs/zh/docs/images/deploy10.png differ diff --git a/docs/zh/docs/images/deploy10_1.png b/docs/zh/docs/images/deploy10_1.png new file mode 100644 index 0000000..eed1841 Binary files /dev/null and b/docs/zh/docs/images/deploy10_1.png differ diff --git a/docs/zh/docs/images/deploy10_2.png b/docs/zh/docs/images/deploy10_2.png new file mode 100644 index 0000000..eed1841 Binary files /dev/null and b/docs/zh/docs/images/deploy10_2.png differ diff --git a/docs/zh/docs/images/deploy10_3.png b/docs/zh/docs/images/deploy10_3.png new file mode 100644 index 0000000..eed1841 Binary files /dev/null and b/docs/zh/docs/images/deploy10_3.png differ diff --git a/docs/zh/docs/images/deploy10_4.png b/docs/zh/docs/images/deploy10_4.png new file mode 100644 index 0000000..eed1841 Binary files /dev/null and b/docs/zh/docs/images/deploy10_4.png differ diff --git a/docs/zh/docs/images/deploy12.png b/docs/zh/docs/images/deploy12.png new file mode 100644 index 0000000..aa9d2bf Binary files /dev/null and b/docs/zh/docs/images/deploy12.png differ diff --git a/docs/zh/docs/images/deploy13.png b/docs/zh/docs/images/deploy13.png new file mode 100644 index 0000000..dfbb16a Binary files /dev/null and b/docs/zh/docs/images/deploy13.png differ diff --git a/docs/zh/docs/images/deploy13_1.png b/docs/zh/docs/images/deploy13_1.png new file mode 100644 index 0000000..dfbb16a Binary files /dev/null and b/docs/zh/docs/images/deploy13_1.png differ diff --git a/docs/zh/docs/images/deploy13_2.png b/docs/zh/docs/images/deploy13_2.png new file mode 100644 index 0000000..dfbb16a Binary files /dev/null and b/docs/zh/docs/images/deploy13_2.png differ diff --git a/docs/zh/docs/images/deploy13_3.png b/docs/zh/docs/images/deploy13_3.png new file mode 100644 index 0000000..dfbb16a Binary files /dev/null and b/docs/zh/docs/images/deploy13_3.png differ diff --git a/docs/zh/docs/images/deploy14.png b/docs/zh/docs/images/deploy14.png new file mode 100644 index 0000000..78e06c9 Binary files /dev/null and b/docs/zh/docs/images/deploy14.png differ diff --git a/docs/zh/docs/images/deploy14_1.png b/docs/zh/docs/images/deploy14_1.png new file mode 100644 index 0000000..78e06c9 Binary files /dev/null and b/docs/zh/docs/images/deploy14_1.png differ diff --git a/docs/zh/docs/images/deploy15.png b/docs/zh/docs/images/deploy15.png new file mode 100644 index 0000000..b82ff9a Binary files /dev/null and b/docs/zh/docs/images/deploy15.png differ diff --git a/docs/zh/docs/images/deploy15_1.png b/docs/zh/docs/images/deploy15_1.png new file mode 100644 index 0000000..b82ff9a Binary files /dev/null and b/docs/zh/docs/images/deploy15_1.png differ diff --git a/docs/zh/docs/images/deploy16.png b/docs/zh/docs/images/deploy16.png new file mode 100644 index 0000000..971f701 Binary files /dev/null and b/docs/zh/docs/images/deploy16.png differ diff --git a/docs/zh/docs/images/deploy16_1.png b/docs/zh/docs/images/deploy16_1.png new file mode 100644 index 0000000..971f701 Binary files /dev/null and b/docs/zh/docs/images/deploy16_1.png differ diff --git a/docs/zh/docs/images/deploy17.png b/docs/zh/docs/images/deploy17.png new file mode 100644 index 0000000..9fd9571 Binary files /dev/null and b/docs/zh/docs/images/deploy17.png differ diff --git a/docs/zh/docs/images/deploy17_1.png b/docs/zh/docs/images/deploy17_1.png new file mode 100644 index 0000000..9fd9571 Binary files /dev/null and b/docs/zh/docs/images/deploy17_1.png differ diff --git a/docs/zh/docs/images/deploy17_2.png b/docs/zh/docs/images/deploy17_2.png new file mode 100644 index 0000000..9fd9571 Binary files /dev/null and b/docs/zh/docs/images/deploy17_2.png differ diff --git a/docs/zh/docs/images/deploy18.png b/docs/zh/docs/images/deploy18.png new file mode 100644 index 0000000..4819dce Binary files /dev/null and b/docs/zh/docs/images/deploy18.png differ diff --git a/docs/zh/docs/images/edit b/docs/zh/docs/images/edit new file mode 100644 index 0000000..ae67449 --- /dev/null +++ b/docs/zh/docs/images/edit @@ -0,0 +1,145 @@ +[External] Steps to Enable MIG Support in Kubernetes - Google Docs
\ No newline at end of file diff --git a/docs/zh/docs/images/enableuser.png b/docs/zh/docs/images/enableuser.png new file mode 100644 index 0000000..e1708c5 Binary files /dev/null and b/docs/zh/docs/images/enableuser.png differ diff --git a/docs/zh/docs/images/enableuser_1.png b/docs/zh/docs/images/enableuser_1.png new file mode 100644 index 0000000..e1708c5 Binary files /dev/null and b/docs/zh/docs/images/enableuser_1.png differ diff --git a/docs/zh/docs/images/etcd-get01.png b/docs/zh/docs/images/etcd-get01.png new file mode 100644 index 0000000..5b9b202 Binary files /dev/null and b/docs/zh/docs/images/etcd-get01.png differ diff --git a/docs/zh/docs/images/etcd01.png b/docs/zh/docs/images/etcd01.png new file mode 100644 index 0000000..0d6476d Binary files /dev/null and b/docs/zh/docs/images/etcd01.png differ diff --git a/docs/zh/docs/images/etcd04.png b/docs/zh/docs/images/etcd04.png new file mode 100644 index 0000000..f494b38 Binary files /dev/null and b/docs/zh/docs/images/etcd04.png differ diff --git a/docs/zh/docs/images/etcd05.png b/docs/zh/docs/images/etcd05.png new file mode 100644 index 0000000..770b6e7 Binary files /dev/null and b/docs/zh/docs/images/etcd05.png differ diff --git a/docs/zh/docs/images/etcd06.png b/docs/zh/docs/images/etcd06.png new file mode 100644 index 0000000..528d3e5 Binary files /dev/null and b/docs/zh/docs/images/etcd06.png differ diff --git a/docs/zh/docs/images/etcd07.png b/docs/zh/docs/images/etcd07.png new file mode 100644 index 0000000..9e9f725 Binary files /dev/null and b/docs/zh/docs/images/etcd07.png differ diff --git a/docs/zh/docs/images/etcd08.png b/docs/zh/docs/images/etcd08.png new file mode 100644 index 0000000..002d0c5 Binary files /dev/null and b/docs/zh/docs/images/etcd08.png differ diff --git a/docs/zh/docs/images/etcd09.png b/docs/zh/docs/images/etcd09.png new file mode 100644 index 0000000..d5cfbeb Binary files /dev/null and b/docs/zh/docs/images/etcd09.png differ diff --git a/docs/zh/docs/images/exclusive01.png b/docs/zh/docs/images/exclusive01.png new file mode 100644 index 0000000..e76fbdf Binary files /dev/null and b/docs/zh/docs/images/exclusive01.png differ diff --git a/docs/zh/docs/images/exclusive01_1.png b/docs/zh/docs/images/exclusive01_1.png new file mode 100644 index 0000000..e76fbdf Binary files /dev/null and b/docs/zh/docs/images/exclusive01_1.png differ diff --git a/docs/zh/docs/images/exclusive02.png b/docs/zh/docs/images/exclusive02.png new file mode 100644 index 0000000..dc5124d Binary files /dev/null and b/docs/zh/docs/images/exclusive02.png differ diff --git a/docs/zh/docs/images/exclusive02_1.png b/docs/zh/docs/images/exclusive02_1.png new file mode 100644 index 0000000..dc5124d Binary files /dev/null and b/docs/zh/docs/images/exclusive02_1.png differ diff --git a/docs/zh/docs/images/exclusive03.png b/docs/zh/docs/images/exclusive03.png new file mode 100644 index 0000000..653c0ec Binary files /dev/null and b/docs/zh/docs/images/exclusive03.png differ diff --git a/docs/zh/docs/images/exclusive03_1.png b/docs/zh/docs/images/exclusive03_1.png new file mode 100644 index 0000000..653c0ec Binary files /dev/null and b/docs/zh/docs/images/exclusive03_1.png differ diff --git a/docs/zh/docs/images/exclusive04.png b/docs/zh/docs/images/exclusive04.png new file mode 100644 index 0000000..32cf7d2 Binary files /dev/null and b/docs/zh/docs/images/exclusive04.png differ diff --git a/docs/zh/docs/images/exclusive04_1.png b/docs/zh/docs/images/exclusive04_1.png new file mode 100644 index 0000000..32cf7d2 Binary files /dev/null and b/docs/zh/docs/images/exclusive04_1.png differ diff --git a/docs/zh/docs/images/falco-exporter-install-1.png b/docs/zh/docs/images/falco-exporter-install-1.png new file mode 100644 index 0000000..371093a Binary files /dev/null and b/docs/zh/docs/images/falco-exporter-install-1.png differ diff --git a/docs/zh/docs/images/falco-exporter-install-2.png b/docs/zh/docs/images/falco-exporter-install-2.png new file mode 100644 index 0000000..0d8a176 Binary files /dev/null and b/docs/zh/docs/images/falco-exporter-install-2.png differ diff --git a/docs/zh/docs/images/falco-exporter-install-3.png b/docs/zh/docs/images/falco-exporter-install-3.png new file mode 100644 index 0000000..8137208 Binary files /dev/null and b/docs/zh/docs/images/falco-exporter-install-3.png differ diff --git a/docs/zh/docs/images/falco-exporter-install-4.png b/docs/zh/docs/images/falco-exporter-install-4.png new file mode 100644 index 0000000..2c34bf0 Binary files /dev/null and b/docs/zh/docs/images/falco-exporter-install-4.png differ diff --git a/docs/zh/docs/images/falco-exporter-install-5.png b/docs/zh/docs/images/falco-exporter-install-5.png new file mode 100644 index 0000000..d7d8586 Binary files /dev/null and b/docs/zh/docs/images/falco-exporter-install-5.png differ diff --git a/docs/zh/docs/images/falco-exporter-install-6.png b/docs/zh/docs/images/falco-exporter-install-6.png new file mode 100644 index 0000000..e326082 Binary files /dev/null and b/docs/zh/docs/images/falco-exporter-install-6.png differ diff --git a/docs/zh/docs/images/falco-install-1.png b/docs/zh/docs/images/falco-install-1.png new file mode 100644 index 0000000..9f001a8 Binary files /dev/null and b/docs/zh/docs/images/falco-install-1.png differ diff --git a/docs/zh/docs/images/falco-install-2.png b/docs/zh/docs/images/falco-install-2.png new file mode 100644 index 0000000..20f19de Binary files /dev/null and b/docs/zh/docs/images/falco-install-2.png differ diff --git a/docs/zh/docs/images/falco-install-3.png b/docs/zh/docs/images/falco-install-3.png new file mode 100644 index 0000000..82bf30b Binary files /dev/null and b/docs/zh/docs/images/falco-install-3.png differ diff --git a/docs/zh/docs/images/falco-install-4.png b/docs/zh/docs/images/falco-install-4.png new file mode 100644 index 0000000..8dd1ee0 Binary files /dev/null and b/docs/zh/docs/images/falco-install-4.png differ diff --git a/docs/zh/docs/images/falco_cluster.png b/docs/zh/docs/images/falco_cluster.png new file mode 100644 index 0000000..d4d4101 Binary files /dev/null and b/docs/zh/docs/images/falco_cluster.png differ diff --git a/docs/zh/docs/images/falco_cluster_1.png b/docs/zh/docs/images/falco_cluster_1.png new file mode 100644 index 0000000..d4d4101 Binary files /dev/null and b/docs/zh/docs/images/falco_cluster_1.png differ diff --git a/docs/zh/docs/images/favicon.ico b/docs/zh/docs/images/favicon.ico new file mode 100644 index 0000000..a6e4cd4 Binary files /dev/null and b/docs/zh/docs/images/favicon.ico differ diff --git a/docs/zh/docs/images/favicon1.ico b/docs/zh/docs/images/favicon1.ico new file mode 100644 index 0000000..5642350 Binary files /dev/null and b/docs/zh/docs/images/favicon1.ico differ diff --git a/docs/zh/docs/images/fd02.png b/docs/zh/docs/images/fd02.png new file mode 100644 index 0000000..fb3f8ce Binary files /dev/null and b/docs/zh/docs/images/fd02.png differ diff --git a/docs/zh/docs/images/fd03.png b/docs/zh/docs/images/fd03.png new file mode 100644 index 0000000..5661464 Binary files /dev/null and b/docs/zh/docs/images/fd03.png differ diff --git a/docs/zh/docs/images/fdpractice.png b/docs/zh/docs/images/fdpractice.png new file mode 100644 index 0000000..33fefd4 Binary files /dev/null and b/docs/zh/docs/images/fdpractice.png differ diff --git a/docs/zh/docs/images/gmagpiereport.png b/docs/zh/docs/images/gmagpiereport.png new file mode 100644 index 0000000..f9505d2 Binary files /dev/null and b/docs/zh/docs/images/gmagpiereport.png differ diff --git a/docs/zh/docs/images/gpu_mig03.png b/docs/zh/docs/images/gpu_mig03.png new file mode 100644 index 0000000..3b6ae6b Binary files /dev/null and b/docs/zh/docs/images/gpu_mig03.png differ diff --git a/docs/zh/docs/images/group00.png b/docs/zh/docs/images/group00.png new file mode 100644 index 0000000..7c019e6 Binary files /dev/null and b/docs/zh/docs/images/group00.png differ diff --git a/docs/zh/docs/images/group01.png b/docs/zh/docs/images/group01.png new file mode 100644 index 0000000..426efd4 Binary files /dev/null and b/docs/zh/docs/images/group01.png differ diff --git a/docs/zh/docs/images/group02.png b/docs/zh/docs/images/group02.png new file mode 100644 index 0000000..fc6f1c2 Binary files /dev/null and b/docs/zh/docs/images/group02.png differ diff --git a/docs/zh/docs/images/group03.png b/docs/zh/docs/images/group03.png new file mode 100644 index 0000000..4fb0522 Binary files /dev/null and b/docs/zh/docs/images/group03.png differ diff --git a/docs/zh/docs/images/group04.png b/docs/zh/docs/images/group04.png new file mode 100644 index 0000000..d887759 Binary files /dev/null and b/docs/zh/docs/images/group04.png differ diff --git a/docs/zh/docs/images/group05.png b/docs/zh/docs/images/group05.png new file mode 100644 index 0000000..35dcd4e Binary files /dev/null and b/docs/zh/docs/images/group05.png differ diff --git a/docs/zh/docs/images/group06.png b/docs/zh/docs/images/group06.png new file mode 100644 index 0000000..6f8eeeb Binary files /dev/null and b/docs/zh/docs/images/group06.png differ diff --git a/docs/zh/docs/images/helm01.png b/docs/zh/docs/images/helm01.png new file mode 100644 index 0000000..5cc8f6d Binary files /dev/null and b/docs/zh/docs/images/helm01.png differ diff --git a/docs/zh/docs/images/helm02.png b/docs/zh/docs/images/helm02.png new file mode 100644 index 0000000..7dc3dca Binary files /dev/null and b/docs/zh/docs/images/helm02.png differ diff --git a/docs/zh/docs/images/helm03.png b/docs/zh/docs/images/helm03.png new file mode 100644 index 0000000..023c361 Binary files /dev/null and b/docs/zh/docs/images/helm03.png differ diff --git a/docs/zh/docs/images/helm04.png b/docs/zh/docs/images/helm04.png new file mode 100644 index 0000000..dabb1d6 Binary files /dev/null and b/docs/zh/docs/images/helm04.png differ diff --git a/docs/zh/docs/images/helm05.png b/docs/zh/docs/images/helm05.png new file mode 100644 index 0000000..31c287d Binary files /dev/null and b/docs/zh/docs/images/helm05.png differ diff --git a/docs/zh/docs/images/helm06.png b/docs/zh/docs/images/helm06.png new file mode 100644 index 0000000..ff986ee Binary files /dev/null and b/docs/zh/docs/images/helm06.png differ diff --git a/docs/zh/docs/images/helm07.png b/docs/zh/docs/images/helm07.png new file mode 100644 index 0000000..939b100 Binary files /dev/null and b/docs/zh/docs/images/helm07.png differ diff --git a/docs/zh/docs/images/helm08.png b/docs/zh/docs/images/helm08.png new file mode 100644 index 0000000..0868983 Binary files /dev/null and b/docs/zh/docs/images/helm08.png differ diff --git a/docs/zh/docs/images/helm09.png b/docs/zh/docs/images/helm09.png new file mode 100644 index 0000000..eb80566 Binary files /dev/null and b/docs/zh/docs/images/helm09.png differ diff --git a/docs/zh/docs/images/helm10.png b/docs/zh/docs/images/helm10.png new file mode 100644 index 0000000..a4acff6 Binary files /dev/null and b/docs/zh/docs/images/helm10.png differ diff --git a/docs/zh/docs/images/helm11.png b/docs/zh/docs/images/helm11.png new file mode 100644 index 0000000..8bc0d50 Binary files /dev/null and b/docs/zh/docs/images/helm11.png differ diff --git a/docs/zh/docs/images/helm12.png b/docs/zh/docs/images/helm12.png new file mode 100644 index 0000000..08cefee Binary files /dev/null and b/docs/zh/docs/images/helm12.png differ diff --git a/docs/zh/docs/images/helm13.png b/docs/zh/docs/images/helm13.png new file mode 100644 index 0000000..0854b37 Binary files /dev/null and b/docs/zh/docs/images/helm13.png differ diff --git a/docs/zh/docs/images/helm14.png b/docs/zh/docs/images/helm14.png new file mode 100644 index 0000000..6b1a16b Binary files /dev/null and b/docs/zh/docs/images/helm14.png differ diff --git a/docs/zh/docs/images/helm2048.png b/docs/zh/docs/images/helm2048.png new file mode 100644 index 0000000..98aa448 Binary files /dev/null and b/docs/zh/docs/images/helm2048.png differ diff --git a/docs/zh/docs/images/helmdetail.png b/docs/zh/docs/images/helmdetail.png new file mode 100644 index 0000000..7d9bab9 Binary files /dev/null and b/docs/zh/docs/images/helmdetail.png differ diff --git a/docs/zh/docs/images/helmlist.png b/docs/zh/docs/images/helmlist.png new file mode 100644 index 0000000..0d280b2 Binary files /dev/null and b/docs/zh/docs/images/helmlist.png differ diff --git a/docs/zh/docs/images/helmsyn.png b/docs/zh/docs/images/helmsyn.png new file mode 100644 index 0000000..b55501f Binary files /dev/null and b/docs/zh/docs/images/helmsyn.png differ diff --git a/docs/zh/docs/images/iam.png b/docs/zh/docs/images/iam.png new file mode 100644 index 0000000..7cd3f31 Binary files /dev/null and b/docs/zh/docs/images/iam.png differ diff --git a/docs/zh/docs/images/ingress.svg b/docs/zh/docs/images/ingress.svg new file mode 100644 index 0000000..450a0aa --- /dev/null +++ b/docs/zh/docs/images/ingress.svg @@ -0,0 +1 @@ +
cluster
Ingress-managed
load balancer
routing rule
Ingress
Pod
Service
Pod
client
\ No newline at end of file diff --git a/docs/zh/docs/images/ingress01.png b/docs/zh/docs/images/ingress01.png new file mode 100644 index 0000000..8c80aa6 Binary files /dev/null and b/docs/zh/docs/images/ingress01.png differ diff --git a/docs/zh/docs/images/ingress02.png b/docs/zh/docs/images/ingress02.png new file mode 100644 index 0000000..45e9731 Binary files /dev/null and b/docs/zh/docs/images/ingress02.png differ diff --git a/docs/zh/docs/images/ingress03.png b/docs/zh/docs/images/ingress03.png new file mode 100644 index 0000000..04abd5d Binary files /dev/null and b/docs/zh/docs/images/ingress03.png differ diff --git a/docs/zh/docs/images/ingress04.png b/docs/zh/docs/images/ingress04.png new file mode 100644 index 0000000..3b0b44b Binary files /dev/null and b/docs/zh/docs/images/ingress04.png differ diff --git a/docs/zh/docs/images/ingress05.png b/docs/zh/docs/images/ingress05.png new file mode 100644 index 0000000..c3220c5 Binary files /dev/null and b/docs/zh/docs/images/ingress05.png differ diff --git a/docs/zh/docs/images/inspect01.png b/docs/zh/docs/images/inspect01.png new file mode 100644 index 0000000..9f9a187 Binary files /dev/null and b/docs/zh/docs/images/inspect01.png differ diff --git a/docs/zh/docs/images/inspect03.png b/docs/zh/docs/images/inspect03.png new file mode 100644 index 0000000..74fe6b3 Binary files /dev/null and b/docs/zh/docs/images/inspect03.png differ diff --git a/docs/zh/docs/images/inspect05.png b/docs/zh/docs/images/inspect05.png new file mode 100644 index 0000000..36b5e4f Binary files /dev/null and b/docs/zh/docs/images/inspect05.png differ diff --git a/docs/zh/docs/images/installcronhpa.png b/docs/zh/docs/images/installcronhpa.png new file mode 100644 index 0000000..6675a13 Binary files /dev/null and b/docs/zh/docs/images/installcronhpa.png differ diff --git a/docs/zh/docs/images/installcronhpa1.png b/docs/zh/docs/images/installcronhpa1.png new file mode 100644 index 0000000..10db2e8 Binary files /dev/null and b/docs/zh/docs/images/installcronhpa1.png differ diff --git a/docs/zh/docs/images/installcronhpa2.png b/docs/zh/docs/images/installcronhpa2.png new file mode 100644 index 0000000..e2df9eb Binary files /dev/null and b/docs/zh/docs/images/installcronhpa2.png differ diff --git a/docs/zh/docs/images/installcronhpa3.png b/docs/zh/docs/images/installcronhpa3.png new file mode 100644 index 0000000..4c0a68a Binary files /dev/null and b/docs/zh/docs/images/installcronhpa3.png differ diff --git a/docs/zh/docs/images/job01.png b/docs/zh/docs/images/job01.png new file mode 100644 index 0000000..8805b79 Binary files /dev/null and b/docs/zh/docs/images/job01.png differ diff --git a/docs/zh/docs/images/job02-1.png b/docs/zh/docs/images/job02-1.png new file mode 100644 index 0000000..e81b33e Binary files /dev/null and b/docs/zh/docs/images/job02-1.png differ diff --git a/docs/zh/docs/images/job02.png b/docs/zh/docs/images/job02.png new file mode 100644 index 0000000..b494ee6 Binary files /dev/null and b/docs/zh/docs/images/job02.png differ diff --git a/docs/zh/docs/images/job03.png b/docs/zh/docs/images/job03.png new file mode 100644 index 0000000..d2b816f Binary files /dev/null and b/docs/zh/docs/images/job03.png differ diff --git a/docs/zh/docs/images/job04.png b/docs/zh/docs/images/job04.png new file mode 100644 index 0000000..c25a51b Binary files /dev/null and b/docs/zh/docs/images/job04.png differ diff --git a/docs/zh/docs/images/job08.png b/docs/zh/docs/images/job08.png new file mode 100644 index 0000000..fdf9a5d Binary files /dev/null and b/docs/zh/docs/images/job08.png differ diff --git a/docs/zh/docs/images/job09.png b/docs/zh/docs/images/job09.png new file mode 100644 index 0000000..7e46001 Binary files /dev/null and b/docs/zh/docs/images/job09.png differ diff --git a/docs/zh/docs/images/join001.png b/docs/zh/docs/images/join001.png new file mode 100644 index 0000000..f2e3fd9 Binary files /dev/null and b/docs/zh/docs/images/join001.png differ diff --git a/docs/zh/docs/images/join002.png b/docs/zh/docs/images/join002.png new file mode 100644 index 0000000..2999752 Binary files /dev/null and b/docs/zh/docs/images/join002.png differ diff --git a/docs/zh/docs/images/join003.png b/docs/zh/docs/images/join003.png new file mode 100644 index 0000000..386aabe Binary files /dev/null and b/docs/zh/docs/images/join003.png differ diff --git a/docs/zh/docs/images/joingroup01.png b/docs/zh/docs/images/joingroup01.png new file mode 100644 index 0000000..75eea82 Binary files /dev/null and b/docs/zh/docs/images/joingroup01.png differ diff --git a/docs/zh/docs/images/joingroup02.png b/docs/zh/docs/images/joingroup02.png new file mode 100644 index 0000000..63b680f Binary files /dev/null and b/docs/zh/docs/images/joingroup02.png differ diff --git a/docs/zh/docs/images/labels01.png b/docs/zh/docs/images/labels01.png new file mode 100644 index 0000000..587bade Binary files /dev/null and b/docs/zh/docs/images/labels01.png differ diff --git a/docs/zh/docs/images/labels02.png b/docs/zh/docs/images/labels02.png new file mode 100644 index 0000000..1ae7e17 Binary files /dev/null and b/docs/zh/docs/images/labels02.png differ diff --git a/docs/zh/docs/images/lang00.png b/docs/zh/docs/images/lang00.png new file mode 100644 index 0000000..7e9eeee Binary files /dev/null and b/docs/zh/docs/images/lang00.png differ diff --git a/docs/zh/docs/images/lang01.png b/docs/zh/docs/images/lang01.png new file mode 100644 index 0000000..6e9a6e7 Binary files /dev/null and b/docs/zh/docs/images/lang01.png differ diff --git a/docs/zh/docs/images/lang01_1.png b/docs/zh/docs/images/lang01_1.png new file mode 100644 index 0000000..6e9a6e7 Binary files /dev/null and b/docs/zh/docs/images/lang01_1.png differ diff --git a/docs/zh/docs/images/lang02.png b/docs/zh/docs/images/lang02.png new file mode 100644 index 0000000..0f623f5 Binary files /dev/null and b/docs/zh/docs/images/lang02.png differ diff --git a/docs/zh/docs/images/lang03.png b/docs/zh/docs/images/lang03.png new file mode 100644 index 0000000..465270e Binary files /dev/null and b/docs/zh/docs/images/lang03.png differ diff --git a/docs/zh/docs/images/ldap02.png b/docs/zh/docs/images/ldap02.png new file mode 100644 index 0000000..3639210 Binary files /dev/null and b/docs/zh/docs/images/ldap02.png differ diff --git a/docs/zh/docs/images/mail01.png b/docs/zh/docs/images/mail01.png new file mode 100644 index 0000000..0910c6e Binary files /dev/null and b/docs/zh/docs/images/mail01.png differ diff --git a/docs/zh/docs/images/mail02.png b/docs/zh/docs/images/mail02.png new file mode 100644 index 0000000..9577030 Binary files /dev/null and b/docs/zh/docs/images/mail02.png differ diff --git a/docs/zh/docs/images/mail03.png b/docs/zh/docs/images/mail03.png new file mode 100644 index 0000000..ae7aeee Binary files /dev/null and b/docs/zh/docs/images/mail03.png differ diff --git a/docs/zh/docs/images/mailbox.png b/docs/zh/docs/images/mailbox.png new file mode 100644 index 0000000..5d7ec89 Binary files /dev/null and b/docs/zh/docs/images/mailbox.png differ diff --git a/docs/zh/docs/images/mig2c.4g.20gb.png b/docs/zh/docs/images/mig2c.4g.20gb.png new file mode 100644 index 0000000..f55e9c9 Binary files /dev/null and b/docs/zh/docs/images/mig2c.4g.20gb.png differ diff --git a/docs/zh/docs/images/mig_1c.4g.20gb.png b/docs/zh/docs/images/mig_1c.4g.20gb.png new file mode 100644 index 0000000..93f3027 Binary files /dev/null and b/docs/zh/docs/images/mig_1c.4g.20gb.png differ diff --git a/docs/zh/docs/images/mig_1g5gb.png b/docs/zh/docs/images/mig_1g5gb.png new file mode 100644 index 0000000..cd20462 Binary files /dev/null and b/docs/zh/docs/images/mig_1g5gb.png differ diff --git a/docs/zh/docs/images/mig_4g20gb.png b/docs/zh/docs/images/mig_4g20gb.png new file mode 100644 index 0000000..b4c640f Binary files /dev/null and b/docs/zh/docs/images/mig_4g20gb.png differ diff --git a/docs/zh/docs/images/mig_7m.png b/docs/zh/docs/images/mig_7m.png new file mode 100644 index 0000000..82698f9 Binary files /dev/null and b/docs/zh/docs/images/mig_7m.png differ diff --git a/docs/zh/docs/images/mig_overview.png b/docs/zh/docs/images/mig_overview.png new file mode 100644 index 0000000..d20cf55 Binary files /dev/null and b/docs/zh/docs/images/mig_overview.png differ diff --git a/docs/zh/docs/images/multi-arch-helm.png b/docs/zh/docs/images/multi-arch-helm.png new file mode 100644 index 0000000..b10340e Binary files /dev/null and b/docs/zh/docs/images/multi-arch-helm.png differ diff --git a/docs/zh/docs/images/networkpolicy01.png b/docs/zh/docs/images/networkpolicy01.png new file mode 100644 index 0000000..c5534c4 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy01.png differ diff --git a/docs/zh/docs/images/networkpolicy02.png b/docs/zh/docs/images/networkpolicy02.png new file mode 100644 index 0000000..d7786a0 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy02.png differ diff --git a/docs/zh/docs/images/networkpolicy03.png b/docs/zh/docs/images/networkpolicy03.png new file mode 100644 index 0000000..3f4b353 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy03.png differ diff --git a/docs/zh/docs/images/networkpolicy04.png b/docs/zh/docs/images/networkpolicy04.png new file mode 100644 index 0000000..e3887df Binary files /dev/null and b/docs/zh/docs/images/networkpolicy04.png differ diff --git a/docs/zh/docs/images/networkpolicy05.png b/docs/zh/docs/images/networkpolicy05.png new file mode 100644 index 0000000..a760348 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy05.png differ diff --git a/docs/zh/docs/images/networkpolicy06.png b/docs/zh/docs/images/networkpolicy06.png new file mode 100644 index 0000000..9a9ff6d Binary files /dev/null and b/docs/zh/docs/images/networkpolicy06.png differ diff --git a/docs/zh/docs/images/networkpolicy07.png b/docs/zh/docs/images/networkpolicy07.png new file mode 100644 index 0000000..cb95071 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy07.png differ diff --git a/docs/zh/docs/images/networkpolicy08.png b/docs/zh/docs/images/networkpolicy08.png new file mode 100644 index 0000000..77b61c4 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy08.png differ diff --git a/docs/zh/docs/images/networkpolicy09.png b/docs/zh/docs/images/networkpolicy09.png new file mode 100644 index 0000000..8cb5b2d Binary files /dev/null and b/docs/zh/docs/images/networkpolicy09.png differ diff --git a/docs/zh/docs/images/networkpolicy10.png b/docs/zh/docs/images/networkpolicy10.png new file mode 100644 index 0000000..87708fe Binary files /dev/null and b/docs/zh/docs/images/networkpolicy10.png differ diff --git a/docs/zh/docs/images/networkpolicy11.png b/docs/zh/docs/images/networkpolicy11.png new file mode 100644 index 0000000..b254d95 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy11.png differ diff --git a/docs/zh/docs/images/networkpolicy12.png b/docs/zh/docs/images/networkpolicy12.png new file mode 100644 index 0000000..73d5bc1 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy12.png differ diff --git a/docs/zh/docs/images/networkpolicy13.png b/docs/zh/docs/images/networkpolicy13.png new file mode 100644 index 0000000..3672879 Binary files /dev/null and b/docs/zh/docs/images/networkpolicy13.png differ diff --git a/docs/zh/docs/images/newrole01.png b/docs/zh/docs/images/newrole01.png new file mode 100644 index 0000000..0697210 Binary files /dev/null and b/docs/zh/docs/images/newrole01.png differ diff --git a/docs/zh/docs/images/newrole02.png b/docs/zh/docs/images/newrole02.png new file mode 100644 index 0000000..94dfa28 Binary files /dev/null and b/docs/zh/docs/images/newrole02.png differ diff --git a/docs/zh/docs/images/newrole03.png b/docs/zh/docs/images/newrole03.png new file mode 100644 index 0000000..92be81d Binary files /dev/null and b/docs/zh/docs/images/newrole03.png differ diff --git a/docs/zh/docs/images/newrole04.png b/docs/zh/docs/images/newrole04.png new file mode 100644 index 0000000..7f6f5a3 Binary files /dev/null and b/docs/zh/docs/images/newrole04.png differ diff --git a/docs/zh/docs/images/newrole05.png b/docs/zh/docs/images/newrole05.png new file mode 100644 index 0000000..5b64f91 Binary files /dev/null and b/docs/zh/docs/images/newrole05.png differ diff --git a/docs/zh/docs/images/newrole06.png b/docs/zh/docs/images/newrole06.png new file mode 100644 index 0000000..56c7d1f Binary files /dev/null and b/docs/zh/docs/images/newrole06.png differ diff --git a/docs/zh/docs/images/newrole07.png b/docs/zh/docs/images/newrole07.png new file mode 100644 index 0000000..8626771 Binary files /dev/null and b/docs/zh/docs/images/newrole07.png differ diff --git a/docs/zh/docs/images/newrole08.png b/docs/zh/docs/images/newrole08.png new file mode 100644 index 0000000..bf4af76 Binary files /dev/null and b/docs/zh/docs/images/newrole08.png differ diff --git a/docs/zh/docs/images/newrole09.png b/docs/zh/docs/images/newrole09.png new file mode 100644 index 0000000..0766159 Binary files /dev/null and b/docs/zh/docs/images/newrole09.png differ diff --git a/docs/zh/docs/images/newrole10.png b/docs/zh/docs/images/newrole10.png new file mode 100644 index 0000000..da98ec6 Binary files /dev/null and b/docs/zh/docs/images/newrole10.png differ diff --git a/docs/zh/docs/images/newrole11.png b/docs/zh/docs/images/newrole11.png new file mode 100644 index 0000000..9b75fcc Binary files /dev/null and b/docs/zh/docs/images/newrole11.png differ diff --git a/docs/zh/docs/images/node-details01.png b/docs/zh/docs/images/node-details01.png new file mode 100644 index 0000000..3086c9f Binary files /dev/null and b/docs/zh/docs/images/node-details01.png differ diff --git a/docs/zh/docs/images/node-details02.png b/docs/zh/docs/images/node-details02.png new file mode 100644 index 0000000..f9a361f Binary files /dev/null and b/docs/zh/docs/images/node-details02.png differ diff --git a/docs/zh/docs/images/node-details03.png b/docs/zh/docs/images/node-details03.png new file mode 100644 index 0000000..88154cc Binary files /dev/null and b/docs/zh/docs/images/node-details03.png differ diff --git a/docs/zh/docs/images/npu-smi-info.png b/docs/zh/docs/images/npu-smi-info.png new file mode 100644 index 0000000..33957cf Binary files /dev/null and b/docs/zh/docs/images/npu-smi-info.png differ diff --git a/docs/zh/docs/images/nvidia-gpu-operator-image.jpg b/docs/zh/docs/images/nvidia-gpu-operator-image.jpg new file mode 100644 index 0000000..064210a Binary files /dev/null and b/docs/zh/docs/images/nvidia-gpu-operator-image.jpg differ diff --git a/docs/zh/docs/images/oidc01.png b/docs/zh/docs/images/oidc01.png new file mode 100644 index 0000000..b82d157 Binary files /dev/null and b/docs/zh/docs/images/oidc01.png differ diff --git a/docs/zh/docs/images/olm.png b/docs/zh/docs/images/olm.png new file mode 100644 index 0000000..63fde94 Binary files /dev/null and b/docs/zh/docs/images/olm.png differ diff --git a/docs/zh/docs/images/olm1.png b/docs/zh/docs/images/olm1.png new file mode 100644 index 0000000..2e0d46b Binary files /dev/null and b/docs/zh/docs/images/olm1.png differ diff --git a/docs/zh/docs/images/olm2.png b/docs/zh/docs/images/olm2.png new file mode 100644 index 0000000..1c0ac34 Binary files /dev/null and b/docs/zh/docs/images/olm2.png differ diff --git a/docs/zh/docs/images/olm3.png b/docs/zh/docs/images/olm3.png new file mode 100644 index 0000000..1f6ee33 Binary files /dev/null and b/docs/zh/docs/images/olm3.png differ diff --git a/docs/zh/docs/images/operations01.png b/docs/zh/docs/images/operations01.png new file mode 100644 index 0000000..d404ff2 Binary files /dev/null and b/docs/zh/docs/images/operations01.png differ diff --git a/docs/zh/docs/images/operations02.png b/docs/zh/docs/images/operations02.png new file mode 100644 index 0000000..c5fed9f Binary files /dev/null and b/docs/zh/docs/images/operations02.png differ diff --git a/docs/zh/docs/images/operations03.png b/docs/zh/docs/images/operations03.png new file mode 100644 index 0000000..67285b6 Binary files /dev/null and b/docs/zh/docs/images/operations03.png differ diff --git a/docs/zh/docs/images/perm01.png b/docs/zh/docs/images/perm01.png new file mode 100644 index 0000000..d07470a Binary files /dev/null and b/docs/zh/docs/images/perm01.png differ diff --git a/docs/zh/docs/images/perm02.png b/docs/zh/docs/images/perm02.png new file mode 100644 index 0000000..f90a8c0 Binary files /dev/null and b/docs/zh/docs/images/perm02.png differ diff --git a/docs/zh/docs/images/perm03.png b/docs/zh/docs/images/perm03.png new file mode 100644 index 0000000..344d198 Binary files /dev/null and b/docs/zh/docs/images/perm03.png differ diff --git a/docs/zh/docs/images/perm04.png b/docs/zh/docs/images/perm04.png new file mode 100644 index 0000000..2054ff7 Binary files /dev/null and b/docs/zh/docs/images/perm04.png differ diff --git a/docs/zh/docs/images/perm05.png b/docs/zh/docs/images/perm05.png new file mode 100644 index 0000000..285ecdd Binary files /dev/null and b/docs/zh/docs/images/perm05.png differ diff --git a/docs/zh/docs/images/perm06.png b/docs/zh/docs/images/perm06.png new file mode 100644 index 0000000..b3a3b9c Binary files /dev/null and b/docs/zh/docs/images/perm06.png differ diff --git a/docs/zh/docs/images/perm07.png b/docs/zh/docs/images/perm07.png new file mode 100644 index 0000000..7a2dad5 Binary files /dev/null and b/docs/zh/docs/images/perm07.png differ diff --git a/docs/zh/docs/images/perm08.png b/docs/zh/docs/images/perm08.png new file mode 100644 index 0000000..bd2869e Binary files /dev/null and b/docs/zh/docs/images/perm08.png differ diff --git a/docs/zh/docs/images/platform02.png b/docs/zh/docs/images/platform02.png new file mode 100644 index 0000000..036996c Binary files /dev/null and b/docs/zh/docs/images/platform02.png differ diff --git a/docs/zh/docs/images/platform02_1.png b/docs/zh/docs/images/platform02_1.png new file mode 100644 index 0000000..036996c Binary files /dev/null and b/docs/zh/docs/images/platform02_1.png differ diff --git a/docs/zh/docs/images/platform03.png b/docs/zh/docs/images/platform03.png new file mode 100644 index 0000000..51c0353 Binary files /dev/null and b/docs/zh/docs/images/platform03.png differ diff --git a/docs/zh/docs/images/platform03_1.png b/docs/zh/docs/images/platform03_1.png new file mode 100644 index 0000000..51c0353 Binary files /dev/null and b/docs/zh/docs/images/platform03_1.png differ diff --git a/docs/zh/docs/images/ps01.png b/docs/zh/docs/images/ps01.png new file mode 100644 index 0000000..88202e1 Binary files /dev/null and b/docs/zh/docs/images/ps01.png differ diff --git a/docs/zh/docs/images/ps02.png b/docs/zh/docs/images/ps02.png new file mode 100644 index 0000000..ad2e4d3 Binary files /dev/null and b/docs/zh/docs/images/ps02.png differ diff --git a/docs/zh/docs/images/ps03.png b/docs/zh/docs/images/ps03.png new file mode 100644 index 0000000..5280a1d Binary files /dev/null and b/docs/zh/docs/images/ps03.png differ diff --git a/docs/zh/docs/images/ps04.png b/docs/zh/docs/images/ps04.png new file mode 100644 index 0000000..a1a4c56 Binary files /dev/null and b/docs/zh/docs/images/ps04.png differ diff --git a/docs/zh/docs/images/ps05.png b/docs/zh/docs/images/ps05.png new file mode 100644 index 0000000..7c5cf93 Binary files /dev/null and b/docs/zh/docs/images/ps05.png differ diff --git a/docs/zh/docs/images/ps06.png b/docs/zh/docs/images/ps06.png new file mode 100644 index 0000000..cac6cd0 Binary files /dev/null and b/docs/zh/docs/images/ps06.png differ diff --git a/docs/zh/docs/images/pv01.png b/docs/zh/docs/images/pv01.png new file mode 100644 index 0000000..c95b728 Binary files /dev/null and b/docs/zh/docs/images/pv01.png differ diff --git a/docs/zh/docs/images/pv02.png b/docs/zh/docs/images/pv02.png new file mode 100644 index 0000000..03f5290 Binary files /dev/null and b/docs/zh/docs/images/pv02.png differ diff --git a/docs/zh/docs/images/pv03.png b/docs/zh/docs/images/pv03.png new file mode 100644 index 0000000..f8f4dff Binary files /dev/null and b/docs/zh/docs/images/pv03.png differ diff --git a/docs/zh/docs/images/pv04.png b/docs/zh/docs/images/pv04.png new file mode 100644 index 0000000..d81a984 Binary files /dev/null and b/docs/zh/docs/images/pv04.png differ diff --git a/docs/zh/docs/images/pv05.png b/docs/zh/docs/images/pv05.png new file mode 100644 index 0000000..45657d8 Binary files /dev/null and b/docs/zh/docs/images/pv05.png differ diff --git a/docs/zh/docs/images/pv06.png b/docs/zh/docs/images/pv06.png new file mode 100644 index 0000000..208fa4e Binary files /dev/null and b/docs/zh/docs/images/pv06.png differ diff --git a/docs/zh/docs/images/pv07.png b/docs/zh/docs/images/pv07.png new file mode 100644 index 0000000..f919471 Binary files /dev/null and b/docs/zh/docs/images/pv07.png differ diff --git a/docs/zh/docs/images/pv08.png b/docs/zh/docs/images/pv08.png new file mode 100644 index 0000000..2150f57 Binary files /dev/null and b/docs/zh/docs/images/pv08.png differ diff --git a/docs/zh/docs/images/pv09.png b/docs/zh/docs/images/pv09.png new file mode 100644 index 0000000..1ecbc0d Binary files /dev/null and b/docs/zh/docs/images/pv09.png differ diff --git a/docs/zh/docs/images/pv11.png b/docs/zh/docs/images/pv11.png new file mode 100644 index 0000000..d56804e Binary files /dev/null and b/docs/zh/docs/images/pv11.png differ diff --git a/docs/zh/docs/images/pvc01.png b/docs/zh/docs/images/pvc01.png new file mode 100644 index 0000000..ec26beb Binary files /dev/null and b/docs/zh/docs/images/pvc01.png differ diff --git a/docs/zh/docs/images/pvc02.png b/docs/zh/docs/images/pvc02.png new file mode 100644 index 0000000..d147f28 Binary files /dev/null and b/docs/zh/docs/images/pvc02.png differ diff --git a/docs/zh/docs/images/pvc03.png b/docs/zh/docs/images/pvc03.png new file mode 100644 index 0000000..7666d9c Binary files /dev/null and b/docs/zh/docs/images/pvc03.png differ diff --git a/docs/zh/docs/images/pvc04.png b/docs/zh/docs/images/pvc04.png new file mode 100644 index 0000000..f022ff1 Binary files /dev/null and b/docs/zh/docs/images/pvc04.png differ diff --git a/docs/zh/docs/images/pvc05.png b/docs/zh/docs/images/pvc05.png new file mode 100644 index 0000000..a01c933 Binary files /dev/null and b/docs/zh/docs/images/pvc05.png differ diff --git a/docs/zh/docs/images/pvc06.png b/docs/zh/docs/images/pvc06.png new file mode 100644 index 0000000..7756b90 Binary files /dev/null and b/docs/zh/docs/images/pvc06.png differ diff --git a/docs/zh/docs/images/pvc07.png b/docs/zh/docs/images/pvc07.png new file mode 100644 index 0000000..bbad24f Binary files /dev/null and b/docs/zh/docs/images/pvc07.png differ diff --git a/docs/zh/docs/images/pvc08.png b/docs/zh/docs/images/pvc08.png new file mode 100644 index 0000000..24b6bec Binary files /dev/null and b/docs/zh/docs/images/pvc08.png differ diff --git a/docs/zh/docs/images/pvc09.png b/docs/zh/docs/images/pvc09.png new file mode 100644 index 0000000..4dee5a9 Binary files /dev/null and b/docs/zh/docs/images/pvc09.png differ diff --git a/docs/zh/docs/images/pvc11.png b/docs/zh/docs/images/pvc11.png new file mode 100644 index 0000000..3e8d575 Binary files /dev/null and b/docs/zh/docs/images/pvc11.png differ diff --git a/docs/zh/docs/images/pvc12.png b/docs/zh/docs/images/pvc12.png new file mode 100644 index 0000000..93cf6b4 Binary files /dev/null and b/docs/zh/docs/images/pvc12.png differ diff --git a/docs/zh/docs/images/pvc14.png b/docs/zh/docs/images/pvc14.png new file mode 100644 index 0000000..a3042f3 Binary files /dev/null and b/docs/zh/docs/images/pvc14.png differ diff --git a/docs/zh/docs/images/pvc15.png b/docs/zh/docs/images/pvc15.png new file mode 100644 index 0000000..f3a45bc Binary files /dev/null and b/docs/zh/docs/images/pvc15.png differ diff --git a/docs/zh/docs/images/pvc16.png b/docs/zh/docs/images/pvc16.png new file mode 100644 index 0000000..942eaef Binary files /dev/null and b/docs/zh/docs/images/pvc16.png differ diff --git a/docs/zh/docs/images/pvc17.png b/docs/zh/docs/images/pvc17.png new file mode 100644 index 0000000..8d15f3b Binary files /dev/null and b/docs/zh/docs/images/pvc17.png differ diff --git a/docs/zh/docs/images/pvc18.png b/docs/zh/docs/images/pvc18.png new file mode 100644 index 0000000..7352a3e Binary files /dev/null and b/docs/zh/docs/images/pvc18.png differ diff --git a/docs/zh/docs/images/quota01.png b/docs/zh/docs/images/quota01.png new file mode 100644 index 0000000..518f86a Binary files /dev/null and b/docs/zh/docs/images/quota01.png differ diff --git a/docs/zh/docs/images/quota02.png b/docs/zh/docs/images/quota02.png new file mode 100644 index 0000000..18cd477 Binary files /dev/null and b/docs/zh/docs/images/quota02.png differ diff --git a/docs/zh/docs/images/quota03.png b/docs/zh/docs/images/quota03.png new file mode 100644 index 0000000..2f64099 Binary files /dev/null and b/docs/zh/docs/images/quota03.png differ diff --git a/docs/zh/docs/images/quota04.png b/docs/zh/docs/images/quota04.png new file mode 100644 index 0000000..9ea4d0e Binary files /dev/null and b/docs/zh/docs/images/quota04.png differ diff --git a/docs/zh/docs/images/quota05.png b/docs/zh/docs/images/quota05.png new file mode 100644 index 0000000..8afa2b5 Binary files /dev/null and b/docs/zh/docs/images/quota05.png differ diff --git a/docs/zh/docs/images/quota06.png b/docs/zh/docs/images/quota06.png new file mode 100644 index 0000000..6f431fa Binary files /dev/null and b/docs/zh/docs/images/quota06.png differ diff --git a/docs/zh/docs/images/quota07.png b/docs/zh/docs/images/quota07.png new file mode 100644 index 0000000..6017e39 Binary files /dev/null and b/docs/zh/docs/images/quota07.png differ diff --git a/docs/zh/docs/images/quota08.png b/docs/zh/docs/images/quota08.png new file mode 100644 index 0000000..7519eb0 Binary files /dev/null and b/docs/zh/docs/images/quota08.png differ diff --git a/docs/zh/docs/images/regis01.PNG b/docs/zh/docs/images/regis01.PNG new file mode 100644 index 0000000..d17ceec Binary files /dev/null and b/docs/zh/docs/images/regis01.PNG differ diff --git a/docs/zh/docs/images/regis02.PNG b/docs/zh/docs/images/regis02.PNG new file mode 100644 index 0000000..2c7d515 Binary files /dev/null and b/docs/zh/docs/images/regis02.PNG differ diff --git a/docs/zh/docs/images/regis03.PNG b/docs/zh/docs/images/regis03.PNG new file mode 100644 index 0000000..88b6854 Binary files /dev/null and b/docs/zh/docs/images/regis03.PNG differ diff --git a/docs/zh/docs/images/regis04.PNG b/docs/zh/docs/images/regis04.PNG new file mode 100644 index 0000000..0527e95 Binary files /dev/null and b/docs/zh/docs/images/regis04.PNG differ diff --git a/docs/zh/docs/images/regis05.PNG b/docs/zh/docs/images/regis05.PNG new file mode 100644 index 0000000..896c8da Binary files /dev/null and b/docs/zh/docs/images/regis05.PNG differ diff --git a/docs/zh/docs/images/res-gp01.png b/docs/zh/docs/images/res-gp01.png new file mode 100644 index 0000000..e43670a Binary files /dev/null and b/docs/zh/docs/images/res-gp01.png differ diff --git a/docs/zh/docs/images/sc-share01.png b/docs/zh/docs/images/sc-share01.png new file mode 100644 index 0000000..78d8a4b Binary files /dev/null and b/docs/zh/docs/images/sc-share01.png differ diff --git a/docs/zh/docs/images/sc-share02.png b/docs/zh/docs/images/sc-share02.png new file mode 100644 index 0000000..d83a8e6 Binary files /dev/null and b/docs/zh/docs/images/sc-share02.png differ diff --git a/docs/zh/docs/images/sc02.png b/docs/zh/docs/images/sc02.png new file mode 100644 index 0000000..778cfaf Binary files /dev/null and b/docs/zh/docs/images/sc02.png differ diff --git a/docs/zh/docs/images/schedule01.png b/docs/zh/docs/images/schedule01.png new file mode 100644 index 0000000..3c3c0b5 Binary files /dev/null and b/docs/zh/docs/images/schedule01.png differ diff --git a/docs/zh/docs/images/schedule01_1.png b/docs/zh/docs/images/schedule01_1.png new file mode 100644 index 0000000..3c3c0b5 Binary files /dev/null and b/docs/zh/docs/images/schedule01_1.png differ diff --git a/docs/zh/docs/images/schedule01_2.png b/docs/zh/docs/images/schedule01_2.png new file mode 100644 index 0000000..3c3c0b5 Binary files /dev/null and b/docs/zh/docs/images/schedule01_2.png differ diff --git a/docs/zh/docs/images/schedule02.png b/docs/zh/docs/images/schedule02.png new file mode 100644 index 0000000..9b4d962 Binary files /dev/null and b/docs/zh/docs/images/schedule02.png differ diff --git a/docs/zh/docs/images/schedule03.png b/docs/zh/docs/images/schedule03.png new file mode 100644 index 0000000..3fd4aae Binary files /dev/null and b/docs/zh/docs/images/schedule03.png differ diff --git a/docs/zh/docs/images/schedule04.png b/docs/zh/docs/images/schedule04.png new file mode 100644 index 0000000..200859c Binary files /dev/null and b/docs/zh/docs/images/schedule04.png differ diff --git a/docs/zh/docs/images/secret01.png b/docs/zh/docs/images/secret01.png new file mode 100644 index 0000000..d217b06 Binary files /dev/null and b/docs/zh/docs/images/secret01.png differ diff --git a/docs/zh/docs/images/secret01_1.png b/docs/zh/docs/images/secret01_1.png new file mode 100644 index 0000000..adcb9bb Binary files /dev/null and b/docs/zh/docs/images/secret01_1.png differ diff --git a/docs/zh/docs/images/secret02.png b/docs/zh/docs/images/secret02.png new file mode 100644 index 0000000..cfb1ba8 Binary files /dev/null and b/docs/zh/docs/images/secret02.png differ diff --git a/docs/zh/docs/images/secret02_1.png b/docs/zh/docs/images/secret02_1.png new file mode 100644 index 0000000..37d271b Binary files /dev/null and b/docs/zh/docs/images/secret02_1.png differ diff --git a/docs/zh/docs/images/secret03.png b/docs/zh/docs/images/secret03.png new file mode 100644 index 0000000..d464154 Binary files /dev/null and b/docs/zh/docs/images/secret03.png differ diff --git a/docs/zh/docs/images/secret03_1.png b/docs/zh/docs/images/secret03_1.png new file mode 100644 index 0000000..be2ee01 Binary files /dev/null and b/docs/zh/docs/images/secret03_1.png differ diff --git a/docs/zh/docs/images/secret05.png b/docs/zh/docs/images/secret05.png new file mode 100644 index 0000000..5331b5a Binary files /dev/null and b/docs/zh/docs/images/secret05.png differ diff --git a/docs/zh/docs/images/secret05_1.png b/docs/zh/docs/images/secret05_1.png new file mode 100644 index 0000000..5331b5a Binary files /dev/null and b/docs/zh/docs/images/secret05_1.png differ diff --git a/docs/zh/docs/images/secret05_2.png b/docs/zh/docs/images/secret05_2.png new file mode 100644 index 0000000..5331b5a Binary files /dev/null and b/docs/zh/docs/images/secret05_2.png differ diff --git a/docs/zh/docs/images/secret06.png b/docs/zh/docs/images/secret06.png new file mode 100644 index 0000000..9feccda Binary files /dev/null and b/docs/zh/docs/images/secret06.png differ diff --git a/docs/zh/docs/images/secret07.png b/docs/zh/docs/images/secret07.png new file mode 100644 index 0000000..d5909d5 Binary files /dev/null and b/docs/zh/docs/images/secret07.png differ diff --git a/docs/zh/docs/images/secret09.png b/docs/zh/docs/images/secret09.png new file mode 100644 index 0000000..f5f3983 Binary files /dev/null and b/docs/zh/docs/images/secret09.png differ diff --git a/docs/zh/docs/images/secret10.png b/docs/zh/docs/images/secret10.png new file mode 100644 index 0000000..b9956dc Binary files /dev/null and b/docs/zh/docs/images/secret10.png differ diff --git a/docs/zh/docs/images/security01.png b/docs/zh/docs/images/security01.png new file mode 100644 index 0000000..ca633e1 Binary files /dev/null and b/docs/zh/docs/images/security01.png differ diff --git a/docs/zh/docs/images/security01_1.png b/docs/zh/docs/images/security01_1.png new file mode 100644 index 0000000..b144e57 Binary files /dev/null and b/docs/zh/docs/images/security01_1.png differ diff --git a/docs/zh/docs/images/security01_2.png b/docs/zh/docs/images/security01_2.png new file mode 100644 index 0000000..b144e57 Binary files /dev/null and b/docs/zh/docs/images/security01_2.png differ diff --git a/docs/zh/docs/images/security01_3.png b/docs/zh/docs/images/security01_3.png new file mode 100644 index 0000000..b144e57 Binary files /dev/null and b/docs/zh/docs/images/security01_3.png differ diff --git a/docs/zh/docs/images/security02.png b/docs/zh/docs/images/security02.png new file mode 100644 index 0000000..2a5e1e6 Binary files /dev/null and b/docs/zh/docs/images/security02.png differ diff --git a/docs/zh/docs/images/security03.png b/docs/zh/docs/images/security03.png new file mode 100644 index 0000000..4e72b1b Binary files /dev/null and b/docs/zh/docs/images/security03.png differ diff --git a/docs/zh/docs/images/security04.png b/docs/zh/docs/images/security04.png new file mode 100644 index 0000000..7051be6 Binary files /dev/null and b/docs/zh/docs/images/security04.png differ diff --git a/docs/zh/docs/images/security04_1.png b/docs/zh/docs/images/security04_1.png new file mode 100644 index 0000000..7051be6 Binary files /dev/null and b/docs/zh/docs/images/security04_1.png differ diff --git a/docs/zh/docs/images/security05.png b/docs/zh/docs/images/security05.png new file mode 100644 index 0000000..ddd9c76 Binary files /dev/null and b/docs/zh/docs/images/security05.png differ diff --git a/docs/zh/docs/images/security06.png b/docs/zh/docs/images/security06.png new file mode 100644 index 0000000..22405f4 Binary files /dev/null and b/docs/zh/docs/images/security06.png differ diff --git a/docs/zh/docs/images/security07.png b/docs/zh/docs/images/security07.png new file mode 100644 index 0000000..2b79f79 Binary files /dev/null and b/docs/zh/docs/images/security07.png differ diff --git a/docs/zh/docs/images/security09.png b/docs/zh/docs/images/security09.png new file mode 100644 index 0000000..c4937c5 Binary files /dev/null and b/docs/zh/docs/images/security09.png differ diff --git a/docs/zh/docs/images/security10.png b/docs/zh/docs/images/security10.png new file mode 100644 index 0000000..aadb3ff Binary files /dev/null and b/docs/zh/docs/images/security10.png differ diff --git a/docs/zh/docs/images/security11.png b/docs/zh/docs/images/security11.png new file mode 100644 index 0000000..c183e08 Binary files /dev/null and b/docs/zh/docs/images/security11.png differ diff --git a/docs/zh/docs/images/security12.png b/docs/zh/docs/images/security12.png new file mode 100644 index 0000000..bd46827 Binary files /dev/null and b/docs/zh/docs/images/security12.png differ diff --git a/docs/zh/docs/images/security13.png b/docs/zh/docs/images/security13.png new file mode 100644 index 0000000..b5cfd65 Binary files /dev/null and b/docs/zh/docs/images/security13.png differ diff --git a/docs/zh/docs/images/security14.png b/docs/zh/docs/images/security14.png new file mode 100644 index 0000000..133a77f Binary files /dev/null and b/docs/zh/docs/images/security14.png differ diff --git a/docs/zh/docs/images/security15.png b/docs/zh/docs/images/security15.png new file mode 100644 index 0000000..7b1e65d Binary files /dev/null and b/docs/zh/docs/images/security15.png differ diff --git a/docs/zh/docs/images/security16.png b/docs/zh/docs/images/security16.png new file mode 100644 index 0000000..cda643f Binary files /dev/null and b/docs/zh/docs/images/security16.png differ diff --git a/docs/zh/docs/images/security17.png b/docs/zh/docs/images/security17.png new file mode 100644 index 0000000..4f8ac69 Binary files /dev/null and b/docs/zh/docs/images/security17.png differ diff --git a/docs/zh/docs/images/security18.png b/docs/zh/docs/images/security18.png new file mode 100644 index 0000000..844ea8a Binary files /dev/null and b/docs/zh/docs/images/security18.png differ diff --git a/docs/zh/docs/images/security19.png b/docs/zh/docs/images/security19.png new file mode 100644 index 0000000..ffff177 Binary files /dev/null and b/docs/zh/docs/images/security19.png differ diff --git a/docs/zh/docs/images/security20.png b/docs/zh/docs/images/security20.png new file mode 100644 index 0000000..66f97b1 Binary files /dev/null and b/docs/zh/docs/images/security20.png differ diff --git a/docs/zh/docs/images/service01.png b/docs/zh/docs/images/service01.png new file mode 100644 index 0000000..c066d58 Binary files /dev/null and b/docs/zh/docs/images/service01.png differ diff --git a/docs/zh/docs/images/service02.png b/docs/zh/docs/images/service02.png new file mode 100644 index 0000000..8f4e3e6 Binary files /dev/null and b/docs/zh/docs/images/service02.png differ diff --git a/docs/zh/docs/images/settings01.png b/docs/zh/docs/images/settings01.png new file mode 100644 index 0000000..802484b Binary files /dev/null and b/docs/zh/docs/images/settings01.png differ diff --git a/docs/zh/docs/images/snapshot01.png b/docs/zh/docs/images/snapshot01.png new file mode 100644 index 0000000..3f2c416 Binary files /dev/null and b/docs/zh/docs/images/snapshot01.png differ diff --git a/docs/zh/docs/images/snapshot02.png b/docs/zh/docs/images/snapshot02.png new file mode 100644 index 0000000..119355e Binary files /dev/null and b/docs/zh/docs/images/snapshot02.png differ diff --git a/docs/zh/docs/images/snapshot03.png b/docs/zh/docs/images/snapshot03.png new file mode 100644 index 0000000..0b4b9aa Binary files /dev/null and b/docs/zh/docs/images/snapshot03.png differ diff --git a/docs/zh/docs/images/snapshot04.png b/docs/zh/docs/images/snapshot04.png new file mode 100644 index 0000000..e714c6a Binary files /dev/null and b/docs/zh/docs/images/snapshot04.png differ diff --git a/docs/zh/docs/images/snapshot05.png b/docs/zh/docs/images/snapshot05.png new file mode 100644 index 0000000..b939af5 Binary files /dev/null and b/docs/zh/docs/images/snapshot05.png differ diff --git a/docs/zh/docs/images/sophon.png b/docs/zh/docs/images/sophon.png new file mode 100644 index 0000000..63b7907 Binary files /dev/null and b/docs/zh/docs/images/sophon.png differ diff --git a/docs/zh/docs/images/sso1.png b/docs/zh/docs/images/sso1.png new file mode 100644 index 0000000..2bb01bd Binary files /dev/null and b/docs/zh/docs/images/sso1.png differ diff --git a/docs/zh/docs/images/sso3.png b/docs/zh/docs/images/sso3.png new file mode 100644 index 0000000..d666dad Binary files /dev/null and b/docs/zh/docs/images/sso3.png differ diff --git a/docs/zh/docs/images/state01.png b/docs/zh/docs/images/state01.png new file mode 100644 index 0000000..ceeabb5 Binary files /dev/null and b/docs/zh/docs/images/state01.png differ diff --git a/docs/zh/docs/images/state02.png b/docs/zh/docs/images/state02.png new file mode 100644 index 0000000..c51593c Binary files /dev/null and b/docs/zh/docs/images/state02.png differ diff --git a/docs/zh/docs/images/state03yaml.png b/docs/zh/docs/images/state03yaml.png new file mode 100644 index 0000000..c67b0ce Binary files /dev/null and b/docs/zh/docs/images/state03yaml.png differ diff --git a/docs/zh/docs/images/state05.png b/docs/zh/docs/images/state05.png new file mode 100644 index 0000000..8156821 Binary files /dev/null and b/docs/zh/docs/images/state05.png differ diff --git a/docs/zh/docs/images/state10.png b/docs/zh/docs/images/state10.png new file mode 100644 index 0000000..e443570 Binary files /dev/null and b/docs/zh/docs/images/state10.png differ diff --git a/docs/zh/docs/images/state11.png b/docs/zh/docs/images/state11.png new file mode 100644 index 0000000..85518cb Binary files /dev/null and b/docs/zh/docs/images/state11.png differ diff --git a/docs/zh/docs/images/state12.png b/docs/zh/docs/images/state12.png new file mode 100644 index 0000000..a642027 Binary files /dev/null and b/docs/zh/docs/images/state12.png differ diff --git a/docs/zh/docs/images/suanova.png b/docs/zh/docs/images/suanova.png new file mode 100644 index 0000000..cbe6548 Binary files /dev/null and b/docs/zh/docs/images/suanova.png differ diff --git a/docs/zh/docs/images/taint-add-remove.png b/docs/zh/docs/images/taint-add-remove.png new file mode 100644 index 0000000..89e86c7 Binary files /dev/null and b/docs/zh/docs/images/taint-add-remove.png differ diff --git a/docs/zh/docs/images/taint-change.png b/docs/zh/docs/images/taint-change.png new file mode 100644 index 0000000..c2ae2de Binary files /dev/null and b/docs/zh/docs/images/taint-change.png differ diff --git a/docs/zh/docs/images/taint-click--cluster-name.png b/docs/zh/docs/images/taint-click--cluster-name.png new file mode 100644 index 0000000..0d1d649 Binary files /dev/null and b/docs/zh/docs/images/taint-click--cluster-name.png differ diff --git a/docs/zh/docs/images/tep04.png b/docs/zh/docs/images/tep04.png new file mode 100644 index 0000000..f6e74f1 Binary files /dev/null and b/docs/zh/docs/images/tep04.png differ diff --git a/docs/zh/docs/images/tep05.png b/docs/zh/docs/images/tep05.png new file mode 100644 index 0000000..841c588 Binary files /dev/null and b/docs/zh/docs/images/tep05.png differ diff --git a/docs/zh/docs/images/upgradeclsuter00.png b/docs/zh/docs/images/upgradeclsuter00.png new file mode 100644 index 0000000..998fb73 Binary files /dev/null and b/docs/zh/docs/images/upgradeclsuter00.png differ diff --git a/docs/zh/docs/images/upgradecluster01.png b/docs/zh/docs/images/upgradecluster01.png new file mode 100644 index 0000000..1b36e6d Binary files /dev/null and b/docs/zh/docs/images/upgradecluster01.png differ diff --git a/docs/zh/docs/images/upgradecluster02.png b/docs/zh/docs/images/upgradecluster02.png new file mode 100644 index 0000000..80a250c Binary files /dev/null and b/docs/zh/docs/images/upgradecluster02.png differ diff --git a/docs/zh/docs/images/upgradecluster03.png b/docs/zh/docs/images/upgradecluster03.png new file mode 100644 index 0000000..2d6334f Binary files /dev/null and b/docs/zh/docs/images/upgradecluster03.png differ diff --git a/docs/zh/docs/images/user_configmap_to_volume.jpg b/docs/zh/docs/images/user_configmap_to_volume.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/vgpu-addon.png b/docs/zh/docs/images/vgpu-addon.png new file mode 100644 index 0000000..a0ceafc Binary files /dev/null and b/docs/zh/docs/images/vgpu-addon.png differ diff --git a/docs/zh/docs/images/vgpu-cluster.png b/docs/zh/docs/images/vgpu-cluster.png new file mode 100644 index 0000000..140e1d3 Binary files /dev/null and b/docs/zh/docs/images/vgpu-cluster.png differ diff --git a/docs/zh/docs/images/vgpu-deployment.png b/docs/zh/docs/images/vgpu-deployment.png new file mode 100644 index 0000000..7d79d08 Binary files /dev/null and b/docs/zh/docs/images/vgpu-deployment.png differ diff --git a/docs/zh/docs/images/vgpu-pod.png b/docs/zh/docs/images/vgpu-pod.png new file mode 100644 index 0000000..a5d0323 Binary files /dev/null and b/docs/zh/docs/images/vgpu-pod.png differ diff --git a/docs/zh/docs/images/vgpu-quota.png b/docs/zh/docs/images/vgpu-quota.png new file mode 100644 index 0000000..754b12d Binary files /dev/null and b/docs/zh/docs/images/vgpu-quota.png differ diff --git a/docs/zh/docs/images/visual02.png b/docs/zh/docs/images/visual02.png new file mode 100644 index 0000000..34e445d Binary files /dev/null and b/docs/zh/docs/images/visual02.png differ diff --git a/docs/zh/docs/images/visual06.png b/docs/zh/docs/images/visual06.png new file mode 100644 index 0000000..be5895c Binary files /dev/null and b/docs/zh/docs/images/visual06.png differ diff --git a/docs/zh/docs/images/webh01.png b/docs/zh/docs/images/webh01.png new file mode 100644 index 0000000..18f3c2a Binary files /dev/null and b/docs/zh/docs/images/webh01.png differ diff --git a/docs/zh/docs/images/webh02.png b/docs/zh/docs/images/webh02.png new file mode 100644 index 0000000..6933458 Binary files /dev/null and b/docs/zh/docs/images/webh02.png differ diff --git a/docs/zh/docs/images/webh03.png b/docs/zh/docs/images/webh03.png new file mode 100644 index 0000000..43e91f1 Binary files /dev/null and b/docs/zh/docs/images/webh03.png differ diff --git a/docs/zh/docs/images/webh04.png b/docs/zh/docs/images/webh04.png new file mode 100644 index 0000000..5af346d Binary files /dev/null and b/docs/zh/docs/images/webh04.png differ diff --git a/docs/zh/docs/images/webh05.png b/docs/zh/docs/images/webh05.png new file mode 100644 index 0000000..91d609a Binary files /dev/null and b/docs/zh/docs/images/webh05.png differ diff --git a/docs/zh/docs/images/webh06.png b/docs/zh/docs/images/webh06.png new file mode 100644 index 0000000..ef376da Binary files /dev/null and b/docs/zh/docs/images/webh06.png differ diff --git a/docs/zh/docs/images/worker01.png b/docs/zh/docs/images/worker01.png new file mode 100644 index 0000000..0707b29 Binary files /dev/null and b/docs/zh/docs/images/worker01.png differ diff --git a/docs/zh/docs/images/worker02.png b/docs/zh/docs/images/worker02.png new file mode 100644 index 0000000..afd1574 Binary files /dev/null and b/docs/zh/docs/images/worker02.png differ diff --git a/docs/zh/docs/images/worker03.png b/docs/zh/docs/images/worker03.png new file mode 100644 index 0000000..544b38b Binary files /dev/null and b/docs/zh/docs/images/worker03.png differ diff --git a/docs/zh/docs/images/worker04.png b/docs/zh/docs/images/worker04.png new file mode 100644 index 0000000..c318791 Binary files /dev/null and b/docs/zh/docs/images/worker04.png differ diff --git a/docs/zh/docs/images/worker05.png b/docs/zh/docs/images/worker05.png new file mode 100644 index 0000000..73d2ffc Binary files /dev/null and b/docs/zh/docs/images/worker05.png differ diff --git a/docs/zh/docs/images/worker06.png b/docs/zh/docs/images/worker06.png new file mode 100644 index 0000000..02a5cac Binary files /dev/null and b/docs/zh/docs/images/worker06.png differ diff --git a/docs/zh/docs/images/worker07.png b/docs/zh/docs/images/worker07.png new file mode 100644 index 0000000..cc004fa Binary files /dev/null and b/docs/zh/docs/images/worker07.png differ diff --git a/docs/zh/docs/images/workload_ascendgpu_userguide.jpg b/docs/zh/docs/images/workload_ascendgpu_userguide.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/workload_gpu_userguide.jpg b/docs/zh/docs/images/workload_gpu_userguide.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/workload_iluvatargpu_userguide.jpg b/docs/zh/docs/images/workload_iluvatargpu_userguide.jpg new file mode 100644 index 0000000..e69de29 diff --git a/docs/zh/docs/images/ws01.png b/docs/zh/docs/images/ws01.png new file mode 100644 index 0000000..0ddd4f5 Binary files /dev/null and b/docs/zh/docs/images/ws01.png differ diff --git a/docs/zh/docs/images/ws01_1.png b/docs/zh/docs/images/ws01_1.png new file mode 100644 index 0000000..f986657 Binary files /dev/null and b/docs/zh/docs/images/ws01_1.png differ diff --git a/docs/zh/docs/images/ws01_2.png b/docs/zh/docs/images/ws01_2.png new file mode 100644 index 0000000..0ddd4f5 Binary files /dev/null and b/docs/zh/docs/images/ws01_2.png differ diff --git a/docs/zh/docs/images/ws01_3.png b/docs/zh/docs/images/ws01_3.png new file mode 100644 index 0000000..f986657 Binary files /dev/null and b/docs/zh/docs/images/ws01_3.png differ diff --git a/docs/zh/docs/images/ws01_4.png b/docs/zh/docs/images/ws01_4.png new file mode 100644 index 0000000..f986657 Binary files /dev/null and b/docs/zh/docs/images/ws01_4.png differ diff --git a/docs/zh/docs/images/ws01_5.png b/docs/zh/docs/images/ws01_5.png new file mode 100644 index 0000000..f986657 Binary files /dev/null and b/docs/zh/docs/images/ws01_5.png differ diff --git a/docs/zh/docs/images/ws01_6.png b/docs/zh/docs/images/ws01_6.png new file mode 100644 index 0000000..f986657 Binary files /dev/null and b/docs/zh/docs/images/ws01_6.png differ diff --git a/docs/zh/docs/images/ws02.png b/docs/zh/docs/images/ws02.png new file mode 100644 index 0000000..31e2eda Binary files /dev/null and b/docs/zh/docs/images/ws02.png differ diff --git a/docs/zh/docs/images/ws03.png b/docs/zh/docs/images/ws03.png new file mode 100644 index 0000000..0ca3154 Binary files /dev/null and b/docs/zh/docs/images/ws03.png differ diff --git a/docs/zh/docs/images/ws04.png b/docs/zh/docs/images/ws04.png new file mode 100644 index 0000000..ec12a3a Binary files /dev/null and b/docs/zh/docs/images/ws04.png differ diff --git a/docs/zh/docs/images/ws04_1.png b/docs/zh/docs/images/ws04_1.png new file mode 100644 index 0000000..ec12a3a Binary files /dev/null and b/docs/zh/docs/images/ws04_1.png differ diff --git a/docs/zh/docs/images/wsfd01.png b/docs/zh/docs/images/wsfd01.png new file mode 100644 index 0000000..49bff10 Binary files /dev/null and b/docs/zh/docs/images/wsfd01.png differ diff --git a/docs/zh/docs/index.md b/docs/zh/docs/index.md new file mode 100644 index 0000000..14e6256 --- /dev/null +++ b/docs/zh/docs/index.md @@ -0,0 +1,15 @@ +--- +hide: + - toc + - navigation +--- + +# 豐收二號檔案站 + +這是豐收二號 AI 算力中心的檔案站。 + +- [終端用戶手冊](./end-user/index.md):在容器化環境中,使用雲主機,開發 AI 算法,構建訓練和推理任務 +- [管理員手冊](./admin/index.md):為容器化終端用戶做好運維工作,保障平台平穩高效運行 +- [開發者手冊](./openapi/index.md):匯總了 5 個模塊的 OpenAPI 手冊 + +![home](./admin/images/home.png) diff --git a/docs/zh/docs/openapi/baize/index.md b/docs/zh/docs/openapi/baize/index.md new file mode 100644 index 0000000..38ea5f6 --- /dev/null +++ b/docs/zh/docs/openapi/baize/index.md @@ -0,0 +1 @@ +# diff --git a/docs/zh/docs/openapi/baize/v0.107.4.json b/docs/zh/docs/openapi/baize/v0.107.4.json new file mode 100644 index 0000000..10ab175 --- /dev/null +++ b/docs/zh/docs/openapi/baize/v0.107.4.json @@ -0,0 +1,6480 @@ +{ + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "schemes": [ + "http" + ], + "swagger": "2.0", + "info": { + "title": "Baize swagger api docs", + "version": "v1alpha1" + }, + "host": "demo-dev.daocloud.io", + "paths": { + "/apis/baize.io/v1alpha1/clusters": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取集群列表", + "operationId": "ClusterService_ListClusters", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAIClustersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/clusters/{cluster}/namespaces": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取集群命名空间", + "operationId": "ClusterService_ListClusterNamespaces", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/clusters/{cluster}/queues": { + "post": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_CreateQueue", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "name": { + "type": "string", + "required": [ + "name" + ] + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1QueueResource" + } + }, + "strategy": { + "title": "队列策略", + "$ref": "#/definitions/v1alpha1QueueStrategy" + }, + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + }, + "workspace": { + "type": "integer", + "format": "int32" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Queue" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/clusters/{cluster}/queues/{name}": { + "get": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_GetQueue", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "enum": [ + "QUEUE_TYPE_UNSPECIFIED", + "KUEUE" + ], + "type": "string", + "default": "QUEUE_TYPE_UNSPECIFIED", + "description": "队列类型", + "name": "type", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Queue" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + }, + "put": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_UpdateQueue", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1QueueResource" + } + }, + "strategy": { + "title": "队列策略", + "$ref": "#/definitions/v1alpha1QueueStrategy" + }, + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + }, + "workspace": { + "type": "integer", + "format": "int32" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Queue" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + }, + "delete": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_DeleteQueue", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Queue" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/clusters/{cluster}/queues/{name}/json": { + "get": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_GetQueueByJSON", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "enum": [ + "QUEUE_TYPE_UNSPECIFIED", + "KUEUE" + ], + "type": "string", + "default": "QUEUE_TYPE_UNSPECIFIED", + "description": "队列类型", + "name": "type", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueueJSON" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/clusters/{cluster}/settings/gpu-resources": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取集群 GPU 配置", + "operationId": "ClusterService_GetClusterGPUSettings", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GPUSettingsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/current-user/permission": { + "get": { + "tags": [ + "PermissionService" + ], + "operationId": "PermissionService_GetCurrentUserPermission", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UserPermission" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/datasets/conda/options": { + "get": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_GetDatasetCondaOptions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetDatasetCondaOptionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/devices/gpus": { + "get": { + "tags": [ + "DeviceService" + ], + "summary": "ListDevicesGPUs 获取 GPU 设备列表", + "operationId": "DeviceService_ListDevicesGPUs", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDevicesGPUsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:*" + } + }, + "/apis/baize.io/v1alpha1/grafana-dashboards/admin-overview": { + "get": { + "tags": [ + "MetricsService" + ], + "summary": "管理员概览面板", + "operationId": "MetricsService_GetAdminGrafanaDashboard", + "parameters": [ + { + "type": "string", + "description": "可选,不选为全部集群", + "name": "cluster", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "起始时间", + "name": "from", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "结束时间,且作为单值指标的时间点", + "name": "to", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GrafanaDashboard" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/metrics/multiple-queries": { + "get": { + "tags": [ + "MetricsService" + ], + "summary": "查询具体的单一指标\ndeprecated, use GetAdminGrafanaDashboard instead", + "operationId": "MetricsService_QueryMultipleVectors", + "parameters": [ + { + "type": "array", + "items": { + "enum": [ + "QUERY_METRIC_UNSPECIFIED", + "QUERY_METRIC_GPU_INSTALLED_NODES", + "QUERY_METRIC_TOTAL_NODES", + "QUERY_METRIC_INUSE_GPUS", + "QUERY_METRIC_TOTAL_GPUS", + "QUERY_METRIC_INUSE_CPUS", + "QUERY_METRIC_TOTAL_CPUS", + "QUERY_METRIC_INUSE_MEM", + "QUERY_METRIC_TOTAL_MEM", + "QUERY_METRIC_INUSE_VGPU_MEM", + "QUERY_METRIC_TOTAL_VGPU_MEM", + "QUERY_METRIC_TOTAL_CLUSTERS" + ], + "type": "string" + }, + "collectionFormat": "multi", + "name": "queryMetrics", + "in": "query" + }, + { + "type": "string", + "format": "uint64", + "name": "time", + "in": "query" + }, + { + "type": "string", + "name": "cluster", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1MultipleVectorQueryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/metrics/time-series-queries": { + "get": { + "tags": [ + "MetricsService" + ], + "summary": "查询时间序列指标\ndeprecated, use GetAdminGrafanaDashboard instead", + "operationId": "MetricsService_QueryTimeSeriesVectors", + "parameters": [ + { + "type": "array", + "items": { + "enum": [ + "QUERY_TIME_SERIES_UNSPECIFIED", + "QUERY_TIME_SERIES_METRIC_GPU_DISTRIBUTION", + "QUERY_TIME_SERIES_METRIC_GPU_UTILIZATION" + ], + "type": "string" + }, + "collectionFormat": "multi", + "name": "queryMetrics", + "in": "query" + }, + { + "enum": [ + "QUERY_TIME_SERIES_METRIC_RANGES_UNSPECIFIED", + "QUERY_TIME_SERIES_METRIC_RANGES_LAST_3_DAYS", + "QUERY_TIME_SERIES_METRIC_RANGES_LAST_7_DAYS", + "QUERY_TIME_SERIES_METRIC_RANGES_LAST_15_DAYS" + ], + "type": "string", + "default": "QUERY_TIME_SERIES_METRIC_RANGES_UNSPECIFIED", + "name": "queryMetricRange", + "in": "query" + }, + { + "type": "string", + "name": "cluster", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryTimeSeriesVectorsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/notebook-images": { + "get": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_GetNotebookImageList", + "parameters": [ + { + "enum": [ + "TYPE_UNSPECIFIED", + "JUPYTER", + "CODE" + ], + "type": "string", + "default": "TYPE_UNSPECIFIED", + "description": "镜像类型,可以为空,空表示 Jupyter", + "name": "type", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1NotebookImageListResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/queues": { + "get": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_ListQueues", + "parameters": [ + { + "type": "string", + "name": "cluster", + "in": "query" + }, + { + "enum": [ + "QUEUE_TYPE_UNSPECIFIED", + "KUEUE" + ], + "type": "string", + "default": "QUEUE_TYPE_UNSPECIFIED", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListQueueResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:workspace" + } + }, + "/apis/baize.io/v1alpha1/workspace/{workspace}/queues": { + "get": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_ListQueues2", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "query" + }, + { + "enum": [ + "QUEUE_TYPE_UNSPECIFIED", + "KUEUE" + ], + "type": "string", + "default": "QUEUE_TYPE_UNSPECIFIED", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListQueueResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:workspace" + } + }, + "/apis/baize.io/v1alpha1/workspaces": { + "get": { + "tags": [ + "WorkspaceService" + ], + "operationId": "WorkspaceService_ListWorkspaces", + "parameters": [ + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + }, + { + "type": "string", + "name": "cluster", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListWorkspacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/analysis": { + "get": { + "tags": [ + "AnalysisManagement" + ], + "operationId": "AnalysisManagement_ListAnalysis", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "query" + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "queueName", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAnalysisResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:type, owner" + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取集群列表", + "operationId": "ClusterService_ListClusters2", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAIClustersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取集群命名空间", + "operationId": "ClusterService_ListClusterNamespaces2", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/analysis": { + "get": { + "tags": [ + "AnalysisManagement" + ], + "operationId": "AnalysisManagement_ListAnalysis2", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "queueName", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAnalysisResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:type, owner" + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/analysis/{name}": { + "delete": { + "tags": [ + "AnalysisManagement" + ], + "operationId": "AnalysisManagement_DeleteAnalysis", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Analysis" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/datasets": { + "get": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_ListDatasets", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDatasetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:type, uri, phase" + }, + "post": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_CreateDataset", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "boundPVC": { + "title": "绑定 PVC 设置", + "$ref": "#/definitions/v1alpha1DatasetBoundPVC" + }, + "description": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "secretOptions": { + "$ref": "#/definitions/v1alpha1SecretOptions" + }, + "source": { + "title": "定义数据源", + "$ref": "#/definitions/v1alpha1DataSource" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Dataset" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/datasets/{name}": { + "get": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_GetDataset", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Dataset" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + }, + "put": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_UpdateDataset", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "conda": { + "$ref": "#/definitions/v1alpha1DataSourceOptionsConda" + }, + "secretOptions": { + "$ref": "#/definitions/v1alpha1SecretOptions" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Dataset" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + }, + "delete": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_DeleteDataset", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Dataset" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/datasets/{name}/actions": { + "post": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_DatasetDoAction", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/DatasetActionRequestAction" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Dataset" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/datasets/{name}/related-instances": { + "get": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_GetRelatedInstances", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RelatedInstancesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:datasets" + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/datasets/{name}/sync-process": { + "get": { + "tags": [ + "DatasetManagement" + ], + "operationId": "DatasetManagement_GetDatasetSyncProcess", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1DatasetSyncProcess" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/grafana-dashboards": { + "get": { + "tags": [ + "MetricsService" + ], + "summary": "工作负载实例监控面板", + "operationId": "MetricsService_GetWorkloadGrafanaDashboard", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "pod", + "in": "query" + }, + { + "type": "string", + "name": "container", + "in": "query" + }, + { + "type": "string", + "description": "起始时间", + "name": "from", + "in": "query" + }, + { + "type": "string", + "description": "结束时间,且作为单值指标的时间点", + "name": "to", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GrafanaDashboard" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/inference-serving": { + "get": { + "tags": [ + "InferenceServingManagement" + ], + "summary": "获取推理服务列表", + "operationId": "InferenceServingManagement_ListInferenceServings", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListInferenceServingsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:phase, lastUpdated" + }, + "post": { + "tags": [ + "InferenceServingManagement" + ], + "summary": "创建推理服务", + "operationId": "InferenceServingManagement_CreateInferenceServing", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "auth": { + "$ref": "#/definitions/v1alpha1ServingAuth" + }, + "framework": { + "$ref": "#/definitions/v1alpha1Framework" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "models": { + "type": "array", + "title": "模型配置,暂时只支持一个,这里用数组只是为了扩展", + "items": { + "$ref": "#/definitions/v1alpha1ServingConfig" + } + }, + "name": { + "type": "string", + "required": [ + "name" + ] + }, + "podConfig": { + "title": "kubernetes pod 配置", + "$ref": "#/definitions/commonPodConfig" + }, + "replicas": { + "type": "integer", + "format": "int32" + }, + "serviceConfig": { + "$ref": "#/definitions/v1alpha1ServiceConfig" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1InferenceServing" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/inference-serving/{name}": { + "get": { + "tags": [ + "InferenceServingManagement" + ], + "summary": "获取推理服务", + "operationId": "InferenceServingManagement_GetInferenceServing", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1InferenceServing" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + }, + "put": { + "tags": [ + "InferenceServingManagement" + ], + "summary": "更新推理服务", + "operationId": "InferenceServingManagement_UpdateInferenceServing", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "auth": { + "$ref": "#/definitions/v1alpha1ServingAuth" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "models": { + "type": "array", + "title": "模型配置,暂时只支持一个,这里用数组只是为了扩展", + "items": { + "$ref": "#/definitions/v1alpha1ServingConfig" + } + }, + "podConfig": { + "title": "kubernetes pod 配置", + "$ref": "#/definitions/commonPodConfig" + }, + "replicas": { + "type": "integer", + "format": "int32" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1InferenceServing" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + }, + "delete": { + "tags": [ + "InferenceServingManagement" + ], + "summary": "删除推理服务", + "operationId": "InferenceServingManagement_DeleteInferenceServing", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1InferenceServing" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/jobs": { + "get": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_ListJobs2", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "cluster 表示查询所有集群的 Job。", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "namespace 表示查询所有命名空间的 Job。", + "name": "namespace", + "in": "path", + "required": true + }, + { + "enum": [ + "JOB_TYPE_UNSPECIFIED", + "PYTORCH", + "TENSORFLOW", + "PADDLE", + "MPI", + "MXNET" + ], + "type": "string", + "default": "JOB_TYPE_UNSPECIFIED", + "description": "任务类型,如果为空,表示所有任务类型。\n\n - MPI: XGBOOST = 4;", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:trainingMode, runningDuration" + }, + "post": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_CreateJob", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "analysis": { + "title": "任务分析", + "$ref": "#/definitions/v1alpha1AnalysisConfig" + }, + "baseConfig": { + "$ref": "#/definitions/v1alpha1JobCreationBaseConfig" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string", + "required": [ + "name" + ] + }, + "roleConfig": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1JobRoleDifferenceConfig" + } + }, + "trainingConfig": { + "title": "训练配置", + "$ref": "#/definitions/v1alpha1TrainingConfig" + }, + "trainingMode": { + "$ref": "#/definitions/v1alpha1TrainingMode" + }, + "type": { + "$ref": "#/definitions/v1alpha1JobType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/jobs/{name}": { + "get": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_GetJob", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "enum": [ + "JOB_TYPE_UNSPECIFIED", + "PYTORCH", + "TENSORFLOW", + "PADDLE", + "MPI", + "MXNET" + ], + "type": "string", + "default": "JOB_TYPE_UNSPECIFIED", + "description": " - MPI: XGBOOST = 4;", + "name": "type", + "in": "query" + }, + { + "type": "boolean", + "description": "是否删除关联的任务分析工作负载", + "name": "deleteAnalysis", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + }, + "delete": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_DeleteJob", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "deleteAnalysis": { + "type": "boolean", + "title": "是否删除关联的任务分析工作负载" + }, + "type": { + "$ref": "#/definitions/v1alpha1JobType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/jobs/{name}/actions": { + "post": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_DoJobAction", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/JobActionRequestAction" + }, + "params": { + "$ref": "#/definitions/JobActionRequestParams" + }, + "type": { + "$ref": "#/definitions/v1alpha1JobType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/jobs/{name}/schedulers": { + "put": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_ListSchedulers", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "analysis": { + "title": "任务分析", + "$ref": "#/definitions/v1alpha1AnalysisConfig" + }, + "baseConfig": { + "$ref": "#/definitions/v1alpha1JobCreationBaseConfig" + }, + "description": { + "type": "string" + }, + "roleConfig": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1JobRoleDifferenceConfig" + } + }, + "trainingConfig": { + "title": "训练配置", + "$ref": "#/definitions/v1alpha1TrainingConfig" + }, + "trainingMode": { + "$ref": "#/definitions/v1alpha1TrainingMode" + }, + "type": { + "$ref": "#/definitions/v1alpha1JobType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1JobSchedulersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/localqueues": { + "post": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_CreateLocalQueue", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateLocalQueueResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/notebooks": { + "get": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_ListNotebooks2", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "queueName", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNotebooksResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:type" + }, + "post": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_CreateNotebook", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "analysis": { + "title": "任务分析", + "$ref": "#/definitions/v1alpha1AnalysisConfig" + }, + "config": { + "$ref": "#/definitions/v1alpha1NotebookConfig" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string", + "required": [ + "name" + ] + }, + "priorityClass": { + "type": "string", + "title": "notebook Pod 的优先级,Baize 会内建三个优先级:\nbaize-high-priority\nbaize-medium-priority\nbaize-low-priority\n目前只支持这三个,后续可能会支持系统其他优先级。" + }, + "queueName": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/v1alpha1NotebookType" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Notebook" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/notebooks/{name}": { + "get": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_GetNotebook", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "是否删除关联的任务分析工作负载", + "name": "deleteAnalysis", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Notebook" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + }, + "put": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_UpdateNotebook", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "analysis": { + "title": "任务分析", + "$ref": "#/definitions/v1alpha1AnalysisConfig" + }, + "config": { + "$ref": "#/definitions/v1alpha1NotebookConfig" + }, + "description": { + "type": "string" + }, + "priorityClass": { + "type": "string", + "title": "notebook Pod 的优先级,Baize 会内建三个优先级:\nbaize-high-priority\nbaize-medium-priority\nbaize-low-priority\n目前只支持这三个,后续可能会支持系统其他优先级。" + }, + "queueName": { + "type": "string" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Notebook" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + }, + "delete": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_DeleteNotebook", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "deleteAnalysis": { + "type": "boolean", + "title": "是否删除关联的任务分析工作负载" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Notebook" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/notebooks/{name}/actions": { + "post": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_NotebookDoAction", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/NotebookActionRequestAction" + } + } + } + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Notebook" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/pvcs": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取 PVC 列表", + "operationId": "ClusterService_ListPVCs", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPVCsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:storageClass, capacity" + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/namespaces/{namespace}/resources/{name}/instances": { + "get": { + "tags": [ + "PodsManagement" + ], + "operationId": "PodsManagement_GetPodInstanceList", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "enum": [ + "JOB_TYPE_UNSPECIFIED", + "PYTORCH", + "TENSORFLOW", + "PADDLE", + "NOTEBOOK", + "INFERENCE", + "MXNET", + "MPI" + ], + "type": "string", + "default": "JOB_TYPE_UNSPECIFIED", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PodInstanceListResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/queues/{name}/capacites": { + "get": { + "tags": [ + "QueueManagement" + ], + "operationId": "QueueManagement_CheckQueue", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "enum": [ + "QUEUE_TYPE_UNSPECIFIED", + "KUEUE" + ], + "type": "string", + "default": "QUEUE_TYPE_UNSPECIFIED", + "description": "队列类型", + "name": "type", + "in": "query" + }, + { + "type": "string", + "name": "namespace", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CheckQueueResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/clusters/{cluster}/storage-classes": { + "get": { + "tags": [ + "ClusterService" + ], + "summary": "获取存储类列表", + "operationId": "ClusterService_ListStorageClasses", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListStorageClassesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:provisioner" + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/grafana-dashboards/dev-overview": { + "get": { + "tags": [ + "MetricsService" + ], + "summary": "开发者视角概览面板", + "operationId": "MetricsService_GetDevGrafanaDashboard", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "起始时间", + "name": "from", + "in": "query" + }, + { + "type": "string", + "format": "int64", + "description": "结束时间,且作为单值指标的时间点", + "name": "to", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GrafanaDashboard" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/jobs": { + "get": { + "tags": [ + "JobsManagement" + ], + "operationId": "JobsManagement_ListJobs", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "enum": [ + "JOB_TYPE_UNSPECIFIED", + "PYTORCH", + "TENSORFLOW", + "PADDLE", + "MPI", + "MXNET" + ], + "type": "string", + "default": "JOB_TYPE_UNSPECIFIED", + "description": "任务类型,如果为空,表示所有任务类型。\n\n - MPI: XGBOOST = 4;", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "cluster 表示查询所有集群的 Job。", + "name": "cluster", + "in": "query" + }, + { + "type": "string", + "description": "namespace 表示查询所有命名空间的 Job。", + "name": "namespace", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:trainingMode, runningDuration" + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/metrics/dev-dashboard-multiple-queries": { + "get": { + "tags": [ + "MetricsService" + ], + "summary": "查询开发者面板指标\ndeprecated, use GetDevGrafanaDashboard instead", + "operationId": "MetricsService_QueryDevDashboardMultipleVectors", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "array", + "items": { + "enum": [ + "DEV_DASH_QUERY_METRIC_UNSPECIFIED", + "DEV_DASH_QUERY_RUNNING_NOTEBOOKS", + "DEV_DASH_QUERY_TOTAL_NOTEBOOKS", + "DEV_DASH_QUERY_RUNNING_PYTORCH_JOBS", + "DEV_DASH_QUERY_TOTAL_PYTORCH_JOBS", + "DEV_DASH_QUERY_RUNNING_TENSORFLOW_JOBS", + "DEV_DASH_QUERY_TOTAL_TENSORFLOW_JOBS", + "DEV_DASH_QUERY_TOTAL_DATASETS", + "DEV_DASH_TASKS_STATS" + ], + "type": "string" + }, + "collectionFormat": "multi", + "name": "queryMetrics", + "in": "query" + }, + { + "type": "string", + "format": "uint64", + "name": "time", + "in": "query" + }, + { + "type": "string", + "name": "cluster", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1MultipleDevDashboardVectorQueryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + } + } + }, + "/apis/baize.io/v1alpha1/workspaces/{workspace}/notebooks": { + "get": { + "tags": [ + "NotebookService" + ], + "operationId": "NotebookService_ListNotebooks", + "parameters": [ + { + "type": "integer", + "format": "int32", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "cluster", + "in": "query" + }, + { + "type": "string", + "name": "namespace", + "in": "query" + }, + { + "type": "string", + "name": "queueName", + "in": "query" + }, + { + "type": "integer", + "format": "int64", + "description": "总共有多少条目,请求时可以不用传递", + "name": "page.total", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage", + "name": "page.page", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "description": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize", + "name": "page.pageSize", + "in": "query" + }, + { + "type": "string", + "description": "排序规则,支持字符串和数字类型的字段进行排序", + "name": "page.sort", + "in": "query" + }, + { + "type": "string", + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "name": "page.search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNotebooksResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "description": "额外支持的搜索、排序字段:type" + } + } + }, + "definitions": { + "DataSourceOptionsCondaPackageManager": { + "type": "string", + "default": "PACKAGE_MANAGER_UNSPECIFIED", + "enum": [ + "PACKAGE_MANAGER_UNSPECIFIED", + "PIP", + "CONDA" + ] + }, + "DataSourceOptionsGit": { + "type": "object", + "properties": { + "branch": { + "type": "string", + "title": "Git 分支名称,不填写默认为主分支" + }, + "commit": { + "type": "string", + "title": "需要 checkout 的 commit,不填写不做 checkout" + }, + "depth": { + "type": "integer", + "format": "int32", + "title": "克隆的深度,不填写克隆所有历史,填写 1\n只克隆最近一次提交,可以减少克隆时间,无法和 commit 同时使用" + }, + "submodules": { + "type": "boolean", + "title": "是否克隆子模块" + } + } + }, + "DataSourceOptionsS3": { + "type": "object", + "properties": { + "endpoint": { + "type": "string", + "title": "S3 访问端点,可以是域名或者 IP" + }, + "region": { + "type": "string", + "title": "S3 存储桶区域" + } + } + }, + "DatasetActionRequestAction": { + "type": "string", + "default": "ACTION_UNSPECIFIED", + "enum": [ + "ACTION_UNSPECIFIED", + "RERUN" + ] + }, + "DatasetBoundPVCAccessMode": { + "type": "string", + "default": "ACCESS_MODE_UNSPECIFIED", + "enum": [ + "ACCESS_MODE_UNSPECIFIED", + "READ_ONLY_MANY", + "READ_WRITE_ONCE", + "READ_WRITE_MANY" + ] + }, + "DatasetStatusPhase": { + "type": "string", + "title": "- PENDING: 刚创建完的状态\n - READY: 可以被挂载的状态\n - PROCESSING: 正在处理中的状态\n - FAILED: 处理失败的状态,无法被挂载", + "default": "DATA_SET_PHASE_UNSPECIFIED", + "enum": [ + "DATA_SET_PHASE_UNSPECIFIED", + "PENDING", + "READY", + "PROCESSING", + "FAILED" + ] + }, + "FrameworkTriton": { + "type": "object", + "properties": { + "backend": { + "title": "Triton 后端类型", + "$ref": "#/definitions/TritonBackend" + } + } + }, + "InferenceServingStatusModelStatus": { + "type": "object", + "properties": { + "accessPath": { + "type": "string", + "title": "模型的访问路径,如 /v2/llama/generate\n如果要能够直接访问,需要和 .status.access_base_url 拼接。" + }, + "name": { + "type": "string" + } + } + }, + "InferenceServingStatusPhase": { + "type": "string", + "default": "PHASE_UNSPECIFIED", + "enum": [ + "PHASE_UNSPECIFIED", + "PENDING", + "UPDATING_OR_CREATING", + "RUNNING", + "FAILED", + "DELETING", + "STOPPED" + ] + }, + "JobActionRequestAction": { + "type": "string", + "title": "- RESTART: 重启任务", + "default": "JOB_ACTION_UNSPECIFIED", + "enum": [ + "JOB_ACTION_UNSPECIFIED", + "RESTART", + "CHANGE_PRIORITY" + ] + }, + "JobActionRequestParams": { + "type": "object", + "properties": { + "priorityClass": { + "type": "string", + "title": "当 action = CHANGE_PRIORITY 时,需要传入 priority_class" + } + } + }, + "JobSchedulersResponseScheduler": { + "type": "object", + "properties": { + "alias": { + "type": "string" + }, + "default": { + "type": "boolean", + "title": "如果 default = true,表示默认应该选择的调度器,这个可能是配置在 training-center 的配置。" + }, + "enabledFeatures": { + "type": "array", + "items": { + "$ref": "#/definitions/SchedulerFeature" + } + }, + "name": { + "type": "string" + } + } + }, + "KubeVolumeVolumeType": { + "description": " - PERSISTENT_VOLUME_CLAIM: The volume is a persistent volume claim.", + "type": "string", + "default": "VOLUME_TYPE_UNSPECIFIED", + "enum": [ + "VOLUME_TYPE_UNSPECIFIED", + "PERSISTENT_VOLUME_CLAIM", + "DATASET", + "DATASET_RUNTIME_ENV" + ] + }, + "ModelInputFormat": { + "description": "- FORMAT_NONE: @@ .. cpp:enumerator:: Format::FORMAT_NONE = 0\n@@\n@@ The input has no specific format. This is the default.\n@@\n - FORMAT_NHWC: @@ .. cpp:enumerator:: Format::FORMAT_NHWC = 1\n@@\n@@ HWC image format. Tensors with this format require 3 dimensions\n@@ if the model does not support batching (max_batch_size = 0) or 4\n@@ dimensions if the model does support batching (max_batch_size\n@@ >= 1). In either case the 'dims' below should only specify the\n@@ 3 non-batch dimensions (i.e. HWC or CHW).\n@@\n - FORMAT_NCHW: @@ .. cpp:enumerator:: Format::FORMAT_NCHW = 2\n@@\n@@ CHW image format. Tensors with this format require 3 dimensions\n@@ if the model does not support batching (max_batch_size = 0) or 4\n@@ dimensions if the model does support batching (max_batch_size\n@@ >= 1). In either case the 'dims' below should only specify the\n@@ 3 non-batch dimensions (i.e. HWC or CHW).\n@@", + "type": "string", + "title": "@@\n@@ .. cpp:enum:: Format\n@@\n@@ The format for the input.\n@@", + "default": "FORMAT_NONE", + "enum": [ + "FORMAT_NONE", + "FORMAT_NHWC", + "FORMAT_NCHW" + ] + }, + "NotebookActionRequestAction": { + "type": "string", + "default": "ACTION_UNSPECIFIED", + "enum": [ + "ACTION_UNSPECIFIED", + "START", + "STOP" + ] + }, + "NotebookConfigKubeMetadata": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "NotebookConfigServiceType": { + "description": " - NODE_PORT: The notebook is exposed as a NodePort service.\n - LOAD_BALANCER: The notebook is exposed as a LoadBalancer service.", + "type": "string", + "default": "SERVICE_TYPE_UNSPECIFIED", + "enum": [ + "SERVICE_TYPE_UNSPECIFIED", + "NODE_PORT", + "LOAD_BALANCER" + ] + }, + "PodInstanceContainer": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "RelatedInstancesResponseInstance": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "SchedulerFeature": { + "type": "string", + "title": "- BINPACK: 任务队列", + "default": "FEATURE_UNSPECIFIED", + "enum": [ + "FEATURE_UNSPECIFIED", + "BINPACK", + "GANG", + "FAIR" + ] + }, + "SecretOptionsAkSkAuth": { + "type": "object", + "properties": { + "accessKey": { + "type": "string" + }, + "secretKey": { + "type": "string" + } + } + }, + "SecretOptionsAuthType": { + "type": "string", + "title": "- AUTH_TYPE_UNSPECIFIED: 不需要认证\n - BASIC: 使用用户名密码认证\n - SSH: 使用 SSH 证书认证\n - TOKEN: 使用 Token 认证\n - AK_SK: 使用 AK/SK 认证", + "default": "AUTH_TYPE_UNSPECIFIED", + "enum": [ + "AUTH_TYPE_UNSPECIFIED", + "BASIC", + "SSH", + "TOKEN", + "AK_SK" + ] + }, + "SecretOptionsBasicAuth": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "SecretOptionsSSHAuth": { + "type": "object", + "properties": { + "passphrase": { + "type": "string" + }, + "privateKey": { + "type": "string" + } + } + }, + "SecretOptionsTokenAuth": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "ServingAuthAuthType": { + "type": "string", + "default": "AUTH_TYPE_UNSPECIFIED", + "enum": [ + "AUTH_TYPE_UNSPECIFIED", + "TRITON_RESTRICTED_KEY" + ] + }, + "ServingAuthTritonRestrictedKeyValue": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "ServingConfigTritonModelConfig": { + "type": "object", + "properties": { + "customConfig": { + "type": "string", + "title": "用于自定义配置" + }, + "inputs": { + "type": "array", + "items": { + "$ref": "#/definitions/tritonModelInput" + } + }, + "maxBatchSize": { + "type": "integer", + "format": "int32" + }, + "outputs": { + "type": "array", + "items": { + "$ref": "#/definitions/tritonModelOutput" + } + } + } + }, + "ServingConfigTritonServingConfig": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/ServingConfigTritonModelConfig" + }, + "customModelConfig": { + "type": "object", + "title": "可以用于自定义 python 后端的模型配置,\n比如 model.py: \"import torch\\nimport torchvision\\nfrom torchvision import models\\n\\nmodel = models.resnet50(pretrained=True)\\nmodel.eval()\"\n暂时用不到", + "additionalProperties": { + "type": "string" + } + }, + "vllm": { + "title": "deprecated, DO NOT USE ME", + "$ref": "#/definitions/v1alpha1ServingConfigVLLM" + } + } + }, + "StatusPhase": { + "description": " - PENDING: The analysis is being prepared for use.\n - RUNNING: The analysis is active and ready to use.\n - STOPPED: The analysis is being stopped.\n - FAILED: The analysis is failed.", + "type": "string", + "default": "PHASE_UNSPECIFIED", + "enum": [ + "PHASE_UNSPECIFIED", + "PENDING", + "RUNNING", + "STOPPED", + "FAILED" + ] + }, + "TritonBackend": { + "type": "string", + "title": "- TRITON_BACKEND_VLLM: deprecated: DO NOT USE ME", + "default": "TRITON_BACKEND_UNSPECIFIED", + "enum": [ + "TRITON_BACKEND_UNSPECIFIED", + "TRITON_BACKEND_PYTORCH", + "TRITON_BACKEND_TENSORFLOW", + "TRITON_BACKEND_VLLM", + "TRITON_BACKEND_ONNX" + ] + }, + "VLLMLoraModel": { + "type": "object", + "properties": { + "relativePath": { + "type": "string", + "title": "模型文件相对于数据集的位置" + }, + "volume": { + "title": "数据集,不需要传 mountPath,会自动。", + "$ref": "#/definitions/commonKubeVolume" + } + } + }, + "commonAffinity": { + "description": "The following message is from k8s official: https://github.com/kubernetes/api/blob/master/core/v1/generated.proto\nAffinity is a group of affinity scheduling rules.", + "type": "object", + "properties": { + "nodeAffinity": { + "description": "Describes node affinity scheduling rules for the pod.", + "$ref": "#/definitions/commonNodeAffinity" + }, + "podAffinity": { + "description": "Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).", + "$ref": "#/definitions/commonPodAffinity" + }, + "podAntiAffinity": { + "description": "Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).", + "$ref": "#/definitions/commonPodAntiAffinity" + } + } + }, + "commonKubeEnv": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "commonKubeVolume": { + "type": "object", + "properties": { + "mountPath": { + "type": "string" + }, + "name": { + "type": "string" + }, + "readOnly": { + "type": "boolean" + }, + "type": { + "$ref": "#/definitions/KubeVolumeVolumeType" + } + } + }, + "commonLabelSelector": { + "type": "object", + "properties": { + "matchExpressions": { + "description": "matchExpressions is a list of label selector requirements. The requirements are ANDed.", + "type": "array", + "items": { + "$ref": "#/definitions/commonLabelSelectorRequirement" + } + }, + "matchLabels": { + "description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\nmap is equivalent to an element of matchExpressions, whose key field is \"key\", the\noperator is \"In\", and the values array contains only \"value\". The requirements are ANDed.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "commonLabelSelectorRequirement": { + "type": "object", + "properties": { + "key": { + "type": "string", + "title": "key is the label key that the selector applies to.\n+patchMergeKey=key\n+patchStrategy=merge" + }, + "operator": { + "description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist.", + "type": "string" + }, + "values": { + "description": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. This array is replaced during a strategic\nmerge patch.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "commonNodeAffinity": { + "description": "Node affinity is a group of node affinity scheduling rules.", + "type": "object", + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "description": "The scheduler will prefer to schedule pods to nodes that satisfy\nthe affinity expressions specified by this field, but it may choose\na node that violates one or more of the expressions. The node that is\nmost preferred is the one with the greatest sum of weights, i.e.\nfor each node that meets all of the scheduling requirements (resource\nrequest, requiredDuringScheduling affinity expressions, etc.),\ncompute a sum by iterating through the elements of this field and adding\n\"weight\" to the sum if the node matches the corresponding matchExpressions; the\nnode(s) with the highest sum are the most preferred.", + "type": "array", + "items": { + "$ref": "#/definitions/commonPreferredSchedulingTerm" + } + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "description": "If the affinity requirements specified by this field are not met at\nscheduling time, the pod will not be scheduled onto the node.\nIf the affinity requirements specified by this field cease to be met\nat some point during pod execution (e.g. due to an update), the system\nmay or may not try to eventually evict the pod from its node.", + "$ref": "#/definitions/commonNodeSelector" + } + } + }, + "commonNodeSelector": { + "type": "object", + "title": "A node selector represents the union of the results of one or more label queries\nover a set of nodes; that is, it represents the OR of the selectors represented\nby the node selector terms.\n+structType=atomic", + "properties": { + "nodeSelectorTerms": { + "description": "Required. A list of node selector terms. The terms are ORed.", + "type": "array", + "items": { + "$ref": "#/definitions/commonNodeSelectorTerm" + } + } + } + }, + "commonNodeSelectorRequirement": { + "description": "A node selector requirement is a selector that contains values, a key, and an operator\nthat relates the key and values.", + "type": "object", + "properties": { + "key": { + "description": "The label key that the selector applies to.", + "type": "string" + }, + "operator": { + "description": "Represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.", + "type": "string" + }, + "values": { + "description": "An array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or DoesNotExist,\nthe values array must be empty. If the operator is Gt or Lt, the values\narray must have a single element, which will be interpreted as an integer.\nThis array is replaced during a strategic merge patch.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "commonNodeSelectorTerm": { + "type": "object", + "title": "A null or empty node selector term matches no objects. The requirements of\nthem are ANDed.\nThe TopologySelectorTerm type implements a subset of the NodeSelectorTerm.\n+structType=atomic", + "properties": { + "matchExpressions": { + "description": "A list of node selector requirements by node's labels.", + "type": "array", + "items": { + "$ref": "#/definitions/commonNodeSelectorRequirement" + } + }, + "matchFields": { + "description": "A list of node selector requirements by node's fields.", + "type": "array", + "items": { + "$ref": "#/definitions/commonNodeSelectorRequirement" + } + } + } + }, + "commonPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32", + "title": "当前页索引,从 1 开始,为 0 时,会自动重置为默认值 constants.DefaultPage" + }, + "pageSize": { + "type": "integer", + "format": "int32", + "title": "每页数据量,为 -1 时表示查询全部,为 0 时会重置为默认值\nconstants.DefaultPageSize" + }, + "search": { + "description": "搜索关键字,支持模糊搜索,精准匹配和高级搜索.", + "type": "string" + }, + "sort": { + "type": "string", + "title": "排序规则,支持字符串和数字类型的字段进行排序" + }, + "total": { + "type": "integer", + "format": "int64", + "title": "总共有多少条目,请求时可以不用传递" + } + } + }, + "commonPodAffinity": { + "description": "Pod affinity is a group of inter pod affinity scheduling rules.", + "type": "object", + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "description": "The scheduler will prefer to schedule pods to nodes that satisfy\nthe affinity expressions specified by this field, but it may choose\na node that violates one or more of the expressions. The node that is\nmost preferred is the one with the greatest sum of weights, i.e.\nfor each node that meets all of the scheduling requirements (resource\nrequest, requiredDuringScheduling affinity expressions, etc.),\ncompute a sum by iterating through the elements of this field and adding\n\"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\nnode(s) with the highest sum are the most preferred.", + "type": "array", + "items": { + "$ref": "#/definitions/commonWeightedPodAffinityTerm" + } + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "description": "If the affinity requirements specified by this field are not met at\nscheduling time, the pod will not be scheduled onto the node.\nIf the affinity requirements specified by this field cease to be met\nat some point during pod execution (e.g. due to a pod label update), the\nsystem may or may not try to eventually evict the pod from its node.\nWhen there are multiple elements, the lists of nodes corresponding to each\npodAffinityTerm are intersected, i.e. all terms must be satisfied.", + "type": "array", + "items": { + "$ref": "#/definitions/commonPodAffinityTerm" + } + } + } + }, + "commonPodAffinityTerm": { + "type": "object", + "properties": { + "labelSelector": { + "description": "A label query over a set of resources, in this case pods.", + "$ref": "#/definitions/commonLabelSelector" + }, + "namespaceSelector": { + "description": "A label query over the set of namespaces that the term applies to.\nThe term is applied to the union of the namespaces selected by this field\nand the ones listed in the namespaces field.\nnull selector and null or empty namespaces list means \"this pod's namespace\".\nAn empty selector ({}) matches all namespaces.\nThis field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled.", + "$ref": "#/definitions/commonLabelSelector" + }, + "namespaces": { + "type": "array", + "title": "namespaces specifies a static list of namespace names that the term applies to.\nThe term is applied to the union of the namespaces listed in this field\nand the ones selected by namespaceSelector.\nnull or empty namespaces list and null namespaceSelector means \"this pod's namespace\"", + "items": { + "type": "string" + } + }, + "topologyKey": { + "description": "This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\nthe labelSelector in the specified namespaces, where co-located is defined as running on a node\nwhose value of the label with key topologyKey matches that of any node on which any of the\nselected pods is running.\nEmpty topologyKey is not allowed.", + "type": "string" + } + } + }, + "commonPodAntiAffinity": { + "description": "Pod anti affinity is a group of inter pod anti affinity scheduling rules.", + "type": "object", + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "description": "The scheduler will prefer to schedule pods to nodes that satisfy\nthe anti-affinity expressions specified by this field, but it may choose\na node that violates one or more of the expressions. The node that is\nmost preferred is the one with the greatest sum of weights, i.e.\nfor each node that meets all of the scheduling requirements (resource\nrequest, requiredDuringScheduling anti-affinity expressions, etc.),\ncompute a sum by iterating through the elements of this field and adding\n\"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\nnode(s) with the highest sum are the most preferred.", + "type": "array", + "items": { + "$ref": "#/definitions/commonWeightedPodAffinityTerm" + } + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "description": "If the anti-affinity requirements specified by this field are not met at\nscheduling time, the pod will not be scheduled onto the node.\nIf the anti-affinity requirements specified by this field cease to be met\nat some point during pod execution (e.g. due to a pod label update), the\nsystem may or may not try to eventually evict the pod from its node.\nWhen there are multiple elements, the lists of nodes corresponding to each\npodAffinityTerm are intersected, i.e. all terms must be satisfied.", + "type": "array", + "items": { + "$ref": "#/definitions/commonPodAffinityTerm" + } + } + } + }, + "commonPodConfig": { + "type": "object", + "title": "PodTemplateConfig is a configuration for a pod template,\nit includes the environment variables, volumes, resources, affinity and schedulerName.\nThe configuration is used to create a pod template for serving or job?", + "properties": { + "affinity": { + "description": "The affinity of the pod.", + "$ref": "#/definitions/commonAffinity" + }, + "kubeEnvs": { + "description": "The environment variables of the pod.", + "type": "array", + "items": { + "$ref": "#/definitions/commonKubeEnv" + } + }, + "kubeVolumes": { + "description": "The volumes of the pod.", + "type": "array", + "items": { + "$ref": "#/definitions/commonKubeVolume" + } + }, + "priorityClass": { + "type": "string", + "title": "the priority class of pod.\nbaize-high-priority\nbaize-medium-priority\nbaize-low-priority\n目前只支持这三个,后续可能会支持系统其他优先级。" + }, + "queue": { + "type": "string", + "title": "queue name" + }, + "resources": { + "description": "The resources of the pod.", + "$ref": "#/definitions/commonResources" + }, + "schedulerName": { + "description": "The name of the scheduler to use.", + "type": "string" + }, + "tolerationSeconds": { + "type": "string", + "format": "int64" + } + } + }, + "commonPreferredSchedulingTerm": { + "description": "An empty preferred scheduling term matches all objects with implicit weight 0\n(i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).", + "type": "object", + "properties": { + "preference": { + "description": "A node selector term, associated with the corresponding weight.", + "$ref": "#/definitions/commonNodeSelectorTerm" + }, + "weight": { + "description": "Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.", + "type": "integer", + "format": "int32" + } + } + }, + "commonResources": { + "type": "object", + "properties": { + "limits": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "requests": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "commonWeightedPodAffinityTerm": { + "type": "object", + "title": "The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)", + "properties": { + "podAffinityTerm": { + "description": "Required. A pod affinity term, associated with the corresponding weight.", + "$ref": "#/definitions/commonPodAffinityTerm" + }, + "weight": { + "description": "weight associated with matching the corresponding podAffinityTerm,\nin the range 1-100.", + "type": "integer", + "format": "int32" + } + } + }, + "googlerpcStatus": { + "type": "object", + "properties": { + "id": { + "description": "错误 ID,用于判断错误类型", + "type": "string" + }, + "message": { + "description": "错误消息,会自动切换中英文", + "type": "string" + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "protobufNullValue": { + "description": "`NullValue` is a singleton enumeration to represent the null value for the\n`Value` type union.\n\n The JSON representation for `NullValue` is JSON `null`.\n\n - NULL_VALUE: Null value.", + "type": "string", + "default": "NULL_VALUE", + "enum": [ + "NULL_VALUE" + ] + }, + "rpcStatus": { + "type": "object", + "properties": { + "id": { + "description": "错误 ID,用于判断错误类型", + "type": "string" + }, + "message": { + "description": "错误消息,会自动切换中英文", + "type": "string" + } + } + }, + "tritonDataType": { + "description": "- TYPE_INVALID: @@ .. cpp:enumerator:: DataType::INVALID = 0\n - TYPE_BOOL: @@ .. cpp:enumerator:: DataType::BOOL = 1\n - TYPE_UINT8: @@ .. cpp:enumerator:: DataType::UINT8 = 2\n - TYPE_UINT16: @@ .. cpp:enumerator:: DataType::UINT16 = 3\n - TYPE_UINT32: @@ .. cpp:enumerator:: DataType::UINT32 = 4\n - TYPE_UINT64: @@ .. cpp:enumerator:: DataType::UINT64 = 5\n - TYPE_INT8: @@ .. cpp:enumerator:: DataType::INT8 = 6\n - TYPE_INT16: @@ .. cpp:enumerator:: DataType::INT16 = 7\n - TYPE_INT32: @@ .. cpp:enumerator:: DataType::INT32 = 8\n - TYPE_INT64: @@ .. cpp:enumerator:: DataType::INT64 = 9\n - TYPE_FP16: @@ .. cpp:enumerator:: DataType::FP16 = 10\n - TYPE_FP32: @@ .. cpp:enumerator:: DataType::FP32 = 11\n - TYPE_FP64: @@ .. cpp:enumerator:: DataType::FP64 = 12\n - TYPE_STRING: @@ .. cpp:enumerator:: DataType::STRING = 13\n - TYPE_BF16: @@ .. cpp:enumerator:: DataType::BF16 = 14", + "type": "string", + "title": "@@\n@@.. cpp:enum:: DataType\n@@\n@@ Data types supported for input and output tensors.\n@@", + "default": "TYPE_INVALID", + "enum": [ + "TYPE_INVALID", + "TYPE_BOOL", + "TYPE_UINT8", + "TYPE_UINT16", + "TYPE_UINT32", + "TYPE_UINT64", + "TYPE_INT8", + "TYPE_INT16", + "TYPE_INT32", + "TYPE_INT64", + "TYPE_FP16", + "TYPE_FP32", + "TYPE_FP64", + "TYPE_STRING", + "TYPE_BF16" + ] + }, + "tritonModelInput": { + "type": "object", + "title": "@@\n@@.. cpp:var:: message ModelInput\n@@\n@@ An input required by the model.\n@@", + "properties": { + "allowRaggedBatch": { + "type": "boolean", + "title": "@@ .. cpp:var:: bool allow_ragged_batch\n@@\n@@ Whether or not the input is allowed to be \"ragged\" in a dynamically\n@@ created batch. Default is false indicating that two requests will\n@@ only be batched if this tensor has the same shape in both requests.\n@@ True indicates that two requests can be batched even if this tensor\n@@ has a different shape in each request.\n@@" + }, + "dataType": { + "title": "@@ .. cpp:var:: DataType data_type\n@@\n@@ The data-type of the input.\n@@", + "$ref": "#/definitions/tritonDataType" + }, + "dims": { + "type": "array", + "title": "@@ .. cpp:var:: int64 dims (repeated)\n@@\n@@ The dimensions/shape of the input tensor that must be provided\n@@ when invoking the inference API for this model.\n@@", + "items": { + "type": "string", + "format": "int64" + } + }, + "format": { + "title": "@@ .. cpp:var:: Format format\n@@\n@@ The format of the input. Optional.\n@@", + "$ref": "#/definitions/ModelInputFormat" + }, + "isShapeTensor": { + "type": "boolean", + "title": "@@ .. cpp:var:: bool is_shape_tensor\n@@\n@@ Whether or not the input is a shape tensor to the model. This field\n@@ is currently supported only for the TensorRT model. An error will be\n@@ generated if this specification does not comply with underlying\n@@ model.\n@@" + }, + "name": { + "type": "string", + "title": "@@ .. cpp:var:: string name\n@@\n@@ The name of the input.\n@@" + }, + "optional": { + "type": "boolean", + "title": "@@ .. cpp:var:: bool optional\n@@\n@@ Whether or not the input is optional for the model execution.\n@@ If true, the input is not required in the inference request.\n@@ Default value is false.\n@@" + }, + "reshape": { + "title": "@@ .. cpp:var:: ModelTensorReshape reshape\n@@\n@@ The shape expected for this input by the backend. The input will\n@@ be reshaped to this before being presented to the backend. The\n@@ reshape must have the same number of elements as the input shape\n@@ specified by 'dims'. Optional.\n@@", + "$ref": "#/definitions/tritonModelTensorReshape" + } + } + }, + "tritonModelOutput": { + "type": "object", + "title": "@@\n@@.. cpp:var:: message ModelOutput\n@@\n@@ An output produced by the model.\n@@", + "properties": { + "dataType": { + "title": "@@ .. cpp:var:: DataType data_type\n@@\n@@ The data-type of the output.\n@@", + "$ref": "#/definitions/tritonDataType" + }, + "dims": { + "type": "array", + "title": "@@ .. cpp:var:: int64 dims (repeated)\n@@\n@@ The dimensions/shape of the output tensor.\n@@", + "items": { + "type": "string", + "format": "int64" + } + }, + "isShapeTensor": { + "type": "boolean", + "title": "@@ .. cpp:var:: bool is_shape_tensor\n@@\n@@ Whether or not the output is a shape tensor to the model. This field\n@@ is currently supported only for the TensorRT model. An error will be\n@@ generated if this specification does not comply with underlying\n@@ model.\n@@" + }, + "labelFilename": { + "type": "string", + "title": "@@ .. cpp:var:: string label_filename\n@@\n@@ The label file associated with this output. Should be specified only\n@@ for outputs that represent classifications. Optional.\n@@" + }, + "name": { + "type": "string", + "title": "@@ .. cpp:var:: string name\n@@\n@@ The name of the output.\n@@" + }, + "reshape": { + "title": "@@ .. cpp:var:: ModelTensorReshape reshape\n@@\n@@ The shape produced for this output by the backend. The output will\n@@ be reshaped from this to the shape specified in 'dims' before being\n@@ returned in the inference response. The reshape must have the same\n@@ number of elements as the output shape specified by 'dims'. Optional.\n@@", + "$ref": "#/definitions/tritonModelTensorReshape" + } + } + }, + "tritonModelTensorReshape": { + "type": "object", + "title": "@@\n@@.. cpp:var:: message ModelTensorReshape\n@@\n@@ Reshape specification for input and output tensors.\n@@", + "properties": { + "shape": { + "type": "array", + "title": "@@ .. cpp:var:: int64 shape (repeated)\n@@\n@@ The shape to use for reshaping.\n@@", + "items": { + "type": "string", + "format": "int64" + } + } + } + }, + "v1alpha1AICluster": { + "type": "object", + "properties": { + "clusterStatus": { + "$ref": "#/definitions/v1alpha1ClusterStatus" + }, + "name": { + "type": "string" + }, + "withAiSuite": { + "type": "boolean" + } + } + }, + "v1alpha1Analysis": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "creationTimestamp": { + "type": "string", + "format": "date-time" + }, + "kubeVolumes": { + "description": "Which volume to mount to the monitor.", + "type": "array", + "items": { + "$ref": "#/definitions/commonKubeVolume" + } + }, + "logPath": { + "description": "The path that contains the tensorboard, visualdl, or other monitor logs.", + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "queueName": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha1AnalysisStatus" + }, + "type": { + "description": "The type of the monitor.", + "$ref": "#/definitions/v1alpha1AnalysisType" + }, + "workspace": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1AnalysisConfig": { + "type": "object", + "properties": { + "enabled": { + "description": "Whether to enable the monitor.", + "type": "boolean" + }, + "kubeVolumes": { + "description": "Which volume to mount to the monitor.", + "type": "array", + "items": { + "$ref": "#/definitions/commonKubeVolume" + } + }, + "logPath": { + "description": "The path that contains the tensorboard, visualdl, or other monitor logs.", + "type": "string" + }, + "type": { + "description": "The type of the monitor.", + "$ref": "#/definitions/v1alpha1AnalysisType" + } + } + }, + "v1alpha1AnalysisStatus": { + "type": "object", + "properties": { + "accessUrl": { + "description": "The url of the analysis (tensorboard, visualdl) panel.", + "type": "string" + }, + "message": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/StatusPhase" + } + } + }, + "v1alpha1AnalysisType": { + "description": "Different types of monitor.\n\n - TENSORBOARD: The monitor as TensorBoard.", + "type": "string", + "default": "TYPE_UNSPECIFIED", + "enum": [ + "TYPE_UNSPECIFIED", + "TENSORBOARD" + ] + }, + "v1alpha1CheckQueueResponse": { + "type": "object", + "properties": { + "exist": { + "type": "boolean" + }, + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + } + } + }, + "v1alpha1ClusterNamespace": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "clusterStatus": { + "$ref": "#/definitions/v1alpha1ClusterStatus" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1ClusterStatus": { + "type": "string", + "default": "CLUSTER_STATUS_UNSPECIFIED", + "enum": [ + "CLUSTER_STATUS_UNSPECIFIED", + "CLUSTER_STATUS_RUNNING", + "CLUSTER_STATUS_NOT_RUNNING", + "CLUSTER_STATUS_UNKNOWN" + ] + }, + "v1alpha1CreateLocalQueueResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha1QueueStatus" + }, + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + }, + "workspace": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1DataSource": { + "type": "object", + "properties": { + "options": { + "title": "非敏感数据配置参数", + "$ref": "#/definitions/v1alpha1DataSourceOptions" + }, + "type": { + "title": "数据源类型", + "$ref": "#/definitions/v1alpha1DataSourceType" + }, + "uri": { + "type": "string", + "title": "数据源地址,除去 GIT 类型之外的数据集都需要以协议开头,如:http://、https://、s3://、pvc://、nfs://" + } + } + }, + "v1alpha1DataSourceOptions": { + "type": "object", + "properties": { + "conda": { + "$ref": "#/definitions/v1alpha1DataSourceOptionsConda" + }, + "git": { + "$ref": "#/definitions/DataSourceOptionsGit" + }, + "http": { + "$ref": "#/definitions/v1alpha1DataSourceOptionsHttp" + }, + "s3": { + "$ref": "#/definitions/DataSourceOptionsS3" + } + } + }, + "v1alpha1DataSourceOptionsConda": { + "type": "object", + "properties": { + "condaEnvironmentYml": { + "type": "string" + }, + "gpuType": { + "type": "string", + "title": "是否使用 GPU, 为空表示不使用 GPU\n直接传 GPU 卡的 Resources name, 比如 nvidia.com/gpu, 或者 nvidia.com/vgpu" + }, + "packageManager": { + "$ref": "#/definitions/DataSourceOptionsCondaPackageManager" + }, + "pipExtraIndexUrl": { + "type": "string" + }, + "pipIndexUrl": { + "type": "string" + }, + "pipRequirementsTxt": { + "type": "string" + }, + "pythonVersion": { + "type": "string" + } + } + }, + "v1alpha1DataSourceOptionsHttp": { + "type": "object", + "properties": { + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1DataSourceType": { + "type": "string", + "default": "DATA_SOURCE_TYPE_UNSPECIFIED", + "enum": [ + "DATA_SOURCE_TYPE_UNSPECIFIED", + "GIT", + "S3", + "HTTP", + "PVC", + "NFS", + "CONDA" + ] + }, + "v1alpha1Dataset": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "cluster": { + "type": "string" + }, + "creationTimestamp": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "name": { + "type": "string", + "required": [ + "name" + ] + }, + "namespace": { + "type": "string" + }, + "pvcName": { + "type": "string", + "title": "需要挂载的 PVC 名称" + }, + "secretRef": { + "type": "string", + "title": "数据源敏感数据存储的 Secret 名称。" + }, + "source": { + "title": "定义数据源", + "$ref": "#/definitions/v1alpha1DataSource" + }, + "status": { + "$ref": "#/definitions/v1alpha1DatasetStatus" + } + } + }, + "v1alpha1DatasetBoundPVC": { + "type": "object", + "properties": { + "accessMode": { + "$ref": "#/definitions/DatasetBoundPVCAccessMode" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "capacity": { + "type": "string", + "format": "int64", + "title": "PVC 容量,单位为 bytes。" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "storageClassName": { + "type": "string", + "title": "currently we do not support custom pvc name.\n string name = 1;" + } + } + }, + "v1alpha1DatasetStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/DatasetStatusPhase" + } + } + }, + "v1alpha1DatasetSyncProcess": { + "type": "object", + "properties": { + "status": { + "title": "Dataset 状态,只有到 phase 为 PROCESSING 时,才需要展示", + "$ref": "#/definitions/v1alpha1DatasetStatus" + }, + "syncProcess": { + "type": "number", + "format": "float", + "title": "预热进度,0 - 100 之间的值,表示百分比。" + } + } + }, + "v1alpha1DevDashboardQueryMetric": { + "type": "string", + "default": "DEV_DASH_QUERY_METRIC_UNSPECIFIED", + "enum": [ + "DEV_DASH_QUERY_METRIC_UNSPECIFIED", + "DEV_DASH_QUERY_RUNNING_NOTEBOOKS", + "DEV_DASH_QUERY_TOTAL_NOTEBOOKS", + "DEV_DASH_QUERY_RUNNING_PYTORCH_JOBS", + "DEV_DASH_QUERY_TOTAL_PYTORCH_JOBS", + "DEV_DASH_QUERY_RUNNING_TENSORFLOW_JOBS", + "DEV_DASH_QUERY_TOTAL_TENSORFLOW_JOBS", + "DEV_DASH_QUERY_TOTAL_DATASETS", + "DEV_DASH_TASKS_STATS" + ] + }, + "v1alpha1DevDashboardVectorQueryResponse": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "metric": { + "$ref": "#/definitions/v1alpha1DevDashboardQueryMetric" + }, + "status": { + "$ref": "#/definitions/v1alpha1DevDashboardVectorQueryResponseStatus" + }, + "vector": { + "$ref": "#/definitions/v1alpha1Vector" + } + } + }, + "v1alpha1DevDashboardVectorQueryResponseStatus": { + "type": "string", + "default": "STATUS_UNSPECIFIED", + "enum": [ + "STATUS_UNSPECIFIED", + "SUCCESS", + "FAILURE" + ] + }, + "v1alpha1DeviceGPU": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "deviceUUID": { + "type": "string" + }, + "modelName": { + "type": "string" + }, + "nodeIP": { + "type": "string" + }, + "serialNumber": { + "type": "string" + }, + "totalFrameBufferMemory": { + "type": "string", + "format": "int64" + }, + "usedFrameBufferMemory": { + "type": "string", + "format": "int64" + }, + "vendor": { + "type": "string" + } + } + }, + "v1alpha1Framework": { + "type": "object", + "properties": { + "triton": { + "title": "Triton配置", + "$ref": "#/definitions/FrameworkTriton" + }, + "type": { + "title": "推理框架类型,目前支持Triton", + "$ref": "#/definitions/v1alpha1FrameworkType" + }, + "vllm": { + "$ref": "#/definitions/v1alpha1FrameworkVLLM" + } + } + }, + "v1alpha1FrameworkType": { + "type": "string", + "default": "FRAMEWORK_TYPE_UNSPECIFIED", + "enum": [ + "FRAMEWORK_TYPE_UNSPECIFIED", + "FRAMEWORK_TYPE_TRITON", + "FRAMEWORK_TYPE_VLLM" + ] + }, + "v1alpha1FrameworkVLLM": { + "type": "object", + "title": "VLLM Engine args" + }, + "v1alpha1GPUResourceSetting": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "title": "gpu workload type resources alias" + }, + "aliasZh": { + "type": "string", + "title": "gpu workload type resources zh alias" + }, + "description": { + "type": "string", + "title": "gpu workload type resources description" + }, + "isAllocatable": { + "type": "boolean", + "title": "Resource quota can be allocated" + }, + "key": { + "type": "string", + "title": "gpu workload type resources key" + }, + "range": { + "title": "gpu resource range", + "$ref": "#/definitions/v1alpha1ResourceRange" + } + } + }, + "v1alpha1GPUSetting": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "title": "alias is gpu card alias" + }, + "resource": { + "type": "array", + "title": "gpu card resource setting", + "items": { + "$ref": "#/definitions/v1alpha1GPUResourceSetting" + } + }, + "type": { + "type": "string", + "title": "type is gpu card type" + } + } + }, + "v1alpha1GPUSettingsResponse": { + "type": "object", + "title": "GPUSettingResponse is the response message for GPUSetting", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPUSetting" + } + } + } + }, + "v1alpha1GetDatasetCondaOptionsResponse": { + "type": "object", + "properties": { + "pythonVersions": { + "type": "array", + "title": "支持的 Python 版本", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1GrafanaDashboard": { + "type": "object", + "properties": { + "urlEN": { + "type": "string", + "title": "英文面板的 URL" + }, + "urlZH": { + "type": "string", + "title": "中文面板的 URL" + } + } + }, + "v1alpha1InferenceServing": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "authType": { + "$ref": "#/definitions/ServingAuthAuthType" + }, + "cluster": { + "type": "string" + }, + "framework": { + "$ref": "#/definitions/v1alpha1Framework" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "lastUpdated": { + "type": "string", + "format": "date-time" + }, + "models": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ServingConfig" + } + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "podConfig": { + "title": "kubernetes pod 配置", + "$ref": "#/definitions/commonPodConfig" + }, + "replicas": { + "type": "integer", + "format": "int32" + }, + "serviceConfig": { + "$ref": "#/definitions/v1alpha1ServiceConfig" + }, + "status": { + "$ref": "#/definitions/v1alpha1InferenceServingStatus" + } + } + }, + "v1alpha1InferenceServingStatus": { + "type": "object", + "properties": { + "accessBaseUrl": { + "type": "string", + "title": "服务访问地址" + }, + "availableReplicas": { + "type": "integer", + "format": "int32" + }, + "models": { + "type": "array", + "title": "模型状态,暂时只支持一个,这里用数组只是为了扩展", + "items": { + "$ref": "#/definitions/InferenceServingStatusModelStatus" + } + }, + "phase": { + "title": "推理服务状态", + "$ref": "#/definitions/InferenceServingStatusPhase" + } + } + }, + "v1alpha1Job": { + "type": "object", + "properties": { + "analysis": { + "title": "任务分析", + "$ref": "#/definitions/v1alpha1AnalysisConfig" + }, + "baseConfig": { + "$ref": "#/definitions/v1alpha1JobCreationBaseConfig" + }, + "cluster": { + "type": "string" + }, + "creationTimestamp": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string" + }, + "jobSpec": { + "type": "object" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1JobPhase" + }, + "roleConfig": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1JobRoleDifferenceConfig" + } + }, + "runningDuration": { + "type": "integer", + "format": "int32", + "title": "任务运行时长" + }, + "totalResources": { + "title": "任务总资源(对所有容器做统计)", + "$ref": "#/definitions/commonResources" + }, + "trainingConfig": { + "title": "训练配置", + "$ref": "#/definitions/v1alpha1TrainingConfig" + }, + "trainingMode": { + "$ref": "#/definitions/v1alpha1TrainingMode" + }, + "type": { + "$ref": "#/definitions/v1alpha1JobType" + } + } + }, + "v1alpha1JobCreationBaseConfig": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "image": { + "type": "string" + }, + "imagePullSecret": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "noOverrideEnvPath": { + "type": "boolean" + }, + "podConfig": { + "$ref": "#/definitions/commonPodConfig" + }, + "shmSize": { + "type": "integer", + "format": "int32", + "title": "SHM 空间的大小,单位 MB\n为 0 表示不分配 SHM 空间" + }, + "workingDir": { + "type": "string" + } + } + }, + "v1alpha1JobPhase": { + "type": "string", + "title": "- JOB_PHASE_UNSPECIFIED: Unspecified type.\n - CREATED: 任务创建成功。\n - RUNNING: 任务运行中。\n - FAILED: 任务运行失败。\n - SUCCEEDED: 任务运行成功。\n - SUSPENDED: 任务停止。", + "default": "JOB_PHASE_UNSPECIFIED", + "enum": [ + "JOB_PHASE_UNSPECIFIED", + "CREATED", + "RUNNING", + "FAILED", + "SUCCEEDED", + "SUSPENDED" + ] + }, + "v1alpha1JobRoleDifferenceConfig": { + "type": "object", + "properties": { + "replicas": { + "type": "integer", + "format": "int32" + }, + "resources": { + "$ref": "#/definitions/commonResources" + } + } + }, + "v1alpha1JobSchedulersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/JobSchedulersResponseScheduler" + } + } + } + }, + "v1alpha1JobType": { + "type": "string", + "title": "- MPI: XGBOOST = 4;", + "default": "JOB_TYPE_UNSPECIFIED", + "enum": [ + "JOB_TYPE_UNSPECIFIED", + "PYTORCH", + "TENSORFLOW", + "PADDLE", + "MPI", + "MXNET" + ] + }, + "v1alpha1ListAIClustersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1AICluster" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListAnalysisResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Analysis" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListClusterNamespaceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ClusterNamespace" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListDatasetResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Dataset" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListDevicesGPUsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1DeviceGPU" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListInferenceServingsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1InferenceServing" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListNotebooksResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Notebook" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListPVCsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaims" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListQueueResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Queue" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListStorageClassesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1StorageClass" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ListWorkspacesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Workspace" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1Matrix": { + "type": "object", + "properties": { + "matrix": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1SampleStream" + } + } + } + }, + "v1alpha1MultipleDevDashboardVectorQueryResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1DevDashboardVectorQueryResponse" + } + } + } + }, + "v1alpha1MultipleVectorQueryResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VectorQueryResponse" + } + } + } + }, + "v1alpha1Notebook": { + "type": "object", + "properties": { + "analysis": { + "title": "任务分析", + "$ref": "#/definitions/v1alpha1AnalysisConfig" + }, + "cluster": { + "type": "string" + }, + "config": { + "$ref": "#/definitions/v1alpha1NotebookConfig" + }, + "creationTimestamp": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "priorityClass": { + "type": "string" + }, + "queueName": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha1NotebookStatus" + }, + "type": { + "$ref": "#/definitions/v1alpha1NotebookType" + }, + "workspace": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1NotebookConfig": { + "type": "object", + "properties": { + "affinity": { + "description": "The affinity of the pod.", + "$ref": "#/definitions/commonAffinity" + }, + "enableSSH": { + "type": "boolean", + "title": "Control whether ssh service is enabled on notebooks" + }, + "image": { + "type": "string" + }, + "kubeEnvs": { + "type": "array", + "items": { + "$ref": "#/definitions/commonKubeEnv" + } + }, + "kubeMetadata": { + "$ref": "#/definitions/NotebookConfigKubeMetadata" + }, + "kubeVolumes": { + "type": "array", + "items": { + "$ref": "#/definitions/commonKubeVolume" + } + }, + "resources": { + "$ref": "#/definitions/commonResources" + }, + "runAsRoot": { + "type": "boolean" + }, + "serviceType": { + "title": "deprecated", + "$ref": "#/definitions/NotebookConfigServiceType" + }, + "token": { + "type": "string", + "title": "deprecated" + }, + "tolerationSeconds": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1NotebookImage": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/v1alpha1NotebookType" + } + } + }, + "v1alpha1NotebookImageListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NotebookImage" + } + } + } + }, + "v1alpha1NotebookStatus": { + "type": "object", + "properties": { + "accessUrl": { + "description": "The url of the notebook.", + "type": "string" + }, + "message": { + "description": "A human readable message indicating details about why the notebook is\nin this condition.", + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1NotebookStatusPhase" + } + } + }, + "v1alpha1NotebookStatusPhase": { + "description": " - PENDING: The notebook is being prepared for use.\n - RUNNING: The notebook is active and ready to use.\n - STOPPED: The notebook is being stopped.\n - FAILED: The notebook is failed.", + "type": "string", + "default": "PHASE_UNSPECIFIED", + "enum": [ + "PHASE_UNSPECIFIED", + "PENDING", + "RUNNING", + "STOPPED", + "FAILED" + ] + }, + "v1alpha1NotebookType": { + "type": "string", + "default": "TYPE_UNSPECIFIED", + "enum": [ + "TYPE_UNSPECIFIED", + "JUPYTER", + "CODE" + ] + }, + "v1alpha1PersistentVolumeClaims": { + "type": "object", + "properties": { + "capacity": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "storageClass": { + "type": "string" + } + } + }, + "v1alpha1PodInstance": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "containerReadyCount": { + "type": "integer", + "format": "int32" + }, + "containerTotalCount": { + "type": "integer", + "format": "int32" + }, + "containers": { + "type": "array", + "items": { + "$ref": "#/definitions/PodInstanceContainer" + } + }, + "creationTimestamp": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string", + "title": "pod name" + }, + "namespace": { + "type": "string" + }, + "nodeName": { + "type": "string" + }, + "phase": { + "type": "string", + "title": "Pod phase" + }, + "podIp": { + "type": "string" + }, + "resources": { + "$ref": "#/definitions/commonResources" + } + } + }, + "v1alpha1PodInstanceListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PodInstance" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1QueryMetric": { + "type": "string", + "default": "QUERY_METRIC_UNSPECIFIED", + "enum": [ + "QUERY_METRIC_UNSPECIFIED", + "QUERY_METRIC_GPU_INSTALLED_NODES", + "QUERY_METRIC_TOTAL_NODES", + "QUERY_METRIC_INUSE_GPUS", + "QUERY_METRIC_TOTAL_GPUS", + "QUERY_METRIC_INUSE_CPUS", + "QUERY_METRIC_TOTAL_CPUS", + "QUERY_METRIC_INUSE_MEM", + "QUERY_METRIC_TOTAL_MEM", + "QUERY_METRIC_INUSE_VGPU_MEM", + "QUERY_METRIC_TOTAL_VGPU_MEM", + "QUERY_METRIC_TOTAL_CLUSTERS" + ] + }, + "v1alpha1QueryTimeSeriesMetric": { + "type": "string", + "default": "QUERY_TIME_SERIES_UNSPECIFIED", + "enum": [ + "QUERY_TIME_SERIES_UNSPECIFIED", + "QUERY_TIME_SERIES_METRIC_GPU_DISTRIBUTION", + "QUERY_TIME_SERIES_METRIC_GPU_UTILIZATION" + ] + }, + "v1alpha1QueryTimeSeriesMetricRange": { + "type": "string", + "default": "QUERY_TIME_SERIES_METRIC_RANGES_UNSPECIFIED", + "enum": [ + "QUERY_TIME_SERIES_METRIC_RANGES_UNSPECIFIED", + "QUERY_TIME_SERIES_METRIC_RANGES_LAST_3_DAYS", + "QUERY_TIME_SERIES_METRIC_RANGES_LAST_7_DAYS", + "QUERY_TIME_SERIES_METRIC_RANGES_LAST_15_DAYS" + ] + }, + "v1alpha1QueryTimeSeriesVectorsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1TimeSeriesVectorQueryResponse" + } + } + } + }, + "v1alpha1Queue": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "cluster": { + "type": "string" + }, + "description": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1QueueResource" + } + }, + "resourcesAvailable": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1QueueResource" + } + }, + "status": { + "$ref": "#/definitions/v1alpha1QueueStatus" + }, + "strategy": { + "title": "队列策略", + "$ref": "#/definitions/v1alpha1QueueStrategy" + }, + "type": { + "title": "队列类型", + "$ref": "#/definitions/v1alpha1QueueType" + }, + "workspace": { + "type": "integer", + "format": "int32" + }, + "workspaceAlias": { + "type": "string" + } + } + }, + "v1alpha1QueueJSON": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + }, + "v1alpha1QueuePhase": { + "type": "string", + "default": "QUEUE_PHASE_UNSPECIFIED", + "enum": [ + "QUEUE_PHASE_UNSPECIFIED", + "READY" + ] + }, + "v1alpha1QueueResource": { + "type": "object", + "properties": { + "borrowingLimit": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1QueueStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1QueuePhase" + } + } + }, + "v1alpha1QueueStrategy": { + "type": "string", + "default": "QUEUE_STRATEGY_UNSPECIFIED", + "enum": [ + "QUEUE_STRATEGY_UNSPECIFIED", + "STRICT_FIFO", + "BEST_EFFORT_FIFO" + ] + }, + "v1alpha1QueueType": { + "type": "string", + "default": "QUEUE_TYPE_UNSPECIFIED", + "enum": [ + "QUEUE_TYPE_UNSPECIFIED", + "KUEUE" + ] + }, + "v1alpha1RelatedInstancesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/RelatedInstancesResponseInstance" + } + }, + "page": { + "$ref": "#/definitions/commonPagination" + } + } + }, + "v1alpha1ResourceRange": { + "type": "object", + "properties": { + "max": { + "type": "integer", + "format": "int32", + "title": "resource max value" + }, + "maxDesc": { + "type": "string", + "title": "max resource description" + }, + "min": { + "type": "integer", + "format": "int32", + "title": "resource min value" + }, + "minDesc": { + "type": "string", + "title": "min resource description" + } + } + }, + "v1alpha1ResourceType": { + "type": "string", + "default": "JOB_TYPE_UNSPECIFIED", + "enum": [ + "JOB_TYPE_UNSPECIFIED", + "PYTORCH", + "TENSORFLOW", + "PADDLE", + "NOTEBOOK", + "INFERENCE", + "MXNET", + "MPI" + ] + }, + "v1alpha1RestartPolicy": { + "type": "string", + "title": "- RESTART_POLICY_NEVER: 如果任务失败,则不重启任务。\n - RESTART_POLICY_ON_FAILURE: 如果任务失败,则重启任务,", + "default": "RESTART_POLICY_UNSPECIFIED", + "enum": [ + "RESTART_POLICY_UNSPECIFIED", + "RESTART_POLICY_NEVER", + "RESTART_POLICY_ON_FAILURE" + ] + }, + "v1alpha1Sample": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "values": { + "$ref": "#/definitions/v1alpha1SamplePair" + } + } + }, + "v1alpha1SamplePair": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "int64" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1SampleStream": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "values": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1SamplePair" + } + } + } + }, + "v1alpha1SecretOptions": { + "type": "object", + "properties": { + "akSk": { + "$ref": "#/definitions/SecretOptionsAkSkAuth" + }, + "authType": { + "title": "认证类型", + "$ref": "#/definitions/SecretOptionsAuthType" + }, + "basic": { + "$ref": "#/definitions/SecretOptionsBasicAuth" + }, + "ssh": { + "$ref": "#/definitions/SecretOptionsSSHAuth" + }, + "token": { + "$ref": "#/definitions/SecretOptionsTokenAuth" + } + } + }, + "v1alpha1ServiceConfig": { + "type": "object", + "properties": { + "serviceType": { + "$ref": "#/definitions/v1alpha1ServiceType" + } + } + }, + "v1alpha1ServiceType": { + "type": "string", + "default": "SERVICE_TYPE_UNSPECIFIED", + "enum": [ + "SERVICE_TYPE_UNSPECIFIED", + "NODE_PORT", + "LOAD_BALANCER", + "CLUSTER_IP" + ] + }, + "v1alpha1ServingAuth": { + "type": "object", + "properties": { + "authType": { + "title": "推理服务的认证方式", + "$ref": "#/definitions/ServingAuthAuthType" + }, + "tritonRestrictedKeyValue": { + "title": "Triton 服务的认证方式", + "$ref": "#/definitions/ServingAuthTritonRestrictedKeyValue" + } + } + }, + "v1alpha1ServingConfig": { + "type": "object", + "properties": { + "modelPath": { + "type": "string" + }, + "name": { + "type": "string" + }, + "triton": { + "$ref": "#/definitions/ServingConfigTritonServingConfig" + }, + "version": { + "type": "string" + }, + "vllm": { + "$ref": "#/definitions/v1alpha1ServingConfigVLLM" + } + } + }, + "v1alpha1ServingConfigVLLM": { + "type": "object", + "properties": { + "enableLora": { + "type": "boolean" + }, + "loraModels": { + "type": "array", + "items": { + "$ref": "#/definitions/VLLMLoraModel" + } + }, + "maxCpuLoras": { + "type": "integer", + "format": "int32" + }, + "maxLoras": { + "type": "integer", + "format": "int32" + }, + "maxLorasRank": { + "type": "integer", + "format": "int32" + }, + "tensorParallelSize": { + "type": "integer", + "format": "int32" + }, + "trustRemoteCode": { + "type": "boolean", + "title": "VLLM 模型的配置" + } + } + }, + "v1alpha1StorageClass": { + "type": "object", + "properties": { + "allowReclaim": { + "type": "boolean", + "title": "是否允许扩容" + }, + "cluster": { + "type": "string" + }, + "isDefault": { + "type": "boolean", + "title": "是否默认存储类" + }, + "name": { + "type": "string" + }, + "provisioner": { + "type": "string" + } + } + }, + "v1alpha1TimeSeriesVectorQueryResponse": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "matrix": { + "$ref": "#/definitions/v1alpha1Matrix" + }, + "metric": { + "$ref": "#/definitions/v1alpha1QueryTimeSeriesMetric" + }, + "status": { + "$ref": "#/definitions/v1alpha1TimeSeriesVectorQueryResponseStatus" + } + } + }, + "v1alpha1TimeSeriesVectorQueryResponseStatus": { + "type": "string", + "default": "STATUS_UNSPECIFIED", + "enum": [ + "STATUS_UNSPECIFIED", + "SUCCESS", + "FAILURE" + ] + }, + "v1alpha1TrainingConfig": { + "type": "object", + "properties": { + "maxRetries": { + "type": "integer", + "format": "int32", + "title": "最大重启次数" + }, + "maxTrainingDuration": { + "type": "string", + "format": "int64", + "title": "最大训练时长,以秒为单位" + }, + "restartPolicy": { + "$ref": "#/definitions/v1alpha1RestartPolicy" + } + } + }, + "v1alpha1TrainingMode": { + "type": "string", + "title": "- TRAINING_MODE_UNSPECIFIED: Unspecified type.\n - SINGLE: 单机模式。\n - DISTRIBUTED: 分布式模式。", + "default": "TRAINING_MODE_UNSPECIFIED", + "enum": [ + "TRAINING_MODE_UNSPECIFIED", + "SINGLE", + "DISTRIBUTED" + ] + }, + "v1alpha1UserPermission": { + "type": "object", + "properties": { + "isBaizeOwner": { + "type": "boolean", + "title": "string name =1;\n是否是 Baize 平台管理员" + } + } + }, + "v1alpha1Vector": { + "type": "object", + "properties": { + "vector": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Sample" + } + } + } + }, + "v1alpha1VectorQueryResponse": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "metric": { + "$ref": "#/definitions/v1alpha1QueryMetric" + }, + "status": { + "$ref": "#/definitions/v1alpha1VectorQueryResponseStatus" + }, + "vector": { + "$ref": "#/definitions/v1alpha1Vector" + } + } + }, + "v1alpha1VectorQueryResponseStatus": { + "type": "string", + "default": "STATUS_UNSPECIFIED", + "enum": [ + "STATUS_UNSPECIFIED", + "SUCCESS", + "FAILURE" + ] + }, + "v1alpha1Workspace": { + "type": "object", + "properties": { + "alias": { + "type": "string" + }, + "workspaceId": { + "type": "integer", + "format": "int32" + } + } + } + }, + "tags": [ + { + "name": "AnalysisManagement" + }, + { + "name": "ClusterService" + }, + { + "name": "DatasetManagement" + }, + { + "name": "DeviceService" + }, + { + "name": "JobsManagement" + }, + { + "name": "MetricsService" + }, + { + "name": "NotebookService" + }, + { + "name": "PermissionService" + }, + { + "name": "PodsManagement" + }, + { + "name": "QueueManagement" + }, + { + "name": "InferenceServingManagement" + }, + { + "name": "WorkspaceService" + } + ] +} diff --git a/docs/zh/docs/openapi/ghippo/index.md b/docs/zh/docs/openapi/ghippo/index.md new file mode 100644 index 0000000..4d6f136 --- /dev/null +++ b/docs/zh/docs/openapi/ghippo/index.md @@ -0,0 +1 @@ +# diff --git a/docs/zh/docs/openapi/ghippo/v0.31.0.json b/docs/zh/docs/openapi/ghippo/v0.31.0.json new file mode 100644 index 0000000..1babbff --- /dev/null +++ b/docs/zh/docs/openapi/ghippo/v0.31.0.json @@ -0,0 +1,12574 @@ +{ + "swagger": "2.0", + "info": { + "title": "全局管理", + "version": "v0.31.0" + }, + "tags": [ + { + "name": "About" + }, + { + "name": "Audit" + }, + { + "name": "BatchAudits" + }, + { + "name": "Client" + }, + { + "name": "Account" + }, + { + "name": "FeatureGate" + }, + { + "name": "GProducts" + }, + { + "name": "GProductLicenses" + }, + { + "name": "Group" + }, + { + "name": "IDP" + }, + { + "name": "KeycloakEvent" + }, + { + "name": "Login" + }, + { + "name": "LoginPage" + }, + { + "name": "Message" + }, + { + "name": "Oauth2" + }, + { + "name": "OIDC" + }, + { + "name": "Openapi" + }, + { + "name": "ProductNavigator" + }, + { + "name": "Publish" + }, + { + "name": "Role" + }, + { + "name": "SecurityPolicy" + }, + { + "name": "SmtpSetting" + }, + { + "name": "Theme" + }, + { + "name": "TopNavigator" + }, + { + "name": "Users" + }, + { + "name": "Webhook" + }, + { + "name": "Workspace" + }, + { + "name": "Ldap" + }, + { + "name": "Audit" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/apis/ghippo.io/v1alpha1/.well-known/openid-configuration": { + "get": { + "operationId": "OIDC_WellKnown", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oidcWellKnownResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "OIDC" + ] + } + }, + "/apis/ghippo.io/v1alpha1/about/developers": { + "get": { + "operationId": "About_ListDevelopers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/aboutListDevelopersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "About" + ] + } + }, + "/apis/ghippo.io/v1alpha1/about/opensources": { + "get": { + "operationId": "About_ListOpenSources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/aboutListOpenSourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "description": "page: 当前页码,默认值为1", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "每页数量,默认为 10", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "About" + ] + } + }, + "/apis/ghippo.io/v1alpha1/about/versions": { + "get": { + "operationId": "About_ListGProductVersions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/aboutListGProductVersionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "About" + ] + } + }, + "/apis/ghippo.io/v1alpha1/audits/batch": { + "post": { + "operationId": "BatchAudits_BatchInsertAudits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/batchauditBatchInsertAuditsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/batchauditBatchInsertAuditsRequest" + } + } + ], + "tags": [ + "BatchAudits" + ] + } + }, + "/apis/ghippo.io/v1alpha1/audits/clear": { + "get": { + "operationId": "Audit_GetAutoClearAuditTime", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetAutoClearAuditTimeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha1/audits/external": { + "get": { + "summary": "来自外部传递进来的审计日志,用于不经过apiserver的请求,例如直接请求keycloak的请求,由前端埋点调用", + "operationId": "Audit_ExternalAudit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditExternalAuditResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "externalType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "loginFailed", + "forgetPassword", + "resetPassword" + ], + "default": "loginFailed" + }, + { + "name": "resourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "code", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha1/audits/limit-range": { + "get": { + "operationId": "Audit_GetLimitRangeTime", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetLimitRangeTimeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha1/audits/reports/resources": { + "get": { + "operationId": "Audit_GetAuditResourceReport", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetAuditResourceReportResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha1/audits/reports/users": { + "get": { + "operationId": "Audit_GetAuditUserReport", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetAuditUserReportResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha1/auth-token": { + "get": { + "operationId": "Openapi_AuthToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditAuthTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Openapi" + ] + } + }, + "/apis/ghippo.io/v1alpha1/authenticate-with-password": { + "post": { + "summary": "gRPC 调用,不暴露给 OpenAPI", + "operationId": "Login_AuthenticateWithPassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginAuthenticateWithPasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/loginAuthenticateWithPasswordRequest" + } + } + ], + "tags": [ + "Login" + ] + } + }, + "/apis/ghippo.io/v1alpha1/certs": { + "get": { + "operationId": "Openapi_Certs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditCertsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Openapi" + ] + } + }, + "/apis/ghippo.io/v1alpha1/clients": { + "get": { + "operationId": "Client_ListClients", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clientListClientsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clientId", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Client" + ] + }, + "post": { + "operationId": "Client_CreateClient", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clientCreateClientResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/clientCreateClientRequest" + } + } + ], + "tags": [ + "Client" + ] + } + }, + "/apis/ghippo.io/v1alpha1/clients/{id}": { + "get": { + "operationId": "Client_GetClient", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clientGetClientResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Client" + ] + }, + "delete": { + "operationId": "Client_DeleteClient", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clientDeleteClientResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Client" + ] + }, + "put": { + "operationId": "Client_UpdateClient", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clientUpdateClientResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "baseUrl": { + "type": "string", + "title": "repeated string redirect_uris = 4 [(validate.rules).repeated.min_items = 1];" + } + } + } + } + ], + "tags": [ + "Client" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user": { + "get": { + "operationId": "Account_GetUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1currentuserGetUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/accesstoken": { + "post": { + "operationId": "Account_CreateAccessToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserCreateAccessTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/currentuserCreateAccessTokenRequest" + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/accesstokens": { + "get": { + "operationId": "Account_ListAccessTokens", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserListAccessTokensResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/accesstokens/{id}": { + "delete": { + "operationId": "Account_DeleteAccessToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserDeleteAccessTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/email": { + "put": { + "operationId": "Account_UpdateEmail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserUpdateEmailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/currentuserUpdateEmailRequest" + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/global-permissions": { + "get": { + "operationId": "Account_GetGlobalPermissions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserGetGlobalPermissionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/language": { + "put": { + "operationId": "Account_UpdateLanguage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserUpdateLanguageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/currentuserUpdateLanguageRequest" + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/password": { + "put": { + "operationId": "Account_UpdatePassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserUpdatePasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/currentuserUpdatePasswordRequest" + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/password-description": { + "get": { + "operationId": "Account_PasswordDescription", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserPasswordDescriptionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/set-password": { + "put": { + "operationId": "Account_SetCurrentUserPassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserSetCurrentUserPasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/currentuserSetCurrentUserPasswordRequest" + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/sshkeys": { + "get": { + "operationId": "Account_ListSSHKeys", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserListSSHKeysResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Account" + ] + }, + "post": { + "operationId": "Account_CreateSSHKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserCreateSSHKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/currentuserCreateSSHKeyRequest" + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/current-user/sshkeys/{sshkeyId}": { + "delete": { + "operationId": "Account_DeleteSSHKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserDeleteSSHKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "sshkeyId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "id", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Account" + ] + }, + "put": { + "operationId": "Account_UpdateSSHKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/currentuserUpdateSSHKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "sshkeyId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "sshKeyName": { + "type": "string" + }, + "publicKey": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Account" + ] + } + }, + "/apis/ghippo.io/v1alpha1/exclusiveresource-types": { + "get": { + "operationId": "Workspace_ListExclusiveResourceTypes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListExclusiveResourceTypesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/feature-gate": { + "get": { + "operationId": "FeatureGate_ListFeatureGates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/feature_gateListFeatureGatesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "FeatureGate" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folderrolenames": { + "get": { + "operationId": "Role_ListFolderRoleNames", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListFolderRoleNamesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folderroles/{name}/members-folders": { + "get": { + "operationId": "Role_ListMembersFoldersByFolderRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListMembersFoldersByFolderRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders": { + "get": { + "operationId": "Workspace_ListFolders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListFoldersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + }, + "post": { + "operationId": "Workspace_CreateFolder", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceCreateFolderResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/workspaceCreateFolderRequest" + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders-tree": { + "get": { + "operationId": "Workspace_ListFolderTree", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListFolderTreeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}": { + "get": { + "operationId": "Workspace_GetFolder", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceGetFolderResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + }, + "delete": { + "summary": "TODO: sub folder删不删?", + "operationId": "Workspace_DeleteFolder", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceDeleteFolderResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + }, + "put": { + "operationId": "Workspace_UpdateFolder", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceUpdateFolderResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "title": "string name = 1 [(validate.rules).string.min_len = 1];" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/authorize": { + "post": { + "operationId": "Workspace_Authorize", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceAuthorizeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "memberName": { + "type": "string", + "title": "string role_name = 2;" + }, + "memberType": { + "type": "string" + }, + "memberId": { + "type": "string" + }, + "roleNames": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/deauthorize": { + "put": { + "operationId": "Workspace_Deauthorize", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceDeauthorizeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "roleName": { + "type": "string" + }, + "memberName": { + "type": "string" + }, + "memberType": { + "type": "string" + }, + "memberId": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/groups": { + "get": { + "operationId": "Workspace_FolderListGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceFolderListGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/members-roles": { + "get": { + "operationId": "Workspace_ListMembersRolesByFolder", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListMembersRolesByFolderResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "memberName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "memberType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "roleName", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/permissions": { + "get": { + "operationId": "Workspace_FolderListPermissions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceFolderListPermissionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/reauthorize": { + "put": { + "operationId": "Workspace_Reauthorize", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceReauthorizeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "oldRoleName": { + "type": "string" + }, + "newRoleName": { + "type": "string" + }, + "memberName": { + "type": "string" + }, + "memberType": { + "type": "string" + }, + "memberId": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/folders/{folderId}/users": { + "get": { + "operationId": "Workspace_FolderListUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceFolderListUsersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "folderId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "pageSize", + "description": "每页条数", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "description": "当前页", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/gproduct-licenses": { + "get": { + "operationId": "GProductLicenses_ListGProductLicenses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseListGProductLicensesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "GProductLicenses" + ] + }, + "put": { + "operationId": "GProductLicenses_UpdateGProductLicenses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseUpdateGProductLicensesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/gproductlicenseUpdateGProductLicensesRequest" + } + } + ], + "tags": [ + "GProductLicenses" + ] + } + }, + "/apis/ghippo.io/v1alpha1/gproduct-licenses/esn": { + "get": { + "operationId": "GProductLicenses_GetGProductLicensesESN", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseGetGProductLicensesESNResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "GProductLicenses" + ] + } + }, + "/apis/ghippo.io/v1alpha1/gproduct-licenses/over-quota": { + "get": { + "operationId": "GProductLicenses_GetGProductLicensesOverQuota", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseGetGProductLicensesOverQuotaResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "GProductLicenses" + ] + } + }, + "/apis/ghippo.io/v1alpha1/gproduct-licenses/yaml": { + "get": { + "operationId": "GProductLicenses_GetGProductLicensesYaml", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseGetGProductLicenseYamlResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "GProductLicenses" + ] + } + }, + "/apis/ghippo.io/v1alpha1/gproduct-licenses/{id}": { + "get": { + "operationId": "GProductLicenses_GetGProductLicenses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseGetGProductLicensesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "GProductLicenses" + ] + }, + "delete": { + "operationId": "GProductLicenses_DeleteGProductLicenses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductlicenseDeleteProductLicensesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "GProductLicenses" + ] + } + }, + "/apis/ghippo.io/v1alpha1/gproducts": { + "get": { + "operationId": "GProducts_ListGProducts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/gproductListGProductsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "GProducts" + ] + } + }, + "/apis/ghippo.io/v1alpha1/groups": { + "get": { + "operationId": "Group_ListGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupListGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Group" + ] + }, + "post": { + "operationId": "Group_CreateGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupCreateGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/groupCreateGroupRequest" + } + } + ], + "tags": [ + "Group" + ] + } + }, + "/apis/ghippo.io/v1alpha1/groups/{id}": { + "get": { + "operationId": "Group_GetGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupGetGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Group" + ] + }, + "delete": { + "operationId": "Group_DeleteGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupDeleteGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Group" + ] + }, + "put": { + "operationId": "Group_UpdateGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupUpdateGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Group" + ] + } + }, + "/apis/ghippo.io/v1alpha1/groups/{id}/members": { + "get": { + "operationId": "Group_GroupMembers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupGroupMembersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Group" + ] + } + }, + "/apis/ghippo.io/v1alpha1/groups/{id}/members/{userId}": { + "delete": { + "operationId": "Group_DeleteUserFromGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupDeleteUserFromGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "userId", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Group" + ] + }, + "post": { + "operationId": "Group_AddUserToGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupAddUserToGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "userId", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Group" + ] + } + }, + "/apis/ghippo.io/v1alpha1/groups/{id}/roles": { + "get": { + "operationId": "Group_ListGroupRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupListGroupRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "type", + "description": "role type", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "authorized", + "description": "是否授权", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Group" + ] + }, + "put": { + "operationId": "Group_UpdateGroupRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupUpdateGroupRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "addRoles": { + "type": "array", + "items": { + "type": "string" + } + }, + "removeRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "Group" + ] + } + }, + "/apis/ghippo.io/v1alpha1/groups/{id}/subjects": { + "get": { + "operationId": "Group_ListGroupSubjects", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/groupListGroupSubjectResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Group" + ] + } + }, + "/apis/ghippo.io/v1alpha1/idp": { + "get": { + "operationId": "IDP_ListIDPs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpListIDPsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "IDP" + ] + }, + "post": { + "operationId": "IDP_CreateIDP", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpCreateIDPResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/idpCreateIDPRequest" + } + } + ], + "tags": [ + "IDP" + ] + } + }, + "/apis/ghippo.io/v1alpha1/idp/wellknown-url": { + "get": { + "operationId": "IDP_GetWellKnownUrl", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpGetWellKnownUrlResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "IDP" + ] + } + }, + "/apis/ghippo.io/v1alpha1/idp/{alias}": { + "get": { + "operationId": "IDP_GetIDP", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpGetIDPResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "alias", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "IDP" + ] + }, + "delete": { + "operationId": "IDP_DeleteIDP", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpDeleteIDPResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "alias", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "IDP" + ] + }, + "put": { + "operationId": "IDP_UpdateIDP", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpUpdateIDPResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "alias", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "displayName": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "clientAuthentications": { + "$ref": "#/definitions/idpClientAuthentications" + }, + "providerId": { + "$ref": "#/definitions/v1alpha1idpProviderType" + }, + "authorizationUrl": { + "type": "string" + }, + "userInfoUrl": { + "type": "string" + }, + "tokenUrl": { + "type": "string" + }, + "logoutUrl": { + "type": "string" + }, + "enableAutoLinkFlow": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + } + } + } + } + ], + "tags": [ + "IDP" + ] + } + }, + "/apis/ghippo.io/v1alpha1/idp/{alias}/redirect-url": { + "get": { + "operationId": "IDP_GetRedirectUrl", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/idpGetRedirectUrlResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "alias", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "IDP" + ] + } + }, + "/apis/ghippo.io/v1alpha1/keycloak-event": { + "post": { + "operationId": "KeycloakEvent_KeycloakEvent", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/keycloakeventKeycloakEventResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/keycloakeventKeycloakEventRequest" + } + } + ], + "tags": [ + "KeycloakEvent" + ] + } + }, + "/apis/ghippo.io/v1alpha1/login": { + "get": { + "operationId": "Login_RedirectLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginLoginGetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "callbackUrl", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Login" + ] + }, + "post": { + "operationId": "Login_OIDCLogin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginLoginPostResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/loginLoginPostRequest" + } + } + ], + "tags": [ + "Login" + ] + } + }, + "/apis/ghippo.io/v1alpha1/login-page/info": { + "get": { + "operationId": "LoginPage_GetInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginpageGetLoginPageInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "LoginPage" + ] + }, + "put": { + "operationId": "LoginPage_UpdateInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginpageUpdateLoginPageInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/loginpageUpdateLoginPageInfoRequest" + } + } + ], + "tags": [ + "LoginPage" + ] + } + }, + "/apis/ghippo.io/v1alpha1/login-page/reset": { + "post": { + "operationId": "LoginPage_ResetInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginpageResetLoginPageInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "LoginPage" + ] + } + }, + "/apis/ghippo.io/v1alpha1/login-page/version": { + "get": { + "operationId": "LoginPage_GetVersion", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginpageGetLoginPageVersionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "LoginPage" + ] + } + }, + "/apis/ghippo.io/v1alpha1/logout": { + "delete": { + "operationId": "Login_OIDCLogout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginLogoutResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Login" + ] + } + }, + "/apis/ghippo.io/v1alpha1/messages": { + "get": { + "operationId": "Message_ListMessages", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageListMessagesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "unreadCount", + "description": "是否只返回统计未读数量", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "read", + "description": "是否只返回已读或未读,传\"read\"或\"unread\"来区分,不传返回已读和未读的消息", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "all", + "read", + "unread" + ], + "default": "all" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/messages/count": { + "get": { + "operationId": "Message_GetMessagesCount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageGetMessagesCountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/messages/delete": { + "post": { + "operationId": "Message_DeleteMessages", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageDeleteMessagesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/messageDeleteMessagesRequest" + } + } + ], + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/messages/system/system-message": { + "get": { + "operationId": "Message_GetSystemMessage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageGetSystemMessageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/messages/toggle-unread": { + "get": { + "operationId": "Message_ToggleUnreadMessage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageToggleUnreadMessageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "next", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/messages/{id}": { + "get": { + "operationId": "Message_GetMessage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageGetMessageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/oauth2": { + "get": { + "operationId": "Oauth2_GetOauth2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oauthGetOauth2Response" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Oauth2" + ] + }, + "delete": { + "operationId": "Oauth2_DeleteOauth2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oauthDeleteOauth2Response" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "providerType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "wechatwork" + ], + "default": "wechatwork" + } + ], + "tags": [ + "Oauth2" + ] + }, + "post": { + "operationId": "Oauth2_CreateOauth2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oauthCreateOauth2Response" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/oauthCreateOauth2Request" + } + } + ], + "tags": [ + "Oauth2" + ] + }, + "put": { + "operationId": "Oauth2_UpdateOauth2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oauthUpdateOauth2Response" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/oauthUpdateOauth2Request" + } + } + ], + "tags": [ + "Oauth2" + ] + } + }, + "/apis/ghippo.io/v1alpha1/oauth2/redirect-domain": { + "get": { + "operationId": "Oauth2_GetOauth2RedirectDomain", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oauthGetOauth2RedirectDomainResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Oauth2" + ] + } + }, + "/apis/ghippo.io/v1alpha1/oidc/ghippo-client-config": { + "get": { + "operationId": "OIDC_GhippoClientConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oidcGhippoClientConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "OIDC" + ] + } + }, + "/apis/ghippo.io/v1alpha1/oidc/logout": { + "get": { + "operationId": "OIDC_RedirectFrontendLogout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oidcRedirectFrontendLogoutResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "OIDC" + ] + }, + "delete": { + "operationId": "OIDC_OIDCLogout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oidcOIDCLogoutResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "OIDC" + ] + } + }, + "/apis/ghippo.io/v1alpha1/oidc/token": { + "post": { + "operationId": "OIDC_OIDCToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oidcOIDCTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/oidcOIDCTokenRequest" + } + } + ], + "tags": [ + "OIDC" + ] + } + }, + "/apis/ghippo.io/v1alpha1/oidc/userinfo": { + "get": { + "operationId": "OIDC_OIDCUserInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/oidcOIDCUserInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "OIDC" + ] + } + }, + "/apis/ghippo.io/v1alpha1/permissions": { + "get": { + "operationId": "Role_ListAllPermissions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListAllPermissionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/platformroles/{name}/members": { + "get": { + "operationId": "Role_ListMembersByPlatformRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListMembersByPlatformRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/product-nav/info": { + "get": { + "operationId": "ProductNavigator_Info", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/productnavProductNavResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "ProductNavigator" + ] + } + }, + "/apis/ghippo.io/v1alpha1/publish/messages": { + "post": { + "operationId": "Publish_PublishMessage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/publishPublishMessageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/publishPublishMessageRequest" + } + } + ], + "tags": [ + "Publish" + ] + } + }, + "/apis/ghippo.io/v1alpha1/read-messages": { + "post": { + "operationId": "Message_SetReadMessages", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/messageSetReadMessagesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/messageSetReadMessagesRequest" + } + } + ], + "tags": [ + "Message" + ] + } + }, + "/apis/ghippo.io/v1alpha1/refresh-token": { + "post": { + "operationId": "Login_RefreshToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginRefreshTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/loginRefreshTokenRequest" + } + } + ], + "tags": [ + "Login" + ] + } + }, + "/apis/ghippo.io/v1alpha1/resourcequota-types": { + "get": { + "operationId": "Workspace_ListResourceQuotaTypes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListResourceQuotaTypesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/roles": { + "get": { + "operationId": "Role_ListRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "pageSize", + "description": "每页条数", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "description": "当前页", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "roleType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "query_all_role_type", + "query_system", + "query_custom" + ], + "default": "query_all_role_type" + }, + { + "name": "scope", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "query_all_auth_scope", + "query_platform", + "query_folder", + "query_workspace" + ], + "default": "query_all_auth_scope" + } + ], + "tags": [ + "Role" + ] + }, + "post": { + "operationId": "Role_CreateRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleCreateRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/roleCreateRoleRequest" + } + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/roles/check-role-name/{name}": { + "get": { + "operationId": "Role_CheckRoleName", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleCheckRoleNameResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/roles/role-member-count/{name}": { + "get": { + "operationId": "Role_GetRoleMemberCount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleGetRoleMemberCountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/roles/{name}": { + "get": { + "operationId": "Role_GetRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleGetRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Role" + ] + }, + "delete": { + "operationId": "Role_DeleteRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleDeleteRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Role" + ] + }, + "put": { + "operationId": "Role_UpdateRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleUpdateRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "description": { + "type": "string", + "title": "globalRoleType type = 2;" + }, + "perms": { + "type": "array", + "items": { + "$ref": "#/definitions/rolePermission" + }, + "title": "AuthScope scope = 3;" + } + } + } + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/accountlockout": { + "get": { + "operationId": "SecurityPolicy_GetAccountLockoutPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetAccountLockoutPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetAccountLockoutPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetAccountLockoutPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetAccountLockoutPolicyRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/logout": { + "get": { + "operationId": "SecurityPolicy_GetLogoutPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetLogoutPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetLogoutPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetLogoutPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetLogoutPolicyRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/mfa": { + "get": { + "operationId": "SecurityPolicy_GetMFA", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetMFAResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetMFA", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetMFAResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetMFARequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/password": { + "get": { + "operationId": "SecurityPolicy_GetPasswordPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetPasswordPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetPasswordPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetPasswordPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetPasswordPolicyRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/system": { + "get": { + "operationId": "SecurityPolicy_GetSystemSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetSystemSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetSystemSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetSystemSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetSystemSessionLimitRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/time": { + "get": { + "operationId": "SecurityPolicy_GetTimeSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetTimeSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetTimeSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetTimeSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetTimeSessionLimitRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/user": { + "get": { + "operationId": "SecurityPolicy_GetUserSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetUserSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetUserSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetUserSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetUserSessionLimitRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/securitypolicy/sessiontimeout": { + "get": { + "operationId": "SecurityPolicy_GetSessionTimeout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicyGetSessionTimeoutResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SecurityPolicy" + ] + }, + "put": { + "operationId": "SecurityPolicy_SetSessionTimeout", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/securitypolicySetSessionTimeoutResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/securitypolicySetSessionTimeoutRequest" + } + } + ], + "tags": [ + "SecurityPolicy" + ] + } + }, + "/apis/ghippo.io/v1alpha1/session-limit": { + "post": { + "operationId": "Login_CheckSessionLimit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/loginCheckSessionLimitResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/loginCheckSessionLimitRequest" + } + } + ], + "tags": [ + "Login" + ] + } + }, + "/apis/ghippo.io/v1alpha1/sharedresource-types": { + "get": { + "operationId": "Workspace_ListSharedResourceTypes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListSharedResourceTypesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/smtp-setting": { + "get": { + "operationId": "SmtpSetting_GetSmtpServer", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/smtpsettingGetSmtpServerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SmtpSetting" + ] + }, + "put": { + "operationId": "SmtpSetting_SetSmtpServer", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/smtpsettingSetSmtpServerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/smtpsettingSetSmtpServerRequest" + } + } + ], + "tags": [ + "SmtpSetting" + ] + } + }, + "/apis/ghippo.io/v1alpha1/smtp-setting/conn-test": { + "post": { + "operationId": "SmtpSetting_SmtpServerConnTest", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/smtpsettingSmtpConnTestResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/smtpsettingSmtpConnTestRequest" + } + } + ], + "tags": [ + "SmtpSetting" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/footer-theme": { + "get": { + "operationId": "Theme_GetFooterThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeGetFooterThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + }, + "post": { + "operationId": "Theme_SetFooterThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeSetFooterThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/themeSetFooterThemeConfigRequest" + } + } + ], + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/footer/reset": { + "post": { + "operationId": "Theme_ResetFooterThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeResetFooterThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/login_page": { + "get": { + "operationId": "Theme_GetLoginThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeGetLoginThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + }, + "post": { + "operationId": "Theme_SetLoginThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeSetLoginThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/themeSetLoginThemeConfigRequest" + } + } + ], + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/login_page.css": { + "get": { + "operationId": "Theme_GetLoginThemeCSS", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiHttpBody" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/login_page/reset": { + "post": { + "operationId": "Theme_ResetLoginThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeResetLoginThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/theme": { + "get": { + "operationId": "Theme_GetThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeGetThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + }, + "post": { + "operationId": "Theme_SetThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeSetThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/themeSetThemeConfigRequest" + } + } + ], + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/theme.css": { + "get": { + "operationId": "Theme_GetThemeCSS", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiHttpBody" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/themes/theme/reset": { + "post": { + "operationId": "Theme_ResetThemeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/themeResetThemeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Theme" + ] + } + }, + "/apis/ghippo.io/v1alpha1/top-nav": { + "post": { + "operationId": "TopNavigator_SetTopNav", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/topnavSetTopNavResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/topnavSetTopNavRequest" + } + } + ], + "tags": [ + "TopNavigator" + ] + } + }, + "/apis/ghippo.io/v1alpha1/top-nav/info": { + "get": { + "operationId": "TopNavigator_Info", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/topnavTopNavResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "TopNavigator" + ] + } + }, + "/apis/ghippo.io/v1alpha1/top-nav/reset": { + "post": { + "operationId": "TopNavigator_ResetTopNav", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/topnavResetTopNavResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "TopNavigator" + ] + } + }, + "/apis/ghippo.io/v1alpha1/update-quota-check": { + "post": { + "operationId": "Workspace_UpdateQuotaCheck", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceUpdateQuotaCheckResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/workspaceUpdateQuotaCheckRequest" + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users": { + "get": { + "operationId": "Users_ListUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userListUsersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "pageSize", + "description": "每页条数", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "description": "当前页", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Users" + ] + }, + "post": { + "operationId": "Users_CreateUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userCreateUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/userCreateUserRequest" + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/check-user-email/{username}": { + "get": { + "operationId": "Users_CheckUserEmail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userCheckUserEmailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/check/{username}": { + "get": { + "operationId": "Users_CheckUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userCheckUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/username/{username}": { + "get": { + "operationId": "Users_GetUserByName", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1userGetUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/without-password": { + "post": { + "operationId": "Users_CreateUserWithoutPassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userCreateUserWithoutPasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/userCreateUserWithoutPasswordRequest" + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}": { + "get": { + "operationId": "Users_GetUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1userGetUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + }, + "delete": { + "operationId": "Users_DeleteUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userDeleteUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + }, + "put": { + "operationId": "Users_UpdateUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userUpdateUserResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "email": { + "type": "string" + }, + "description": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "lastname": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/accesstoken": { + "post": { + "operationId": "Users_CreateUserAccessToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userCreateUserAccessTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/accesstokens": { + "get": { + "operationId": "Users_ListUserAccessTokens", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userListUserAccessTokensResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/accesstokens/{aid}": { + "delete": { + "operationId": "Users_DeleteUserAccessToken", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userDeleteUserAccessTokenResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "aid", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/groups": { + "get": { + "operationId": "Users_ListUserGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userListUserGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/mfa": { + "delete": { + "operationId": "Users_ResetUserMFA", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userResetUserMFAResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/password": { + "put": { + "operationId": "Users_SetUserPassword", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userSetUserPasswordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/roles": { + "get": { + "operationId": "Users_ListUserRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userListUserRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "search", + "description": "搜索关键字", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "type", + "description": "role type", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "authorized", + "description": "是否授权", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Users" + ] + }, + "put": { + "operationId": "Users_UpdateUserRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userUpdateUserRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "addRoles": { + "type": "array", + "items": { + "type": "string" + } + }, + "removeRoles": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{id}/subjects": { + "get": { + "operationId": "Users_ListUserSubjects", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userListUserSubjectResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/users/{username}/sshkeys/verify": { + "post": { + "operationId": "Users_VerifyUserSSHPublicKey", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/userVerifyUserSSHPublicKeyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "username", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "publicKey": { + "type": "string", + "format": "byte" + } + } + } + } + ], + "tags": [ + "Users" + ] + } + }, + "/apis/ghippo.io/v1alpha1/webhook": { + "get": { + "operationId": "Webhook_ListWebhooksByClientId", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookListWebhooksByClientIdResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "clientId", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Webhook" + ] + }, + "post": { + "operationId": "Webhook_CreateWebhook", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookCreateWebhookResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/webhookCreateWebhookRequest" + } + } + ], + "tags": [ + "Webhook" + ] + } + }, + "/apis/ghippo.io/v1alpha1/webhook-record": { + "get": { + "operationId": "Webhook_ListWebhookRecordsByClientId", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookListWebhookRecordsByClientIdResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clientId", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "all", + "successful", + "failed" + ], + "default": "all" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Webhook" + ] + } + }, + "/apis/ghippo.io/v1alpha1/webhook-record/{id}": { + "get": { + "operationId": "Webhook_GetWebhookRecord", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookGetWebhookRecordResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Webhook" + ] + } + }, + "/apis/ghippo.io/v1alpha1/webhook/{id}": { + "get": { + "operationId": "Webhook_GetWebhook", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookGetWebhookResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Webhook" + ] + }, + "delete": { + "operationId": "Webhook_DeleteWebhook", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookDeleteWebhookResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Webhook" + ] + }, + "put": { + "operationId": "Webhook_UpdateWebhook", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/webhookUpdateWebhookResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "resourceType": { + "$ref": "#/definitions/v1alpha1webhookResourceType" + }, + "action": { + "$ref": "#/definitions/webhookAction" + }, + "url": { + "type": "string" + }, + "method": { + "$ref": "#/definitions/webhookMethod" + }, + "headers": { + "type": "string", + "title": "map headers = 8;" + }, + "requestParameter": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Webhook" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspace-sharedresource-quota": { + "get": { + "operationId": "Workspace_GetWorkspaceSharedResourceQuota", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceGetWorkspaceSharedResourceQuotaResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "resourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "resourceType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "notFormatted", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspace-sharedresource-quota-hard": { + "put": { + "operationId": "Workspace_SetQuotaHardForWorkspaceSharedResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceSetQuotaHardForWorkspaceSharedResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/workspaceSetQuotaHardForWorkspaceSharedResourceRequest" + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspacerolenames": { + "get": { + "operationId": "Role_ListWorkspaceRoleNames", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListWorkspaceRoleNamesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaceroles/{name}/members-workspaces": { + "get": { + "operationId": "Role_ListMembersWorkspacesByWorkspaceRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleListMembersWorkspacesByWorkspaceRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Role" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces": { + "get": { + "operationId": "Workspace_ListWorkspaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListWorkspacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + }, + "post": { + "operationId": "Workspace_CreateWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceCreateWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/workspaceCreateWorkspaceRequest" + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}": { + "get": { + "operationId": "Workspace_GetWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceGetWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + }, + "delete": { + "summary": "TODO: sub ws删不删?", + "operationId": "Workspace_DeleteWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceDeleteWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/available-exclusiveresources": { + "get": { + "operationId": "Workspace_ListAvailableExclusiveResourcesByWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListAvailableExclusiveResourcesByWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "resourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "resourceType", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "resourceScope", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/available-sharedresources": { + "get": { + "operationId": "Workspace_ListAvailableSharedResourcesByWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListAvailableSharedResourcesByWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "resourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "resourceType", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/bind-exclusiveresource": { + "post": { + "operationId": "Workspace_BindExclusiveResourceToWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceBindExclusiveResourceToWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "resourceScope": { + "type": "string" + }, + "gproduct": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/bind-sharedresource": { + "post": { + "operationId": "Workspace_BindSharedResourceToWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceBindSharedResourceToWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "resourceScope": { + "type": "string" + }, + "gproduct": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/bind-sharedresource-setquota": { + "post": { + "operationId": "Workspace_BindSharedResourceAndSetQuotaHardToWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceBindSharedResourceAndSetQuotaHardToWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "description": "cluster 资源 resource_scope 为空\nstring resource_scope = 4 [(validate.rules).string.min_len = 1];", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "gproduct": { + "type": "string" + }, + "quotaHard": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/exclusiveresources": { + "get": { + "operationId": "Workspace_ListExclusiveResourcesByWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListExclusiveResourcesByWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "resourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "resourceType", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/members-roles": { + "get": { + "operationId": "Workspace_ListMembersRolesByWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListMembersRolesByWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "memberName", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/move": { + "post": { + "operationId": "Workspace_MoveWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceMoveWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "destFolderId": { + "type": "integer", + "format": "int32" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/move-folders": { + "get": { + "operationId": "Workspace_MoveWorkspaceFolderList", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceMoveWorkspaceFolderListResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "folder", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/sharedresource/{resourceName}/quota-types": { + "get": { + "operationId": "Workspace_ListWorkspaceShareResourceQuotaTypes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListWorkspaceShareResourceQuotaTypesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "resourceName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/sharedresources": { + "get": { + "operationId": "Workspace_ListSharedResourcesByWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceListSharedResourcesByWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "resourceName", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/unbind-resource": { + "put": { + "operationId": "Workspace_UnbindResourceFromWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/workspaceUnbindResourceFromWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "resourceScope": { + "type": "string" + }, + "gproduct": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldap": { + "post": { + "operationId": "Ldap_CreateLdap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapCreateLdapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ldapCreateLdapRequest" + } + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldaps": { + "get": { + "operationId": "Ldap_ListLdaps", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapListLdapsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldaps/{id}": { + "get": { + "operationId": "Ldap_GetLdap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapGetLdapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Ldap" + ] + }, + "delete": { + "operationId": "Ldap_DeleteLdap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapDeleteLdapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Ldap" + ] + }, + "put": { + "operationId": "Ldap_UpdateLdap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapUpdateLdapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "vendor": { + "$ref": "#/definitions/ldapLdapVendor" + }, + "startTls": { + "type": "string", + "description": "Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling." + }, + "connectionUrl": { + "type": "string" + }, + "usersDn": { + "type": "string", + "title": "Full DN of LDAP tree where your users are. This DN is the parent of LDAP users.\nIt could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have DN like 'uid=john,ou=users,dc=example,dc=com'" + }, + "bindDn": { + "type": "string", + "title": "DN of LDAP admin, which will be used by Keycloak to access LDAP server" + }, + "bindCredential": { + "type": "string", + "description": "Password of LDAP admin." + }, + "userObjectClasses": { + "type": "string", + "description": "All values of LDAP objectClass attribute for users in LDAP divided by comma.\nFor example: 'inetOrgPerson, organizationalPerson' .\nNewly created Keycloak users will be written to LDAP with all those object classes and existing LDAP user records are found just if they contain all those object classes." + }, + "usernameLdapAttribute": { + "type": "string", + "title": "Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server vendors it can be 'uid'.\nFor Active directory it can be 'sAMAccountName' or 'cn'.\nThe attribute should be filled for all LDAP user records you want to import from LDAP to Keycloak" + }, + "fullSyncPeriod": { + "type": "string", + "title": "Period for full synchronization in seconds: -1 手动同步" + }, + "rdnLdapAttribute": { + "type": "string", + "description": "Name of the LDAP attribute, which is used as RDN (top attribute) of typical user DN.\nUsually it's the same as the Username LDAP attribute, however it is not required.\nFor example for Active directory, it is common to use 'cn' as RDN attribute when username attribute might be 'sAMAccountName'." + }, + "uuidLdapAttribute": { + "type": "string", + "description": "Name of the LDAP attribute, which is used as a unique object identifier (UUID) for objects in LDAP.\nFor many LDAP server vendors, it is 'entryUUID'; however some are different.\nFor example, for Active directory it should be 'objectGUID'.\nIf your LDAP server does not support the notion of UUID, you can use any other attribute that is supposed to be unique among LDAP users in tree.\nFor example 'uid' or 'entryDN'." + }, + "editMode": { + "type": "string", + "description": "READ_ONLY is a read-only LDAP store.\nWRITABLE means data will be synced back to LDAP on demand." + }, + "readTimeout": { + "type": "string", + "description": "LDAP read timeout in milliseconds. This timeout applies for LDAP read operations." + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "userLdapFilter": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldaps/{id}/group": { + "get": { + "operationId": "Ldap_GetLdapGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapGetLdapGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Ldap" + ] + }, + "post": { + "operationId": "Ldap_CreateLdapGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapCreateLdapGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "groupDn": { + "type": "string" + }, + "groupObjectClasses": { + "type": "string" + }, + "groupNameLdapAttribute": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldaps/{id}/sync": { + "get": { + "operationId": "Ldap_SyncUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapSyncUsersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldaps/{ldapId}/group/{id}": { + "delete": { + "operationId": "Ldap_DeleteLdapGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapDeleteLdapGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "ldapId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Ldap" + ] + }, + "put": { + "operationId": "Ldap_UpdateLdapGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapUpdateLdapGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "ldapId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "groupDn": { + "type": "string" + }, + "groupObjectClasses": { + "type": "string" + }, + "groupNameLdapAttribute": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/ldaps/{ldapId}/group/{id}/sync": { + "get": { + "operationId": "Ldap_SyncLdapGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapSyncLdapGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "ldapId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/testLdapAuthentication": { + "post": { + "operationId": "Ldap_TestLdapAuthentication", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapTestLdapAuthenticationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ldapTestLdapAuthenticationRequest" + } + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha2/testLdapConnection": { + "post": { + "operationId": "Ldap_TestLdapConnection", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ldapTestLdapConnectionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ldapTestLdapConnectionRequest" + } + } + ], + "tags": [ + "Ldap" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits": { + "get": { + "operationId": "Audit_ListAudits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditListAuditsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "sourceType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "all", + "succeeded", + "failed" + ], + "default": "all" + }, + { + "name": "searchType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "fuzzy", + "exact" + ], + "default": "fuzzy" + }, + { + "name": "searchUser", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "gproduct", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/clear": { + "post": { + "operationId": "Audit_ClearAuditsNow", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditClearAuditsNowResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/auditClearAuditsNowRequest" + } + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/export": { + "get": { + "operationId": "Audit_ExportAudits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiHttpBody" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sourceType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "gproduct", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "all", + "succeeded", + "failed" + ], + "default": "all" + }, + { + "name": "searchType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "fuzzy", + "exact" + ], + "default": "fuzzy" + }, + { + "name": "searchUser", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "exportType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "Csv", + "Excel" + ], + "default": "Csv" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/export/uri": { + "get": { + "operationId": "Audit_GetExportURI", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetExportURIResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "module", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "audit", + "kube_audit" + ], + "default": "audit" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/kube": { + "get": { + "operationId": "Audit_ListKubeAudits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditListKubeAuditsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "sourceType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "all", + "succeeded", + "failed" + ], + "default": "all" + }, + { + "name": "searchType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "fuzzy", + "exact" + ], + "default": "fuzzy" + }, + { + "name": "searchUser", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "搜索偏移量", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "分页大小", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/kube/clear": { + "post": { + "operationId": "Audit_ClearKubeAuditsNow", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditClearKubeAuditsNowResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/auditClearKubeAuditsNowRequest" + } + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/kube/export": { + "get": { + "operationId": "Audit_ExportKubeAudits", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiHttpBody" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sourceType", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sourceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "all", + "succeeded", + "failed" + ], + "default": "all" + }, + { + "name": "searchType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "fuzzy", + "exact" + ], + "default": "fuzzy" + }, + { + "name": "searchUser", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "exportType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "Csv", + "Excel" + ], + "default": "Csv" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/kube/{id}": { + "get": { + "operationId": "Audit_GetKubeAuditDetail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetKubeAuditDetailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/set-auto-clear": { + "put": { + "operationId": "Audit_SetAutoClearAuditSetting", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditSetAutoClearAuditSettingResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/auditSetAutoClearAuditSettingRequest" + } + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/set-auto-clear/kube": { + "put": { + "operationId": "Audit_SetAutoClearKubeAuditSetting", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditSetAutoClearKubeAuditSettingResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/auditSetAutoClearKubeAuditSettingRequest" + } + } + ], + "tags": [ + "Audit" + ] + } + }, + "/apis/ghippo.io/v1alpha3/audits/{id}": { + "get": { + "operationId": "Audit_GetAuditDetail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/auditGetAuditDetailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Audit" + ] + } + } + }, + "definitions": { + "aboutDeveloper": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "aboutGProductVersion": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "aboutListDevelopersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/aboutDeveloper" + } + } + } + }, + "aboutListGProductVersionsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/aboutGProductVersion" + } + } + } + }, + "aboutListOpenSourcesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/aboutOpenSource" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1aboutPagination" + } + } + }, + "aboutOpenSource": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "开源软件名称" + }, + "license": { + "type": "string", + "title": "开源协议" + } + } + }, + "apiHttpBody": { + "type": "object", + "properties": { + "contentType": { + "type": "string", + "description": "The HTTP Content-Type header value specifying the content type of the body." + }, + "data": { + "type": "string", + "format": "byte", + "description": "The HTTP request/response body as raw binary." + }, + "extensions": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + }, + "description": "Application specific response metadata. Must be set in the first response\nfor streaming APIs." + } + }, + "description": "Message that represents an arbitrary HTTP body. It should only be used for\npayload formats that can't be represented as JSON, such as raw binary or\nan HTML page.\n\n\nThis message can be used both in streaming and non-streaming API methods in\nthe request as well as the response.\n\nIt can be used as a top-level request field, which is convenient if one\nwants to extract parameters from either the URL or HTTP template into the\nrequest fields and also want access to the raw HTTP body.\n\nExample:\n\n message GetResourceRequest {\n // A unique request id.\n string request_id = 1;\n\n // The raw HTTP body is bound to this field.\n google.api.HttpBody http_body = 2;\n\n }\n\n service ResourceService {\n rpc GetResource(GetResourceRequest)\n returns (google.api.HttpBody);\n rpc UpdateResource(google.api.HttpBody)\n returns (google.protobuf.Empty);\n\n }\n\nExample with streaming methods:\n\n service CaldavService {\n rpc GetCalendar(stream google.api.HttpBody)\n returns (stream google.api.HttpBody);\n rpc UpdateCalendar(stream google.api.HttpBody)\n returns (stream google.api.HttpBody);\n\n }\n\nUse of this type only changes how the request and response bodies are\nhandled, all other features will continue to work unchanged." + }, + "auditAuditInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "auditName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "gproduct": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha3auditStatusType" + }, + "user": { + "type": "string" + }, + "client": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "createdAt": { + "type": "string" + } + } + }, + "auditAuthTokenResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "auditCertsResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "$ref": "#/definitions/auditKey" + } + } + } + }, + "auditClearAuditsNowRequest": { + "type": "object", + "properties": { + "days": { + "type": "integer", + "format": "int32" + } + } + }, + "auditClearAuditsNowResponse": { + "type": "object" + }, + "auditClearKubeAuditsNowRequest": { + "type": "object", + "properties": { + "days": { + "type": "integer", + "format": "int32" + } + } + }, + "auditClearKubeAuditsNowResponse": { + "type": "object" + }, + "auditExportTypes": { + "type": "string", + "enum": [ + "Csv", + "Excel" + ], + "default": "Csv" + }, + "auditExternalAuditResponse": { + "type": "object" + }, + "auditExternalType": { + "type": "string", + "enum": [ + "loginFailed", + "forgetPassword", + "resetPassword" + ], + "default": "loginFailed" + }, + "auditGetAuditDetailResponse": { + "type": "object", + "properties": { + "audit": { + "type": "string" + } + } + }, + "auditGetAuditResourceReportResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/auditResourceReport" + } + } + } + }, + "auditGetAuditUserReportResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/auditUserReport" + } + } + } + }, + "auditGetAutoClearAuditTimeResponse": { + "type": "object", + "properties": { + "kubeDays": { + "type": "integer", + "format": "int32" + }, + "ghippoDays": { + "type": "integer", + "format": "int32" + } + } + }, + "auditGetExportURIResponse": { + "type": "object", + "properties": { + "uri": { + "type": "string" + }, + "method": { + "$ref": "#/definitions/auditRequestMethod" + } + } + }, + "auditGetKubeAuditDetailResponse": { + "type": "object", + "properties": { + "audit": { + "type": "string" + } + } + }, + "auditGetLimitRangeTimeResponse": { + "type": "object", + "properties": { + "day": { + "type": "integer", + "format": "int32" + } + } + }, + "auditKey": { + "type": "object", + "properties": { + "kid": { + "type": "string" + }, + "kty": { + "type": "string" + }, + "e": { + "type": "string" + }, + "n": { + "type": "string" + }, + "alg": { + "type": "string" + }, + "use": { + "type": "string" + } + } + }, + "auditKubeAuditInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "auditName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "resourceName": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha3auditStatusType" + }, + "user": { + "type": "string" + }, + "client": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "createdAt": { + "type": "string" + } + } + }, + "auditListAuditsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/auditAuditInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha3auditPagination" + } + } + }, + "auditListKubeAuditsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/auditKubeAuditInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha3auditPagination" + } + } + }, + "auditModules": { + "type": "string", + "enum": [ + "audit", + "kube_audit" + ], + "default": "audit" + }, + "auditRequestMethod": { + "type": "string", + "enum": [ + "GET", + "POST", + "PUT", + "DELETE", + "PATCH" + ], + "default": "GET" + }, + "auditResourceReport": { + "type": "object", + "properties": { + "ResourceType": { + "type": "string" + }, + "EventName": { + "type": "string" + }, + "Count": { + "type": "integer", + "format": "int32" + } + } + }, + "auditSetAutoClearAuditSettingRequest": { + "type": "object", + "properties": { + "days": { + "type": "integer", + "format": "int32" + } + } + }, + "auditSetAutoClearAuditSettingResponse": { + "type": "object" + }, + "auditSetAutoClearKubeAuditSettingRequest": { + "type": "object", + "properties": { + "days": { + "type": "integer", + "format": "int32" + } + } + }, + "auditSetAutoClearKubeAuditSettingResponse": { + "type": "object" + }, + "auditUserReport": { + "type": "object", + "properties": { + "UserName": { + "type": "string" + }, + "TotalCount": { + "type": "integer", + "format": "int32" + }, + "SuccessCount": { + "type": "integer", + "format": "int32" + }, + "FailedCount": { + "type": "integer", + "format": "int32" + } + } + }, + "batchauditBatchInsertAuditsRequest": { + "type": "object", + "properties": { + "audits": { + "type": "string" + } + }, + "title": "@openapiv2-ignore" + }, + "batchauditBatchInsertAuditsResponse": { + "type": "object", + "title": "@openapiv2-ignore" + }, + "clientClientInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "secret": { + "type": "string", + "title": "bool enabled = 4;\nrepeated string redirect_uris = 5;" + }, + "baseUrl": { + "type": "string" + } + } + }, + "clientCreateClientRequest": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "baseUrl": { + "type": "string" + } + } + }, + "clientCreateClientResponse": { + "type": "object" + }, + "clientDeleteClientResponse": { + "type": "object" + }, + "clientGetClientResponse": { + "type": "object", + "properties": { + "client": { + "$ref": "#/definitions/clientClientInfo" + } + } + }, + "clientListClientsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/clientClientInfo" + } + } + } + }, + "clientUpdateClientResponse": { + "type": "object" + }, + "currentuserCreateAccessTokenRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + }, + "currentuserCreateAccessTokenResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "currentuserCreateSSHKeyRequest": { + "type": "object", + "properties": { + "sshKeyName": { + "type": "string" + }, + "publicKey": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + }, + "currentuserCreateSSHKeyResponse": { + "type": "object" + }, + "currentuserDeleteAccessTokenResponse": { + "type": "object" + }, + "currentuserDeleteSSHKeyResponse": { + "type": "object" + }, + "currentuserGetGlobalPermissionsResponse": { + "type": "object", + "properties": { + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/currentuserGlobalPermission" + } + } + } + }, + "currentuserGlobalPermission": { + "type": "string", + "enum": [ + "Unknown", + "ListUser", + "CreateUser", + "UpdateUser", + "DeleteUser", + "AuthorizeUser", + "ListGroup", + "CreateGroup", + "UpdateGroup", + "DeleteGroup", + "UpdateGroupUser", + "AuthorizeGroup", + "GetRole", + "GetIdp", + "CreateIdp", + "UpdateIdp", + "DeleteIdp", + "GetAudit", + "DeleteAudit", + "GetSecurityPolicy", + "UpdateSecurityPolicy", + "GetSMTP", + "UpdateSMTP", + "GetAppearance", + "UpdateAppearance", + "GetLicense", + "UpdateLicense", + "DeleteLicense", + "GetWorkspace", + "GetAboutPlatform", + "DeleteRole", + "UpdateRole", + "CreateRole", + "AccountingAndBilling", + "ReportManagement", + "GetClient", + "DeleteClient", + "UpdateClient", + "CreateClient", + "EditCluster", + "GetAccountingBilling", + "UpdateAccountingBilling", + "GetReportManagement", + "UpdateReportManagement", + "GetBillingSetting", + "UpdateBillingSetting" + ], + "default": "Unknown" + }, + "currentuserListAccessTokensResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1currentuserAccessToken" + } + } + } + }, + "currentuserListSSHKeysResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/currentuserSSHKey" + } + } + } + }, + "currentuserPasswordDescriptionResponse": { + "type": "object", + "properties": { + "allowModify": { + "type": "boolean" + }, + "emptyPassword": { + "type": "boolean" + } + } + }, + "currentuserSSHKey": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "sshKeyName": { + "type": "string" + }, + "publicKey": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + }, + "currentuserSetCurrentUserPasswordRequest": { + "type": "object", + "properties": { + "oldPassword": { + "type": "string" + }, + "newPassword": { + "type": "string" + } + } + }, + "currentuserSetCurrentUserPasswordResponse": { + "type": "object" + }, + "currentuserUpdateEmailRequest": { + "type": "object", + "properties": { + "email": { + "type": "string" + } + } + }, + "currentuserUpdateEmailResponse": { + "type": "object" + }, + "currentuserUpdateLanguageRequest": { + "type": "object", + "properties": { + "locale": { + "type": "string" + } + } + }, + "currentuserUpdateLanguageResponse": { + "type": "object" + }, + "currentuserUpdatePasswordRequest": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + } + }, + "currentuserUpdatePasswordResponse": { + "type": "object" + }, + "currentuserUpdateSSHKeyResponse": { + "type": "object" + }, + "feature_gateFeatureGateID": { + "type": "string", + "enum": [ + "CreateUserInWorkspace" + ], + "default": "CreateUserInWorkspace" + }, + "feature_gateFeatureGateInfo": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/feature_gateFeatureGateID", + "title": "唯一标志符" + }, + "description": { + "type": "string", + "title": "关于此 FeatureGate 的描述" + }, + "enabled": { + "type": "boolean", + "title": "是否启用" + } + } + }, + "feature_gateListFeatureGatesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/feature_gateFeatureGateInfo" + } + } + } + }, + "googlerpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "gproductListGProductsResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1gproductGProduct" + } + } + } + }, + "gproductlicenseDeleteProductLicensesResponse": { + "type": "object" + }, + "gproductlicenseGProductLicense": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "module": { + "type": "string" + }, + "level": { + "type": "string" + }, + "status": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + }, + "gproductlicenseGProductLicenseInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "module": { + "type": "string" + }, + "licenseKey": { + "type": "string" + }, + "licenseLevel": { + "type": "string" + }, + "physicalUsedCpu": { + "type": "string" + }, + "physicalMaxCpu": { + "type": "string" + }, + "virtualUsedCpu": { + "type": "string" + }, + "virtualMaxCpu": { + "type": "string" + }, + "expiredAt": { + "type": "string" + }, + "usedNode": { + "type": "string" + }, + "maxNode": { + "type": "string" + }, + "physicalUsedGpu": { + "type": "string" + }, + "physicalMaxGpu": { + "type": "string" + } + } + }, + "gproductlicenseGetGProductLicenseYamlResponse": { + "type": "object", + "properties": { + "yaml": { + "type": "string" + } + } + }, + "gproductlicenseGetGProductLicensesESNResponse": { + "type": "object", + "properties": { + "esn": { + "type": "string" + } + } + }, + "gproductlicenseGetGProductLicensesOverQuotaResponse": { + "type": "object", + "properties": { + "expireSoonLicenses": { + "type": "array", + "items": { + "$ref": "#/definitions/gproductlicenseGProductLicense" + } + }, + "expiredLicenses": { + "type": "array", + "items": { + "$ref": "#/definitions/gproductlicenseGProductLicense" + } + } + } + }, + "gproductlicenseGetGProductLicensesResponse": { + "type": "object", + "properties": { + "license": { + "$ref": "#/definitions/gproductlicenseGProductLicenseInfo" + } + } + }, + "gproductlicenseListGProductLicensesResponse": { + "type": "object", + "properties": { + "licenses": { + "type": "array", + "items": { + "$ref": "#/definitions/gproductlicenseGProductLicense" + } + } + } + }, + "gproductlicenseUpdateGProductLicensesRequest": { + "type": "object", + "properties": { + "yaml": { + "type": "string" + } + } + }, + "gproductlicenseUpdateGProductLicensesResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "licenses": { + "type": "array", + "items": { + "$ref": "#/definitions/gproductlicenseGProductLicense" + } + } + } + }, + "groupAddUserToGroupResponse": { + "type": "object" + }, + "groupCreateGroupRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "groupCreateGroupResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "groupDeleteGroupResponse": { + "type": "object" + }, + "groupDeleteUserFromGroupResponse": { + "type": "object" + }, + "groupGetGroupResponse": { + "type": "object", + "properties": { + "group": { + "$ref": "#/definitions/groupGroupInfo" + } + } + }, + "groupGroupInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "userCount": { + "type": "integer", + "format": "int64" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "canAuthorize": { + "type": "boolean" + } + } + }, + "groupGroupMembersResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1groupPagination" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1groupUser" + } + } + } + }, + "groupGroupSubject": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "roleId": { + "type": "string" + }, + "type": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "subjectName": { + "type": "string" + } + } + }, + "groupListGroupRolesResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1groupPagination" + }, + "authorizedCount": { + "type": "integer", + "format": "int64" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1groupRoleInfo" + } + } + } + }, + "groupListGroupSubjectResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1groupPagination" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/groupGroupSubject" + } + } + } + }, + "groupListGroupsResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1groupPagination" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/groupGroupInfo" + } + } + } + }, + "groupUpdateGroupResponse": { + "type": "object" + }, + "groupUpdateGroupRolesResponse": { + "type": "object" + }, + "idpClientAuthentications": { + "type": "string", + "enum": [ + "client_secret_post", + "client_secret_basic", + "client_secret_jwt", + "private_key_jwt" + ], + "default": "client_secret_post" + }, + "idpCreateIDPRequest": { + "type": "object", + "properties": { + "displayName": { + "type": "string", + "title": "string id = 1;" + }, + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "clientAuthentications": { + "$ref": "#/definitions/idpClientAuthentications" + }, + "providerId": { + "$ref": "#/definitions/v1alpha1idpProviderType" + }, + "authorizationUrl": { + "type": "string" + }, + "userInfoUrl": { + "type": "string" + }, + "tokenUrl": { + "type": "string" + }, + "logoutUrl": { + "type": "string" + }, + "enableAutoLinkFlow": { + "type": "boolean" + }, + "alias": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + } + }, + "idpCreateIDPResponse": { + "type": "object" + }, + "idpDeleteIDPResponse": { + "type": "object" + }, + "idpGetIDPResponse": { + "type": "object", + "properties": { + "idpInfo": { + "$ref": "#/definitions/idpIDPInfo" + } + } + }, + "idpGetRedirectUrlResponse": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + } + }, + "idpGetWellKnownUrlResponse": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + } + }, + "idpIDPInfo": { + "type": "object", + "properties": { + "displayName": { + "type": "string", + "title": "string id = 1;" + }, + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "clientAuthentications": { + "$ref": "#/definitions/idpClientAuthentications" + }, + "providerId": { + "$ref": "#/definitions/v1alpha1idpProviderType" + }, + "authorizationUrl": { + "type": "string" + }, + "userInfoUrl": { + "type": "string" + }, + "tokenUrl": { + "type": "string" + }, + "logoutUrl": { + "type": "string" + }, + "enableAutoLinkFlow": { + "type": "boolean" + }, + "alias": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + } + }, + "idpListIDPsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/idpIDPInfo" + } + } + } + }, + "idpUpdateIDPResponse": { + "type": "object", + "properties": { + "alias": { + "type": "string" + } + } + }, + "keycloakeventAuthDetails": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "ipAddress": { + "type": "string" + }, + "realmId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "username": { + "type": "string" + }, + "sessionId": { + "type": "string" + } + }, + "title": "参考 ExtendedAuthDetails 类的定义" + }, + "keycloakeventKeycloakEventRequest": { + "type": "object", + "properties": { + "realmId": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "operationType": { + "type": "string" + }, + "resourcePath": { + "type": "string" + }, + "representation": { + "type": "string", + "title": "json string" + }, + "uid": { + "type": "string" + }, + "authDetails": { + "$ref": "#/definitions/keycloakeventAuthDetails" + }, + "type": { + "type": "string" + }, + "details": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "error": { + "type": "string" + } + } + }, + "keycloakeventKeycloakEventResponse": { + "type": "object" + }, + "ldapCreateLdapGroupResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "ldapCreateLdapRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "vendor": { + "$ref": "#/definitions/ldapLdapVendor", + "title": "LDAP vendor (provider), only is other" + }, + "startTls": { + "type": "string", + "description": "Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling." + }, + "connectionUrl": { + "type": "string" + }, + "usersDn": { + "type": "string", + "title": "Full DN of LDAP tree where your users are. This DN is the parent of LDAP users.\nIt could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have DN like 'uid=john,ou=users,dc=example,dc=com'" + }, + "bindDn": { + "type": "string", + "title": "DN of LDAP admin, which will be used by Keycloak to access LDAP server" + }, + "bindCredential": { + "type": "string", + "description": "Password of LDAP admin." + }, + "userObjectClasses": { + "type": "string", + "description": "All values of LDAP objectClass attribute for users in LDAP divided by comma.\nFor example: 'inetOrgPerson, organizationalPerson' .\nNewly created Keycloak users will be written to LDAP with all those object classes and existing LDAP user records are found just if they contain all those object classes." + }, + "usernameLdapAttribute": { + "type": "string", + "title": "Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server vendors it can be 'uid'.\nFor Active directory it can be 'sAMAccountName' or 'cn'.\nThe attribute should be filled for all LDAP user records you want to import from LDAP to Keycloak" + }, + "fullSyncPeriod": { + "type": "string", + "title": "Period for full synchronization in seconds: -1 手动同步" + }, + "rdnLdapAttribute": { + "type": "string", + "description": "Name of the LDAP attribute, which is used as RDN (top attribute) of typical user DN.\nUsually it's the same as the Username LDAP attribute, however it is not required.\nFor example for Active directory, it is common to use 'cn' as RDN attribute when username attribute might be 'sAMAccountName'." + }, + "uuidLdapAttribute": { + "type": "string", + "description": "Name of the LDAP attribute, which is used as a unique object identifier (UUID) for objects in LDAP.\nFor many LDAP server vendors, it is 'entryUUID'; however some are different.\nFor example, for Active directory it should be 'objectGUID'.\nIf your LDAP server does not support the notion of UUID, you can use any other attribute that is supposed to be unique among LDAP users in tree.\nFor example 'uid' or 'entryDN'." + }, + "editMode": { + "type": "string", + "description": "READ_ONLY is a read-only LDAP store.\nWRITABLE means data will be synced back to LDAP on demand." + }, + "readTimeout": { + "type": "string", + "description": "LDAP read timeout in milliseconds. This timeout applies for LDAP read operations." + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "userLdapFilter": { + "type": "string" + } + } + }, + "ldapCreateLdapResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "ldapDeleteLdapGroupResponse": { + "type": "object" + }, + "ldapDeleteLdapResponse": { + "type": "object" + }, + "ldapGetLdapGroupResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "groupDn": { + "type": "string" + }, + "groupObjectClasses": { + "type": "string" + }, + "groupNameLdapAttribute": { + "type": "string" + } + } + }, + "ldapGetLdapResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "vendor": { + "$ref": "#/definitions/ldapLdapVendor" + }, + "startTls": { + "type": "string" + }, + "connectionUrl": { + "type": "string" + }, + "usersDn": { + "type": "string" + }, + "bindDn": { + "type": "string" + }, + "bindCredential": { + "type": "string" + }, + "userObjectClasses": { + "type": "string" + }, + "usernameLdapAttribute": { + "type": "string" + }, + "fullSyncPeriod": { + "type": "string" + }, + "rdnLdapAttribute": { + "type": "string" + }, + "uuidLdapAttribute": { + "type": "string" + }, + "editMode": { + "type": "string" + }, + "readTimeout": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "userLdapFilter": { + "type": "string" + } + } + }, + "ldapLdapVendor": { + "type": "string", + "enum": [ + "other", + "ad" + ], + "default": "other" + }, + "ldapListLdap": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "vendor": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + } + }, + "ldapListLdapsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/ldapListLdap" + } + } + } + }, + "ldapSyncLdapGroupsResponse": { + "type": "object", + "properties": { + "ignored": { + "type": "boolean" + }, + "added": { + "type": "integer", + "format": "int32" + }, + "updated": { + "type": "integer", + "format": "int32" + }, + "removed": { + "type": "integer", + "format": "int32" + }, + "failed": { + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string" + } + } + }, + "ldapSyncUsersResponse": { + "type": "object", + "properties": { + "ignored": { + "type": "boolean" + }, + "added": { + "type": "integer", + "format": "int32" + }, + "updated": { + "type": "integer", + "format": "int32" + }, + "removed": { + "type": "integer", + "format": "int32" + }, + "failed": { + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string" + } + } + }, + "ldapTestLdapAuthenticationRequest": { + "type": "object", + "properties": { + "bindDn": { + "type": "string", + "title": "DN of LDAP admin, which will be used by Keycloak to access LDAP server" + }, + "bindCredential": { + "type": "string", + "description": "Password of LDAP admin." + }, + "connectionUrl": { + "type": "string", + "title": "Connection URL to your LDAP server" + }, + "connectionTimeout": { + "type": "string", + "title": "LDAP Connection Timeout in milliseconds: 选填" + }, + "action": { + "type": "string", + "title": "测试事件类型: 选填, testAuthentication" + }, + "startTls": { + "type": "string", + "title": "Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling. 选填" + }, + "useTruststoreSpi": { + "type": "string", + "title": "Specifies whether LDAP connection will use the truststore SPI with the truststore configured.\n'Always' means that it will always use it.\n'Never' means that it will not use it.\n'Only for ldaps' means that it will use if your connection URL use ldaps.\n选填" + }, + "componentId": { + "type": "string", + "title": "Ldap id: 选填, uuid. 如果 bind_credential 的值等于 \"**********\", 则此字段是必填参" + } + } + }, + "ldapTestLdapAuthenticationResponse": { + "type": "object" + }, + "ldapTestLdapConnectionRequest": { + "type": "object", + "properties": { + "connectionUrl": { + "type": "string", + "title": "Connection URL to your LDAP server" + }, + "bindDn": { + "type": "string", + "title": "DN of LDAP admin, which will be used by Keycloak to access LDAP server: 选填" + }, + "bindCredential": { + "type": "string", + "title": "Password of LDAP admin. 选填" + }, + "connectionTimeout": { + "type": "string", + "title": "LDAP Connection Timeout in milliseconds: 选填" + }, + "action": { + "type": "string", + "title": "测试事件类型: 选填, testConnection" + }, + "startTls": { + "type": "string", + "description": "Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling." + }, + "useTruststoreSpi": { + "type": "string", + "title": "Specifies whether LDAP connection will use the truststore SPI with the truststore configured.\n'Always' means that it will always use it.\n'Never' means that it will not use it.\n'Only for ldaps' means that it will use if your connection URL use ldaps.\n选填" + }, + "componentId": { + "type": "string", + "title": "Ldap id: 选填, uuid" + } + } + }, + "ldapTestLdapConnectionResponse": { + "type": "object" + }, + "ldapUpdateLdapGroupResponse": { + "type": "object" + }, + "ldapUpdateLdapResponse": { + "type": "object" + }, + "loginAuthenticateWithPasswordRequest": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "loginAuthenticateWithPasswordResponse": { + "type": "object", + "properties": { + "idToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "loginCheckSessionLimitRequest": { + "type": "object", + "properties": { + "username": { + "type": "string" + } + } + }, + "loginCheckSessionLimitResponse": { + "type": "object" + }, + "loginLoginGetResponse": { + "type": "object" + }, + "loginLoginPostRequest": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "state": { + "type": "string" + }, + "sessionState": { + "type": "string" + }, + "callbackUrl": { + "type": "string" + }, + "useSso": { + "type": "string" + } + } + }, + "loginLoginPostResponse": { + "type": "object", + "properties": { + "idToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "loginLogoutResponse": { + "type": "object", + "properties": { + "externalLogoutUrl": { + "type": "string" + } + } + }, + "loginRefreshTokenRequest": { + "type": "object", + "properties": { + "refreshToken": { + "type": "string" + } + } + }, + "loginRefreshTokenResponse": { + "type": "object", + "properties": { + "idToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + } + } + }, + "loginpageGetLoginPageInfoResponse": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "format": "int32" + }, + "platformName": { + "type": "string" + }, + "copyright": { + "type": "string" + }, + "tabName": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "favicon": { + "type": "string" + }, + "background": { + "type": "string" + }, + "customBg": { + "type": "boolean" + }, + "isVideo": { + "type": "boolean" + } + } + }, + "loginpageGetLoginPageVersionResponse": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "format": "int32" + } + } + }, + "loginpageResetLoginPageInfoResponse": { + "type": "object" + }, + "loginpageUpdateLoginPageInfoRequest": { + "type": "object", + "properties": { + "platformName": { + "type": "string" + }, + "copyright": { + "type": "string" + }, + "tabName": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "favicon": { + "type": "string" + }, + "background": { + "type": "string" + }, + "isVideo": { + "type": "boolean" + } + } + }, + "loginpageUpdateLoginPageInfoResponse": { + "type": "object" + }, + "messageDeleteMessagesRequest": { + "type": "object", + "properties": { + "ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + } + }, + "messageDeleteMessagesResponse": { + "type": "object" + }, + "messageGetMessageResponse": { + "type": "object", + "properties": { + "message": { + "$ref": "#/definitions/messageMessageInfo" + } + } + }, + "messageGetMessagesCountResponse": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32" + }, + "readTotal": { + "type": "integer", + "format": "int32" + }, + "unreadTotal": { + "type": "integer", + "format": "int32" + } + } + }, + "messageGetSystemMessageResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "show": { + "type": "boolean" + } + } + }, + "messageListMessagesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/messageMessageInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1messagePagination" + } + } + }, + "messageMessageInfo": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "type": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "message": { + "type": "string" + }, + "read": { + "$ref": "#/definitions/messageReadType" + }, + "createdAt": { + "type": "string" + } + } + }, + "messageReadType": { + "type": "string", + "enum": [ + "all", + "read", + "unread" + ], + "default": "all" + }, + "messageSetReadMessagesRequest": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "ids": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + } + }, + "messageSetReadMessagesResponse": { + "type": "object" + }, + "messageToggleUnreadMessageResponse": { + "type": "object", + "properties": { + "message": { + "$ref": "#/definitions/messageMessageInfo" + } + } + }, + "oauthCreateOauth2Request": { + "type": "object", + "properties": { + "providerType": { + "$ref": "#/definitions/v1alpha1oauthProviderType" + }, + "displayName": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "agentId": { + "type": "string" + } + } + }, + "oauthCreateOauth2Response": { + "type": "object" + }, + "oauthDeleteOauth2Response": { + "type": "object" + }, + "oauthGetOauth2RedirectDomainResponse": { + "type": "object", + "properties": { + "redirectDomain": { + "type": "string" + } + } + }, + "oauthGetOauth2Response": { + "type": "object", + "properties": { + "providerType": { + "$ref": "#/definitions/v1alpha1oauthProviderType" + }, + "displayName": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "agentId": { + "type": "string" + } + } + }, + "oauthUpdateOauth2Request": { + "type": "object", + "properties": { + "providerType": { + "$ref": "#/definitions/v1alpha1oauthProviderType" + }, + "displayName": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "agentId": { + "type": "string" + } + } + }, + "oauthUpdateOauth2Response": { + "type": "object" + }, + "oidcGhippoClientConfigResponse": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "groupsClaim": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "userClaim": { + "type": "string" + }, + "clientSecret": { + "type": "string" + } + } + }, + "oidcOIDCLogoutResponse": { + "type": "object" + }, + "oidcOIDCTokenRequest": { + "type": "object", + "properties": { + "clientId": { + "type": "string" + }, + "grantType": { + "type": "string" + }, + "clientSecret": { + "type": "string" + }, + "code": { + "type": "string", + "title": "string response_type = 4 [(validate.rules).string.min_len = 1];" + }, + "redirectUri": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "scope": { + "type": "string" + } + } + }, + "oidcOIDCTokenResponse": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + }, + "idToken": { + "type": "string" + }, + "expiresIn": { + "type": "integer", + "format": "int32" + }, + "refreshExpiresIn": { + "type": "integer", + "format": "int32" + }, + "refreshToken": { + "type": "string" + }, + "tokenType": { + "type": "string" + }, + "notBeforePolicy": { + "type": "integer", + "format": "int32" + }, + "sessionState": { + "type": "string" + }, + "scope": { + "type": "string" + } + } + }, + "oidcOIDCUserInfoResponse": { + "type": "object", + "properties": { + "sub": { + "type": "string" + }, + "preferredUsername": { + "type": "string" + }, + "email": { + "type": "string" + }, + "locale": { + "type": "string" + } + } + }, + "oidcRedirectFrontendLogoutResponse": { + "type": "object" + }, + "oidcWellKnownResponse": { + "type": "object", + "properties": { + "issuer": { + "type": "string" + }, + "authorizationEndpoint": { + "type": "string" + }, + "tokenEndpoint": { + "type": "string" + }, + "jwksUri": { + "type": "string" + }, + "userinfoEndpoint": { + "type": "string" + }, + "introspectionEndpoint": { + "type": "string" + }, + "idTokenSigningAlgValuesSupported": { + "type": "array", + "items": { + "type": "string" + } + }, + "endSessionEndpoint": { + "type": "string" + } + } + }, + "productnavProductMenu": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "iconUrl": { + "type": "string" + }, + "target": { + "type": "string" + }, + "menus": { + "type": "array", + "items": { + "$ref": "#/definitions/productnavProductMenu" + } + } + } + }, + "productnavProductNavCategory": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "menus": { + "type": "array", + "items": { + "$ref": "#/definitions/productnavProductMenu" + } + } + } + }, + "productnavProductNavResponse": { + "type": "object", + "properties": { + "categories": { + "type": "array", + "items": { + "$ref": "#/definitions/productnavProductNavCategory" + } + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics." + } + }, + "additionalProperties": {}, + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(&foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := &pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := &pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": ,\n \"lastName\": \n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" + }, + "publishPublishMessageRequest": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "type": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "message": { + "type": "string" + }, + "messageUid": { + "type": "string" + } + } + }, + "publishPublishMessageResponse": { + "type": "object" + }, + "roleAuthScope": { + "type": "string", + "enum": [ + "platform", + "folder", + "workspace" + ], + "default": "platform", + "title": "- platform: unknown_auth_scope = 0;" + }, + "roleAuthScopeAllPermissions": { + "type": "object", + "properties": { + "authScope": { + "$ref": "#/definitions/roleAuthScope" + }, + "categoryPerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleCategoryAllPermissions" + } + } + } + }, + "roleCategory": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localizedName": { + "type": "string" + } + } + }, + "roleCategoryAllPermissions": { + "type": "object", + "properties": { + "category": { + "$ref": "#/definitions/roleCategory" + }, + "resourcePerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleResourceAllPermissions" + } + } + } + }, + "roleCategoryPermissions": { + "type": "object", + "properties": { + "category": { + "$ref": "#/definitions/roleCategory" + }, + "resourcePerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleResourcePermissions" + } + } + } + }, + "roleCheckRoleNameResponse": { + "type": "object", + "properties": { + "exist": { + "type": "boolean" + } + } + }, + "roleCreateRoleRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string", + "title": "string gproduct = 2 [(validate.rules).string = {min_len: 1, max_len: 63}];\nglobalRoleType type = 3;" + }, + "scope": { + "$ref": "#/definitions/roleAuthScope" + }, + "perms": { + "type": "array", + "items": { + "$ref": "#/definitions/rolePermission" + } + } + } + }, + "roleCreateRoleResponse": { + "type": "object" + }, + "roleDeleteRoleResponse": { + "type": "object" + }, + "roleGProductAllPermissions": { + "type": "object", + "properties": { + "gproduct": { + "$ref": "#/definitions/v1alpha1roleGProduct" + }, + "authscopePerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAuthScopeAllPermissions" + }, + "title": "map gproduct = 1;" + } + } + }, + "roleGProductPermissions": { + "type": "object", + "properties": { + "gproduct": { + "$ref": "#/definitions/v1alpha1roleGProduct", + "title": "string gproduct = 1;" + }, + "categoryPerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleCategoryPermissions" + } + } + } + }, + "roleGetRoleMemberCountResponse": { + "type": "object", + "properties": { + "userCount": { + "type": "integer", + "format": "int32" + }, + "groupCount": { + "type": "integer", + "format": "int32" + } + } + }, + "roleGetRoleResponse": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/roleglobalRoleType" + }, + "description": { + "type": "string" + }, + "scope": { + "$ref": "#/definitions/roleAuthScope" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "gproductPerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleGProductPermissions" + } + } + } + }, + "roleListAllPermissionsResponse": { + "type": "object", + "properties": { + "gproductPerms": { + "type": "array", + "items": { + "$ref": "#/definitions/roleGProductAllPermissions" + } + } + } + }, + "roleListFolderRoleNamesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/roleRoleName" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1rolePagination" + } + } + }, + "roleListMembersByPlatformRoleResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/roleMember" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1rolePagination" + } + } + }, + "roleListMembersFoldersByFolderRoleResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/roleMemberFolder" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1rolePagination" + } + } + }, + "roleListMembersWorkspacesByWorkspaceRoleResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/roleMemberWorkspace" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1rolePagination" + } + } + }, + "roleListRolesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1roleRoleInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1rolePagination" + } + } + }, + "roleListWorkspaceRoleNamesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/roleRoleName" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1rolePagination" + } + } + }, + "roleMember": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "roleMemberFolder": { + "type": "object", + "properties": { + "memberName": { + "type": "string" + }, + "memberType": { + "type": "string" + }, + "folderId": { + "type": "integer", + "format": "int32" + }, + "folderAlias": { + "type": "string" + }, + "memberId": { + "type": "string" + } + } + }, + "roleMemberWorkspace": { + "type": "object", + "properties": { + "memberName": { + "type": "string" + }, + "memberType": { + "type": "string" + }, + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "workspaceAlias": { + "type": "string" + }, + "memberId": { + "type": "string" + } + } + }, + "rolePermission": { + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "gproduct": { + "type": "string" + } + } + }, + "roleQueryAuthScope": { + "type": "string", + "enum": [ + "query_all_auth_scope", + "query_platform", + "query_folder", + "query_workspace" + ], + "default": "query_all_auth_scope" + }, + "roleQueryRoleType": { + "type": "string", + "enum": [ + "query_all_role_type", + "query_system", + "query_custom" + ], + "default": "query_all_role_type" + }, + "roleResourceAction": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localizedName": { + "type": "string" + }, + "tips": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "roleResourceActionWithDependency": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/roleResourceAction" + }, + "dependPerms": { + "type": "array", + "items": { + "$ref": "#/definitions/rolePermission" + } + } + } + }, + "roleResourceAllPermissions": { + "type": "object", + "properties": { + "resourceType": { + "$ref": "#/definitions/v1alpha1roleResourceType" + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/definitions/roleResourceActionWithDependency" + } + } + } + }, + "roleResourcePermissions": { + "type": "object", + "properties": { + "resourceType": { + "$ref": "#/definitions/v1alpha1roleResourceType" + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/definitions/roleResourceAction" + } + } + } + }, + "roleRoleName": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "authScope": { + "$ref": "#/definitions/roleAuthScope" + }, + "description": { + "type": "string" + } + } + }, + "roleUpdateRoleResponse": { + "type": "object" + }, + "roleglobalRoleType": { + "type": "string", + "enum": [ + "system", + "custom" + ], + "default": "system", + "title": "TODO: 改为 RoleType" + }, + "securitypolicyGetAccountLockoutPolicyResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxLoginFailures": { + "type": "integer", + "format": "int32" + }, + "maxFailuresWaitSeconds": { + "type": "integer", + "format": "int32" + }, + "failureResetSeconds": { + "type": "integer", + "format": "int32" + } + } + }, + "securitypolicyGetLogoutPolicyResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "securitypolicyGetMFAResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "securitypolicyGetPasswordPolicyResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/securitypolicyPasswordPolicyInfo" + } + } + } + }, + "securitypolicyGetSessionTimeoutResponse": { + "type": "object", + "properties": { + "timeoutSeconds": { + "type": "integer", + "format": "int32" + } + } + }, + "securitypolicyGetSystemSessionLimitResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + } + } + }, + "securitypolicyGetTimeSessionLimitResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "start": { + "type": "string" + }, + "end": { + "type": "string" + } + } + }, + "securitypolicyGetUserSessionLimitResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + } + } + }, + "securitypolicyPasswordPolicyInfo": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/securitypolicyPasswordPolicyType" + }, + "value": { + "type": "string" + } + } + }, + "securitypolicyPasswordPolicyType": { + "type": "string", + "enum": [ + "MinimumLengthLabel", + "NotRecentlyUsedLabel", + "NotUsernameLabel", + "NotEmailLabel", + "DigitsLabel", + "UppercaseCharactersLabel", + "LowercaseCharactersLabel", + "SpecialCharactersLabel", + "ExpirePasswordLabel" + ], + "default": "MinimumLengthLabel" + }, + "securitypolicySetAccountLockoutPolicyRequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxLoginFailures": { + "type": "integer", + "format": "int32", + "title": "failures count >= 0" + }, + "maxFailuresWaitSeconds": { + "type": "integer", + "format": "int32", + "title": "Lock time >= 60s" + }, + "failureResetSeconds": { + "type": "integer", + "format": "int32", + "title": "reset time >= 60s" + } + } + }, + "securitypolicySetAccountLockoutPolicyResponse": { + "type": "object" + }, + "securitypolicySetLogoutPolicyRequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "securitypolicySetLogoutPolicyResponse": { + "type": "object" + }, + "securitypolicySetMFARequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "securitypolicySetMFAResponse": { + "type": "object" + }, + "securitypolicySetPasswordPolicyRequest": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/securitypolicyPasswordPolicyInfo" + } + } + } + }, + "securitypolicySetPasswordPolicyResponse": { + "type": "object" + }, + "securitypolicySetSessionTimeoutRequest": { + "type": "object", + "properties": { + "timeoutSeconds": { + "type": "integer", + "format": "int32", + "title": "timeout > 3600s" + } + } + }, + "securitypolicySetSessionTimeoutResponse": { + "type": "object" + }, + "securitypolicySetSystemSessionLimitRequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + } + } + }, + "securitypolicySetSystemSessionLimitResponse": { + "type": "object" + }, + "securitypolicySetTimeSessionLimitRequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "start": { + "type": "string" + }, + "end": { + "type": "string" + } + } + }, + "securitypolicySetTimeSessionLimitResponse": { + "type": "object" + }, + "securitypolicySetUserSessionLimitRequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + } + } + }, + "securitypolicySetUserSessionLimitResponse": { + "type": "object" + }, + "smtpsettingGetSmtpServerResponse": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "format": "int32" + }, + "ssl": { + "type": "boolean" + }, + "starttls": { + "type": "boolean" + }, + "from": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "smtpsettingSetSmtpServerRequest": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "format": "int32" + }, + "ssl": { + "type": "boolean" + }, + "starttls": { + "type": "boolean" + }, + "from": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "smtpsettingSetSmtpServerResponse": { + "type": "object" + }, + "smtpsettingSmtpConnTestRequest": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "format": "int32" + }, + "ssl": { + "type": "boolean" + }, + "starttls": { + "type": "boolean" + }, + "from": { + "type": "string" + }, + "to": { + "type": "string" + }, + "user": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "smtpsettingSmtpConnTestResponse": { + "type": "object" + }, + "themeGetFooterThemeConfigResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "css": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "themeGetLoginThemeConfigResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "css": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "themeGetThemeConfigResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "css": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "themeResetFooterThemeConfigResponse": { + "type": "object" + }, + "themeResetLoginThemeConfigResponse": { + "type": "object" + }, + "themeResetThemeConfigResponse": { + "type": "object" + }, + "themeSetFooterThemeConfigRequest": { + "type": "object", + "properties": { + "css": { + "type": "string" + } + } + }, + "themeSetFooterThemeConfigResponse": { + "type": "object" + }, + "themeSetLoginThemeConfigRequest": { + "type": "object", + "properties": { + "css": { + "type": "string" + } + } + }, + "themeSetLoginThemeConfigResponse": { + "type": "object" + }, + "themeSetThemeConfigRequest": { + "type": "object", + "properties": { + "css": { + "type": "string" + } + } + }, + "themeSetThemeConfigResponse": { + "type": "object" + }, + "topnavResetTopNavResponse": { + "type": "object" + }, + "topnavSetTopNavRequest": { + "type": "object", + "properties": { + "icon": { + "type": "string" + }, + "favicon": { + "type": "string" + }, + "tabName": { + "type": "string" + } + } + }, + "topnavSetTopNavResponse": { + "type": "object" + }, + "topnavTopNavResponse": { + "type": "object", + "properties": { + "icon": { + "type": "string" + }, + "favicon": { + "type": "string" + }, + "tabName": { + "type": "string" + } + } + }, + "userCheckUserEmailResponse": { + "type": "object", + "properties": { + "existed": { + "type": "boolean" + } + } + }, + "userCheckUserResponse": { + "type": "object", + "properties": { + "existed": { + "type": "boolean" + } + } + }, + "userCreateUserAccessTokenResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "token": { + "type": "string" + } + } + }, + "userCreateUserRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "description": { + "type": "string" + }, + "temporary": { + "type": "boolean" + } + } + }, + "userCreateUserResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "userCreateUserWithoutPasswordRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "userCreateUserWithoutPasswordResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + }, + "userDeleteUserAccessTokenResponse": { + "type": "object" + }, + "userDeleteUserResponse": { + "type": "object" + }, + "userListUserAccessTokensResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1userAccessToken" + } + } + } + }, + "userListUserGroupsResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1userPagination" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1userGroup" + } + } + } + }, + "userListUserRolesResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1userPagination" + }, + "authorizedCount": { + "type": "integer", + "format": "int64" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1userRoleInfo" + } + } + } + }, + "userListUserSubjectResponse": { + "type": "object", + "properties": { + "pagination": { + "$ref": "#/definitions/v1alpha1userPagination" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/userUserSubject" + } + } + } + }, + "userListUsersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1userGetUserResponse" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1userPagination" + } + } + }, + "userResetUserMFAResponse": { + "type": "object" + }, + "userSetUserPasswordResponse": { + "type": "object" + }, + "userUpdateUserResponse": { + "type": "object" + }, + "userUpdateUserRolesResponse": { + "type": "object" + }, + "userUserSubject": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "subjectName": { + "type": "string" + } + } + }, + "userVerifyUserSSHPublicKeyResponse": { + "type": "object" + }, + "v1alpha1aboutPagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1currentuserAccessToken": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + }, + "v1alpha1currentuserGetUserResponse": { + "type": "object", + "properties": { + "uid": { + "type": "string" + }, + "username": { + "type": "string" + }, + "email": { + "type": "string" + }, + "locale": { + "type": "string" + }, + "source": { + "type": "string" + } + } + }, + "v1alpha1gproductGProduct": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "url": { + "type": "string" + }, + "uiAssetsUrl": { + "type": "string" + }, + "needImportLicense": { + "type": "boolean" + }, + "needUpdateExpiredLicense": { + "type": "boolean" + } + } + }, + "v1alpha1groupPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1groupRoleInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "authorized": { + "type": "boolean" + } + } + }, + "v1alpha1groupUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "v1alpha1idpProviderType": { + "type": "string", + "enum": [ + "oidc" + ], + "default": "oidc" + }, + "v1alpha1messagePagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1oauthProviderType": { + "type": "string", + "enum": [ + "wechatwork" + ], + "default": "wechatwork" + }, + "v1alpha1roleGProduct": { + "type": "object", + "properties": { + "gproduct": { + "type": "string" + }, + "localizedName": { + "type": "string" + } + } + }, + "v1alpha1rolePagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1roleResourceType": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "localizedName": { + "type": "string" + } + } + }, + "v1alpha1roleRoleInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/roleglobalRoleType" + }, + "description": { + "type": "string" + }, + "scope": { + "$ref": "#/definitions/roleAuthScope" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "v1alpha1userAccessToken": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "expiredAt": { + "type": "string" + } + } + }, + "v1alpha1userGetUserResponse": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "description": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "lastname": { + "type": "string" + }, + "source": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "lastLoginAt": { + "type": "string" + }, + "canAuthorize": { + "type": "boolean" + } + } + }, + "v1alpha1userGroup": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1userPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1userRoleInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "authorized": { + "type": "boolean" + } + } + }, + "v1alpha1webhookPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1webhookResourceType": { + "type": "string", + "enum": [ + "resource_type_user" + ], + "default": "resource_type_user" + }, + "v1alpha1webhookStatus": { + "type": "string", + "enum": [ + "all", + "successful", + "failed" + ], + "default": "all" + }, + "v1alpha1workspaceGroup": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "userCount": { + "type": "integer", + "format": "int64" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "canAuthorize": { + "type": "boolean" + }, + "authorized": { + "type": "boolean" + } + } + }, + "v1alpha1workspacePagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1workspaceUser": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "description": { + "type": "string" + }, + "firstname": { + "type": "string" + }, + "lastname": { + "type": "string" + }, + "source": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "canAuthorize": { + "type": "boolean" + }, + "authorized": { + "type": "boolean" + } + } + }, + "v1alpha3auditPagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha3auditSearchType": { + "type": "string", + "enum": [ + "fuzzy", + "exact" + ], + "default": "fuzzy" + }, + "v1alpha3auditStatusType": { + "type": "string", + "enum": [ + "all", + "succeeded", + "failed" + ], + "default": "all" + }, + "webhookAction": { + "type": "string", + "enum": [ + "action_create", + "action_update", + "action_delete", + "action_login", + "action_logout" + ], + "default": "action_create" + }, + "webhookCreateWebhookRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "resourceType": { + "$ref": "#/definitions/v1alpha1webhookResourceType" + }, + "action": { + "$ref": "#/definitions/webhookAction" + }, + "url": { + "type": "string" + }, + "method": { + "$ref": "#/definitions/webhookMethod" + }, + "headers": { + "type": "string" + }, + "requestParameter": { + "type": "string" + } + } + }, + "webhookCreateWebhookResponse": { + "type": "object" + }, + "webhookDeleteWebhookResponse": { + "type": "object" + }, + "webhookGetWebhookRecordResponse": { + "type": "object", + "properties": { + "webhookRecordInfo": { + "$ref": "#/definitions/webhookWebhookRecordInfo" + } + } + }, + "webhookGetWebhookResponse": { + "type": "object", + "properties": { + "webhookInfo": { + "$ref": "#/definitions/webhookWebhookInfo" + } + } + }, + "webhookListWebhookRecordsByClientIdResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/webhookWebhookRecordInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1webhookPagination" + } + } + }, + "webhookListWebhooksByClientIdResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/webhookWebhookInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1webhookPagination" + } + } + }, + "webhookMethod": { + "type": "string", + "enum": [ + "method_get", + "method_post", + "method_put", + "method_delete", + "method_patch" + ], + "default": "method_get" + }, + "webhookStatusResponse": { + "type": "string", + "enum": [ + "response_unknown", + "response_successful", + "response_failed" + ], + "default": "response_unknown" + }, + "webhookUpdateWebhookResponse": { + "type": "object" + }, + "webhookWebhookInfo": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "clientId": { + "type": "string" + }, + "resourceType": { + "$ref": "#/definitions/v1alpha1webhookResourceType" + }, + "action": { + "$ref": "#/definitions/webhookAction" + }, + "url": { + "type": "string" + }, + "method": { + "$ref": "#/definitions/webhookMethod" + }, + "headers": { + "type": "string" + }, + "requestParameter": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "webhookWebhookRecordInfo": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "clientId": { + "type": "string" + }, + "webhookId": { + "type": "integer", + "format": "int32" + }, + "webhookName": { + "type": "string" + }, + "resourceType": { + "$ref": "#/definitions/v1alpha1webhookResourceType" + }, + "action": { + "$ref": "#/definitions/webhookAction" + }, + "url": { + "type": "string" + }, + "method": { + "$ref": "#/definitions/webhookMethod" + }, + "eventTime": { + "type": "string" + }, + "eventData": { + "type": "string" + }, + "statusCode": { + "type": "integer", + "format": "int32" + }, + "status": { + "$ref": "#/definitions/webhookStatusResponse" + }, + "requestedAt": { + "type": "string" + }, + "request": { + "type": "string" + }, + "respondedAt": { + "type": "string" + }, + "response": { + "type": "string" + }, + "errMessage": { + "type": "string" + } + } + }, + "workspaceAuthorizeResponse": { + "type": "object" + }, + "workspaceBindExclusiveResourceToWorkspaceResponse": { + "type": "object" + }, + "workspaceBindSharedResourceAndSetQuotaHardToWorkspaceResponse": { + "type": "object" + }, + "workspaceBindSharedResourceToWorkspaceResponse": { + "type": "object" + }, + "workspaceClusterStatus": { + "type": "string", + "enum": [ + "StatusUnknown", + "StatusRunning", + "StatusNotRunning" + ], + "default": "StatusUnknown" + }, + "workspaceCreateFolderRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Deprecated: Do not use." + }, + "alias": { + "type": "string" + }, + "parentFolderId": { + "type": "integer", + "format": "int32" + } + } + }, + "workspaceCreateFolderResponse": { + "type": "object", + "properties": { + "folderId": { + "type": "integer", + "format": "int32" + } + } + }, + "workspaceCreateWorkspaceRequest": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "title": "string name = 1 [(validate.rules).string.max_len = 64];" + }, + "parentFolderId": { + "type": "integer", + "format": "int32" + } + } + }, + "workspaceCreateWorkspaceResponse": { + "type": "object", + "properties": { + "workspaceId": { + "type": "integer", + "format": "int32" + } + } + }, + "workspaceDeauthorizeResponse": { + "type": "object" + }, + "workspaceDeleteFolderResponse": { + "type": "object" + }, + "workspaceDeleteWorkspaceResponse": { + "type": "object" + }, + "workspaceFolderInfo": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string", + "description": "Deprecated: Do not use." + }, + "alias": { + "type": "string" + } + } + }, + "workspaceFolderListGroupsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1workspaceGroup" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceFolderListPermissionsResponse": { + "type": "object", + "properties": { + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceFolderPermission" + } + } + } + }, + "workspaceFolderListUsersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1workspaceUser" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceFolderPermission": { + "type": "string", + "enum": [ + "Unknown", + "CreateFolder", + "UpdateFolder", + "GetFolder", + "DeleteFolder", + "AuthorizeFolder", + "CreateWorkspace", + "UpdateWorkspace", + "GetWorkspace", + "DeleteWorkspace", + "AuthorizeWorkspace", + "ResourceBindingWorkspace", + "UpdateResourceQuotaWorkspace" + ], + "default": "Unknown" + }, + "workspaceFolderTree": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "alias": { + "type": "string" + }, + "isWorkspace": { + "type": "boolean" + }, + "parentId": { + "type": "integer", + "format": "int32" + }, + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceFolderTree" + } + }, + "permissions": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceFolderPermission" + } + }, + "resourceKind": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceWorkspaceResourceKindEnum" + } + } + } + }, + "workspaceGetFolderResponse": { + "type": "object", + "properties": { + "folder": { + "$ref": "#/definitions/workspaceFolderInfo" + } + } + }, + "workspaceGetWorkspaceResponse": { + "type": "object", + "properties": { + "workspace": { + "$ref": "#/definitions/workspaceWorkspaceInfo" + } + } + }, + "workspaceGetWorkspaceSharedResourceQuotaResponse": { + "type": "object", + "properties": { + "setting": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "allocatable": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "used": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "workspaceListAvailableExclusiveResourcesByWorkspaceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceResourceInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListAvailableSharedResourcesByWorkspaceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceResourceInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListExclusiveResourceTypesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "workspaceListExclusiveResourcesByWorkspaceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceWorkspacesResourceInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListFolderTreeResponse": { + "type": "object", + "properties": { + "folderTree": { + "$ref": "#/definitions/workspaceFolderTree" + }, + "defaultId": { + "type": "integer", + "format": "int32" + } + } + }, + "workspaceListFoldersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceFolderInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListMembersRolesByFolderResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceMemberRoleFolderInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListMembersRolesByWorkspaceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceMemberRoleWorkspaceInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListResourceQuotaTypesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "workspaceListSharedResourceTypesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "workspaceListSharedResourcesByWorkspaceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceWorkspacesResourceInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceListWorkspaceShareResourceQuotaTypesResponse": { + "type": "object", + "properties": { + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceResourceQuotaType" + } + } + } + }, + "workspaceListWorkspacesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceWorkspaceInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceMemberRoleFolderInfo": { + "type": "object", + "properties": { + "memberName": { + "type": "string" + }, + "memberType": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "folderId": { + "type": "integer", + "format": "int32" + }, + "memberId": { + "type": "string" + } + } + }, + "workspaceMemberRoleWorkspaceInfo": { + "type": "object", + "properties": { + "memberName": { + "type": "string" + }, + "memberType": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "memberId": { + "type": "string" + } + } + }, + "workspaceMoveWorkspaceFolderListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceMoverWorkspaceFolder" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1workspacePagination" + } + } + }, + "workspaceMoveWorkspaceResponse": { + "type": "object" + }, + "workspaceMoverWorkspaceFolder": { + "type": "object", + "properties": { + "folderId": { + "type": "integer", + "format": "int32" + }, + "folderAlias": { + "type": "string" + }, + "parentId": { + "type": "integer", + "format": "int32" + }, + "parentAlias": { + "type": "string" + } + } + }, + "workspaceReauthorizeResponse": { + "type": "object" + }, + "workspaceResourceInfo": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "gproduct": { + "type": "string" + }, + "resourceScope": { + "type": "string" + }, + "bound": { + "type": "boolean" + }, + "clusterStatus": { + "$ref": "#/definitions/workspaceClusterStatus" + } + } + }, + "workspaceResourceQuotaType": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "alias": { + "type": "string" + }, + "resource": { + "type": "array", + "items": { + "$ref": "#/definitions/workspaceResourceQuotaTypeKey" + } + } + } + }, + "workspaceResourceQuotaTypeKey": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "alias": { + "type": "string" + }, + "aliasZh": { + "type": "string" + } + } + }, + "workspaceSetQuotaHardForWorkspaceSharedResourceRequest": { + "type": "object", + "properties": { + "workspaceResourceId": { + "type": "integer", + "format": "int32" + }, + "quotaHard": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "workspaceSetQuotaHardForWorkspaceSharedResourceResponse": { + "type": "object" + }, + "workspaceUnbindResourceFromWorkspaceResponse": { + "type": "object" + }, + "workspaceUpdateFolderResponse": { + "type": "object" + }, + "workspaceUpdateQuotaCheckRequest": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "gproduct": { + "type": "string" + }, + "resourceScope": { + "type": "string", + "title": "cluster 资源 resource_scope 为空" + }, + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "quotaHard": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "workspaceUpdateQuotaCheckResponse": { + "type": "object", + "properties": { + "passed": { + "type": "boolean" + }, + "reason": { + "type": "string" + } + } + }, + "workspaceWorkspaceInfo": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "alias": { + "type": "string" + } + } + }, + "workspaceWorkspaceResourceKindEnum": { + "type": "string", + "enum": [ + "resource_group", + "shared_resource", + "registry", + "kangaroo_registry", + "kangaroo_project" + ], + "default": "resource_group" + }, + "workspaceWorkspacesResourceInfo": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "resourceType": { + "type": "string" + }, + "resourceScope": { + "type": "string" + }, + "gproduct": { + "type": "string" + }, + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "workspaceResourceId": { + "type": "integer", + "format": "int32" + }, + "module": { + "type": "string" + }, + "clusterStatus": { + "$ref": "#/definitions/workspaceClusterStatus" + } + } + } + } +} diff --git a/docs/zh/docs/openapi/index.md b/docs/zh/docs/openapi/index.md new file mode 100644 index 0000000..d4ff747 --- /dev/null +++ b/docs/zh/docs/openapi/index.md @@ -0,0 +1,61 @@ +# OpenAPI 文档 + +这是面向开发者的一些 OpenAPI 文档。 + +- [云主机 OpenAPI 文档](./virtnest/index.md) +- [AI Lab OpenAPI 文档](./baize/index.md) +- [容器管理 OpenAPI 文档](./kpanda/index.md) +- [可观测性 OpenAPI 文档](./insight/index.md) +- [全局管理 OpenAPI 文档](./ghippo/index.md) + +## 获取 OpenAPI 访问密钥 + +访问密钥(Access Key)可用于访问 OpenAPI 和持续发布,用户可在个人中心参照以下步骤获取密钥并访问 API。 + +登录 AI 算力平台,在右上角的下拉菜单中找到 __个人中心__ ,可以在 __访问密钥__ 页面管理账号的访问密钥。 + +![ak list](../images/platform02_1.png) + +![created a key](../images/platform03_1.png) + +!!! info + + 访问密钥信息仅显示一次。如果您忘记了访问密钥信息,您需要重新创建新的访问密钥。 + +## 使用密钥访问 API + +在访问算丰 AI 算力平台openAPI 时,在请求中加上请求头 `Authorization:Bearer ${token}` 以标识访问者的身份, +其中 `${token}` 是上一步中获取到的密钥。 + +**请求示例** + +```bash +curl -X GET -H 'Authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRKVjlBTHRBLXZ4MmtQUC1TQnVGS0dCSWc1cnBfdkxiQVVqM2U3RVByWnMiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjE0MTU5NjksImlhdCI6MTY2MDgxMTE2OSwiaXNzIjoiZ2hpcHBvLmlvIiwic3ViIjoiZjdjOGIxZjUtMTc2MS00NjYwLTg2MWQtOWI3MmI0MzJmNGViIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJncm91cHMiOltdfQ.RsUcrAYkQQ7C6BxMOrdD3qbBRUt0VVxynIGeq4wyIgye6R8Ma4cjxG5CbU1WyiHKpvIKJDJbeFQHro2euQyVde3ygA672ozkwLTnx3Tu-_mB1BubvWCBsDdUjIhCQfT39rk6EQozMjb-1X1sbLwzkfzKMls-oxkjagI_RFrYlTVPwT3Oaw-qOyulRSw7Dxd7jb0vINPq84vmlQIsI3UuTZSNO5BCgHpubcWwBss-Aon_DmYA-Et_-QtmPBA3k8E2hzDSzc7eqK0I68P25r9rwQ3DeKwD1dbRyndqWORRnz8TLEXSiCFXdZT2oiMrcJtO188Ph4eLGut1-4PzKhwgrQ' https://demo-dev.daocloud.io/apis/ghippo.io/v1alpha1/users?page=1&pageSize=10 -k +``` + +**请求结果** + +```json +{ + "items": [ + { + "id": "a7cfd010-ebbe-4601-987f-d098d9ef766e", + "name": "a", + "email": "", + "description": "", + "firstname": "", + "lastname": "", + "source": "locale", + "enabled": true, + "createdAt": "1660632794800", + "updatedAt": "0", + "lastLoginAt": "" + } + ], + "pagination": { + "page": 1, + "pageSize": 10, + "total": 1 + } +} +``` diff --git a/docs/zh/docs/openapi/insight/index.md b/docs/zh/docs/openapi/insight/index.md new file mode 100644 index 0000000..bb8670f --- /dev/null +++ b/docs/zh/docs/openapi/insight/index.md @@ -0,0 +1 @@ +# diff --git a/docs/zh/docs/openapi/insight/v0.28.0.json b/docs/zh/docs/openapi/insight/v0.28.0.json new file mode 100644 index 0000000..b6a00bc --- /dev/null +++ b/docs/zh/docs/openapi/insight/v0.28.0.json @@ -0,0 +1,11427 @@ +{ + "swagger": "2.0", + "info": { + "title": "可观测性", + "version": "v0.28.0" + }, + "tags": [ + { + "name": "Insight" + }, + { + "name": "FeatureGate" + }, + { + "name": "Alert" + }, + { + "name": "Log" + }, + { + "name": "Metric" + }, + { + "name": "Resource" + }, + { + "name": "Tracing" + }, + { + "name": "ServiceGraph" + }, + { + "name": "Event" + }, + { + "name": "Probe" + }, + { + "name": "Overview" + }, + { + "name": "NetFlow" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/apis/insight.io/v1alpha1/agentinstallparam": { + "post": { + "operationId": "Insight_GetHelmInstallConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1helmInstallConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1helmInstallConfigRequest" + } + } + ], + "tags": [ + "Insight" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/alertcount": { + "get": { + "operationId": "Alert_CountAlert", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CountAlertResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "resolved", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "targetType", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TARGET_TYPE_UNSPECIFIED", + "GLOBAL", + "CLUSTER", + "NAMESPACE", + "NODE", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET", + "POD" + ], + "default": "TARGET_TYPE_UNSPECIFIED" + }, + { + "name": "target", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "severity", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SEVERITY_UNSPECIFIED", + "CRITICAL", + "WARNING", + "INFO" + ], + "default": "SEVERITY_UNSPECIFIED" + }, + { + "name": "start", + "description": "start == 0 means from 1970.01.01", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "description": "step unit is minute\nstep == 0 means return total alert count num", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "groupByType", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/alerts": { + "get": { + "operationId": "Alert_ListAlerts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAlertsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "resolved", + "description": "set resolved to True shows alert histories", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "groupName", + "description": "filter alerts by group name fuzzily", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "groupId", + "description": "filter alerts by group id", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "ruleName", + "description": "filter alerts by rule name fuzzily", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "ruleId", + "description": "filter alerts by rule id", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "description": "filter alerts by cluster name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "filter alerts by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "severity", + "description": "filter alerts by severity", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SEVERITY_UNSPECIFIED", + "CRITICAL", + "WARNING", + "INFO" + ], + "default": "SEVERITY_UNSPECIFIED" + }, + { + "name": "targetType", + "description": "filter alerts by target_type", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TARGET_TYPE_UNSPECIFIED", + "GLOBAL", + "CLUSTER", + "NAMESPACE", + "NODE", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET", + "POD" + ], + "default": "TARGET_TYPE_UNSPECIFIED" + }, + { + "name": "target", + "description": "filter alerts by target", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- start_at,desc or start_at\n- start_at,asc\n- severity,desc or severity\n- severity,asc\n- rule_name,desc or rule_name\n- rule_name,asc\n\nthe default sort is start_at,desc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/alerts/{id}": { + "get": { + "operationId": "Alert_GetAlert", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Alert" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string", + "format": "int64" + }, + { + "name": "resolved", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/groups": { + "get": { + "operationId": "Alert_ListGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "builtin", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "name", + "description": "filter group by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "description": "filter alerts by cluster name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "filter alerts by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- name,desc or name\n- name,asc\n- create_at,desc or create_at\n- create_at,asc\n\nthe default sort is name,asc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/alertv1alpha1Group" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateGroupRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/groups/validate": { + "post": { + "operationId": "Alert_ValidateGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ValidateGroupResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1ValidateGroupRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/groups/{id}": { + "get": { + "operationId": "Alert_GetGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/alertv1alpha1Group" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "summary": "UpdateGroup only can update group description and notify", + "operationId": "Alert_UpdateGroup", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/alertv1alpha1Group" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateGroupBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/groups/{id}/rules": { + "get": { + "operationId": "Alert_ListGroupRules", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRulesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "filter rule by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "severity", + "description": "filter rules by severity", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SEVERITY_UNSPECIFIED", + "CRITICAL", + "WARNING", + "INFO" + ], + "default": "SEVERITY_UNSPECIFIED" + }, + { + "name": "status", + "description": "filter rules by status", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "UNSPECIFIED", + "FIRING", + "ENABLED" + ], + "default": "UNSPECIFIED" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- name,desc or name\n- rule_name,asc\n- severity,desc or severity\n- severity,asc\n- status,desc or status\n- status,asc\n- source,desc or source\n- source,asc\n- create_at,desc or create_at\n- create_at,asc\n\nthe default sort is name,asc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_AddGroupRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Rule" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "description": "required;", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertAddGroupRuleBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/groups/{id}/rules/{name}": { + "get": { + "operationId": "Alert_GetGroupRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Rule" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "description": "required; id is group id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "required; name is rule name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteGroupRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "description": "required; id is group id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "required; name is rule name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateGroupRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Rule" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "description": "required; id is group id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "required;", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateGroupRuleBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/history/clean": { + "put": { + "operationId": "Alert_CleanAlertHistory", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CleanAlertHistoryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/history/retentionperiod": { + "get": { + "operationId": "Alert_GetAlertHistoryRetentionPeriod", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1AlertHistoryRetentionPeriod" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateAlertHistoryRetentionPeriod", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1AlertHistoryRetentionPeriod" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/hook": { + "post": { + "operationId": "Alert_AlertHook", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1AMHookRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/inhibitions": { + "get": { + "summary": "Inhibition", + "operationId": "Alert_ListInhibitions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1InhibitionList" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- name,desc or name\n- name,asc\n- create_at,desc or create_at\n- create_at,asc\n\nthe default sort is name,asc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateInhibition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Inhibition" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateInhibitionRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/inhibitions/{id}": { + "get": { + "operationId": "Alert_GetInhibition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Inhibition" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteInhibition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateInhibition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Inhibition" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateInhibitionBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/providers": { + "get": { + "operationId": "Alert_ListProviders", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListProvidersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "filter template by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- update_at,desc or update_at\n- update_at,asc\n\nthe default sort is update_at,desc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "exactSearch", + "description": "exact search by name", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateProvider", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ProviderDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Provider" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/providers/{name}": { + "get": { + "operationId": "Alert_GetProvider", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ProviderDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "ProviderType type = 2 [ (validate.rules).enum.defined_only = true ];", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteProvider", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ProviderDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "ProviderType type = 2 [ (validate.rules).enum.defined_only = true ];", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateProvider", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ProviderDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateProviderBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/receivers": { + "get": { + "operationId": "Alert_ListReceivers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListReceiverResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "type", + "description": "filter receivers by type", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "RECEIVER_TYPE_UNSPECIFIED", + "webhook", + "email", + "dingtalk", + "wecom", + "sms" + ], + "default": "RECEIVER_TYPE_UNSPECIFIED" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- create_at,desc or create_at\n- create_at,asc\n\nthe default sort is create_at,desc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "exactSearch", + "description": "exact search by name", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateReceiver", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ReceiverDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Receiver" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/receivers/test": { + "post": { + "operationId": "Alert_TestReceiver", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1Receiver" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/receivers/{name}": { + "get": { + "operationId": "Alert_GetReceiver", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ReceiverDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "type", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "RECEIVER_TYPE_UNSPECIFIED", + "webhook", + "email", + "dingtalk", + "wecom", + "sms" + ], + "default": "RECEIVER_TYPE_UNSPECIFIED" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteReceiver", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ReceiverDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateReceiver", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ReceiverDataResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateReceiverBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/rule-template-summary": { + "get": { + "summary": "RuleTemplate", + "operationId": "Alert_ListRuleTemplateSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRuleTemplateSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "targetType", + "description": "filter by target type", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TARGET_TYPE_UNSPECIFIED", + "GLOBAL", + "CLUSTER", + "NAMESPACE", + "NODE", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET", + "POD" + ], + "default": "TARGET_TYPE_UNSPECIFIED" + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/rule-templates": { + "get": { + "operationId": "Alert_ListRuleTemplates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRuleTemplatesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "builtin", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "name", + "description": "filter group by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- name,desc or name\n- name,asc\n- create_at,desc or create_at\n- create_at,asc\n- update_at,desc or update_at\n- update_at,asc\n\nthe default sort is name,asc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "targetType", + "description": "filter by target type", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TARGET_TYPE_UNSPECIFIED", + "GLOBAL", + "CLUSTER", + "NAMESPACE", + "NODE", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET", + "POD" + ], + "default": "TARGET_TYPE_UNSPECIFIED" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateRuleTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RuleTemplate" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateRuleTemplateRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/rule-templates/{id}": { + "get": { + "operationId": "Alert_GetRuleTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RuleTemplate" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteRuleTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateRuleTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RuleTemplate" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateRuleTemplateBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/rules/preview": { + "post": { + "operationId": "Alert_PreviewRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PreviewRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1PreviewRuleRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/silences": { + "get": { + "operationId": "Alert_ListSilences", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListSilencesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "expired", + "description": "set \"expired\" to false show silences that vaild for now, otherwise show\nexpired silences", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateSilence", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Silence" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateSilenceRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/silences/preview": { + "post": { + "operationId": "Alert_PreviewSilence", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PreviewSilenceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1PreviewSilenceRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/silences/{id}": { + "get": { + "operationId": "Alert_GetSilence", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Silence" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteSilence", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateSilence", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Silence" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateSilenceBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/smtp": { + "get": { + "operationId": "Alert_GetSMTPStatus", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetSMTPStatusResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/templates": { + "get": { + "operationId": "Alert_ListTemplates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListTemplatesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "filter template by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- update_at,desc or update_at\n- update_at,asc\n\nthe default sort is update_at,desc", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "exactSearch", + "description": "exact search by name", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Alert" + ] + }, + "post": { + "operationId": "Alert_CreateTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Template" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateTemplateRequest" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/alert/templates/{name}": { + "get": { + "operationId": "Alert_GetTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Template" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "delete": { + "operationId": "Alert_DeleteTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Alert" + ] + }, + "put": { + "operationId": "Alert_UpdateTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Template" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/AlertUpdateTemplateBody" + } + } + ], + "tags": [ + "Alert" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters": { + "get": { + "operationId": "Resource_ListClusters", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClustersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "showAllCluster", + "description": "show_all_cluster default is false, will only return cluster with\ninsight-agent installed; if set to true, will return all cluster.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes": { + "get": { + "summary": "get the list of probes of cluster and namespace scope", + "operationId": "Probe_ListProbes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListProbesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sorts", + "description": "sorts determines the data list order, do not support multiple sort option.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- job_name,desc or job_name\n- job_name,asc\n- create_at,desc or create_at\n- create_at,asc\n\nthe default sort is create_at,desc", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Probe" + ] + }, + "post": { + "summary": "create one probe of cluster and namespace scope", + "operationId": "Probe_AddProbe", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Probe" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ProbeAddProbeBody" + } + } + ], + "tags": [ + "Probe" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes/{jobName}": { + "get": { + "summary": "get one probe by probe name of cluster and namespace scope", + "operationId": "Probe_GetProbe", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Probe" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "jobName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Probe" + ] + }, + "delete": { + "summary": "delete one probe by probe name of cluster and namespace scope", + "operationId": "Probe_DeleteProbe", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "jobName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Probe" + ] + }, + "put": { + "summary": "update probe content of cluster and namespace scope", + "operationId": "Probe_UpdateProbe", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1empty" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "jobName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ProbeUpdateProbeBody" + } + } + ], + "tags": [ + "Probe" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{clusterName}/probers": { + "get": { + "summary": "get the list of prober(blackbox-exporter) of cluster scope", + "operationId": "Probe_ListProbers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterProbersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Probe" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/agent": { + "get": { + "operationId": "Resource_GetAgentSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1AgentSummary" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "use cluster_name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/cronjobs": { + "get": { + "operationId": "Resource_ListCronjobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCronJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter jobs by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter jobs by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter jobs by phase\n\n - JOB_STATE_UNSPECIFIED: Job is unspecified.\n - JOB_STATE_WAITING: Waiting for job ready.\n - JOB_STATE_RUNNING: Job is working.\n - JOB_STATE_COMPLETED: Jobs has completed.\n - JOB_STATE_DELETING: Jobs is being deleted.\n - JOB_STATE_FAILED: Jobs is not ready to work .", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "JOB_STATE_UNSPECIFIED", + "JOB_STATE_WAITING", + "JOB_STATE_RUNNING", + "JOB_STATE_COMPLETED", + "JOB_STATE_DELETING", + "JOB_STATE_FAILED" + ], + "default": "JOB_STATE_UNSPECIFIED" + }, + { + "name": "name", + "description": "filter jobs by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/daemonsets": { + "get": { + "operationId": "Resource_ListDaemonsets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListWorkloadsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter workloads by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter workloads by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "filter workloads by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter workloads by phase", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNKNOWN", + "WORKLOAD_STATE_RUNNING", + "WORKLOAD_STATE_DELETING", + "WORKLOAD_STATE_NOT_READY", + "WORKLOAD_STATE_STOPPED", + "WORKLOAD_STATE_WAITING" + ], + "default": "WORKLOAD_STATE_UNKNOWN" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/deployments": { + "get": { + "operationId": "Resource_ListDeployments", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListWorkloadsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter workloads by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter workloads by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "filter workloads by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter workloads by phase", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNKNOWN", + "WORKLOAD_STATE_RUNNING", + "WORKLOAD_STATE_DELETING", + "WORKLOAD_STATE_NOT_READY", + "WORKLOAD_STATE_STOPPED", + "WORKLOAD_STATE_WAITING" + ], + "default": "WORKLOAD_STATE_UNKNOWN" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/jobs": { + "get": { + "operationId": "Resource_ListJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter jobs by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter jobs by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter jobs by phase\n\n - JOB_STATE_UNSPECIFIED: Job is unspecified.\n - JOB_STATE_WAITING: Waiting for job ready.\n - JOB_STATE_RUNNING: Job is working.\n - JOB_STATE_COMPLETED: Jobs has completed.\n - JOB_STATE_DELETING: Jobs is being deleted.\n - JOB_STATE_FAILED: Jobs is not ready to work .", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "JOB_STATE_UNSPECIFIED", + "JOB_STATE_WAITING", + "JOB_STATE_RUNNING", + "JOB_STATE_COMPLETED", + "JOB_STATE_DELETING", + "JOB_STATE_FAILED" + ], + "default": "JOB_STATE_UNSPECIFIED" + }, + { + "name": "name", + "description": "filter jobs by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces": { + "get": { + "operationId": "Resource_ListNamespaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNamespacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}": { + "get": { + "operationId": "Resource_GetCronjob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CronJob" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}/pods": { + "get": { + "operationId": "Resource_GetCronjobPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}": { + "get": { + "operationId": "Resource_GetDaemonset", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Workload" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}/pods": { + "get": { + "operationId": "Resource_GetDaemonsetPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}": { + "get": { + "operationId": "Resource_GetDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Workload" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}/pods": { + "get": { + "operationId": "Resource_GetDeploymentPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name}": { + "get": { + "operationId": "Resource_GetJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name}/pods": { + "get": { + "operationId": "Resource_GetJobPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}": { + "get": { + "operationId": "Resource_GetPod", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Pod" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}/containers": { + "get": { + "operationId": "Resource_ListPodContainers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListContainersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter nodes by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter nodes by namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "filter containers by name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name}": { + "get": { + "operationId": "Resource_GetService", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Service" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}": { + "get": { + "operationId": "Resource_GetStatefulset", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Workload" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}/pods": { + "get": { + "operationId": "Resource_GetStatefulsetPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{name}": { + "get": { + "operationId": "Resource_GetNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1NamespaceDetail" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/nodes": { + "get": { + "operationId": "Resource_ListNodes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNodesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter nodes by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "phase", + "description": "filter nodes by phase\n\n - NODE_PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - NODE_PHASE_READY: The node is ready to work.\n - NODE_PHASE_NOT_READY: The node is not ready.\n - NODE_PHASE_UNKNOWN: The node state is unknown.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "NODE_PHASE_UNSPECIFIED", + "NODE_PHASE_READY", + "NODE_PHASE_NOT_READY", + "NODE_PHASE_UNKNOWN" + ], + "default": "NODE_PHASE_UNSPECIFIED" + }, + { + "name": "name", + "description": "filter nodes by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/nodes/{name}": { + "get": { + "operationId": "Resource_GetNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apiresourcev1alpha1Node" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/nodes/{name}/gpu": { + "get": { + "operationId": "Resource_GetNodeGPUDashboard", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetGPUResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "gpuVendors", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "start", + "description": "start unix timestamp with seconds unit\ndefault now - 1h", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "end", + "description": "end unix timestamp with seconds unit\ndefault now", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/pods": { + "get": { + "operationId": "Resource_ListPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter nodes by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter nodes by namespaces", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter nodes by status\n\n - POD_PHASE_UNKNOWN: PodUnknown means that for some reason the state of the pod could not be\nobtained, typically due to an error in communicating with the host of the\npod.\n - POD_PHASE_PENDING: PodPending means the pod has been accepted by the system, but one or more\nof the containers has not been started. This includes time before being\nbound to a node, as well as time spent pulling images onto the host.\n - POD_PHASE_RUNNING: PodRunning means the pod has been bound to a node and all of the containers\nhave been started. At least one container is still running or is in the\nprocess of being restarted. PodSucceeded means that all containers in the\npod have voluntarily terminated with a container exit code of 0, and the\nsystem is not going to restart any of these containers.\n - POD_PHASE_SUCCEED: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).\n - POD_PHASE_FAILED: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "POD_PHASE_UNSPECIFIED", + "POD_PHASE_UNKNOWN", + "POD_PHASE_PENDING", + "POD_PHASE_RUNNING", + "POD_PHASE_SUCCEED", + "POD_PHASE_FAILED" + ], + "default": "POD_PHASE_UNSPECIFIED" + }, + { + "name": "name", + "description": "filter pods by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/services": { + "get": { + "operationId": "Resource_ListServices", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListServicesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter services by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter services by namespaces", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "filter services by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{cluster}/statefulsets": { + "get": { + "operationId": "Resource_ListStatefulsets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListWorkloadsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "filter workloads by cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "filter workloads by namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "filter workloads by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter workloads by phase", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNKNOWN", + "WORKLOAD_STATE_RUNNING", + "WORKLOAD_STATE_DELETING", + "WORKLOAD_STATE_NOT_READY", + "WORKLOAD_STATE_STOPPED", + "WORKLOAD_STATE_WAITING" + ], + "default": "WORKLOAD_STATE_UNKNOWN" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clusters/{name}": { + "get": { + "operationId": "Resource_GetCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterDetail" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/clustersummary": { + "get": { + "operationId": "Resource_ListClusterSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "filter cluster by name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "version", + "description": "filter cluster by k8s version", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "filter cluster by phase\n\n - CLUSTER_PHASE_UNSPECIFIED: The cluster state is unspecified.\n - UNKNOWN: The cluster state is unknown.\n - CREATING: The cluster is being created.\n - RUNNING: The cluster is running.\n - UPDATING: The cluster is updating.\n - DELETING: The cluster is being deleted.\n - FAILED: The cluster operations failed.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "CLUSTER_PHASE_UNSPECIFIED", + "UNKNOWN", + "CREATING", + "RUNNING", + "UPDATING", + "DELETING", + "FAILED" + ], + "default": "CLUSTER_PHASE_UNSPECIFIED" + }, + { + "name": "showAllCluster", + "description": "show_all_cluster default is false, will only return cluster with\ninsight-agent installed; if set to true, will return all cluster.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/config": { + "get": { + "operationId": "Insight_GetGlobalConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GlobalConfig" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Insight" + ] + } + }, + "/apis/insight.io/v1alpha1/event/cluster/{clusterName}/events": { + "get": { + "operationId": "Event_QueryEvents", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryEventResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "description": "Required.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "startTime", + "description": "startTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now-24 hour.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "endTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Optional.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.type", + "description": " - Normal: use lowercase to keep the same as the original Kubernetes event data", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TYPE_UNSPECIFIED", + "Normal", + "Warning" + ], + "default": "TYPE_UNSPECIFIED" + }, + { + "name": "filter.involveObjectKind", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.reason", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.involveObjectName", + "description": "fuzzy search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.message", + "description": "fuzzy search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sort", + "description": "sort determines the data list order.\nparameter and sort direction divided by comma.\nsupport sorts:\n- timestamp,desc\n- timestamp,asc\n- type,desc\n- type,asc\n\nOptional.\nDefault = timestamp,desc", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.\nOptional.\nDefault = 1.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.\nOptional.\nDefault = 10.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Event" + ] + } + }, + "/apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/context": { + "get": { + "operationId": "Event_QueryEventContext", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryEventResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "description": "Required.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "timestamp", + "description": "timestamp e.g. 2023-06-20T16:05:16.887681657Z\nRequired.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Optional.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.type", + "description": " - Normal: use lowercase to keep the same as the original Kubernetes event data", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TYPE_UNSPECIFIED", + "Normal", + "Warning" + ], + "default": "TYPE_UNSPECIFIED" + }, + { + "name": "filter.involveObjectKind", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.reason", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.involveObjectName", + "description": "fuzzy search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "filter.message", + "description": "fuzzy search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "before", + "description": "Optional.\ndefault = 50", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "after", + "description": "Optional.\ndefault = 50", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Event" + ] + } + }, + "/apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/count": { + "post": { + "operationId": "Event_QueryEventCount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryEventCountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "description": "Required.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EventQueryEventCountBody" + } + } + ], + "tags": [ + "Event" + ] + } + }, + "/apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/filter-options": { + "get": { + "operationId": "Event_QueryEventFilterOptions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryEventFilterOptionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "description": "Required.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "startTime", + "description": "startTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now-24 hour.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "endTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Optional.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Event" + ] + } + }, + "/apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/histogram": { + "get": { + "operationId": "Event_QueryEventHistogram", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryEventHistogramResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "description": "Required.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "startTime", + "description": "startTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now-24 hour.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "endTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "interval", + "description": "interval e.g 1440s\nRequired.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Optional.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Event" + ] + } + }, + "/apis/insight.io/v1alpha1/event/reasons": { + "get": { + "operationId": "Event_GetReasons", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetReasonsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Event" + ] + } + }, + "/apis/insight.io/v1alpha1/feature-gates": { + "get": { + "operationId": "FeatureGate_GetFeatureGates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1FeatureGatesResp" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "FeatureGate" + ] + } + }, + "/apis/insight.io/v1alpha1/feature-gates/{id}": { + "get": { + "operationId": "FeatureGate_GetFeatureGateByID", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1FeatureGate" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "METRICS", + "LOGGING", + "TRACING", + "GRAPH_VIRTUAL_NODE", + "LOG_ALERT", + "NET_FLOW" + ] + } + ], + "tags": [ + "FeatureGate" + ] + } + }, + "/apis/insight.io/v1alpha1/jaeger/v2/traces": { + "get": { + "operationId": "Tracing_FindJaegerTraces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1TracesResponseChunk" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "serviceName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "operationName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "tags", + "description": "e.g. tags[host.name]=localhost&tags[url]=http://test/test\n\nThis is a request variable of the map type. The query format is \"map_name[key]=value\", e.g. If the map name is Age, the key type is string, and the value type is integer, the query parameter is expressed as Age[\"bob\"]=18", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "start", + "description": "e.g. 2022-06-24T08:00:47.850Z", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "description": "e.g. 2022-06-24T08:00:47.850Z", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "durationMin", + "description": "Span min duration. such as \"300ms\", \"-1.5h\" or \"2h45m\". Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "durationMax", + "description": "Span min duration. such as \"300ms\", \"-1.5h\" or \"2h45m\". Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "limit", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "only for auth", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/jaeger/v2/traces/{traceId}": { + "get": { + "operationId": "Tracing_FindJaegerTrace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1TracesResponseChunk" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "traceId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "only for auth", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/log/context": { + "post": { + "operationId": "Log_QueryLogContext", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryLogResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1QueryLogContextRequest" + } + } + ], + "tags": [ + "Log" + ] + } + }, + "/apis/insight.io/v1alpha1/log/export": { + "post": { + "operationId": "Log_DownloadLog", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1DownloadLogResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1DownloadLogRequest" + } + } + ], + "tags": [ + "Log" + ] + } + }, + "/apis/insight.io/v1alpha1/log/filepaths": { + "get": { + "operationId": "Log_ListLogFilePaths", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListLogFilePathsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "node", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Log" + ] + } + }, + "/apis/insight.io/v1alpha1/log/histogram": { + "post": { + "operationId": "Log_QueryLogHistogram", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryLogHistogramResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1QueryLogHistogramRequest" + } + } + ], + "tags": [ + "Log" + ] + } + }, + "/apis/insight.io/v1alpha1/log/query": { + "post": { + "operationId": "Log_QueryLog", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryLogResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1QueryLogRequest" + } + } + ], + "tags": [ + "Log" + ] + } + }, + "/apis/insight.io/v1alpha1/log/search": { + "get": { + "operationId": "Log_SearchLog", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1SearchLogResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "index", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "query", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Log" + ] + } + }, + "/apis/insight.io/v1alpha1/metric/query": { + "get": { + "operationId": "Metric_QueryMetric", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PrometheusQueryResult" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "query", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "time", + "description": "Optional, current server time is used if the time parameter is omitted.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + } + ], + "tags": [ + "Metric" + ] + }, + "post": { + "operationId": "Metric_BatchQueryMetric", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1BatchQueryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1BatchQueryRequest" + } + } + ], + "tags": [ + "Metric" + ] + } + }, + "/apis/insight.io/v1alpha1/metric/queryrange": { + "get": { + "operationId": "Metric_QueryRangeMetric", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PrometheusQueryRangeResult" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "query", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "start", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "in": "query", + "required": false, + "type": "number", + "format": "double" + } + ], + "tags": [ + "Metric" + ] + }, + "post": { + "operationId": "Metric_BatchQueryRangeMetric", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1BatchQueryRangeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1BatchQueryRangeRequest" + } + } + ], + "tags": [ + "Metric" + ] + } + }, + "/apis/insight.io/v1alpha1/net_flow/config": { + "get": { + "operationId": "NetFlow_GetNetFlow", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "NetFlow" + ] + } + }, + "/apis/insight.io/v1alpha1/overview/resources/count": { + "get": { + "operationId": "Overview_GetResourcesCount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetResourcesCountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "time", + "description": "time unix timestamp .e.g. 1697597347\ndefault now", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "filters", + "description": "default [CLUSTER_NORMAL_TOTAL, CLUSTER_TOTAL, NODE_NORMAL_TOTAL, NODE_TOTAL, DEPLOYMENT_NORMAL_TOTAL, DEPLOYMENT_TOTAL\nSTATEFULSET_NORMAL_TOTAL, STATEFULSET_TOTAL, DAEMONSET_NORMAL_TOTAL, DAEMONSET_TOTAL, JOB_NORMAL_TOTAL, JOB_TOTAL\nPOD_NORMAL_TOTAL, POD_TOTAL, LOG_TOTAL, TRACE_TOTAL]", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "RESOURCE_TYPE_UNSPECIFIED", + "CLUSTER_NORMAL_TOTAL", + "CLUSTER_TOTAL", + "NODE_NORMAL_TOTAL", + "NODE_TOTAL", + "DEPLOYMENT_NORMAL_TOTAL", + "DEPLOYMENT_TOTAL", + "STATEFULSET_NORMAL_TOTAL", + "STATEFULSET_TOTAL", + "DAEMONSET_NORMAL_TOTAL", + "DAEMONSET_TOTAL", + "JOB_NORMAL_TOTAL", + "JOB_TOTAL", + "POD_NORMAL_TOTAL", + "POD_TOTAL", + "LOG_TOTAL", + "TRACE_TOTAL" + ] + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Overview" + ] + } + }, + "/apis/insight.io/v1alpha1/overview/resources/range": { + "get": { + "operationId": "Overview_GetResourcesRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetResourcesRangeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "filters", + "description": "default [NODE_TOTAL, POD_NORMAL_TOTAL, POD_ABNORMAL_TOTAL]", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "RESOURCE_TYPE_UNSPECIFIED", + "NODE_TOTAL", + "POD_TOTAL", + "POD_ABNORMAL_TOTAL", + "POD_NORMAL_TOTAL" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "start", + "description": "start unix timestamp .e.g. 1697597347\ndefault end - 1hour", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "end", + "description": "end unix timestamp .e.g. 1697597347\ndefault now", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "description": "step time step in second, default 60", + "in": "query", + "required": false, + "type": "number", + "format": "double" + } + ], + "tags": [ + "Overview" + ] + } + }, + "/apis/insight.io/v1alpha1/overview/resources/usage": { + "get": { + "operationId": "Overview_GetResourcesUsage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetResourcesUsageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "filters", + "description": "default [CLUSTER_CPU_USAGE, NODE_CPU_USAGE]", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "RESOURCE_TYPE_UNSPECIFIED", + "CLUSTER_CPU_USAGE", + "CLUSTER_MEM_USAGE", + "CLUSTER_DISK_USAGE", + "NODE_CPU_USAGE", + "NODE_MEM_USAGE", + "NODE_DISK_USAGE" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "limit", + "description": "limit The max element of result in desc order\ndefault 5", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "start", + "description": "start unix timestamp .e.g. 1697597347\ndefault end - 1hour", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "end", + "description": "end unix timestamp .e.g. 1697597347\ndefault now", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "description": "step time step in second, default 60", + "in": "query", + "required": false, + "type": "number", + "format": "double" + } + ], + "tags": [ + "Overview" + ] + } + }, + "/apis/insight.io/v1alpha1/overview/services/monitor": { + "get": { + "operationId": "Overview_GetServicesMonitor", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetServicesMonitorResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "filters", + "description": "filter\ndefault [AVG_LATENCY, ERR_RATE]\nif It's AVG_LATENCY the result value uses ms as unit otherwise uses percentage as unit", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "MONITOR_TYPE_UNSPECIFIED", + "AVG_LATENCY", + "ERR_RATE" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "limit", + "description": "limit The max element of result in desc order\ndefault 5", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "time", + "description": "timestamp unix timestamp .e.g. 1697597347\ndefault now", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "spanKinds", + "description": "spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.\nOptional. Default = [SPAN_KIND_SERVER, SPAN_KIND_CLIENT].\n\n - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default.\nImplementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application,\nas opposed to an operation happening at the boundaries. Default value.\n - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other\nremote network request.\n - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service.\n - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker.\nUnlike CLIENT and SERVER, there is often no direct critical path latency relationship\nbetween producer and consumer spans. A PRODUCER span ends when the message was accepted\nby the broker while the logical processing of the message might span a much longer time.\n - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker.\nLike the PRODUCER kind, there is often no direct critical path latency relationship\nbetween producer and consumer spans.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SPAN_KIND_UNSPECIFIED", + "SPAN_KIND_INTERNAL", + "SPAN_KIND_SERVER", + "SPAN_KIND_CLIENT", + "SPAN_KIND_PRODUCER", + "SPAN_KIND_CONSUMER" + ] + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Overview" + ] + } + }, + "/apis/insight.io/v1alpha1/pods/{name}/gpu": { + "get": { + "operationId": "Resource_GetPodGPUDashboard", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetGPUResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "start", + "description": "start unix timestamp with seconds unit\ndefault now - 1h", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "end", + "description": "end unix timestamp with seconds unit\ndefault now", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/pods/{name}/jvm": { + "post": { + "operationId": "Resource_GetPodJVMInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PodJVMInfo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "required;", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ResourceGetPodJVMInfoBody" + } + } + ], + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/server/component": { + "get": { + "operationId": "Resource_GetServerComponentSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ServerComponentSummary" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Resource" + ] + } + }, + "/apis/insight.io/v1alpha1/service-graph/graph": { + "post": { + "operationId": "ServiceGraph_GetGraph", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Graph" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1BaseGraphQuery" + } + } + ], + "tags": [ + "ServiceGraph" + ] + } + }, + "/apis/insight.io/v1alpha1/service-graph/node-metrics": { + "get": { + "operationId": "ServiceGraph_GetNodeMetrics", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1NodeMetricResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Required. e.g. cluster = 7760a3f4-bfca-4c1e-8731-aea80838525f", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "service", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "extensionFilters", + "description": "extension_filters eg. skoala_registry=ire-111,instance=xxx", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "end_time 结束时间 unix timestamp,单位 ms", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "lookback", + "description": "lookback 回退时间 unix timestamp,单位 ms", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "description": "step 时间步长 unix timestamp,单位 ms", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "ratePer", + "description": "ratePer 变化率计算步长 unix timestamp,单位 ms", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "clusterName", + "description": "Required. e.g. clusterName=kpanda-global-cluster must give one of\ncluster,clusterName in a query", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "spanKinds", + "description": "spanKinds is the list of span kinds to include (logical OR) in the\nresulting metrics aggregation. Optional. Default = [SPAN_KIND_SERVER].\n\n - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default.\nImplementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application,\nas opposed to an operation happening at the boundaries. Default value.\n - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other\nremote network request.\n - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service.\n - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker.\nUnlike CLIENT and SERVER, there is often no direct critical path latency relationship\nbetween producer and consumer spans. A PRODUCER span ends when the message was accepted\nby the broker while the logical processing of the message might span a much longer time.\n - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker.\nLike the PRODUCER kind, there is often no direct critical path latency relationship\nbetween producer and consumer spans.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SPAN_KIND_UNSPECIFIED", + "SPAN_KIND_INTERNAL", + "SPAN_KIND_SERVER", + "SPAN_KIND_CLIENT", + "SPAN_KIND_PRODUCER", + "SPAN_KIND_CONSUMER" + ] + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "ServiceGraph" + ] + } + }, + "/apis/insight.io/v1alpha1/traces/apdex": { + "get": { + "operationId": "Tracing_GetServiceApdex", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PrometheusQueryResult" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "apdexThreshold", + "description": "Unit is milseconds.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "startTime", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "endTime", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "extensionFilters", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/traces/clusters/{clusterName}/operations": { + "get": { + "operationId": "Tracing_QueryOperations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1QueryOperationsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "serviceName", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/traces/operation-detail": { + "get": { + "operationId": "Tracing_GetOperationDetail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetOperationDetailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusterName", + "description": "Required.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Required. namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "serviceName", + "description": "Required. At least one service name must be provided.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sort", + "description": "Optional.\nsort determines the data list order.\nparameter and sort direction divided by comma.\nsupport sorts:\n- reqRate,desc\n- reqRate,asc\n- errRate,desc\n- errRate,asc\n- p50Latency,desc\n- p50Latency,asc\n- p95Latency,desc\n- p95Latency,asc\n- p99Latency,desc\n- p99Latency,asc\n\nthe default sort is P95_latency,desc", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Optional. page is current page.\nDefault = 1.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Optional. size is the data number shown per page.\nDefault = 10.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "extensionFilters", + "description": "Optional. support extension labels search\nsupport multiple labels, split by comma\neg. span_name=HTTP", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "end_time is the ending time of the time series query range.\nOptional. Default = now.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "lookback", + "description": "lookback is the duration from the end_time to look back on for metrics data points.\nFor example, if set to 1h, the query would span from end_time-1h to end_time.\nOptional. Default = 1h.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "description": "step size is the duration between data points of the query results.\nFor example, if set to 5s, the results would produce a data point every 5 seconds\nfrom the start_time to end_time.\nOptional. Default = 1m.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "ratePer", + "description": "ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric.\nOptional. Default = 1m.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "spanKinds", + "description": "spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.\nOptional. Default = [SPAN_KIND_SERVER, SPAN_KIND_CLIENT].\n\n - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default.\nImplementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application,\nas opposed to an operation happening at the boundaries. Default value.\n - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other\nremote network request.\n - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service.\n - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker.\nUnlike CLIENT and SERVER, there is often no direct critical path latency relationship\nbetween producer and consumer spans. A PRODUCER span ends when the message was accepted\nby the broker while the logical processing of the message might span a much longer time.\n - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker.\nLike the PRODUCER kind, there is often no direct critical path latency relationship\nbetween producer and consumer spans.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SPAN_KIND_UNSPECIFIED", + "SPAN_KIND_INTERNAL", + "SPAN_KIND_SERVER", + "SPAN_KIND_CLIENT", + "SPAN_KIND_PRODUCER", + "SPAN_KIND_CONSUMER" + ] + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/traces/service-detail": { + "get": { + "operationId": "Tracing_GetServiceDetail", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetServiceDetailResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Optional. namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "instanceName", + "description": "Optional. instance name(k8s.pod.name)", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "extensionFilters", + "description": "Optional. support extension search\neg.service_name=my-otel-demo-adservice", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "serviceNames", + "description": "service_names are the service names to fetch metrics from.\nThe results will be grouped by service_name.\nRequired. At least one service name must be provided.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "groupByOperation", + "description": "groupByOperation determines if the metrics returned should be grouped by operation.\nOptional. Default = false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "endTime", + "description": "end_time is the ending time of the time series query range.\nOptional. Default = now.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "lookback", + "description": "lookback is the duration from the end_time to look back on for metrics data points.\nFor example, if set to 1h, the query would span from end_time-1h to end_time.\nOptional. Default = 1h.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "step", + "description": "step size is the duration between data points of the query results.\nFor example, if set to 5s, the results would produce a data point every 5 seconds\nfrom the start_time to end_time.\nOptional. Default = 5s.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "ratePer", + "description": "ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric.\nOptional. Default = 10m.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "spanKinds", + "description": "spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.\nOptional. Default = [SPAN_KIND_SERVER].\n\n - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default.\nImplementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application,\nas opposed to an operation happening at the boundaries. Default value.\n - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other\nremote network request.\n - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service.\n - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker.\nUnlike CLIENT and SERVER, there is often no direct critical path latency relationship\nbetween producer and consumer spans. A PRODUCER span ends when the message was accepted\nby the broker while the logical processing of the message might span a much longer time.\n - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker.\nLike the PRODUCER kind, there is often no direct critical path latency relationship\nbetween producer and consumer spans.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SPAN_KIND_UNSPECIFIED", + "SPAN_KIND_INTERNAL", + "SPAN_KIND_SERVER", + "SPAN_KIND_CLIENT", + "SPAN_KIND_PRODUCER", + "SPAN_KIND_CONSUMER" + ] + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/traces/service-names": { + "get": { + "operationId": "Tracing_ListServiceNames", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetServiceNamesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/traces/services": { + "get": { + "operationId": "Tracing_GetServices", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetServicesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "description": "Optional. namespace", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "extensionFilters", + "description": "Optional. support extension search\neg.service_name=my-otel-demo-adservice", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "end_time is the ending time of the time series query range.\nOptional. Default = now.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "lookback", + "description": "lookback is the duration from the end_time to look back on for metrics data points.\nFor example, if set to 1h, the query would span from end_time-1h to end_time.\nOptional. Default = 1h.", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "spanKinds", + "description": "spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.\nOptional. Default = [SPAN_KIND_SERVER, SPAN_KIND_CLIENT].\n\n - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default.\nImplementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application,\nas opposed to an operation happening at the boundaries. Default value.\n - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other\nremote network request.\n - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service.\n - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker.\nUnlike CLIENT and SERVER, there is often no direct critical path latency relationship\nbetween producer and consumer spans. A PRODUCER span ends when the message was accepted\nby the broker while the logical processing of the message might span a much longer time.\n - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker.\nLike the PRODUCER kind, there is often no direct critical path latency relationship\nbetween producer and consumer spans.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SPAN_KIND_UNSPECIFIED", + "SPAN_KIND_INTERNAL", + "SPAN_KIND_SERVER", + "SPAN_KIND_CLIENT", + "SPAN_KIND_PRODUCER", + "SPAN_KIND_CONSUMER" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sort", + "description": "sorts determines the data list order.\nparameter and sort direction divided by comma.\nyou can also only give the parameter,the desc sort will apply it by default\nsupport sorts:\n- service_name,desc or service_name\n- service_name,asc\n- req_rate,desc or req_rate\n- req_rate,asc\n- rep_latency,desc or rep_latency\n- rep_latency,asc\n- error_rate,desc or error_rate\n- error_rate,asc\n\nthe default sort is service_name,asc", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "clusterName", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Tracing" + ] + } + }, + "/apis/insight.io/v1alpha1/userinfo": { + "get": { + "operationId": "Insight_GetUserinfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1userinfo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Insight" + ] + } + }, + "/apis/insight.io/v1alpha1/version": { + "get": { + "operationId": "Insight_GetVersion", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1VersionInfo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Insight" + ] + } + } + }, + "definitions": { + "AlertAddGroupRuleBody": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1alpha1CreateGroupRule" + } + } + }, + "AlertUpdateGroupBody": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "notificationTemplate": { + "type": "string" + }, + "receivers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1groupReceiver" + } + }, + "notifyRepeatConfig": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1repeatConfig" + } + } + } + }, + "AlertUpdateGroupRuleBody": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "expr": { + "type": "string" + }, + "thresholdSymbol": { + "type": "string", + "title": "when create rule from metric_tpl,use thresholdSymbol and thresholdNum to\ncomplete the promql" + }, + "thresholdNum": { + "type": "number", + "format": "float" + }, + "duration": { + "type": "string", + "title": "For evaluation interval in time.Duration format,like 30s, 1m, 1h" + }, + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "customized labels" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "customized annotations" + }, + "logFilterCondition": { + "$ref": "#/definitions/v1alpha1RuleFilterCondition", + "description": "logs alert part\nonly need when rule source is LOG_TPL." + }, + "logQueryString": { + "type": "string" + } + } + }, + "AlertUpdateInhibitionBody": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "sourceMatchers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + }, + "title": "required; support maxium 100 matches" + }, + "targetMatchers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + }, + "title": "required; support maxium 100 matches" + }, + "equal": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "AlertUpdateProviderBody": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1ProviderType" + }, + "aliyun": { + "$ref": "#/definitions/ProviderAliyunConfig" + }, + "tencent": { + "$ref": "#/definitions/ProviderTencentConfig" + }, + "custom": { + "$ref": "#/definitions/ProviderCustomConfig" + }, + "template": { + "type": "string" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "AlertUpdateReceiverBody": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1ReceiverType" + }, + "webhook": { + "$ref": "#/definitions/v1alpha1WebhookConfig" + }, + "email": { + "$ref": "#/definitions/v1alpha1EmailConfig" + }, + "wecom": { + "$ref": "#/definitions/v1alpha1WecomConfig" + }, + "dingtalk": { + "$ref": "#/definitions/v1alpha1DingtalkConfig" + }, + "sms": { + "$ref": "#/definitions/v1alpha1SmsConfig" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "AlertUpdateRuleTemplateBody": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1CreateGroupRule" + } + } + } + }, + "AlertUpdateSilenceBody": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "matches": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + }, + "title": "required; support maxium 100 matches" + }, + "activeTimeInterval": { + "$ref": "#/definitions/v1alpha1timeInterval", + "title": "optional; null means rule always valid" + } + } + }, + "AlertUpdateTemplateBody": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "body": { + "$ref": "#/definitions/v1alpha1TemplateBody" + } + } + }, + "ClusterProbersResponseConfigmapMeta": { + "type": "object", + "properties": { + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "name": { + "type": "string" + }, + "data": { + "type": "string" + } + } + }, + "ClusterProbersResponseProber": { + "type": "object", + "properties": { + "prober": { + "$ref": "#/definitions/v1alpha1ProberSpec" + }, + "modules": { + "type": "array", + "items": { + "type": "string" + } + }, + "configmapMeta": { + "$ref": "#/definitions/ClusterProbersResponseConfigmapMeta" + } + } + }, + "EventInvolvedObject": { + "type": "object", + "properties": { + "kind": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "EventQueryEventCountBody": { + "type": "object", + "properties": { + "startTime": { + "type": "string", + "description": "startTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now-24 hour." + }, + "endTime": { + "type": "string", + "description": "endTime e.g. 2006-01-02T15:04:05.999999999Z07:00\nOptional.\nDefault = now." + }, + "namespace": { + "type": "string", + "description": "Optional." + }, + "filters": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1EventFilter" + }, + "description": "support key value:\n- name: imagePullFail\n value: {\"reason\":\"BackOff\",\"message\":\"Back-off pulling image\"}\n- name: healthyCheckFail\n value: {\"reason\":\"Unhealthy\"}\n- name: podFailed\n value: {\"involve_object_kind\":\"Pod\",\"reason\":\"Failed\"}\n- name: podFailedScheduling\n value: {\"involve_object_kind\":\"Pod\",\"reason\":\"FailedScheduling\"}\n- name: podOOMKilling\n value: {\"involve_object_kind\":\"Pod\",\"reason\":\"OOMKilling\"}\n- name: podFailedMount\n value: {\"reason\":\"FailedMount\"}\nRequired.\nDefault = [imagePullFail, healthyCheckFail, podFailed, podFailedScheduling, podOOMKilling, podFailedMount]." + } + } + }, + "EventSource": { + "type": "object", + "properties": { + "component": { + "type": "string" + }, + "host": { + "type": "string" + } + } + }, + "GetResourcesCountRequestResourcesFilter": { + "type": "string", + "enum": [ + "RESOURCE_TYPE_UNSPECIFIED", + "CLUSTER_NORMAL_TOTAL", + "CLUSTER_TOTAL", + "NODE_NORMAL_TOTAL", + "NODE_TOTAL", + "DEPLOYMENT_NORMAL_TOTAL", + "DEPLOYMENT_TOTAL", + "STATEFULSET_NORMAL_TOTAL", + "STATEFULSET_TOTAL", + "DAEMONSET_NORMAL_TOTAL", + "DAEMONSET_TOTAL", + "JOB_NORMAL_TOTAL", + "JOB_TOTAL", + "POD_NORMAL_TOTAL", + "POD_TOTAL", + "LOG_TOTAL", + "TRACE_TOTAL" + ], + "default": "RESOURCE_TYPE_UNSPECIFIED" + }, + "GetResourcesRangeRequestResourceFilter": { + "type": "string", + "enum": [ + "RESOURCE_TYPE_UNSPECIFIED", + "NODE_TOTAL", + "POD_TOTAL", + "POD_ABNORMAL_TOTAL", + "POD_NORMAL_TOTAL" + ], + "default": "RESOURCE_TYPE_UNSPECIFIED" + }, + "GetResourcesUsageRequestResourceFilters": { + "type": "string", + "enum": [ + "RESOURCE_TYPE_UNSPECIFIED", + "CLUSTER_CPU_USAGE", + "CLUSTER_MEM_USAGE", + "CLUSTER_DISK_USAGE", + "NODE_CPU_USAGE", + "NODE_MEM_USAGE", + "NODE_DISK_USAGE" + ], + "default": "RESOURCE_TYPE_UNSPECIFIED" + }, + "GetServicesMonitorRequestMonitorFilter": { + "type": "string", + "enum": [ + "MONITOR_TYPE_UNSPECIFIED", + "AVG_LATENCY", + "ERR_RATE" + ], + "default": "MONITOR_TYPE_UNSPECIFIED" + }, + "NodePosition": { + "type": "object", + "properties": { + "x": { + "type": "number", + "format": "float" + }, + "y": { + "type": "number", + "format": "float" + } + }, + "title": "Position 可用于标记节点在画布中的位置。\n如果存在此值,那么就是后端计算出位置之后前端直接渲染。\n如果不需要,也可以不实现,由前端选择合适的方式进行展现,或者自己实现。" + }, + "PreviewRuleRequestParams": { + "type": "object", + "properties": { + "start": { + "type": "string", + "format": "int64", + "title": "default end - 1h" + }, + "end": { + "type": "string", + "format": "int64", + "title": "default now" + }, + "step": { + "type": "number", + "format": "double", + "title": "default 60" + } + }, + "title": "Describes querying data size paramaters" + }, + "ProbeAddProbeBody": { + "type": "object", + "properties": { + "probe": { + "$ref": "#/definitions/v1alpha1ProbeSpec" + } + } + }, + "ProbeUpdateProbeBody": { + "type": "object", + "properties": { + "module": { + "type": "string" + }, + "targets": { + "$ref": "#/definitions/v1alpha1Targets" + }, + "interval": { + "type": "string" + }, + "scrapeTimeout": { + "type": "string" + } + } + }, + "ProviderAliyunConfig": { + "type": "object", + "properties": { + "signName": { + "type": "string" + }, + "templateCode": { + "type": "string" + }, + "accessKeyId": { + "type": "string" + }, + "accessKeySecret": { + "type": "string" + } + } + }, + "ProviderCustomConfig": { + "type": "object" + }, + "ProviderTencentConfig": { + "type": "object", + "properties": { + "templateId": { + "type": "string" + }, + "smsSdkAppId": { + "type": "string" + }, + "sign": { + "type": "string" + }, + "secretId": { + "type": "string" + }, + "secretKey": { + "type": "string" + } + } + }, + "ResourceGetPodJVMInfoBody": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string", + "title": "required;" + }, + "start": { + "type": "string", + "format": "int64" + }, + "end": { + "type": "string", + "format": "int64" + }, + "step": { + "type": "number", + "format": "double" + } + } + }, + "StatusPhase": { + "type": "string", + "enum": [ + "Pending", + "Running", + "Failed" + ], + "default": "Pending" + }, + "TargetsStaticConfig": { + "type": "object", + "properties": { + "static": { + "type": "array", + "items": { + "type": "string" + } + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "relabelingConfigs": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1RelabelConfig" + } + } + } + }, + "TraceProcessMapping": { + "type": "object", + "properties": { + "processId": { + "type": "string" + }, + "process": { + "$ref": "#/definitions/v1alpha1Process" + } + } + }, + "TraceTraceStatus": { + "type": "string", + "enum": [ + "UNHEALTHY", + "HEALTHY" + ], + "default": "UNHEALTHY" + }, + "WorkloadSumKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET" + ], + "default": "KIND_UNSPECIFIED" + }, + "alertv1alpha1CountAlert": { + "type": "object", + "properties": { + "start": { + "type": "string", + "format": "int64" + }, + "end": { + "type": "string", + "format": "int64" + }, + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1countInfo" + } + } + } + }, + "alertv1alpha1Group": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "builtin": { + "type": "boolean" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "targets": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "notificationTemplate": { + "type": "string" + }, + "receivers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1groupReceiver" + } + }, + "notifyRepeatConfig": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1repeatConfig" + } + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "apigraphv1alpha1Node": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "节点 ID,不可重复,可以按照一定规则生成。" + }, + "parent": { + "type": "string", + "title": "父节点的 ID,可选实现,可能在做一些依赖关系的时候会用到。\n也可以用在,比如将多个服务放在一个 Namespace 的匡中这种场景。" + }, + "type": { + "$ref": "#/definitions/v1alpha1NodeType", + "title": "节点类型,可用于前端展现不同的图标,或者进行后一步操作。" + }, + "metadata": { + "$ref": "#/definitions/v1alpha1NodeMetadata" + }, + "position": { + "$ref": "#/definitions/NodePosition", + "title": "节点的位置标记" + }, + "statuses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apigraphv1alpha1Status" + }, + "title": "当前节点各种状态" + } + }, + "title": "Node 表示图上的每一个实体点" + }, + "apigraphv1alpha1Status": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "可以定义一些初步的 name 共识:\nreplicas 表示副本数\navailableReplicas 表示可用副本数\nrequestsPerMinute 请求速率(RPM)\nerrorRate 错误率(%)\navgLatency 平均延迟(ms)\nconnections 连接数\nreceiveBytes 接收吞吐(B/S)\nsendBytes 发送吞吐(B/S)\nhealthyStatus 健康状态;0(未知) | 1(健康) | 2(告警) | 3(异常)" + }, + "value": { + "type": "number", + "format": "float", + "title": "具体的值,只能用浮点数来表示状态。" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "properties 可以给这个 Status 增加一些扩展的参数,\n比如在网格中,流量可能可以分为入口或者出口流量。" + } + }, + "title": "Status 用于定义节点或连线的状态。\n比如希望展示当前服务的 QPS,那么可以如下:\n{ name: qps, value: 100, properties: {protocol: http}}\n如果想要展示命名空间的服务数量:\n{ name: service_count, value: 5}\n具体的释义可以根据各个产品决定。" + }, + "apiprobesv1alpha1Status": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/StatusPhase" + } + } + }, + "apiresourcev1alpha1Condition": { + "type": "object", + "properties": { + "lastTransitionTime": { + "type": "string", + "title": "Last time the condition transitioned from one status to another.\n+optional" + }, + "lastUpdateTime": { + "type": "string", + "title": "Last time we got an update on a given condition.\n+optional" + }, + "message": { + "type": "string", + "title": "A human readable message indicating details about the transition.\n+optional" + }, + "reason": { + "type": "string", + "title": "The reason for the condition's last transition.\n+optional" + }, + "status": { + "type": "string", + "description": "Status of the condition, one of True, False, Unknown." + }, + "type": { + "type": "string", + "description": "Type of condition." + } + }, + "description": "Condition describes the state of a referent at a certain point." + }, + "apiresourcev1alpha1Node": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "operatingSystem": { + "type": "string" + }, + "address": { + "type": "string" + }, + "creationTimestamp": { + "type": "string", + "format": "int64" + }, + "nodeStatus": { + "$ref": "#/definitions/v1alpha1NodeStatus" + }, + "podSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "usage": { + "$ref": "#/definitions/v1alpha1usage" + } + } + }, + "googlerpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "timeIntervaltimeRange": { + "type": "object", + "properties": { + "start": { + "type": "string", + "format": "int64" + }, + "end": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1AMHookRequest": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "groupKey": { + "type": "string" + }, + "status": { + "type": "string" + }, + "receiver": { + "type": "string" + }, + "groupLabels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "commonLabels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "commonAnnotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "externalURL": { + "type": "string" + }, + "alerts": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1AmAlert" + } + }, + "truncatedAlerts": { + "type": "string", + "format": "int64" + } + }, + "title": "alert message send by alertmanager" + }, + "v1alpha1AgentSummary": { + "type": "object", + "properties": { + "insightAgentState": { + "$ref": "#/definitions/v1alpha1insightAgentState" + }, + "agentModuleStatus": { + "$ref": "#/definitions/v1alpha1agentModuleStatus" + } + } + }, + "v1alpha1AggType": { + "type": "string", + "enum": [ + "INTERSECTION", + "UNION" + ], + "default": "INTERSECTION", + "title": "- INTERSECTION: INTERSECTION preform a intersection operation after FilterOperator\n - UNION: UNION preform a union operation after FilterOperator\nCURRENT NOT SUPPORT" + }, + "v1alpha1Alert": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "int64" + }, + "groupName": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "ruleName": { + "type": "string" + }, + "ruleId": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "target": { + "type": "string" + }, + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "value": { + "type": "string" + }, + "notifyResponse": { + "type": "string" + }, + "description": { + "type": "string" + }, + "promQL": { + "type": "string", + "title": "real sql that used to query, add info like cluster, namespaces" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "startAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + }, + "lastSent": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1AlertHistoryRetentionPeriod": { + "type": "object", + "properties": { + "retentionTime": { + "type": "integer", + "format": "int32", + "title": "retention_time unit is day, 0 means no need to clean" + } + } + }, + "v1alpha1AlertSummary": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "int64" + }, + "groupName": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "ruleName": { + "type": "string" + }, + "ruleId": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "target": { + "type": "string" + }, + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "value": { + "type": "string" + }, + "notifyResponse": { + "type": "string" + }, + "description": { + "type": "string" + }, + "startAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + }, + "lastSent": { + "type": "string", + "format": "int64" + }, + "builtin": { + "type": "boolean", + "title": "inherits from group" + } + } + }, + "v1alpha1AmAlert": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "startsAt": { + "type": "string" + }, + "endsAt": { + "type": "string" + }, + "generatorURL": { + "type": "string" + }, + "fingerprint": { + "type": "string" + } + } + }, + "v1alpha1BaseGraphQuery": { + "type": "object", + "properties": { + "clusters": { + "type": "array", + "items": { + "type": "string" + } + }, + "namespaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "services": { + "type": "array", + "items": { + "type": "string" + } + }, + "layer": { + "$ref": "#/definitions/v1alpha1Layer", + "title": "期望展示的 layer 层级,比如 MESH, TRACING" + }, + "start": { + "type": "string", + "format": "int64", + "title": "start 开始时间 unix timestamp,单位 ms" + }, + "end": { + "type": "string", + "format": "int64", + "title": "end 结束时间 unix timestamp,单位 ms" + }, + "extensionLabels": { + "type": "string", + "title": "eg. \"skoala_registry=ireg-1233,instance_name=xxxxx\"" + }, + "graphType": { + "$ref": "#/definitions/v1alpha1GraphType" + }, + "clusterNames": { + "type": "array", + "items": { + "type": "string" + }, + "title": "cluster_names 集群名字列表" + }, + "filters": { + "$ref": "#/definitions/v1alpha1Filter", + "title": "filters optional. Filter defines some filter operation to the graph data\nindependently. After filter operators done, there is a collection operation\non filtered graph data depending on filters.agg_type, finally, there is a\ndependency fetch operation on the second step result as a root graph to\nfetch its dependent data(downstream node or upstream node) from the origin\nGraph with dependency_max_depth depth the root node data will have a\nproperty DEPENDENT_TYPE = ROOT the dependency node data will have a\nproperty DEPENDENT_TYPE = DEPENDENT" + }, + "showVirtualNode": { + "type": "boolean", + "title": "TODO(jian): remove this in next milestone.\nshow virtual node in service graph or not. Default: false" + }, + "showUpDownRelatedNode": { + "type": "boolean", + "title": "show upstream and downstream node. Default: false" + }, + "workloads": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1BasicAuth": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "v1alpha1BatchQueryRangeRequest": { + "type": "object", + "properties": { + "param": { + "$ref": "#/definitions/v1alpha1BatchQueryRangeRequestParam" + }, + "matchLabel": { + "$ref": "#/definitions/v1alpha1MatchLabel" + }, + "queryList": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1BatchQueryRangeRequestParam": { + "type": "object", + "properties": { + "start": { + "type": "string", + "format": "int64" + }, + "end": { + "type": "string", + "format": "int64" + }, + "step": { + "type": "number", + "format": "double" + } + } + }, + "v1alpha1BatchQueryRangeResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1BatchQueryRangeResult" + } + } + } + }, + "v1alpha1BatchQueryRangeResult": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1PrometheusQueryRangeResult" + }, + "status": { + "$ref": "#/definitions/v1alpha1requestStatus" + }, + "errorMessage": { + "type": "string" + } + } + }, + "v1alpha1BatchQueryRequest": { + "type": "object", + "properties": { + "param": { + "$ref": "#/definitions/v1alpha1BatchQueryRequestParam" + }, + "matchLabel": { + "$ref": "#/definitions/v1alpha1MatchLabel" + }, + "queryList": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1BatchQueryRequestParam": { + "type": "object", + "properties": { + "time": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1BatchQueryResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1BatchQueryResult" + } + } + } + }, + "v1alpha1BatchQueryResult": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1PrometheusQueryResult" + }, + "status": { + "$ref": "#/definitions/v1alpha1requestStatus" + }, + "errorMessage": { + "type": "string" + } + } + }, + "v1alpha1CleanAlertHistoryResponse": { + "type": "object", + "properties": { + "num": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1Cluster": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kubeSystemId": { + "type": "string", + "title": "kube-system id" + }, + "phase": { + "$ref": "#/definitions/v1alpha1ClusterPhase" + }, + "role": { + "$ref": "#/definitions/v1alpha1Role" + } + } + }, + "v1alpha1ClusterDetail": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kubeSystemId": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1ClusterPhase" + }, + "provider": { + "$ref": "#/definitions/v1alpha1ClusterProvider", + "description": "Provider represents the cloud provider name of the member cluster." + }, + "kubernetesVersion": { + "type": "string", + "description": "KubernetesVersion represents version of the cluster." + }, + "creationTimestamp": { + "type": "string", + "format": "int64" + }, + "nodeNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "deploymentNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "statefulsetNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "daemonsetNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "podNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "insightAgentStatus": { + "$ref": "#/definitions/v1alpha1insightAgentState" + } + } + }, + "v1alpha1ClusterPhase": { + "type": "string", + "enum": [ + "CLUSTER_PHASE_UNSPECIFIED", + "UNKNOWN", + "CREATING", + "RUNNING", + "UPDATING", + "DELETING", + "FAILED" + ], + "default": "CLUSTER_PHASE_UNSPECIFIED", + "description": " - CLUSTER_PHASE_UNSPECIFIED: The cluster state is unspecified.\n - UNKNOWN: The cluster state is unknown.\n - CREATING: The cluster is being created.\n - RUNNING: The cluster is running.\n - UPDATING: The cluster is updating.\n - DELETING: The cluster is being deleted.\n - FAILED: The cluster operations failed." + }, + "v1alpha1ClusterProbersResponse": { + "type": "object", + "properties": { + "probers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/ClusterProbersResponseProber" + } + } + } + }, + "v1alpha1ClusterProvider": { + "type": "string", + "enum": [ + "GENERIC", + "DAOCLOUD_KUBESPRAY", + "DAOCLOUD_CLUSTER_API", + "DAOCLOUD_DCE4", + "REDHAT_OPENSHIFT4", + "SUSE_RANCHER", + "VMWARE_TANZU", + "AWS_EKS", + "ALIYUN_ACK", + "TENCENT_TKE", + "HUAWEI_CCE", + "MICROSOFT_AZURE" + ], + "default": "GENERIC", + "description": " - GENERIC: GENERIC indicates other providers\n - DAOCLOUD_KUBESPRAY: 1.DaoCloud\nDAOCLOUD_KUBESPRAY indicates a provider of DaoCloud's KubeSpray Engine\n - DAOCLOUD_CLUSTER_API: DAOCLOUD_CLUSTER_API indicates a provider of DaoCloud's Cluster API Engine\n - DAOCLOUD_DCE4: DAOCLOUD_DCE4 indicates a provider of DaoCloud's DCE4 Engine\n - REDHAT_OPENSHIFT4: 2.OverSea Distribtion\nREDHAT_OPENSHIFT4 indicates a provider of RedHat Openshift4\n - SUSE_RANCHER: SUSE_RANCHER indicates a provider of SUSE Rancher\n - VMWARE_TANZU: VMWARE_TANZU indicates a provider of VMware Tanzu\n - AWS_EKS: 3.Public Cloud\nAWS_EKS indicates a provider of AWS EKS\n - ALIYUN_ACK: ALIYUN_ACK indicates a provider of Aliyun ACK\n - TENCENT_TKE: TENCENT_TKE indicates a provider of Tencent TKE.\n - HUAWEI_CCE: TENCENT_TKE indicates a provider of Huawei CCE.\n - MICROSOFT_AZURE: MICROSOFT_AZURE=11; indicates a provider of Microsoft Azure." + }, + "v1alpha1ClusterSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kubeSystemId": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1ClusterPhase" + }, + "nodeNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "insightAgentStatus": { + "$ref": "#/definitions/v1alpha1insightAgentState" + }, + "role": { + "$ref": "#/definitions/v1alpha1Role" + } + } + }, + "v1alpha1ConditionStatus": { + "type": "string", + "enum": [ + "CONDITION_STATUS_UNSPECIFIED", + "True", + "False", + "Unknown" + ], + "default": "CONDITION_STATUS_UNSPECIFIED", + "description": "These are valid condition statuses.\n\n - CONDITION_STATUS_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - True: True means a resource is in the condition.\n - False: False means a resource is not in the condition.\n - Unknown: Unknown means kubernetes can't decide if a resource is in the condition or\nnot." + }, + "v1alpha1ContainerPhase": { + "type": "string", + "enum": [ + "CONTAINER_PHASE_UNSPECIFIED", + "CONTAINER_PHASE_WAITING", + "CONTAINER_PHASE_RUNNING", + "CONTAINER_PHASE_TERMINATED" + ], + "default": "CONTAINER_PHASE_UNSPECIFIED" + }, + "v1alpha1ContainerSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1ContainerPhase" + } + } + }, + "v1alpha1CountAlertResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/alertv1alpha1CountAlert" + } + } + } + }, + "v1alpha1CreateGroupRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "targets": { + "type": "array", + "items": { + "type": "string" + } + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1CreateGroupRule" + } + }, + "notificationTemplate": { + "type": "string" + }, + "receivers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1groupReceiver" + } + }, + "notifyRepeatConfig": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1repeatConfig" + } + } + } + }, + "v1alpha1CreateGroupRule": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "required" + }, + "description": { + "type": "string" + }, + "source": { + "$ref": "#/definitions/v1alpha1RuleSource", + "title": "required" + }, + "expr": { + "type": "string" + }, + "thresholdSymbol": { + "type": "string", + "title": "when create rule from metric_tpl,use thresholdSymbol and thresholdNum to\ncomplete the promql" + }, + "thresholdNum": { + "type": "number", + "format": "float" + }, + "duration": { + "type": "string", + "title": "Supported units: h, m, s" + }, + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "customized labels" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "customized annotations" + }, + "logFilterCondition": { + "$ref": "#/definitions/v1alpha1RuleFilterCondition", + "description": "logs alert part\nonly need when rule source is LOG_TPL." + }, + "logQueryString": { + "type": "string" + } + } + }, + "v1alpha1CreateInhibitionRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "description": { + "type": "string" + }, + "sourceMatchers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + }, + "title": "required; support maxium 100 matches" + }, + "targetMatchers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + }, + "title": "required; support maxium 100 matches" + }, + "equal": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1CreateRuleTemplateRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1CreateGroupRule" + } + } + } + }, + "v1alpha1CreateSilenceRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "description": { + "type": "string" + }, + "matches": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + }, + "title": "required; support maxium 100 matches" + }, + "activeTimeInterval": { + "$ref": "#/definitions/v1alpha1timeInterval", + "title": "optional; null means rule always valid" + } + } + }, + "v1alpha1CreateTemplateRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "body": { + "$ref": "#/definitions/v1alpha1TemplateBody" + } + } + }, + "v1alpha1CronJob": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1CronJobPhase" + }, + "createTimestamp": { + "type": "string", + "format": "int64" + }, + "jobNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiresourcev1alpha1Condition" + }, + "description": "conditions of current cronjob." + } + } + }, + "v1alpha1CronJobPhase": { + "type": "string", + "enum": [ + "CRONJOB_STATE_UNSPECIFIED", + "CRONJOB_STATE_WAITING", + "CRONJOB_STATE_ACTIVATED", + "CRONJOB_STATE_STOPPED", + "CRONJOB_STATE_DELETING" + ], + "default": "CRONJOB_STATE_UNSPECIFIED", + "description": " - CRONJOB_STATE_UNSPECIFIED: CronJob is unspecified.\n - CRONJOB_STATE_WAITING: Waiting for cronjob ready.\n - CRONJOB_STATE_ACTIVATED: The number of pending and running pods.\n - CRONJOB_STATE_STOPPED: CronJob has stopped.\n - CRONJOB_STATE_DELETING: CronJob is being deleted." + }, + "v1alpha1CronJobSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1CronJobPhase" + }, + "jobNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + } + } + }, + "v1alpha1DingtalkConfig": { + "type": "object", + "properties": { + "webhook": { + "type": "string" + }, + "secret": { + "type": "string" + } + } + }, + "v1alpha1DownloadFileType": { + "type": "string", + "enum": [ + "TEXT", + "CSV", + "JSON" + ], + "default": "TEXT" + }, + "v1alpha1DownloadLogRequest": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1DownloadFileType" + }, + "queryLog": { + "$ref": "#/definitions/v1alpha1QueryLogRequest" + }, + "queryLogContext": { + "$ref": "#/definitions/v1alpha1QueryLogContextRequest" + }, + "fields": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1LogField" + } + } + } + }, + "v1alpha1DownloadLogResponse": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + } + }, + "v1alpha1Edge": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "与 Node.id 一致,一个唯一标志符,理论上,Edge 的 ID 可以为空。" + }, + "source": { + "type": "string", + "title": "source 表示当前连线的起始节点 ID" + }, + "target": { + "type": "string", + "title": "target 表示当前连线的目标节点 ID" + }, + "statuses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apigraphv1alpha1Status" + }, + "title": "当前连线各种状态" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "当前连线的一些扩展状态,比如可以展示当前协议,线的展示类型等。\n根据各个产品商议。" + } + }, + "title": "Edge 表示连线,用于连接两个 Node。" + }, + "v1alpha1EmailConfig": { + "type": "object", + "properties": { + "to": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1Event": { + "type": "object", + "properties": { + "reportingComponent": { + "type": "string" + }, + "reason": { + "type": "string" + }, + "lastTimestamp": { + "type": "string", + "title": "e.g. 2023-06-21T01:16:56.000Z" + }, + "count": { + "type": "string", + "format": "int64" + }, + "message": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "source": { + "$ref": "#/definitions/EventSource" + }, + "reportingInstance": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/v1alpha1EventMetadata" + }, + "type": { + "$ref": "#/definitions/v1alpha1EventType" + }, + "firstTimestamp": { + "type": "string", + "title": "e.g. 2023-06-21T01:16:56.000Z" + }, + "involveObject": { + "$ref": "#/definitions/EventInvolvedObject" + }, + "clusterUuid": { + "type": "string" + }, + "timestamp": { + "type": "string", + "title": "unique primary key, e.g. 2023-06-20T16:05:16.887681657Z" + }, + "action": { + "type": "string" + }, + "eventTime": { + "type": "string" + } + } + }, + "v1alpha1EventFilter": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1EventType" + }, + "involveObjectKind": { + "type": "string" + }, + "reason": { + "type": "string" + }, + "involveObjectName": { + "type": "string", + "title": "fuzzy search" + }, + "message": { + "type": "string", + "title": "fuzzy search" + } + } + }, + "v1alpha1EventHistogram": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "title": "timestamp e.g. 2023-06-21T01:48:00.000Z" + }, + "normalCount": { + "type": "string", + "format": "int64" + }, + "warningCount": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1EventMetadata": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "resourceVersion": { + "type": "string" + }, + "creationTimestamp": { + "type": "string" + } + } + }, + "v1alpha1EventType": { + "type": "string", + "enum": [ + "TYPE_UNSPECIFIED", + "Normal", + "Warning" + ], + "default": "TYPE_UNSPECIFIED", + "title": "- Normal: use lowercase to keep the same as the original Kubernetes event data" + }, + "v1alpha1FeatureGate": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v1alpha1FeatureGateIDEnum", + "title": "唯一标志符" + }, + "name": { + "type": "string", + "title": "名字" + }, + "description": { + "type": "string", + "title": "关于此 FeatureGate 的描述" + }, + "enabled": { + "type": "boolean", + "title": "是否启用" + }, + "status": { + "type": "string" + } + } + }, + "v1alpha1FeatureGateIDEnum": { + "type": "string", + "enum": [ + "METRICS", + "LOGGING", + "TRACING", + "GRAPH_VIRTUAL_NODE", + "LOG_ALERT", + "NET_FLOW" + ], + "default": "METRICS" + }, + "v1alpha1FeatureGatesResp": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1FeatureGate" + } + } + } + }, + "v1alpha1Filter": { + "type": "object", + "properties": { + "clauses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1OperatorClause" + }, + "title": "clause define a list of filter clause" + }, + "aggType": { + "$ref": "#/definitions/v1alpha1AggType", + "title": "agg_type define a type of set operation" + }, + "dependencyMaxDepth": { + "type": "integer", + "format": "int32", + "title": "dependency_max_depth display the dependency graph with max depth\ndefault value is 1" + } + } + }, + "v1alpha1FilterDataType": { + "type": "string", + "enum": [ + "NODE_DATA", + "EDGE_DATA" + ], + "default": "NODE_DATA", + "title": "- EDGE_DATA: CURRENT NOT SUPPORT" + }, + "v1alpha1FilterField": { + "type": "string", + "enum": [ + "SERVICE_NAME", + "STATUS_ERROR_RATE", + "STATUS_LATENCY", + "CUSTOM_LABEL" + ], + "default": "SERVICE_NAME", + "title": "- SERVICE_NAME: SERVICE_NAME support operation:\n- FilterOperator_CONTAIN\n- FilterOperator_NOT_CONTAIN\n- FilterOperator_EQUAL\n- FilterOperator_NOT_EQUAL\n- FilterOperator_REGEX_PATTERN\n - STATUS_ERROR_RATE: STATUS_ERROR_RATE support operation:\n- FilterOperator_LE\n- FilterOperator_GE\n - STATUS_LATENCY: STATUS_LATENCY support operation:\n- FilterOperator_LE\n- FilterOperator_GE\n - CUSTOM_LABEL: CURRENT NOT SUPPORT" + }, + "v1alpha1FilterOperator": { + "type": "string", + "enum": [ + "EQ", + "NE", + "LT", + "LE", + "GT", + "GE", + "CONTAIN", + "NOT_CONTAIN", + "EQUAL", + "NOT_EQUAL", + "REGEX_PATTERN" + ], + "default": "EQ", + "title": "- EQ: EQ only support apply on numerical data\n= Equality relation between numerics\n - NE: NE only support apply on numerical data\n!= Inequality relation between numerics\n - LT: LT only support apply on numerical data\n< Less than relation between numerics\n - LE: LE only support apply on numerical data\n<= Less than or equal relation between numerics\n - GT: GT only support apply on numerical data\n> Greater than relation between numerics\n - GE: GE only support apply on numerical data\n>= Greater than or equal relation between numerics\n - CONTAIN: CONTAIN only support apply on string data\nRegularExpression\n - NOT_CONTAIN: NOT_CONTAIN only support apply on string data\nRegularExpression operation\n - EQUAL: EQUAL only support apply on string data\nRegularExpression operation\n - NOT_EQUAL: only support apply on string data\nRegularExpression operation\n - REGEX_PATTERN: only support apply on string data\nRegularExpression operation" + }, + "v1alpha1GetConfigResponse": { + "type": "object", + "properties": { + "grafanaUrl": { + "type": "string" + } + } + }, + "v1alpha1GetGPUResponse": { + "type": "object", + "properties": { + "urls": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1dashboardURL" + } + } + } + }, + "v1alpha1GetOperationDetailResponse": { + "type": "object", + "properties": { + "metrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1MetricsWithOperation" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1GetReasonsResponse": { + "type": "object", + "properties": { + "node": { + "type": "array", + "items": { + "type": "string" + } + }, + "daemonSet": { + "type": "array", + "items": { + "type": "string" + } + }, + "deployment": { + "type": "array", + "items": { + "type": "string" + } + }, + "job": { + "type": "array", + "items": { + "type": "string" + } + }, + "pod": { + "type": "array", + "items": { + "type": "string" + } + }, + "statefulSet": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1GetResourcesCountResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1BatchQueryResult" + }, + "title": "data contain difference metric with a __name__ label which describe the name of metric" + } + } + }, + "v1alpha1GetResourcesRangeResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1BatchQueryRangeResult" + } + } + } + }, + "v1alpha1GetResourcesUsageResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1BatchQueryRangeResult" + } + } + } + }, + "v1alpha1GetSMTPStatusResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "v1alpha1GetServiceDetailResponse": { + "type": "object", + "properties": { + "p95Metrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "请求时延 95 百分位趋势图,时间范围内的" + }, + "p75Metrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "请求时延 75 百分位趋势图,时间范围内的" + }, + "p50Metrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "请求时延 50 百分位趋势图,时间范围内的" + }, + "reqRateMetric": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "吞吐率趋势图,时间范围内的" + }, + "errorsRateMetrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "错误率延趋势图,时间范围内的" + } + } + }, + "v1alpha1GetServiceNamesResponse": { + "type": "object", + "properties": { + "services": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1GetServicesMonitorResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1BatchQueryResult" + } + } + } + }, + "v1alpha1GetServicesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1ServiceItem" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1GlobalConfig": { + "type": "object", + "properties": { + "vmStorageRetentionTime": { + "type": "string" + }, + "logRetentionTime": { + "type": "string" + }, + "traceDataRetentionTime": { + "type": "string" + }, + "traceApdexThreshold": { + "type": "string" + }, + "k8sEventLogRetentionTime": { + "type": "string" + }, + "skoalaLogRetentionTime": { + "type": "string" + } + } + }, + "v1alpha1Graph": { + "type": "object", + "properties": { + "nodes": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apigraphv1alpha1Node" + } + }, + "edges": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Edge" + } + }, + "layer": { + "$ref": "#/definitions/v1alpha1Layer" + }, + "graphType": { + "$ref": "#/definitions/v1alpha1GraphType" + } + }, + "description": "样例 2,根据服务网格的观测数据,画出拓扑图\n{\n\"nodes\": [\n{\n\"id\": \"test-cluster/test-ns\",\n\"type\": \"NAMESPACE\",\n\"metadata\": {\n\"cluster\": \"test-cluster\",\n\"name\": \"test-ns\",\n\"layer\": \"MESH\",\n\"properties\": {\n\"mesh_id\": \"demo-dev\"\n}\n},\n\"status\": [\n{\n\"name\": \"replicas\",\n\"value\": 10,\n\"properties\": {\n\"type\": \"pod\"\n}\n},\n{\n\"name\": \"service_count\",\n\"value\": 5\n}\n]\n},\n{\n\"id\": \"test-cluster/test-ns/services/echo\",\n\"parent\": \"test-cluster/test-ns\",\n\"type\": \"SERVICE\",\n\"metadata\": {\n\"cluster\": \"test-cluster\",\n\"namespace\": \"test-ns\",\n\"name\": \"echo\",\n\"layer\": \"MESH\",\n\"properties\": {\n\"mesh_id\": \"demo-dev\"\n}\n},\n\"status\": [\n{\n\"name\": \"requestsPerMinute\",\n\"value\": 133.5,\n\"properties\": {\n\"direction\": \"in\"\n}\n},\n{\n\"name\": \"requestsPerMinute\",\n\"value\": 2,\n\"properties\": {\n\"direction\": \"out\"\n}\n}\n]\n},\n{\n\"id\": \"test-cluster/test-ns/services/echo-client\",\n\"parent\": \"test-cluster/test-ns\",\n\"type\": \"SERVICE\",\n\"metadata\": {\n\"cluster\": \"test-cluster\",\n\"namespace\": \"test-ns\",\n\"name\": \"echo-client\",\n\"layer\": \"MESH\",\n\"properties\": {\n\"mesh_id\": \"demo-dev\"\n}\n},\n\"status\": [\n{\n\"name\": \"requestsPerMinute\",\n\"value\": 100,\n\"properties\": {\n\"direction\": \"out\"\n}\n}\n]\n}\n],\n\"edges\": [\n{\n\"id\":\n\"test-cluster/test-ns/services/echo-client---test-cluster/test-ns/services/echo\"\n\"source\": \"test-cluster/test-ns/services/echo-client\",\n\"target\": \"test-cluster/test-ns/services/echo\",\n\"status\": [\n{\n\"name\": \"requestsPerMinute\",\n\"value\": 100\n}\n],\n\"properties\": {\n\"protocol\": \"HTTP\"\n}\n}\n],\n\"type\": \"SERVICE_SCOPE\"\n}", + "title": "样例 1,根据 Kubernetes 的资源结构,画出拓扑图(可能不存在节点连线)\n{\n\"nodes\": [\n{\n\"id\": \"test-cluster/test-ns\",\n\"type\": \"NAMESPACE\",\n\"metadata\": {\n\"cluster\": \"test-cluster\",\n\"name\": \"test-ns\",\n\"layer\": \"KUBERNETES\"\n},\n\"status\": [\n{\n\"name\": \"replicas\",\n\"value\": 10,\n\"properties\": {\n\"type\": \"pod\"\n}\n},\n{\n\"name\": \"service_count\",\n\"value\": 5\n}\n]\n},\n{\n\"id\": \"test-cluster/test-ns/services/echo\",\n\"parent\": \"test-cluster/test-ns\",\n\"type\": \"SERVICE\",\n\"metadata\": {\n\"cluster\": \"test-cluster\",\n\"namespace\": \"test-ns\",\n\"name\": \"echo\",\n\"layer\": \"KUBERNETES\"\n},\n\"status\": [\n{\n\"name\": \"replicas\",\n\"value\": 3,\n\"properties\": {\n\"type\": \"pod\"\n}\n}\n]\n}\n],\n\"type\": \"SERVICE_SCOPE\"\n}" + }, + "v1alpha1GraphType": { + "type": "string", + "enum": [ + "GRAPH_UNSPECIFIED", + "CLUSTER_SCOPE", + "NAMESPACE_SCOPE", + "SERVICE_SCOPE", + "WORKLOAD_SCOPE", + "INSTANCE_SCOPE", + "MIXED" + ], + "default": "GRAPH_UNSPECIFIED", + "description": "- CLUSTER_SCOPE: 用于展现集群之间的拓扑关系\n - NAMESPACE_SCOPE: 用于展示命名空间之间的拓扑关系", + "title": "图的展示类型\n与节点类型 NodeType 不同的是,如果 GraphType 为 WORKLOAD,\n但是也可以在接口中返回 Namespace 的 Node 可能用于用户手动展开等场景。" + }, + "v1alpha1GroupSummary": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "builtin": { + "type": "boolean" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "targets": { + "type": "array", + "items": { + "type": "string" + } + }, + "groupRuleStatus": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1groupRuleStatus" + } + }, + "description": { + "type": "string" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1HTTPConfig": { + "type": "object", + "properties": { + "basicAuth": { + "$ref": "#/definitions/v1alpha1BasicAuth" + }, + "bearerToken": { + "type": "string" + }, + "tlsConfig": { + "$ref": "#/definitions/v1alpha1SafeTLSConfig" + }, + "headers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1HTTPHeader" + } + } + } + }, + "v1alpha1HTTPHeader": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "description": "See k8s.io.api.core.v1.HTTPHeader." + }, + "v1alpha1Inhibition": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "description": { + "type": "string" + }, + "sourceMatchers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + } + }, + "targetMatchers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + } + }, + "equal": { + "type": "array", + "items": { + "type": "string" + } + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1InhibitionList": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Inhibition" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1InsightAgentStatus": { + "type": "string", + "enum": [ + "NOT_INSTALLED", + "HEALTHY", + "UNHEALTHY", + "OFFLINE" + ], + "default": "NOT_INSTALLED" + }, + "v1alpha1JVMType": { + "type": "string", + "enum": [ + "JMX", + "OTEL", + "NONE" + ], + "default": "JMX", + "description": " - JMX: metrics exposed by JMX exporter\n - OTEL: metrics exposed by OTEL Java Agent\n - NONE: empty metrics, no jvm collected." + }, + "v1alpha1JVMUrls": { + "type": "object", + "properties": { + "en": { + "type": "string", + "title": "English grafana dashboard url" + }, + "zh": { + "type": "string", + "title": "Chinese grafana dashboard url" + } + } + }, + "v1alpha1Job": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha1JobStatus" + }, + "createTimestamp": { + "type": "string", + "format": "int64" + }, + "jobPodNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiresourcev1alpha1Condition" + }, + "description": "conditions of current job." + } + } + }, + "v1alpha1JobState": { + "type": "string", + "enum": [ + "JOB_STATE_UNSPECIFIED", + "JOB_STATE_WAITING", + "JOB_STATE_RUNNING", + "JOB_STATE_COMPLETED", + "JOB_STATE_DELETING", + "JOB_STATE_FAILED" + ], + "default": "JOB_STATE_UNSPECIFIED", + "description": " - JOB_STATE_UNSPECIFIED: Job is unspecified.\n - JOB_STATE_WAITING: Waiting for job ready.\n - JOB_STATE_RUNNING: Job is working.\n - JOB_STATE_COMPLETED: Jobs has completed.\n - JOB_STATE_DELETING: Jobs is being deleted.\n - JOB_STATE_FAILED: Jobs is not ready to work ." + }, + "v1alpha1JobStatus": { + "type": "object", + "properties": { + "active": { + "type": "integer", + "format": "int32" + }, + "succeed": { + "type": "integer", + "format": "int32" + }, + "failed": { + "type": "integer", + "format": "int32" + }, + "phase": { + "$ref": "#/definitions/v1alpha1JobState" + } + } + }, + "v1alpha1JobSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha1JobStatus" + }, + "jobPodNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + } + } + }, + "v1alpha1KeyValue": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "vType": { + "$ref": "#/definitions/v1alpha1ValueType" + }, + "vStr": { + "type": "string" + }, + "vBool": { + "type": "boolean" + }, + "vInt64": { + "type": "string", + "format": "int64" + }, + "vFloat64": { + "type": "number", + "format": "double" + }, + "vBinary": { + "type": "string", + "format": "byte" + } + } + }, + "v1alpha1Layer": { + "type": "string", + "enum": [ + "LAYER_UNSPECIFIED", + "KUBERNETES", + "MESH", + "OS_LINUX", + "VM", + "INFRA", + "GENERAL" + ], + "default": "LAYER_UNSPECIFIED", + "description": "- KUBERNETES: 直接部署在 Kubernetes 上\n - MESH: 服务网格层级\n - OS_LINUX: 云主机或操作系统层级\n - INFRA: 基础设施层级,\n - GENERAL: 通用层级,可能是传统应用上报的数据", + "title": "像 Skywalking 一样,表示当前所处的层级\n用于展示不同的视图模型,甚至可以展示不同层级之间的关系。" + }, + "v1alpha1ListAlertsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1AlertSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListClusterSummaryResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1ClusterSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListClustersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Cluster" + } + } + } + }, + "v1alpha1ListContainersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1ContainerSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListCronJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1CronJobSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListGroupsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1GroupSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1JobSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListLogFilePathsResponse": { + "type": "object", + "properties": { + "paths": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1ListNamespacesResponse": { + "type": "object", + "properties": { + "namespaces": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Namespace" + } + } + } + }, + "v1alpha1ListNodesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1NodeSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListPodsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1PodSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListProbesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Probe" + }, + "title": "items represents the response of CustomResource" + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListProbesResponse represents list all of the Probe of namespaced scope in cluster" + }, + "v1alpha1ListProvidersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Provider" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListReceiverResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Receiver" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + }, + "title": "list receiver" + }, + "v1alpha1ListRuleTemplateSummaryResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1RuleTemplateSummary" + } + } + } + }, + "v1alpha1ListRuleTemplatesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1RuleTemplate" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListRulesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1RuleSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListServicesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1serviceSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListSilencesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Silence" + } + } + } + }, + "v1alpha1ListTemplatesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1TemplateSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1ListWorkloadsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1workloadSummary" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1LogContextEventFilter": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + } + } + }, + "v1alpha1LogContextResourceFilter": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "pod": { + "type": "string" + }, + "container": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "v1alpha1LogContextSystemFilter": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "node": { + "type": "string" + }, + "file": { + "type": "string" + } + } + }, + "v1alpha1LogField": { + "type": "string", + "enum": [ + "LOG_FIELD_UNSPECIFIED", + "Timestamp", + "Cluster", + "Namespace", + "Pod", + "Container", + "Node", + "File" + ], + "default": "LOG_FIELD_UNSPECIFIED", + "title": "- Namespace: container log only\n - Node: system log only" + }, + "v1alpha1LogHistogramResult": { + "type": "object", + "properties": { + "timestamp": { + "type": "string" + }, + "count": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1LogQueryEventFilter": { + "type": "object", + "properties": { + "logSearch": { + "type": "array", + "items": { + "type": "string" + } + }, + "clusterFilter": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1LogQueryResourceFilter": { + "type": "object", + "properties": { + "logSearch": { + "type": "array", + "items": { + "type": "string" + } + }, + "clusterFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "namespaceFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "workloadSearch": { + "type": "array", + "items": { + "type": "string" + } + }, + "workloadFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "podSearch": { + "type": "array", + "items": { + "type": "string" + } + }, + "podFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "containerSearch": { + "type": "array", + "items": { + "type": "string" + } + }, + "containerFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "traceIdSearch": { + "type": "string" + }, + "luceneFilter": { + "type": "string", + "title": "lucene_filter is a string that contains the lucene query string\nthe syntax is define in https://www.elastic.co/guide/en/elasticsearch/reference/7.16/query-dsl-query-string-query.html#query-string-syntax\nsupport key list:\n- `kubernetes.namespace_name.keyword`\n- `kubernetes.pod_name.keyword`\n- `trace_id.keyword`\n- `kubernetes.container_name.keyword`\n- `log`" + } + } + }, + "v1alpha1LogQueryResult": { + "type": "object", + "properties": { + "log": { + "type": "string" + }, + "timestamp": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1LogQuerySystemFilter": { + "type": "object", + "properties": { + "logSearch": { + "type": "array", + "items": { + "type": "string" + } + }, + "clusterFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "nodeFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "fileFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "luceneFilter": { + "type": "string", + "title": "lucene_filter is a string that contains the lucene query string\nthe syntax is define in https://www.elastic.co/guide/en/elasticsearch/reference/7.16/query-dsl-query-string-query.html#query-string-syntax\nsupport key list:\n- `syslog.host.keyword`\n- `syslog.file.keyword`\n- `syslog.ident.keyword`\n- `log`" + } + } + }, + "v1alpha1MatchLabel": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "extraLabel": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1MetricsEntity": { + "type": "object", + "properties": { + "metrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1samplePair" + } + }, + "metricsAvg": { + "type": "number", + "format": "double" + } + } + }, + "v1alpha1MetricsWithOperation": { + "type": "object", + "properties": { + "operationName": { + "type": "string" + }, + "metricsMap": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1MetricsEntity" + }, + "title": "available keys:\n- reqRate\n- errRate\n- p50Latency\n- p95Latency\n- p99Latency" + }, + "spanKind": { + "$ref": "#/definitions/v1alpha1SpanKind" + } + } + }, + "v1alpha1Namespace": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "role": { + "$ref": "#/definitions/v1alpha1Role" + } + } + }, + "v1alpha1NamespaceDetail": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1NamespacePhase" + }, + "creationTimestamp": { + "type": "string", + "format": "int64" + }, + "deploymentNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "statefulsetNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "daemonsetNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "podNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + } + } + }, + "v1alpha1NamespacePhase": { + "type": "string", + "enum": [ + "NAMESPACE_PHASE_UNSPECIFIED", + "Active", + "Terminating" + ], + "default": "NAMESPACE_PHASE_UNSPECIFIED", + "title": "- NAMESPACE_PHASE_UNSPECIFIED: The namespace state is unspecified.\n - Active: NamespaceActive means the namespace is available for use in the system\n - Terminating: NamespaceTerminating means the namespace is undergoing graceful termination" + }, + "v1alpha1NodeCondition": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of node condition. The built-in set of conditions are: Ready,\nMemoryPressure, DiskPressure, PIDPressure,\nNetworkUnavailable, and SchedulingDisabled." + }, + "status": { + "$ref": "#/definitions/v1alpha1ConditionStatus", + "description": "Status of the condition, one of True, False, Unknown." + }, + "reason": { + "type": "string", + "description": "(brief) reason for the condition's last transition." + }, + "message": { + "type": "string", + "description": "Human readable message indicating details about last transition." + } + }, + "description": "NodeCondition contains condition information for a node." + }, + "v1alpha1NodeMetadata": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "service": { + "type": "string", + "title": "预定义的所属服务信息,可以为空。" + }, + "name": { + "type": "string", + "title": "当前节点需要显示的名字。" + }, + "layer": { + "$ref": "#/definitions/v1alpha1Layer", + "title": "所述层级" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "存储额外的信息,比如版本信息之类的。" + }, + "clusterName": { + "type": "string" + } + } + }, + "v1alpha1NodeMetricResponse": { + "type": "object", + "properties": { + "reqRateMetric": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "吞吐率趋势图,时间范围内的" + }, + "errorsRateMetrics": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "错误率延趋势图,时间范围内的" + }, + "repLatencyMetric": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "平均请求时延趋势图,时间范围内的" + } + } + }, + "v1alpha1NodePhase": { + "type": "string", + "enum": [ + "NODE_PHASE_UNSPECIFIED", + "NODE_PHASE_READY", + "NODE_PHASE_NOT_READY", + "NODE_PHASE_UNKNOWN" + ], + "default": "NODE_PHASE_UNSPECIFIED", + "description": "status includes Ready, NotReady, and Unknown.\n\n - NODE_PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - NODE_PHASE_READY: The node is ready to work.\n - NODE_PHASE_NOT_READY: The node is not ready.\n - NODE_PHASE_UNKNOWN: The node state is unknown." + }, + "v1alpha1NodeStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1NodePhase" + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1NodeCondition" + } + } + } + }, + "v1alpha1NodeSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1NodePhase" + }, + "podNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "gpuVendors": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "title": "NodeSummary only return node name,status and podSummary" + }, + "v1alpha1NodeType": { + "type": "string", + "enum": [ + "NODE_TYPE_UNSPECIFIED", + "CLUSTER", + "NAMESPACE", + "SERVICE", + "WORKLOAD", + "INSTANCE", + "NODE", + "CUSTOM" + ], + "default": "NODE_TYPE_UNSPECIFIED", + "title": "- WORKLOAD: 比如需要展示 Deployment 之类的 Workload\n - INSTANCE: 实例,比如 Pod 的时候可以展示\n - NODE: 节点,如果需要的话\n - CUSTOM: 自定义类型,如果需要的话,推荐通过 metadata.properties.type\n进行详细说明。" + }, + "v1alpha1ObjectMeta": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name must be unique within a namespace. Is required when creating\nresources, although some resources may allow a client to request the\ngeneration of an appropriate name automatically. Name is primarily intended\nfor creation idempotence and configuration definition. Cannot be updated.\nMore info: http://kubernetes.io/docs/identifiers#names\n+optional" + }, + "namespace": { + "type": "string", + "description": "Namespace defines the space within each name must be unique. An empty\nnamespace is equivalent to the \"default\" namespace, but \"default\" is the\ncanonical representation. Not all objects are required to be scoped to a\nnamespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL.\nCannot be updated.\nMore info: http://kubernetes.io/docs/namespaces\n+optional" + }, + "uid": { + "type": "string", + "description": "UID is the unique in time and space value for this object. It is typically\ngenerated by the server on successful creation of a resource and is not\nallowed to change on PUT operations.\n\nPopulated by the system.\nRead-only.\nMore info: http://kubernetes.io/docs/identifiers#uids\n+optional" + }, + "resourceVersion": { + "type": "string", + "description": "An opaque value that represents the internal version of this object that\ncan be used by clients to determine when objects have changed. May be used\nfor optimistic concurrency, change detection, and the watch operation on a\nresource or set of resources. Clients must treat these values as opaque and\npassed unmodified back to the server. They may only be valid for a\nparticular resource or set of resources.\n\nPopulated by the system.\nRead-only.\nValue must be treated as opaque by clients and .\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency" + }, + "creationTimestamp": { + "type": "string", + "description": "CreationTimestamp is a timestamp representing the server time when this\nobject was created. It is not guaranteed to be set in happens-before order\nacross separate operations. Clients may not set this value. It is\nrepresented in RFC3339 form and is in UTC.\n\nPopulated by the system.\nRead-only.\nNull for lists.\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n+optional" + }, + "deletionTimestamp": { + "type": "string", + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be\ndeleted. This field is set by the server when a graceful deletion is\nrequested by the user, and is not directly settable by a client. The\nresource is expected to be deleted (no longer visible from resource lists,\nand not reachable by name) after the time in this field, once the\nfinalizers list is empty. As long as the finalizers list contains items,\ndeletion is blocked. Once the deletionTimestamp is set, this value may not\nbe unset or be set further into the future, although it may be shortened or\nthe resource may be deleted prior to this time. For example, a user may\nrequest that a pod is deleted in 30 seconds. The kubelet will react by\nsending a graceful termination signal to the containers in the pod. After\nthat 30 seconds, the kubelet will send a hard termination signal (SIGKILL)\nto the container and after cleanup, remove the pod from the API. In the\npresence of network partitions, this object may still exist after this\ntimestamp, until an administrator or automated process can determine the\nresource is fully terminated.\nIf not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested.\nRead-only.\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n+optional" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Map of string keys and values that can be used to organize and categorize\n(scope and select) objects. May match selectors of replication controllers\nand services.\nMore info: http://kubernetes.io/docs/labels\n+optional" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Annotations is an unstructured key value map stored with a resource that\nmay be set by external tools to store and retrieve arbitrary metadata. They\nare not queryable and should be preserved when modifying objects. More\ninfo: http://kubernetes.io/docs/annotations +optional" + }, + "ownerReferences": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1OwnerReference" + }, + "title": "List of objects depended by this object. If ALL objects in the list have\nbeen deleted, this object will be garbage collected. If this object is\nmanaged by a controller, then an entry in this list will point to this\ncontroller, with the controller field set to true. There cannot be more\nthan one managing controller. +optional +patchMergeKey=uid\n+patchStrategy=merge" + } + }, + "description": "ObjectMeta is metadata that all persisted resources must have, which includes\nall objects users must create." + }, + "v1alpha1OperatorClause": { + "type": "object", + "properties": { + "dataType": { + "$ref": "#/definitions/v1alpha1FilterDataType", + "title": "data_type define the data type that can be used in filter" + }, + "field": { + "$ref": "#/definitions/v1alpha1FilterField", + "title": "field define the field that can be used in filter" + }, + "operation": { + "$ref": "#/definitions/v1alpha1FilterOperator", + "title": "operation define the operation that can be used in filter" + }, + "stringValue": { + "type": "string" + }, + "floatValue": { + "type": "number", + "format": "float" + } + }, + "title": "OperatorClause definition" + }, + "v1alpha1OwnerReference": { + "type": "object", + "properties": { + "uid": { + "type": "string", + "title": "UID of the referent.\nMore info: http://kubernetes.io/docs/identifiers#uids" + }, + "controller": { + "type": "boolean", + "title": "If true, this reference points to the managing controller.\n+optional" + }, + "name": { + "type": "string", + "description": "Name of the referent." + }, + "kind": { + "type": "string", + "description": "Kind of the referent." + } + }, + "description": "OwnerReference contains enough information to let you identify an owning\nobject. An owning object must be in the same namespace as the dependent, or\nbe cluster-scoped, so there is no namespace field." + }, + "v1alpha1Pagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32", + "description": "Total is the total number of referents." + }, + "page": { + "type": "integer", + "format": "int32", + "description": "Page is current page." + }, + "pageSize": { + "type": "integer", + "format": "int32", + "description": "PageSize is the data number shown per page." + }, + "pages": { + "type": "integer", + "format": "int32", + "description": "Pages is the number of pages." + } + } + }, + "v1alpha1Pod": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1PodPhase" + }, + "createTimestamp": { + "type": "string", + "format": "int64" + }, + "containerNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "podIp": { + "type": "string" + }, + "hostIp": { + "type": "string" + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiresourcev1alpha1Condition" + }, + "description": "conditions of current pod." + } + } + }, + "v1alpha1PodJVMInfo": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1JVMType", + "title": "type means pod exposed by JMX/OTEL/NONE" + }, + "urls": { + "$ref": "#/definitions/v1alpha1JVMUrls", + "title": "jvm grafana dashboard urls" + } + } + }, + "v1alpha1PodPhase": { + "type": "string", + "enum": [ + "POD_PHASE_UNSPECIFIED", + "POD_PHASE_UNKNOWN", + "POD_PHASE_PENDING", + "POD_PHASE_RUNNING", + "POD_PHASE_SUCCEED", + "POD_PHASE_FAILED" + ], + "default": "POD_PHASE_UNSPECIFIED", + "description": " - POD_PHASE_UNKNOWN: PodUnknown means that for some reason the state of the pod could not be\nobtained, typically due to an error in communicating with the host of the\npod.\n - POD_PHASE_PENDING: PodPending means the pod has been accepted by the system, but one or more\nof the containers has not been started. This includes time before being\nbound to a node, as well as time spent pulling images onto the host.\n - POD_PHASE_RUNNING: PodRunning means the pod has been bound to a node and all of the containers\nhave been started. At least one container is still running or is in the\nprocess of being restarted. PodSucceeded means that all containers in the\npod have voluntarily terminated with a container exit code of 0, and the\nsystem is not going to restart any of these containers.\n - POD_PHASE_SUCCEED: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).\n - POD_PHASE_FAILED: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system)." + }, + "v1alpha1PodSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1PodPhase" + }, + "containerNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "podIp": { + "type": "string" + } + } + }, + "v1alpha1PreviewRuleRequest": { + "type": "object", + "properties": { + "params": { + "$ref": "#/definitions/PreviewRuleRequestParams" + }, + "group": { + "$ref": "#/definitions/v1alpha1PreviewRuleRequestGroup" + }, + "rule": { + "$ref": "#/definitions/v1alpha1CreateGroupRule" + } + } + }, + "v1alpha1PreviewRuleRequestGroup": { + "type": "object", + "properties": { + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "targets": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "title": "Describes rule's owner group info" + }, + "v1alpha1PreviewRuleResponse": { + "type": "object", + "properties": { + "matrix": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + } + } + } + }, + "v1alpha1PreviewSilenceRequest": { + "type": "object", + "properties": { + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "matches": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + } + }, + "size": { + "type": "string", + "format": "int64", + "title": "size limits the preview result,\nif not set, will use default 200" + } + } + }, + "v1alpha1PreviewSilenceResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1AlertSummary" + } + } + } + }, + "v1alpha1Probe": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "description": "Kind represents the kind of CustomResource." + }, + "apiVersion": { + "type": "string", + "description": "APIVersion represents the apiVersion of CustomResource." + }, + "metadata": { + "$ref": "#/definitions/v1alpha1ObjectMeta" + }, + "spec": { + "$ref": "#/definitions/v1alpha1ProbeSpec" + }, + "status": { + "$ref": "#/definitions/apiprobesv1alpha1Status" + } + } + }, + "v1alpha1ProbeSpec": { + "type": "object", + "properties": { + "jobName": { + "type": "string" + }, + "module": { + "type": "string" + }, + "prober": { + "$ref": "#/definitions/v1alpha1ProberSpec" + }, + "targets": { + "$ref": "#/definitions/v1alpha1Targets" + }, + "interval": { + "type": "string" + }, + "scrapeTimeout": { + "type": "string" + }, + "relabelings": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1RelabelConfig" + } + }, + "proxyUrl": { + "type": "string" + }, + "enableHttp2": { + "type": "boolean" + }, + "filterRunning": { + "type": "boolean" + }, + "honorTimestamps": { + "type": "boolean" + }, + "honorLabels": { + "type": "boolean" + }, + "metricRelabelings": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1RelabelConfig" + } + }, + "followRedirects": { + "type": "boolean" + }, + "sampleLimit": { + "type": "string", + "format": "uint64", + "title": "TODO: add more: https://github.com/prometheus-operator/prometheus-operator/blob/52d1e55af2d223474aab35bf54bd56c2b9b22385/pkg/apis/monitoring/v1/probe_types.go#L48\ntlsConfig\nbearerTokenSecret\nauthorization\noauth2\nbasicAuth" + } + }, + "title": "Probe represents all fileds of probe rule" + }, + "v1alpha1ProberSpec": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "scheme": { + "type": "string" + }, + "path": { + "type": "string" + }, + "proxyUrl": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1Process": { + "type": "object", + "properties": { + "serviceName": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1KeyValue" + } + } + } + }, + "v1alpha1PrometheusQueryRangeResult": { + "type": "object", + "properties": { + "matrix": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SampleStream" + } + } + } + }, + "v1alpha1PrometheusQueryResult": { + "type": "object", + "properties": { + "vector": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Sample" + } + } + } + }, + "v1alpha1Provider": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/v1alpha1ProviderType" + }, + "aliyun": { + "$ref": "#/definitions/ProviderAliyunConfig" + }, + "tencent": { + "$ref": "#/definitions/ProviderTencentConfig" + }, + "custom": { + "$ref": "#/definitions/ProviderCustomConfig" + }, + "template": { + "type": "string" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1ProviderDataResponse": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1Provider" + } + } + }, + "v1alpha1ProviderType": { + "type": "string", + "enum": [ + "PROVIDER_TYPE_UNSPECIFIED", + "aliyun", + "tencent", + "custom" + ], + "default": "PROVIDER_TYPE_UNSPECIFIED" + }, + "v1alpha1QueryEventCountResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string", + "format": "int64" + } + } + } + }, + "v1alpha1QueryEventFilterOptionsResponse": { + "type": "object", + "properties": { + "reasons": { + "type": "array", + "items": { + "type": "string" + } + }, + "involvedObjectKinds": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1QueryEventHistogramResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1EventHistogram" + } + }, + "totalNormal": { + "type": "string", + "format": "int64" + }, + "totalWarning": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1QueryEventResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Event" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1QueryLogContextRequest": { + "type": "object", + "properties": { + "startTime": { + "type": "string" + }, + "endTime": { + "type": "string" + }, + "before": { + "type": "integer", + "format": "int32" + }, + "after": { + "type": "integer", + "format": "int32" + }, + "nanotimestamp": { + "type": "string" + }, + "resource": { + "$ref": "#/definitions/v1alpha1LogContextResourceFilter" + }, + "system": { + "$ref": "#/definitions/v1alpha1LogContextSystemFilter" + }, + "event": { + "$ref": "#/definitions/v1alpha1LogContextEventFilter" + } + } + }, + "v1alpha1QueryLogHistogramRequest": { + "type": "object", + "properties": { + "startTime": { + "type": "string" + }, + "endTime": { + "type": "string" + }, + "interval": { + "type": "string" + }, + "resource": { + "$ref": "#/definitions/v1alpha1LogQueryResourceFilter" + }, + "system": { + "$ref": "#/definitions/v1alpha1LogQuerySystemFilter" + }, + "event": { + "$ref": "#/definitions/v1alpha1LogQueryEventFilter" + } + } + }, + "v1alpha1QueryLogHistogramResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1LogHistogramResult" + } + } + } + }, + "v1alpha1QueryLogRequest": { + "type": "object", + "properties": { + "startTime": { + "type": "string", + "title": "startTime e.g. 2006-01-02T15:04:05.999999999Z07:00" + }, + "endTime": { + "type": "string", + "title": "startTime e.g. 2006-01-02T15:04:05.999999999Z07:00" + }, + "page": { + "type": "integer", + "format": "int32", + "description": "Page is current page." + }, + "pageSize": { + "type": "integer", + "format": "int32", + "description": "Size is the data number shown per page." + }, + "sorts": { + "type": "array", + "items": { + "type": "string" + } + }, + "resource": { + "$ref": "#/definitions/v1alpha1LogQueryResourceFilter" + }, + "system": { + "$ref": "#/definitions/v1alpha1LogQuerySystemFilter" + }, + "event": { + "$ref": "#/definitions/v1alpha1LogQueryEventFilter" + } + } + }, + "v1alpha1QueryLogResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1LogQueryResult" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1Pagination" + } + } + }, + "v1alpha1QueryOperationsResponse": { + "type": "object", + "properties": { + "operations": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1Receiver": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/v1alpha1ReceiverType" + }, + "webhook": { + "$ref": "#/definitions/v1alpha1WebhookConfig" + }, + "email": { + "$ref": "#/definitions/v1alpha1EmailConfig" + }, + "wecom": { + "$ref": "#/definitions/v1alpha1WecomConfig" + }, + "dingtalk": { + "$ref": "#/definitions/v1alpha1DingtalkConfig" + }, + "sms": { + "$ref": "#/definitions/v1alpha1SmsConfig" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1ReceiverDataResponse": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1Receiver" + } + } + }, + "v1alpha1ReceiverType": { + "type": "string", + "enum": [ + "RECEIVER_TYPE_UNSPECIFIED", + "webhook", + "email", + "dingtalk", + "wecom", + "sms" + ], + "default": "RECEIVER_TYPE_UNSPECIFIED" + }, + "v1alpha1RelabelConfig": { + "type": "object", + "properties": { + "sourceLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "separator": { + "type": "string" + }, + "targetLabel": { + "type": "string" + }, + "regex": { + "type": "string" + }, + "modulus": { + "type": "string", + "format": "uint64" + }, + "replacement": { + "type": "string" + }, + "action": { + "type": "string" + } + } + }, + "v1alpha1ResourceNumSummary": { + "type": "object", + "properties": { + "totalNum": { + "type": "integer", + "format": "int32" + }, + "readyNum": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1Role": { + "type": "string", + "enum": [ + "ROLE_UNSPECIFIED", + "ROLE_VIEWER", + "ROLE_ADMIN" + ], + "default": "ROLE_UNSPECIFIED" + }, + "v1alpha1Rule": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "expr": { + "type": "string" + }, + "thresholdSymbol": { + "type": "string", + "title": "when create rule from metric_tpl,use thresholdSymbol and thresholdNum to\ncomplete the promql" + }, + "thresholdNum": { + "type": "number", + "format": "float" + }, + "duration": { + "type": "string", + "title": "For evaluation interval in time.Duration format,like 30s, 1m, 1h" + }, + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "source": { + "$ref": "#/definitions/v1alpha1RuleSource" + }, + "status": { + "$ref": "#/definitions/v1alpha1RuleStatus" + }, + "promQL": { + "type": "string", + "title": "real sql that used to query, add info like cluster, namespaces" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "customized labels" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "customized annotations" + }, + "description": { + "type": "string" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + }, + "logFilterCondition": { + "$ref": "#/definitions/v1alpha1RuleFilterCondition", + "description": "logs alert part\nonly need when rule source is LOG_TPL." + }, + "logQueryString": { + "type": "string" + } + } + }, + "v1alpha1RuleFilterCondition": { + "type": "string", + "enum": [ + "FILTER_CONDITION_UNSPECIFIED", + "AND", + "OR", + "REG", + "FUZZINESS", + "WILD_CARD" + ], + "default": "FILTER_CONDITION_UNSPECIFIED", + "description": "- AND: union\n - OR: Intersection\n - REG: Regular expressions\n - FUZZINESS: Fuzziness\n - WILD_CARD: Wildcards", + "title": "condition for logs filter string" + }, + "v1alpha1RuleSource": { + "type": "string", + "enum": [ + "RULE_SOURCE_UNSPECIFIED", + "METRIC_TPL", + "PROMQL", + "LOG_TPL", + "EVENT_TPL" + ], + "default": "RULE_SOURCE_UNSPECIFIED" + }, + "v1alpha1RuleStatus": { + "type": "string", + "enum": [ + "UNSPECIFIED", + "FIRING", + "ENABLED" + ], + "default": "UNSPECIFIED" + }, + "v1alpha1RuleSummary": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "source": { + "$ref": "#/definitions/v1alpha1RuleSource" + }, + "expr": { + "type": "string" + }, + "thresholdSymbol": { + "type": "string" + }, + "thresholdNum": { + "type": "number", + "format": "float" + }, + "status": { + "$ref": "#/definitions/v1alpha1RuleStatus" + }, + "description": { + "type": "string" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "logFilterCondition": { + "$ref": "#/definitions/v1alpha1RuleFilterCondition", + "description": "logs alert part\nonly need when rule source is LOG_TPL." + }, + "logQueryString": { + "type": "string" + }, + "duration": { + "type": "string" + } + } + }, + "v1alpha1RuleTemplate": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + }, + "count": { + "type": "integer", + "format": "int32" + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1CreateGroupRule" + } + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1RuleTemplateSummary": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "targetType": { + "$ref": "#/definitions/v1alpha1TargetType" + } + } + }, + "v1alpha1SafeTLSConfig": { + "type": "object", + "properties": { + "insecureSkipVerify": { + "type": "boolean" + } + } + }, + "v1alpha1Sample": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "values": { + "$ref": "#/definitions/v1alpha1samplePair" + } + } + }, + "v1alpha1SampleStream": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "values": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1samplePair" + } + } + } + }, + "v1alpha1SearchLogResponse": { + "type": "object", + "properties": { + "response": { + "type": "string" + } + } + }, + "v1alpha1ServerComponentSummary": { + "type": "object", + "properties": { + "summary": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1serverComponent" + } + } + } + }, + "v1alpha1Service": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "createTimestamp": { + "type": "string", + "format": "int64" + }, + "serviceType": { + "$ref": "#/definitions/v1alpha1ServiceType" + }, + "clusterIp": { + "type": "string" + }, + "workloadData": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1WorkloadSum" + } + } + } + }, + "v1alpha1ServiceItem": { + "type": "object", + "properties": { + "serviceName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "reqRate": { + "type": "number", + "format": "double" + }, + "repLatency": { + "type": "number", + "format": "double" + }, + "errorRate": { + "type": "number", + "format": "double" + } + } + }, + "v1alpha1ServiceType": { + "type": "string", + "enum": [ + "SERVICE_TYPE_UNSPECIFIED", + "CLUSTER_IP", + "NODE_PORT", + "LOAD_BALANCER", + "EXTERNAL_NAME" + ], + "default": "SERVICE_TYPE_UNSPECIFIED", + "description": "- SERVICE_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - CLUSTER_IP: ClusterIP means a service will only be accessible inside the cluster, via\nthe cluster IP.\n - NODE_PORT: NodePort means a service will be exposed on one port of every node, in\naddition to 'ClusterIP' type.\n - LOAD_BALANCER: LoadBalancer means a service will be exposed via an external load balancer\n(if the cloud provider supports it), in addition to 'NodePort' type.\n - EXTERNAL_NAME: ExternalName means a service consists of only a reference to an external\nname that kubedns or equivalent will return as a CNAME record, with no\nexposing or proxying of any pods involved.", + "title": "ServiceType string describes ingress methods for a service" + }, + "v1alpha1Severity": { + "type": "string", + "enum": [ + "SEVERITY_UNSPECIFIED", + "CRITICAL", + "WARNING", + "INFO" + ], + "default": "SEVERITY_UNSPECIFIED" + }, + "v1alpha1Silence": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "description": { + "type": "string" + }, + "matches": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1match" + } + }, + "activeTimeInterval": { + "$ref": "#/definitions/v1alpha1timeInterval" + }, + "expired": { + "type": "boolean" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1SmsConfig": { + "type": "object", + "properties": { + "contact": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1SmsConfigContact" + } + }, + "provider": { + "type": "string", + "title": "provider" + } + } + }, + "v1alpha1SmsConfigContact": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "phone": { + "type": "string" + } + } + }, + "v1alpha1SpanKind": { + "type": "string", + "enum": [ + "SPAN_KIND_UNSPECIFIED", + "SPAN_KIND_INTERNAL", + "SPAN_KIND_SERVER", + "SPAN_KIND_CLIENT", + "SPAN_KIND_PRODUCER", + "SPAN_KIND_CONSUMER" + ], + "default": "SPAN_KIND_UNSPECIFIED", + "description": "SpanKind is the type of span. Can be used to specify additional relationships between spans\nin addition to a parent/child relationship.\n\n - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default.\nImplementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application,\nas opposed to an operation happening at the boundaries. Default value.\n - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other\nremote network request.\n - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service.\n - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker.\nUnlike CLIENT and SERVER, there is often no direct critical path latency relationship\nbetween producer and consumer spans. A PRODUCER span ends when the message was accepted\nby the broker while the logical processing of the message might span a much longer time.\n - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker.\nLike the PRODUCER kind, there is often no direct critical path latency relationship\nbetween producer and consumer spans." + }, + "v1alpha1TargetType": { + "type": "string", + "enum": [ + "TARGET_TYPE_UNSPECIFIED", + "GLOBAL", + "CLUSTER", + "NAMESPACE", + "NODE", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET", + "POD" + ], + "default": "TARGET_TYPE_UNSPECIFIED" + }, + "v1alpha1Targets": { + "type": "object", + "properties": { + "staticConfig": { + "$ref": "#/definitions/TargetsStaticConfig" + } + } + }, + "v1alpha1Template": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "body": { + "$ref": "#/definitions/v1alpha1TemplateBody" + }, + "builtin": { + "type": "boolean" + }, + "createAt": { + "type": "string", + "format": "int64" + }, + "updateAt": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1TemplateBody": { + "type": "object", + "properties": { + "email": { + "$ref": "#/definitions/v1alpha1emailBody" + }, + "wecom": { + "type": "string" + }, + "dingtalk": { + "type": "string" + }, + "webhook": { + "type": "string" + } + } + }, + "v1alpha1TemplateSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "updateAt": { + "type": "string", + "format": "int64" + }, + "builtin": { + "type": "boolean" + } + } + }, + "v1alpha1Trace": { + "type": "object", + "properties": { + "operationName": { + "type": "string" + }, + "processMap": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/TraceProcessMapping" + } + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + } + }, + "traceId": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/TraceTraceStatus" + }, + "spanCount": { + "type": "integer", + "format": "int64" + }, + "startTime": { + "type": "string" + }, + "duration": { + "type": "string" + } + } + }, + "v1alpha1TracesResponseChunk": { + "type": "object", + "properties": { + "traces": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Trace" + } + } + } + }, + "v1alpha1ValidateGroupCode": { + "type": "string", + "enum": [ + "ERR_CODE_UNSPECIFIED", + "ERR_YAML_UNMARSHAL", + "ERR_GROUP_NAME", + "ERR_GROUP_RULES", + "ERR_GROUP_NAME_DUPLICATED", + "ERR_RULE", + "ERR_RULE_ALERT", + "ERR_RULE_RECORD", + "ERR_RULE_FOR", + "ERR_RULE_EXPR", + "ERR_RULE_SEVERITY", + "ERR_RULE_ANNOTATIONS", + "ERR_RULE_LABELS", + "ERR_RULE_ALERT_DUPLICATED", + "ERR_RULE_DESCRIPTION" + ], + "default": "ERR_CODE_UNSPECIFIED", + "title": "- ERR_YAML_UNMARSHAL: VMRule YAML format error\n - ERR_GROUP_NAME: Alert Group's name has error\n - ERR_GROUP_RULES: Alert Group's rule list is empty or more than one\n - ERR_GROUP_NAME_DUPLICATED: Alert Group's name was duplicated\n - ERR_RULE: Alert rule has error\n - ERR_RULE_ALERT: Alert rule's alert name has error\n - ERR_RULE_RECORD: Alert rule's alert name has error\n - ERR_RULE_FOR: Alert rule's for time has error\n - ERR_RULE_EXPR: Alert rule's promql expression has error\n - ERR_RULE_SEVERITY: Alert rule's severity has error\n - ERR_RULE_ANNOTATIONS: Alert rule's annotations has error\n - ERR_RULE_LABELS: Alert rule's labels has error\n - ERR_RULE_ALERT_DUPLICATED: Alert rule's alert was duplicated\n - ERR_RULE_DESCRIPTION: Alert rule's description has error" + }, + "v1alpha1ValidateGroupError": { + "type": "object", + "properties": { + "code": { + "$ref": "#/definitions/v1alpha1ValidateGroupCode" + }, + "message": { + "type": "string" + } + } + }, + "v1alpha1ValidateGroupRequest": { + "type": "object", + "properties": { + "yamlString": { + "type": "string" + }, + "clusterName": { + "type": "string" + }, + "namespace": { + "type": "string" + } + } + }, + "v1alpha1ValidateGroupResponse": { + "type": "object", + "properties": { + "valid": { + "type": "boolean" + }, + "errors": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1ValidateGroupError" + } + }, + "params": { + "$ref": "#/definitions/v1alpha1CreateGroupRequest" + } + } + }, + "v1alpha1ValueType": { + "type": "string", + "enum": [ + "STRING", + "BOOL", + "INT64", + "FLOAT64", + "BINARY" + ], + "default": "STRING" + }, + "v1alpha1VersionInfo": { + "type": "object", + "properties": { + "gitVersion": { + "type": "string" + }, + "gitCommit": { + "type": "string" + }, + "buildDate": { + "type": "string" + }, + "goVersion": { + "type": "string" + }, + "compiler": { + "type": "string" + }, + "platform": { + "type": "string" + } + } + }, + "v1alpha1WebhookConfig": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "httpConfig": { + "$ref": "#/definitions/v1alpha1HTTPConfig" + } + } + }, + "v1alpha1WecomConfig": { + "type": "object", + "properties": { + "webhook": { + "type": "string" + } + } + }, + "v1alpha1Workload": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1WorkloadPhase" + }, + "createTimestamp": { + "type": "string", + "format": "int64" + }, + "podNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "conditions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/apiresourcev1alpha1Condition" + }, + "description": "conditions of current workload." + } + } + }, + "v1alpha1WorkloadKind": { + "type": "string", + "enum": [ + "WORKLOAD_KIND_UNKNOWN", + "WORKLOAD_KIND_DEPLOYMENT", + "WORKLOAD_KIND_STATEFULSET", + "WORKLOAD_KIND_DAEMONSET" + ], + "default": "WORKLOAD_KIND_UNKNOWN" + }, + "v1alpha1WorkloadPhase": { + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNKNOWN", + "WORKLOAD_STATE_RUNNING", + "WORKLOAD_STATE_DELETING", + "WORKLOAD_STATE_NOT_READY", + "WORKLOAD_STATE_STOPPED", + "WORKLOAD_STATE_WAITING" + ], + "default": "WORKLOAD_STATE_UNKNOWN", + "title": "WorkloadPhase describes the state of\nworkload(deployments/daemonsets/statefulsets)" + }, + "v1alpha1WorkloadSum": { + "type": "object", + "properties": { + "workloadKind": { + "$ref": "#/definitions/WorkloadSumKind" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1agentModuleStatus": { + "type": "object", + "properties": { + "pods": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1alpha1Pod" + } + } + } + }, + "v1alpha1countInfo": { + "type": "object", + "properties": { + "target": { + "type": "string", + "description": "target is the object that match the targetType, null means no specific\ntarget or not group_by_type." + }, + "sum": { + "type": "object", + "additionalProperties": { + "type": "string", + "format": "int64" + } + } + } + }, + "v1alpha1dashboardURL": { + "type": "object", + "properties": { + "en": { + "type": "string" + }, + "zh": { + "type": "string" + } + } + }, + "v1alpha1emailBody": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "body": { + "type": "string" + } + } + }, + "v1alpha1empty": { + "type": "object" + }, + "v1alpha1groupReceiver": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1ReceiverType" + }, + "names": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1groupRuleStatus": { + "type": "object", + "properties": { + "status": { + "$ref": "#/definitions/v1alpha1RuleStatus" + }, + "count": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1helmInstallConfigRequest": { + "type": "object", + "properties": { + "chartName": { + "type": "string" + }, + "version": { + "type": "string" + }, + "extra": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "key:registry_host,val:registry_url" + } + } + }, + "v1alpha1helmInstallConfigResponse": { + "type": "object", + "properties": { + "values": { + "type": "string" + } + } + }, + "v1alpha1insightAgentState": { + "type": "object", + "properties": { + "status": { + "$ref": "#/definitions/v1alpha1InsightAgentStatus" + }, + "version": { + "type": "string" + }, + "createTime": { + "type": "string", + "format": "int64" + }, + "traceStatus": { + "$ref": "#/definitions/v1alpha1InsightAgentStatus" + } + } + }, + "v1alpha1match": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1matchType" + }, + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1matchType": { + "type": "string", + "enum": [ + "MATCH_TYPE_UNSPECIFIED", + "EQUAL", + "NOT_EQUAL", + "REGEXP" + ], + "default": "MATCH_TYPE_UNSPECIFIED" + }, + "v1alpha1repeatConfig": { + "type": "object", + "properties": { + "severity": { + "$ref": "#/definitions/v1alpha1Severity" + }, + "interval": { + "type": "integer", + "format": "int32", + "title": "interval unit is hour" + } + } + }, + "v1alpha1requestStatus": { + "type": "string", + "enum": [ + "STATUS_UNSPECIFIED", + "SUCCESS", + "FAIL" + ], + "default": "STATUS_UNSPECIFIED" + }, + "v1alpha1resourceType": { + "type": "string", + "enum": [ + "overview", + "dashboard", + "resourceInsight", + "scenarioInsight", + "dataQuery", + "alertList", + "alertRules", + "notificationSettings", + "alertSilence", + "notificationTemplates", + "dataCollection", + "systemComponents", + "systemSettings", + "netFlow", + "alertInhibition" + ], + "default": "overview", + "title": "refs:\ncharts/insight/templates/ghippo/gproduct-resource-permissions.yaml#resourceTypes" + }, + "v1alpha1samplePair": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "int64" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1serverComponent": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1alpha1serverComponentName", + "title": "serverComponentName is service name" + }, + "workloadName": { + "type": "string", + "title": "workloadName is full workload name in cluster" + }, + "workloadNamespace": { + "type": "string", + "description": "workloadNamespace is namespace that workload installed, null means not in\nthis cluster." + }, + "workloadKind": { + "$ref": "#/definitions/v1alpha1WorkloadKind" + }, + "phase": { + "$ref": "#/definitions/v1alpha1WorkloadPhase" + }, + "availability": { + "type": "boolean" + }, + "message": { + "type": "string", + "title": "message give the reason when service is unavailable" + }, + "version": { + "type": "string" + }, + "podNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + }, + "creationTimestamp": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1serverComponentName": { + "type": "string", + "enum": [ + "NAME_UNSPECIFIED", + "VMINSERT", + "VMALERT", + "VMALERTMANAGER", + "VMSELECT", + "VMSTORAGE", + "GRAFANA", + "JAEGER_COLLECTOR", + "JAEGER_QUERY", + "OPENTELEMETRY_COLLECTOR", + "ELASTICSEARCH" + ], + "default": "NAME_UNSPECIFIED" + }, + "v1alpha1serviceSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "tracingEnabled": { + "type": "boolean", + "title": "tracing enabled" + } + } + }, + "v1alpha1timeInterval": { + "type": "object", + "properties": { + "timeRanges": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/timeIntervaltimeRange" + }, + "description": "if weekday_range is null, start and end is the unix timestamp like\n1678350699;\nif weekday_range is not null, start and end represents a range\nof seconds within a 86400 second day.In this case, start can be greater\nthan end; For example, 17:00 to End of the day would Start at 61200 and End\nat 86400.[default timezone is UTC]\nsupport multiple timerange if weekday_range is not null." + }, + "weekdayRange": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "description": "A list ranges between [0, 6] where 0 = Sunday.\nFor example: [1,2] means Monday and Tuesday.\n[0,1,2,3,4,5,6] means all week." + } + } + }, + "v1alpha1usage": { + "type": "object", + "properties": { + "cpuCapacity": { + "type": "string", + "format": "int64", + "description": "CpuCapacity is the total cpu of the node. Unit: m." + }, + "cpuAllocated": { + "type": "number", + "format": "double", + "description": "CpuAllocated is the total pod cpu request on the node. Unit: m." + }, + "cpuUsage": { + "type": "number", + "format": "double", + "description": "CpuUsage is the actual total pod cpu usage on the node. Unit: m." + }, + "memoryCapacity": { + "type": "string", + "format": "int64", + "description": "MemoryCapacity is the total memory of the node. Unit: byte." + }, + "memoryAllocated": { + "type": "number", + "format": "double", + "description": "MemoryAllocated is the total pod memory request on the node. Unit: byte." + }, + "memoryUsage": { + "type": "number", + "format": "double", + "description": "MemoryUsage is the actual total pod memory usage on the node. Unit: byte." + }, + "storageCapacity": { + "type": "string", + "format": "int64", + "description": "StorageCapacity is the total storage of the node. Unit: byte." + }, + "storageAllocated": { + "type": "string", + "format": "int64", + "description": "StorageAllocated is the total pod storage request on the node. Unit: byte." + }, + "storageUsage": { + "type": "number", + "format": "double", + "description": "StorageUsage is the actual total storage usage on the node. Unit: byte." + } + } + }, + "v1alpha1userinfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "isAdmin": { + "type": "boolean" + }, + "canViewCluster": { + "type": "boolean" + }, + "canViewNs": { + "type": "boolean" + }, + "resourceTypes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1resourceType" + } + } + } + }, + "v1alpha1workloadSummary": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/v1alpha1WorkloadPhase" + }, + "podNumSummary": { + "$ref": "#/definitions/v1alpha1ResourceNumSummary" + } + } + } + } +} diff --git a/docs/zh/docs/openapi/kpanda/index.md b/docs/zh/docs/openapi/kpanda/index.md new file mode 100644 index 0000000..be2f26b --- /dev/null +++ b/docs/zh/docs/openapi/kpanda/index.md @@ -0,0 +1 @@ +# diff --git a/docs/zh/docs/openapi/kpanda/v0.32.2.json b/docs/zh/docs/openapi/kpanda/v0.32.2.json new file mode 100644 index 0000000..5440a04 --- /dev/null +++ b/docs/zh/docs/openapi/kpanda/v0.32.2.json @@ -0,0 +1,34200 @@ +{ + "swagger": "2.0", + "info": { + "title": "容器管理", + "version": "v0.32.2" + }, + "tags": [ + { + "name": "Apiextensions" + }, + { + "name": "Apps" + }, + { + "name": "Batch" + }, + { + "name": "Cluster" + }, + { + "name": "insight" + }, + { + "name": "Core" + }, + { + "name": "Networking" + }, + { + "name": "RBAC" + }, + { + "name": "Autoscaling" + }, + { + "name": "Storage" + }, + { + "name": "Registry" + }, + { + "name": "Image" + }, + { + "name": "Workspace" + }, + { + "name": "ClusterSetting" + }, + { + "name": "CloudShell" + }, + { + "name": "Clusterlcm" + }, + { + "name": "Addon" + }, + { + "name": "EtcdBackupRestore" + }, + { + "name": "StreamService" + }, + { + "name": "SettingService" + }, + { + "name": "FeatureGate" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/apis/kpanda.io/v1alpha1/admincluster": { + "get": { + "summary": "ListAdminClusterSummary List cluster summary by adminCluster", + "operationId": "RBAC_ListAdminClusterSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAdminClusterSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "user", + "description": "user is the cluster's user", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "userGroup", + "description": "userGroup is the cluster user's belong group", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/clusterrolebindings": { + "get": { + "summary": "ListClusterRoleBindings lists a cluster RoleBinding", + "operationId": "RBAC_ListClusterRoleBindings", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterRoleBindingsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the roleBinding belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of the user", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "roleRef", + "description": "RoleRef is the role of the user, it should be the same as when it is created.\nSuch as: cluster-admin, ns-admin, ns-view, ns-edit, ns-admin", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/cronjobs": { + "get": { + "summary": "ListAllCronJobs lists all clusters cronjob", + "operationId": "Batch_ListAllCronJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterCronJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusters", + "description": "Cluster the specified job belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Current status of a cron job.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n+optional\ntodo: split list all jobs and list all cron jobs.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/daemonsets": { + "get": { + "summary": "ListAllDaemonSets lists all daemonSet in all clusters", + "operationId": "Apps_ListAllDaemonSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDaemonSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the workloads belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Cluster represents which namespace the workloads belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/deployments": { + "get": { + "summary": "ListAllDeployments lists all deployment in all clusters", + "operationId": "Apps_ListAllDeployments", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDeploymentsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the workloads belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Cluster represents which namespace the workloads belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/groups": { + "get": { + "summary": "ListGroups lists the groups in the system.", + "operationId": "RBAC_ListGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/jobs": { + "get": { + "summary": "ListAllJobs lists all cluster jobs", + "operationId": "Batch_ListAllJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "clusters", + "description": "Cluster the specified job belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Current status of a cron job.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n+optional\ntodo: split list all jobs and list all cron jobs.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/namespaces": { + "get": { + "summary": "ListNamespaces gets all the namespaces across clusters", + "operationId": "Core_ListNamespaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNamespacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Clusters is to filter namespaces by cluster names", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "workspaceId", + "description": "workspace_id the specified namespace belongs to.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "workspaceAlias", + "description": "workspace_alias the specified namespace belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name is to filter namespaces by namespace name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the job list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the job list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "onlyUnassign", + "description": "Only_unassign is used to distinguish workspaces that are not assigned.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "excludeSystem", + "description": "ExcludeSystem determines to exclude system namespaces, defaults to False.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "includeResourceQuota", + "description": "IncludeQuota used to control whether return namespace resource quota, default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/pods": { + "get": { + "summary": "ListAllPods will list all pod by given cluster and namespace,\nif you want list pods regardless of namespace, please given specify\nnamespace as \"\" and it supports across cluster.", + "operationId": "Core_ListAllPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents the pods belongs to, it is a array\nif you want to query cluster more than one, please use query\nlike '?cluster=cluster1&cluster=cluster2'.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phases is used for filter.\n\n - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Unknown: PodUnknown means that for some reason the state of the pod could not be\nobtained, typically due to an error in communicating with the host of the\npod.\n - Pending: PodPending means the pod has been accepted by the system, but one or more\nof the containers has not been started. This includes time before being\nbound to a node, as well as time spent pulling images onto the host.\n - Running: PodRunning means the pod has been bound to a node and all of the\ncontainers have been started. At least one container is still running or\nis in the process of being restarted. PodSucceeded means that all\ncontainers in the pod have voluntarily terminated with a container exit\ncode of 0, and the system is not going to restart any of these\ncontainers.\n - Succeeded: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).\n - Failed: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Unknown", + "Pending", + "Running", + "Succeeded", + "Failed" + ], + "default": "PHASE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "gpuType", + "description": "gpu_type is filter with pods resources, when value is * search all", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/rolebindings": { + "get": { + "summary": "ListRoleBindings lists the rolebidings created by frontend.", + "operationId": "RBAC_ListRoleBindings", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRoleBindingsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the roleBinding belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the roleBinding belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of the user", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "roleRef", + "description": "RoleRef is the role of the user, it should be the same as when it is created.\nSuch as: cluster-admin, ns-admin, ns-view, ns-edit, ns-admin", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/statefulsets": { + "get": { + "summary": "ListAllStatefulSets lists all statefulSet in all clusters", + "operationId": "Apps_ListAllStatefulSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListStatefulSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the workloads belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "namespace", + "description": "Cluster represents which namespace the workloads belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/asl/users": { + "get": { + "summary": "ListUsers lists the users in the system.", + "operationId": "RBAC_ListUsers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListUsersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cloudshells": { + "post": { + "summary": "CreateCloudShell create a cloudshell in golobal cluster.", + "operationId": "CloudShell_CreateCloudShell", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CloudShell" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateCloudShellRequest" + } + } + ], + "tags": [ + "CloudShell" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cloudshells/{name}": { + "get": { + "summary": "GetCloudShell get a cloudshell in golobal cluster.", + "operationId": "CloudShell_GetCloudShell", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CloudShell" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "name specified the cloudshell name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "CloudShell" + ] + }, + "delete": { + "summary": "DeleteCloudShell delete a cloudshell in golobal cluster.", + "operationId": "CloudShell_DeleteCloudShell", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "name specified the cloudshell name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1CloudShellType", + "description": "type specified the cloudshell command type (exec, logs, bash)." + }, + "cluster": { + "type": "string", + "description": "cluster specified the cluster name for cloudshell." + } + }, + "description": "DeleteCloudShellResponse defines the delete api request." + } + } + ], + "tags": [ + "CloudShell" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm": { + "post": { + "operationId": "Clusterlcm_CreateCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1CreateClusterRequest" + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/available-kube-versions": { + "get": { + "operationId": "Clusterlcm_ListKubeVersions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListKubeVersionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/available-runtime-versions": { + "get": { + "operationId": "Clusterlcm_ListRuntimeVersions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRuntimeVersionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kubeVersion", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/nodes": { + "post": { + "operationId": "Clusterlcm_BatchAddNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "role": { + "$ref": "#/definitions/v1alpha1NodeInfoRole" + }, + "nodeInfos": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeInfo" + } + }, + "type": { + "$ref": "#/definitions/v1alpha1SSHInfoType" + }, + "kubesprayArgs": { + "$ref": "#/definitions/v1alpha1NodeKubesprayArgs" + } + } + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/nodes/{name}": { + "delete": { + "operationId": "Clusterlcm_RemoveNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops": { + "get": { + "operationId": "Clusterlcm_ListClusterlcmOps", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterlcmOpsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The name of the cluster.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The fuzzy-name of the clusterclmOps.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "SortDir determines the order of the data.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "targetCluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "action", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "ACTION_UNSPECIFIED", + "CREATE_CLUSTER", + "UPGRADE_CLUSTER", + "RESET_CLUSTER", + "ADD_NODE", + "REMOVE_NODE" + ], + "default": "ACTION_UNSPECIFIED" + }, + { + "name": "phase", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "STATUS_UNSPECIFIED", + "Running", + "Succeeded", + "Failed", + "Blocked" + ], + "default": "STATUS_UNSPECIFIED" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops/{name}": { + "get": { + "operationId": "Clusterlcm_GetClusterlcmOps", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmOps" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The name of the cluster.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the clusterclmOps.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + }, + "delete": { + "operationId": "Clusterlcm_DeleteClusterlcmOps", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The name of the manger cluster.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the cluster which needs to be create.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops/{name}/json": { + "get": { + "operationId": "Clusterlcm_GetClusterlcmOpsJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetClusterlcmOpsJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The name of the cluster.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the clusterclmOps.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/settings": { + "get": { + "operationId": "Clusterlcm_GetClusterlcmSettings", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterSettings" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The name of the cluster which needs to be create.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{name}/precheck-infos": { + "post": { + "operationId": "Clusterlcm_GetPreCheckClusterInfo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetPreCheckClusterInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "The name of the cluster which needs to be create.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dkgClusterName": { + "type": "string", + "description": "The name of the manger cluster." + }, + "kubeVersion": { + "type": "string", + "title": "kubernetes version of cluster to be created" + }, + "operation": { + "type": "string", + "description": "operation represents the kubean operation name." + } + } + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{name}:check": { + "post": { + "operationId": "Clusterlcm_CheckCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CheckClusterResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{name}:precheck": { + "post": { + "operationId": "Clusterlcm_PreCheckCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "The name of the cluster which needs to be create.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "dkgClusterName": { + "type": "string", + "description": "The name of the manger cluster." + }, + "kubeVersion": { + "type": "string" + }, + "nodeConfig": { + "$ref": "#/definitions/v1alpha1NodeConfig" + } + } + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{name}:reset": { + "post": { + "operationId": "Clusterlcm_ResetCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/cluster-lcm/{name}:upgrade": { + "post": { + "operationId": "Clusterlcm_UpgradeCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterlcmResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "The name of the cluster which needs to upgrade.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "kubernetesVersion": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Clusterlcm" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters": { + "get": { + "summary": "ListClusters lists kpanda cr resources", + "operationId": "Cluster_ListClusters", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClustersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "role", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "CLUSTER_ROLE_UNSPECIFIED", + "CLUSTER_ROLE_MANAGER", + "CLUSTER_ROLE_GLOBAL_SERVICE", + "CLUSTER_ROLE_WORKER", + "CLUSTER_ROLE_THIRD_PARTY" + ], + "default": "CLUSTER_ROLE_UNSPECIFIED" + }, + { + "name": "kubernetesVersion", + "description": "KUBERNETESVERSION cluster k8s version use to support search sub cluster at\nListClusters", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase is used for filter.\n\n - CLUSTER_PHASE_UNSPECIFIED: The cluster state is unspecified.\n - Unknown: The cluster state is unknown.\n - Creating: The cluster is being created.\n - Running: The cluster is running.\n - Updating: The cluster is updating.\n - Deleting: The cluster is being deleted.\n - Failed: The cluster create failed.\n - DeleteFailed: The cluster delete failed.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "CLUSTER_PHASE_UNSPECIFIED", + "Unknown", + "Creating", + "Running", + "Updating", + "Deleting", + "Failed", + "DeleteFailed" + ], + "default": "CLUSTER_PHASE_UNSPECIFIED" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter clusters.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter the clusters.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "managedBy", + "description": "ManagedBy represents who manages the cluster", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the cluster list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the cluster list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether returned data contains\nvirtualCluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "excludeMetrics", + "description": "exclude_metrics\nIf false, contains metrics-related information\nIf true, metrics-related information is not included", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Cluster" + ] + }, + "post": { + "summary": "CreateCluster creates a cluster", + "operationId": "Cluster_CreateCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateOrUpdateClusterResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1IntegrateClusterRequest" + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/validate": { + "post": { + "operationId": "Cluster_ValidateKubeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ValidateKubeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1ValidateKubeConfigRequest" + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/accessiblestorageclasses": { + "get": { + "summary": "ListAccessibleStorageClasses lists all storageclasses in accessible clusters", + "operationId": "Storage_ListAccessibleStorageClasses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAllStorageClassesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "provisioner", + "description": "Provisioner is used for fuzzy search by provisioner.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "reclaimPolicy", + "description": "ReclaimPolicy is used for fuzzy search by reclaimPolicy.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clustercert": { + "post": { + "summary": "CreateOpenAPIClusterCert creates openAPI cluster cert", + "operationId": "Cluster_CreateOpenAPIClusterCert", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateOpenAPIClusterCertResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "one of cluster or kubeSystemID has value", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "kubeSystemID": { + "type": "string", + "description": "kubeSystemID is the cluster system ID." + }, + "expirationSeconds": { + "type": "integer", + "format": "int32", + "description": "ExpirationSeconds is the requested duration of validity of the request." + } + } + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterresourceoverride": { + "post": { + "summary": "CreateClusterResourceOverride creates a cro by given json.", + "operationId": "Autoscaling_CreateClusterResourceOverride", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterResourceOverride" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster defines the cluster name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1ClusterResourceOverride", + "description": "date defines the content of ClusterResourceOverride." + } + } + } + } + ], + "tags": [ + "Autoscaling" + ] + }, + "put": { + "summary": "UpdateClusterResourceOverride updates a cro by given json.", + "operationId": "Autoscaling_UpdateClusterResourceOverride", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterResourceOverride" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster defines the cluster name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1ClusterResourceOverride", + "description": "date defines the content of ClusterResourceOverride." + } + } + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterresourceoverride/{name}": { + "get": { + "summary": "GetClusterResourceOverride gets a cro by name.", + "operationId": "Autoscaling_GetClusterResourceOverride", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterResourceOverride" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster defines the cluster name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name defines the name of ClusterResourceOverride.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "delete": { + "summary": "DeleteClusterResourceOverride deletes a cro by name.", + "operationId": "Autoscaling_DeleteClusterResourceOverride", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster defines the cluster name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name defines the name of ClusterResourceOverride.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterrolebindings": { + "post": { + "summary": "CreateClusterRoleBinding creates a cluster roleBinding batch", + "operationId": "RBAC_CreateClusterRoleBinding", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterRoleBinding" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the clusterRoleBinding belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "subject": { + "$ref": "#/definitions/v1alpha1Subject", + "description": "Subject holds references to the objects the role applies to." + }, + "roleRef": { + "$ref": "#/definitions/v1alpha1RoleRef", + "description": "RoleRef can reference a Role in the current namespace or a ClusterRole in\nthe global namespace. If the RoleRef cannot be resolved, the Authorizer\nmust return an error." + }, + "name": { + "type": "string", + "title": "the name of ClusterRole" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "ownerReferences": { + "type": "array", + "items": { + "$ref": "#/definitions/typesOwnerReference" + } + } + } + } + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterrolebindings/{name}": { + "delete": { + "summary": "DeleteClusterRoleBinding deletes a cluster RoleBinding", + "operationId": "RBAC_DeleteClusterRoleBinding", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the roleBinding belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the clusterrolebinding to delete.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles": { + "get": { + "summary": "ListClusterRoles lists the clusterroles", + "operationId": "RBAC_ListClusterRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of the user", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles/{name}": { + "get": { + "summary": "GetClusterRole gets a ClusterRole", + "operationId": "RBAC_GetClusterRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apirbacv1alpha1ClusterRole" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the clusterrole belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the clusterrole to delete.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + }, + "delete": { + "summary": "DeleteClusterRole deletes a ClusterRole", + "operationId": "RBAC_DeleteClusterRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the clusterrole belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the clusterrole to delete.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + }, + "post": { + "summary": "CreateClusterRole creates a ClusterRole", + "operationId": "RBAC_CreateClusterRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/apirbacv1alpha1ClusterRole" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the clusterrole belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "the name of role.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + } + } + ], + "tags": [ + "RBAC" + ] + }, + "put": { + "summary": "UpdateClusterRole updates a ClusterRole", + "operationId": "RBAC_UpdateClusterRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateClusterRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the clusterrole belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the clusterrole to delete.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + }, + "title": "UpdateClusterRoleRequest the request of update clusterrole" + } + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/configmaps": { + "get": { + "summary": "ListClusterConfigMaps lists all configmaps in the specified cluster,\nregardless of namespace.", + "operationId": "Core_ListClusterConfigMaps", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterConfigMapsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the event list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "name is used for query.\n+optional", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "onlyMetadata", + "description": "OnlyMetadata lists only metadata of configmaps, default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/crd-groups": { + "get": { + "summary": "ListCustomResourceDefinitionGroups lists all groups of customResourceDefinitions in the specified cluster", + "operationId": "Apiextensions_ListCustomResourceDefinitionGroups", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCustomResourceDefinitionGroupsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster to request", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/cronjobs": { + "get": { + "summary": "ListCronJobs Lists cronJobs in a specific cluster", + "operationId": "Batch_ListCronJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCronJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of Workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search.\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/custommetricsummary": { + "get": { + "summary": "ListCustomMetricsSummary return the custom metrics for specified\nresource.", + "operationId": "Autoscaling_ListCustomMetricSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCustomMetricSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the custom metrics belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "The kind of hpa targetRef.\n\n - Pod: The custom metrics for service.\n - Service: The custom metrics for service.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Pod", + "Service" + ], + "default": "KIND_UNSPECIFIED" + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions": { + "get": { + "summary": "ListCustomResourceDefinitions lists customResourceDefinitions in the specified cluster", + "operationId": "Apiextensions_ListCustomResourceDefinitions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCustomResourceDefinitionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster cluster to be queried", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name search the custom resource definitions fo name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "description": "Status search the custom resource definitions fo status", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "group", + "description": "Group is to filter customResourceDefinitions by group.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "post": { + "summary": "CreateCustomResourceDefinition creates a customResourceDefinition to the\nsystem by given customResourceDefinition data", + "operationId": "Apiextensions_CreateCustomResourceDefinition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateCustomResourceDefinitionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified customResourceDefinition belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the customResourceDefinition YAML details." + } + }, + "title": "CreateCustomResourceDefinitionRequest represents post request to a\ncustomResourceDefinition" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions/{name}": { + "get": { + "summary": "GetCustomResourceDefinition gets a customResourceDefinition from\nthe system by given customResourceDefinition name", + "operationId": "Apiextensions_GetCustomResourceDefinition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CustomResourceDefinition" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResourceDefinition belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResourceDefinition.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "delete": { + "summary": "DeleteCustomResourceDefinition deletes a customResourceDefinition from the\nsystem by given customResourceDefinition name", + "operationId": "Apiextensions_DeleteCustomResourceDefinition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified customResourceDefinition belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the metadata.name of the referenced customResourceDefinition.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "put": { + "summary": "UpdateCustomResourceDefinition updates a customResourceDefinition from the\nsystem by given customResourceDefinition name", + "operationId": "Apiextensions_UpdateCustomResourceDefinition", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateCustomResourceDefinitionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified customResourceDefinition belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the customResourceDefinition YAML details." + } + }, + "title": "UpdateCustomResourceDefinitionRequest represents put request to a\ncustomResourceDefinition" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions/{name}/json": { + "get": { + "summary": "GetCustomResourceDefinitionJSON gets a customResourceDefinition json from\nthe system by given customResourceDefinition name", + "operationId": "Apiextensions_GetCustomResourceDefinitionJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetCustomResourceDefinitionJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResourceDefinition belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResourceDefinition.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/daemonsets": { + "get": { + "summary": "ListClusterDaemonSets lists DaemonSet in one cluster", + "operationId": "Apps_ListClusterDaemonSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDaemonSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of Workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/deployments": { + "get": { + "summary": "ListClusterDeployments lists one cluster all namespace's deployments", + "operationId": "Apps_ListClusterDeployments", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDeploymentsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of Workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/etcd:verify": { + "post": { + "summary": "VerifyEtcdConnection verifies the etcd connection.", + "operationId": "EtcdBackupRestore_VerifyEtcdConnection", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1VerifyEtcdConnectionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd snapstore belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "etcdConnectionConfig": { + "$ref": "#/definitions/v1alpha1EtcdConnectionConfig", + "description": "config for etcd connection." + } + } + } + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/snapstores:verify": { + "post": { + "summary": "VerifySnapStore verifies the SnapStore config.", + "operationId": "EtcdBackupRestore_VerifySnapStoreConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1VerifySnapStoreConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd snapstore belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string", + "description": "username or access key id for S3." + }, + "secretAccessKey": { + "type": "string", + "description": "password or secret key for S3." + }, + "bucket": { + "type": "string", + "description": "the bucket name for S3." + }, + "endpoint": { + "type": "string", + "description": "endpoint for S3." + }, + "region": { + "type": "string", + "description": "region for S3." + } + } + } + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies": { + "post": { + "summary": "CreateEtcdBackupStrategy creates a etcd backup strategy.", + "operationId": "EtcdBackupRestore_CreateEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name for EtcdBackupStrategy." + }, + "strategy": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy", + "description": "The data for the etcd backup strategy." + } + } + } + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}": { + "get": { + "summary": "GetEtcdBackupStrategy get a etcd backup strategy in cluster.", + "operationId": "EtcdBackupRestore_GetEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the etcd backup strategy name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + }, + "delete": { + "summary": "DeleteEtcdBackupStrategy delete a etcd backup strategy in cluster.", + "operationId": "EtcdBackupRestore_DeleteEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of etcd backup strategy", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + }, + "put": { + "summary": "UpdateEtcdBackupStrategy updates tcd backup strategy under the cluster", + "operationId": "EtcdBackupRestore_UpdateEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name for EtcdBackupStrategy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "strategy": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy", + "description": "The data for the etcd backup strategy." + } + } + } + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}/json": { + "get": { + "summary": "GetEtcdBackupStrategyJSON get a etcd backup strategy json in cluster.", + "operationId": "EtcdBackupRestore_GetEtcdBackupStrategyJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetEtcdBackupStrategyJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the etcd backup strategy name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}:execute": { + "post": { + "summary": "ExecuteEtcdBackupStrategy executes a etcd backup strategy under the cluster", + "operationId": "EtcdBackupRestore_ExecuteEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ExecuteEtcdBackupStrategyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of etcd backup strategy.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}:pause": { + "post": { + "summary": "PauseEtcdBackupStrategy pauses a etcd backup strategy under the cluster", + "operationId": "EtcdBackupRestore_PauseEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PauseEtcdBackupStrategyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of etcd backup strategy", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}:resume": { + "post": { + "summary": "ResumeEtcdBackupStrategy resumes a etcd backup strategy under the cluster", + "operationId": "EtcdBackupRestore_ResumeEtcdBackupStrategy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ResumeEtcdBackupStrategyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of etcd backup strategy", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{strategy}/snapshots": { + "get": { + "summary": "ListEtcdSnapshots list etcd backup snapshots .", + "operationId": "EtcdBackupRestore_ListEtcdSnapshots", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListEtcdSnapshotsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "strategy", + "description": "strategy represents the name of etcd backup strategy.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{strategy}/snapshots/{name}": { + "delete": { + "summary": "DeleteEtcdBackup delete a etcd backup.", + "operationId": "EtcdBackupRestore_DeleteEtcdSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the etcd backup strategy belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "strategy", + "description": "strategy represents the name of etcd backup strategy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of etcd snapshot.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/events": { + "get": { + "summary": "ListClusterEvents lists all events in the specified cluster,\nregardless of namespace.", + "operationId": "Core_ListClusterEvents", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterEventsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the events belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "type", + "description": "Type is used for query, showing events of specified type.\nUse example: type=WARNING&type=NORMAL.\n\n - EVENT_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Normal: Normal is a normal event type.\n - Warning: Warning is a warning event type.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "EVENT_TYPE_UNSPECIFIED", + "Normal", + "Warning" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "kind", + "description": "Kind is used for query, showing events of specified involvedObject kind,\ne.g. Node.\n+optional", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name is used for query, showing events of specified involvedObject name,\ne.g. node‘s name when kind is Node.\n+optional", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/events/kinds": { + "get": { + "summary": "ListClusterEventKinds lists all involvedObject's kinds of events in the\nspecified cluster, regardless of namespace", + "operationId": "Core_ListClusterEventKinds", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterEventKindsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the events belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gpusummary": { + "get": { + "summary": "ListClusterGPUSummary lists gpu summary of all nodes of the specified cluster.", + "operationId": "Core_ListClusterGPUSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterGPUSummaryResponese" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster defines the cluster name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}": { + "get": { + "summary": "ListCustomResources lists customResources of namespaced scope from the\nsystem", + "operationId": "Apiextensions_ListCustomResources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCustomResourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResources belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResources.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResources.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResources belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResources, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "name is used for query.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showDetail", + "description": "ShowDetail is the presentation details, including metadata, spec, and status", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "ownerReference", + "description": "OwnerReference indicates that the query is based on the OwnerReference.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "post": { + "summary": "CreateCustomResource creates a customResource of namespaced scope to the\nsystem by given customResource data", + "operationId": "Apiextensions_CreateCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "CreateCustomResourceRequest represents create request to create one\nCustomResource of namespaced scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name}": { + "get": { + "summary": "GetCustomResource gets a customResource of namespaced scope from\nthe system", + "operationId": "Apiextensions_GetCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CustomResource" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "showDetail", + "description": "ShowDetail is the presentation details, including metadata, spec, and status", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "delete": { + "summary": "DeleteCustomResource deletes a customResource of namespaced scope from the\nsystem by given customResource name", + "operationId": "Apiextensions_DeleteCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "deletionPropagation", + "description": " - DELETION_PROPAGATION_ORPHAN: Orphans the dependents.\n - DELETION_PROPAGATION_BACKGROUND: Deletes the object from the key-value store, the garbage collector will\ndelete the dependents in the background.\n - DELETION_PROPAGATION_FOREGROUND: The object exists in the key-value store until the garbage collector\ndeletes all the dependents whose ownerReference.blockOwnerDeletion=true\nfrom the key-value store. API sever will put the \"foregroundDeletion\"\nfinalizer on the object, and sets its deletionTimestamp. This policy is\ncascading, i.e., the dependents will be deleted with Foreground.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "DELETION_PROPAGATION_UNSPECIFIED", + "DELETION_PROPAGATION_ORPHAN", + "DELETION_PROPAGATION_BACKGROUND", + "DELETION_PROPAGATION_FOREGROUND" + ], + "default": "DELETION_PROPAGATION_UNSPECIFIED" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "put": { + "summary": "UpdateCustomResource updates a customResource of namespaced scope from the\nsystem by given customResource name", + "operationId": "Apiextensions_UpdateCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateCustomResourceRequest represents update request to update one\nCustomResource of namespaced scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + }, + "patch": { + "summary": "PatchCustomResource patches a customResource of cluster scope from\nthe system by given customResource name", + "operationId": "Apiextensions_PatchCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "patchType": { + "$ref": "#/definitions/PatchCustomResourceRequestPatchType", + "description": "The patch type for patching the resources." + }, + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + }, + "subResources": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "title": "PatchCustomResourceRequest represents patch request to update one\nCustomResource of cluster scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name}/json": { + "get": { + "summary": "GetCustomResourceJSON gets a customResource of namespaced scope json from\nthe system", + "operationId": "Apiextensions_GetCustomResourceJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetCustomResourceJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name}/status": { + "put": { + "summary": "UpdateCustomResourceStatus updates the status of a customResource", + "operationId": "Apiextensions_UpdateCustomResourceStatus", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateCustomResourceStatusResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateCustomResourceStatusRequest requests to update the status of a customResource of namespaced scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}": { + "get": { + "summary": "ListClusterCustomResources lists customResources of cluster scope", + "operationId": "Apiextensions_ListClusterCustomResources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterCustomResourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResources belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResources.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResources.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResources, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "name is used for query.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "showDetail", + "description": "ShowDetail is the presentation details, including metadata, spec, and status", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "post": { + "summary": "CreateClusterCustomResource creates a customResource of cluster scope to\nthe system by given customResource data", + "operationId": "Apiextensions_CreateClusterCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateClusterCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "CreateClusterCustomResourceRequest represents create request to create one\nCustomResource of cluster scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name}": { + "get": { + "summary": "GetClusterCustomResource gets a customResource of cluster scope", + "operationId": "Apiextensions_GetClusterCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CustomResource" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "showDetail", + "description": "ShowDetail is the presentation details, including metadata, spec, and status", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "delete": { + "summary": "DeleteClusterCustomResource deletes a customResource of cluster scope from\nthe system by given customResource name", + "operationId": "Apiextensions_DeleteClusterCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "deletionPropagation", + "description": " - DELETION_PROPAGATION_ORPHAN: Orphans the dependents.\n - DELETION_PROPAGATION_BACKGROUND: Deletes the object from the key-value store, the garbage collector will\ndelete the dependents in the background.\n - DELETION_PROPAGATION_FOREGROUND: The object exists in the key-value store until the garbage collector\ndeletes all the dependents whose ownerReference.blockOwnerDeletion=true\nfrom the key-value store. API sever will put the \"foregroundDeletion\"\nfinalizer on the object, and sets its deletionTimestamp. This policy is\ncascading, i.e., the dependents will be deleted with Foreground.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "DELETION_PROPAGATION_UNSPECIFIED", + "DELETION_PROPAGATION_ORPHAN", + "DELETION_PROPAGATION_BACKGROUND", + "DELETION_PROPAGATION_FOREGROUND" + ], + "default": "DELETION_PROPAGATION_UNSPECIFIED" + } + ], + "tags": [ + "Apiextensions" + ] + }, + "put": { + "summary": "UpdateClusterCustomResource updates a customResource of cluster scope from\nthe system by given customResource name", + "operationId": "Apiextensions_UpdateClusterCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateClusterCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateClusterCustomResourceRequest represents update request to update one\nCustomResource of cluster scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name}/json": { + "get": { + "summary": "GetClusterCustomResourceJSON gets a customResource json of cluster scope", + "operationId": "Apiextensions_GetClusterCustomResourceJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetClusterCustomResourceJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name}/status": { + "put": { + "summary": "UpdateClusterCustomResourceStatus updates the status of a customResource of cluster scope", + "operationId": "Apiextensions_UpdateClusterCustomResourceStatus", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateClusterCustomResourceStatusResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the CustomResource belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "group", + "description": "Group represents the resource group of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "Version represents the resource version of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "resource", + "description": "Resource represents the resource name of CustomResource, which is plural.\nYou can find it in plural field of related CRD definition.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of CustomResource.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateClusterCustomResourceStatusRequest requests to update the status of a CustomResource of cluster scope" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmcharts": { + "get": { + "summary": "ListCharts list chart from repositories.", + "operationId": "Addon_ListHelmCharts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHelmChartsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Helm chart name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "category", + "description": "Category is used for query.\n\n - CATEGORY_UNSPECIFIED: The Category is unspecified.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "CATEGORY_UNSPECIFIED", + "CATEGORY_OTHERS", + "CATEGORY_STORAGE", + "CATEGORY_NETWORKING", + "CATEGORY_MONITORING", + "CATEGORY_DATABASE", + "CATEGORY_DATASERVICE", + "CATEGORY_ECOAPP", + "CATEGORY_BIGDATA", + "CATEGORY_SECURITY", + "CATEGORY_IOTEDGE", + "CATEGORY_INFRA" + ], + "default": "CATEGORY_UNSPECIFIED" + }, + { + "name": "repo", + "description": "The repo name which the charts belongs to.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "required", + "description": "Required indicates whether to display the charts, which are required to install the cluster.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmcharts/installed": { + "get": { + "summary": "ListClusterInstalledHelmChart list the charts which installed belong to repo", + "operationId": "Addon_ListClusterInstalledHelmChart", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterInstalledHelmChartResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repoName", + "description": "repo_name represents which helm repo's name use to list installed helm chart", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmoperations": { + "get": { + "summary": "ListClusterHelmOperations list operation in cluster.", + "operationId": "Addon_ListClusterHelmOperations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterHelmOperationsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified operation belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the event list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "name is used for query.\n+optional", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "releaseName", + "description": "Filter helm_operation by release_name,\nThe release_name is exactly.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmreleases": { + "get": { + "summary": "ListClusterHelmReleases list apps in cluster.", + "operationId": "Addon_ListClusterHelmReleases", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterHelmReleasesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified operation belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the event list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "name is used for query.\n+optional", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "helmChartName", + "description": "the helm releases's chart name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "helmChartRepo", + "description": "the helm releases's chart repo name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos": { + "get": { + "summary": "ListHelmRepos list repo in cluster.", + "operationId": "Addon_ListHelmRepos", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHelmReposResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the repository list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the repository list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "builtIn", + "description": "builtin indicates whether to display the repos required to install the cluster.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Addon" + ] + }, + "post": { + "summary": "CreateHelmRepo create a repo in cluster.", + "operationId": "Addon_CreateHelmRepo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmRepo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name represents for the resource name." + }, + "description": { + "type": "string", + "description": "The description represents for the resource." + }, + "url": { + "type": "string", + "title": "url A http url of the repo to connect to" + }, + "verificationMethod": { + "$ref": "#/definitions/v1alpha1VerificationMethod", + "title": "Repository verification method" + }, + "userName": { + "type": "string", + "title": "Repository user name" + }, + "password": { + "type": "string", + "title": "Repository user password" + }, + "token": { + "type": "string", + "title": "Repository token" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations to attach arbitrary metadata to objects." + }, + "insecureSkipTLSVerify": { + "type": "boolean", + "description": "InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index." + } + } + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}": { + "get": { + "summary": "GetHelmRepo get a repo in cluster.", + "operationId": "Addon_GetHelmRepo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmRepo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + }, + "delete": { + "summary": "DeleteHelmRepo delete a repo in cluster.", + "operationId": "Addon_DeleteHelmRepo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + }, + "put": { + "summary": "UpdateHelmRepo update repo", + "operationId": "Addon_UpdateHelmRepo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmRepo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "The description represents for the resource." + }, + "url": { + "type": "string", + "title": "url A http url of the repo to connect to" + }, + "verificationMethod": { + "$ref": "#/definitions/v1alpha1VerificationMethod", + "title": "Repository verification method" + }, + "userName": { + "type": "string", + "title": "Repository user name" + }, + "password": { + "type": "string", + "title": "Repository user password" + }, + "token": { + "type": "string", + "title": "Repository token" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations to attach arbitrary metadata to objects." + }, + "insecureSkipTLSVerify": { + "type": "boolean", + "description": "InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index." + } + } + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}/json": { + "get": { + "summary": "GetHelmRepoJSON get a repo json in cluster.", + "operationId": "Addon_GetHelmRepoJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmRepoJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}/validate": { + "post": { + "summary": "ValidateHelmRepo verifies if a repo is connectable.", + "operationId": "Addon_ValidateHelmRepo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ValidateHelmRepoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster of the repo", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the repo", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "url": { + "type": "string", + "title": "Url of the repo to connect to" + }, + "verificationMethod": { + "$ref": "#/definitions/v1alpha1VerificationMethod", + "title": "Repository verification method" + }, + "userName": { + "type": "string", + "title": "Repository user name" + }, + "password": { + "type": "string", + "title": "Repository user password" + }, + "insecureSkipTLSVerify": { + "type": "boolean", + "description": "InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index." + } + }, + "title": "ValidateHelmRepoRequest requests to validate the connection to a helm repo" + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}:refresh": { + "post": { + "summary": "RefreshHelmRepo updates a helm repo's index.", + "operationId": "Addon_RefreshHelmRepo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmRepo" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the helmrepo belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}": { + "get": { + "summary": "GetHelmChartVersion get a chart version info from repository.", + "operationId": "Addon_GetHelmChart", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmChartResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repo", + "description": "The repo represents for the charts belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "The version represents for the resource version.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/display": { + "get": { + "summary": "GetHelmChartDisplay get a chart display info from repository.", + "operationId": "Addon_GetHelmChartDisplay", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmChartDisplayResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repo", + "description": "The repo represents for the charts belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "The version represents for the resource version.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/files": { + "get": { + "summary": "GetHelmChartFiles get a chart files from repository.", + "operationId": "Addon_GetHelmChartFiles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmChartFilesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repo", + "description": "The repo represents for the charts belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "The version represents for the resource version.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/manifests": { + "post": { + "summary": "GetHelmChartManifest get a chart manifests info from repository.", + "operationId": "Addon_GetHelmChartManifest", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmChartManifestResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repo", + "description": "The repo represents for the charts belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "The version represents for the resource version." + }, + "releaseName": { + "type": "string", + "description": "release_name is the name of the release." + }, + "namespace": { + "type": "string", + "description": "release_name is the name of the release namspace." + }, + "values": { + "type": "string", + "description": "Config is the set of extra Values added to the chart.\nThese values override the default values inside of the chart." + } + } + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/resources": { + "get": { + "summary": "GetHelmChartResources get the resources contained in charts.", + "operationId": "Addon_GetHelmChartResources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmChartResourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repo", + "description": "The repo represents for the charts belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "version", + "description": "The version represents for the resource version.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}:config": { + "post": { + "summary": "GetHelmInstallConfig create a Release.", + "operationId": "Addon_GetHelmInstallConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmInstallConfig" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repo", + "description": "The repo represents for the charts belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of helmrelease", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "version": { + "type": "string", + "description": "Version is an int which represents the version of the chart." + } + } + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/ingressclasssummary": { + "get": { + "summary": "ListIngressClassSummary gets a list of ingressClass simple information\nfrom the system by given cluster name", + "operationId": "Networking_ListIngressClassSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListIngressClassSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the ingressClass belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the IngressClass to retrieve for a specific namespace scoped.\nIf left empty, it retrieves the cluster scoped IngressClass.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/ingresses": { + "get": { + "summary": "ListClusterIngresses lists all ingresses in the specified cluster.", + "operationId": "Networking_ListClusterIngresses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterIngressesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, must be specified,\nwill return all the ingress of the cluster.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is the number of pages at the beginning.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the number of every page displayed.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy defines sort field, please see message kpanda.io.api.types.SortBy.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy defines the type of sort, default type asc, can also specify desc.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is the name of the ingress.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/jobs": { + "get": { + "summary": "ListJobs lists jobs in a specific cluster", + "operationId": "Batch_ListJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of Workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search.\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/kubeconfig": { + "get": { + "summary": "GetClusterKubeConfig gets the specified cluster's kubeconfig", + "operationId": "Cluster_GetClusterKubeConfig", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetClusterKubeConfigResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/limitranges": { + "get": { + "summary": "ListClusterLimitRanges lists all limitranges in the specified cluster.", + "operationId": "Core_ListClusterLimitRanges", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterLimitRangesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified LimitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the LimitRange list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the LimitRange list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/metallb/check-serviceports": { + "post": { + "summary": "ValidateMetallbSharedIPPortConflict checks whether the service port of\nthe loadBalance service with using shared ip is conflict with other loadBalancer\nservices", + "operationId": "Networking_ValidateMetallbSharedIPPortConflict", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "sharedLoadBalancerIP": { + "type": "string", + "title": "sharedLoadBalancerIP is the shared IP address that needs to be checked\nfor service port conflicts" + }, + "servicePorts": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "title": "servicePorts is the list of service ports that need to be checked for\nconflicts" + } + } + } + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/metallb/ippools": { + "get": { + "summary": "ListMetallbIPPool lists all metallb in the specified cluster and namespace.", + "operationId": "Networking_ListMetallbIPAddressPools", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListMetallbIPPoolResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is the number of pages at the beginning.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the number of every page displayed.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy defines sort field, please see message kpanda.io.api.types.SortBy.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy defines the type of sort, default type asc, can also specify desc.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is the name of the ingress.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/metric": { + "post": { + "operationId": "insight_QueryClusterMetrics", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1MetricResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The name of the cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "param": { + "$ref": "#/definitions/v1alpha1BatchQueryRequestParam", + "title": "The query request param" + }, + "matchLabels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "The labels of match" + }, + "queryList": { + "type": "array", + "items": { + "type": "string" + }, + "title": "The query of List" + } + }, + "title": "ClusterMetricsRequest represents the request of get cluster metrics" + } + } + ], + "tags": [ + "insight" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/metricrange": { + "post": { + "operationId": "insight_QueryClusterMetricsRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1MetricRangeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "the name of the cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "param": { + "$ref": "#/definitions/v1alpha1BatchQueryRangeRequestParam", + "title": "The parameters of query request" + }, + "matchLabels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "The labels of match" + }, + "queryList": { + "type": "array", + "items": { + "type": "string" + }, + "title": "The query of List" + } + }, + "title": "ClusterMetricsRangeRequest represents the request of get cluster metrics range" + } + } + ], + "tags": [ + "insight" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces": { + "get": { + "summary": "ListClusterNamespaces gets all the namespaces of given cluster", + "operationId": "Core_ListClusterNamespaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterNamespacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the namespace list belong to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "workspaceId", + "description": "workspace_id the specified namespace belongs to.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "workspaceAlias", + "description": "workspace_alias the specified namespace belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name is to filter namespaces by namespace name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the job list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the job list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phases is used for filter.\n\n - NAMESPACE_PHASE_UNSPECIFIED: The namespace state is unspecified.\n - Active: NamespaceActive means the namespace is available for use in the system\n - Terminating: NamespaceTerminating means the namespace is undergoing graceful termination", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "NAMESPACE_PHASE_UNSPECIFIED", + "Active", + "Terminating" + ], + "default": "NAMESPACE_PHASE_UNSPECIFIED" + }, + { + "name": "excludeSystem", + "description": "ExcludeSystem determines to exclude system namespaces, defaults to False.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreateNamespace creates a namespace from the system by given namespace name", + "operationId": "Core_CreateNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster the specified namespace belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "workspaceId": { + "type": "integer", + "format": "int32", + "description": "workspace_id the specified namespace belongs to." + }, + "workspaceAlias": { + "type": "string", + "description": "workspace_alias the specified namespace belongs to." + }, + "data": { + "type": "string", + "description": "The data is the service YAML details." + } + }, + "description": "Get Create Namespace information." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps": { + "get": { + "summary": "ListConfigMaps lists configmaps in the specified cluster and namespace.", + "operationId": "Core_ListConfigMaps", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListConfigMapsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "name is used for query.\n+optional", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "onlyMetadata", + "description": "OnlyMetadata lists only metadata of configmaps, default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreateConfigMap creates a configMap under the namespaces of a specific\ncluster", + "operationId": "Core_CreateConfigMap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateConfigMapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "When the current namespace is named, the priority is higher than that in yaml", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the ConfigMap YAML details" + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{configmap}/related": { + "get": { + "summary": "ListConfigMapsRelatedWorkloads list all workloads associated with this cm", + "operationId": "Apps_ListConfigMapsRelatedWorkloads", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListConfigMapRelatedWorkloadsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "configmap", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name}": { + "get": { + "summary": "GetConfigMap gets a configMap under the namespaces of a specific cluster", + "operationId": "Core_GetConfigMap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ConfigMap" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeleteConfigMap deletes a configMap under the namespaces of a specific\ncluster", + "operationId": "Core_DeleteConfigMap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the metadata.name of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateConfigMap updates a configMap under the namespaces of a specific\ncluster", + "operationId": "Core_UpdateConfigMap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateConfigMapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the ConfigMap YAML details" + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name}/json": { + "get": { + "summary": "GetConfigMapJSON gets a configMap json under the namespaces of a specific\ncluster", + "operationId": "Core_GetConfigMapJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetConfigMapJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "patch": { + "summary": "PatchConfigMap patchs a configMap under the namespaces of a specific\ncluster", + "operationId": "Core_PatchConfigMap", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchConfigMapResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the configmap belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "The data is the YAML details" + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/controllerrevisions": { + "get": { + "summary": "query like controllerrevisions?kind=STATEFULSET\norcontrollerrevisions?kind=STATEFULSET", + "operationId": "Apps_ListControllerRevisions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListControllerRevisionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified controllerrevision belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified controllerrevision belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "Kind stands for what type of revisions are needed.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "StatefulSet", + "DaemonSet" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "description": "The name of involvedObject.\nIf the kind is StatefulSet,\nthis presents the name of statefulset.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for controllerrevision name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "SortDir determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers": { + "get": { + "summary": "ListCronHorizontalPodAutoscalers lists cron hpas in the specified cluster and namespace.", + "operationId": "Autoscaling_ListCronHorizontalPodAutoscalers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListCronHorizontalPodAutoscalersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "kind", + "description": "The kind of hpa targetRef.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A hpa which targetRef kind is Deployment.\n - StatefulSet: A hpa which targetRef kind is StatefulSet.\n - ReplicaSet: A hpa which targetRef kind is ReplicaSet.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "ReplicaSet" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "name", + "description": "The workload name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "post": { + "summary": "CreateCronHorizontalPodAutoscaler creates a cron hpa by given json.", + "operationId": "Autoscaling_CreateCronHorizontalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateCronHorizontalPodAutoscalerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "When the current namespace is named, the priority is higher than that in yaml", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the hpa YAML details" + } + } + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers/{name}": { + "delete": { + "summary": "DeleteCronHorizontalPodAutoscaler deletes a cron hpa by given name.", + "operationId": "Autoscaling_DeleteCronHorizontalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the metadata.name of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "put": { + "summary": "UpdateCronHorizontalPodAutoscaler updates the specified cron hpa, the body must\nbe a JSON string.", + "operationId": "Autoscaling_UpdateCronHorizontalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateCronHorizontalPodAutoscalerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the hpa YAML details" + } + } + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers/{name}/json": { + "get": { + "summary": "GetCronHorizontalPodAutoscalerJSON gets the cron hpa by namespace and name,\nreturns a string in JSON format.", + "operationId": "Autoscaling_GetCronHorizontalPodAutoscalerJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetCronHorizontalPodAutoscalerJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced HorizontalPodAutoscaler.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "HorizontalPodAutoscaler name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "stable", + "description": "If stable is true, the v2 version under the corresponding package will be returned.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs": { + "get": { + "summary": "ListClusterCronJobs lists cluster cronJobs under the namespaces of a\nspecific cluster", + "operationId": "Batch_ListClusterCronJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterCronJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "phase", + "description": "Status represents the current state of a job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{cronjob}/jobs": { + "get": { + "summary": "ListJobsByCronJobsName lists Jobs By CronJobs's Name under the namespaces\nof a specific cluster", + "operationId": "Batch_ListJobsByCronJobsName", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListJobsByCronJobNameResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "cronjob", + "description": "Cronjob name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "phase", + "description": "Represents the current state of a cron job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the job list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the job list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Cronjob name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}": { + "get": { + "summary": "GetCronJob gets a cronJob under the namespaces of a specific cluster", + "operationId": "Batch_GetCronJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CronJob" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Cronjob name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + }, + "delete": { + "summary": "DeleteCronJob deletes a cronJob under the namespaces of a specific cluster", + "operationId": "Batch_DeleteCronJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Cronjob name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}:pause": { + "post": { + "summary": "PauseCronJob pauses a cronjob under the namespaces of a specific\ncluster", + "operationId": "Batch_PauseCronJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PauseCronJobResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of cronjob", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "paused": { + "type": "boolean", + "description": "Paused indicates that the cronjob is paused." + } + }, + "title": "PauseCronJobRequest the request of pause cronjob" + } + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}:resume": { + "post": { + "summary": "ResumeCronJob resumes a cronjob under the namespaces of a specific\ncluster", + "operationId": "Batch_ResumeCronJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ResumeCronJobResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the cronjob belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of cronjob", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "paused": { + "type": "boolean", + "description": "Paused indicates that the cronjob is paused." + } + }, + "title": "ResumeCronJobRequest the request of resume CronJob" + } + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets": { + "get": { + "summary": "ListDaemonSets lists daemonSet by JSON under the namespaces of a specific\ncluster", + "operationId": "Apps_ListDaemonSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDaemonSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}": { + "get": { + "summary": "GetDaemonSet gets a daemonSets under the namespaces of a specific cluster", + "operationId": "Apps_GetDaemonSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1DaemonSet" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which namespace the workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Cluster represents which namespace the workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "delete": { + "summary": "DeleteDaemonSet deletes a daemonSets under the namespaces of a specific\ncluster", + "operationId": "Apps_DeleteDaemonSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which namespace the daemonSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the daemonSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of daemonSet", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "patch": { + "summary": "PatchDaemonSet gets a daemonset under the namespaces of a specific cluster", + "operationId": "Apps_PatchDaemonSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchDaemonSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster which the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "The namespace which the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the deployment.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The json data of patch." + } + }, + "description": "The request of patching deployment." + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}:restart": { + "post": { + "summary": "RestartDaemonSet restarts a daemonSets under the namespaces of a specific\ncluster", + "operationId": "Apps_RestartDaemonSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RestartDaemonSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified daemonset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified daemonset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Daemonset name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}:rollback": { + "post": { + "summary": "RollbackDaemonSet rollbacks a daemonSets under the namespaces of a specific\ncluster", + "operationId": "Apps_RollbackDaemonSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RollbackDaemonSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified daemonset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified daemonset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Daemonset name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "revision": { + "type": "string", + "format": "int64", + "description": "The version of Daemonset.\nRevision indicates the revision of the state represented by Data." + } + } + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments": { + "get": { + "summary": "ListDeployments lists deployment by JSON under the namespaces of a specific\ncluster", + "operationId": "Apps_ListDeployments", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListDeploymentsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}": { + "get": { + "summary": "GetDeployment gets a deployment under the namespaces of a specific cluster", + "operationId": "Apps_GetDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Deployment" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which namespace the workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Cluster represents which namespace the workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "delete": { + "summary": "DeleteDeployment deletes a deployment under the namespaces of a specific\ncluster", + "operationId": "Apps_DeleteDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "patch": { + "summary": "PatchDeployment patches a deployment under the namespaces of a\nspecific cluster", + "operationId": "Apps_PatchDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster which the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "The namespace which the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the deployment.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The json data of patch." + } + }, + "description": "The request of patching deployment." + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:pause": { + "post": { + "summary": "PauseDeployment pauses a deployment under the namespaces of a specific\ncluster", + "operationId": "Apps_PauseDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PauseDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:restart": { + "post": { + "summary": "RestartDeployment restarts a deployment under the namespaces of a specific\ncluster", + "operationId": "Apps_RestartDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RestartDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:resume": { + "post": { + "summary": "ResumeDeployment resumes a deployment under the namespaces of a specific\ncluster", + "operationId": "Apps_ResumeDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ResumeDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:rollback": { + "post": { + "summary": "RollbackDeployment rollbacks a deployment under the namespaces of a\nspecific cluster", + "operationId": "Apps_RollbackDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RollbackDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "revision": { + "type": "string", + "format": "int64", + "title": "The revision to rollback to. If set to 0, rollback to the last revision.\n+optional" + } + }, + "title": "RollbackDeploymentRequest the request of Rollback Deployment" + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:start": { + "post": { + "summary": "StartDeployment starts a deployment under the namespace of a specific cluster", + "operationId": "Apps_StartDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1StartDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:stop": { + "post": { + "summary": "StopDeployment starts a deployment under the namespace of a specific cluster", + "operationId": "Apps_StopDeployment", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1StopDeploymentResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/events": { + "get": { + "summary": "ListEvents lists events under the namespaces of a specific cluster", + "operationId": "Core_ListEvents", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListEventsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "Kind represents what type of event is needed.\n\n - KIND_UNSPECIFIED: KIND_UNSPECIFIED is only a meaningless placeholder, to avoid zero not\nreturn.\n - Deployment: ListEvents by deployment.\n - StatefulSet: ListEvents by statefulSet.\n - DaemonSet: ListEvents by daemonSet.\n - Pod: ListEvents by pod.\n - Service: ListEvents by service.\n - Ingress: ListEvents by ingress.\n - Job: ListEvents by job.\n - CronJob: ListEvents by cronJob.\n - HorizontalPodAutoscaler: ListEvents by HorizontalPodAutoscaler.\n - ReplicaSet: ListEvents by replicaset.\n - CronHPA: ListEvents by CronHPA.\n - PersistentVolumeClaim: ListEvents by PersistentVolumeClaim.\n - GroupVersionResource: ListEvents by GroupVersionResource. If kind is set to GroupVersionResource,\nyou must specify the value of group version resource.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet", + "Pod", + "Service", + "Ingress", + "Job", + "CronJob", + "HorizontalPodAutoscaler", + "ReplicaSet", + "CronHPA", + "PersistentVolumeClaim", + "GroupVersionResource" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "description": "The name of involvedObject.\nIf the kind is DEPLOYMENT,\nthis presents the name of deployments.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for event name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the event list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the event list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "type", + "description": "Type is used for query, showing events of specified type.\nUse example: type=WARNING&type=NORMAL.\n\n - EVENT_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Normal: Normal is a normal event type.\n - Warning: Warning is a warning event type.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "EVENT_TYPE_UNSPECIFIED", + "Normal", + "Warning" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "group", + "description": "resource group,used when the kind type is GroupVersionResource.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "version", + "description": "resource version,used when the kind type is GroupVersionResource.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "resource", + "description": "resource name,used when the kind type is GroupVersionResource.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations": { + "get": { + "summary": "ListHelmOperations list operation in cluster.", + "operationId": "Addon_ListHelmOperations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHelmOperationsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the repository list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the repository list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "releaseName", + "description": "Filter helm_operation by release_name,\nThe release_name is exactly.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations/{name}": { + "get": { + "summary": "GetHelmOperation get a operation in cluster.", + "operationId": "Addon_GetHelmOperation", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmOperation" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the daemonSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + }, + "delete": { + "summary": "DeleteHelmOperation delete a operation in cluster.", + "operationId": "Addon_DeleteHelmOperation", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the daemonSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations/{name}/json": { + "get": { + "summary": "GetHelmOperationJSON get a operation json in cluster.", + "operationId": "Addon_GetHelmOperationJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmOperationJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the daemonSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases": { + "get": { + "summary": "ListHelmReleases lists apps in cluster.", + "operationId": "Addon_ListHelmReleases", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHelmReleasesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the releases belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ConfigMap.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the release list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the release list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + }, + "post": { + "summary": "CreateHelmRelease creates a Release.", + "operationId": "Addon_CreateHelmRelease", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateHelmReleaseResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the chart belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helm release belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "repo": { + "type": "string", + "description": "The repo represents for the charts belongs to." + }, + "timeout": { + "type": "string", + "description": "Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)." + }, + "wait": { + "type": "boolean", + "description": "If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout." + }, + "atomic": { + "type": "boolean", + "description": "If set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used." + }, + "debug": { + "type": "boolean", + "description": "Enable verbose output." + }, + "disableHooks": { + "type": "boolean", + "description": "Prevent hooks from running during install." + }, + "disableOpenApiValidation": { + "type": "boolean", + "description": "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema." + }, + "createNamespace": { + "type": "boolean", + "description": "Create the release namespace if not present." + }, + "checkReleaseName": { + "type": "boolean", + "description": "Check whether the release name entered during installation matches the release name in charts annotations." + }, + "chart": { + "$ref": "#/definitions/v1alpha1HelmChartInstall" + } + } + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{helmrelease}/resources": { + "get": { + "summary": "ListHelmReleaseResources lists resources related to the specified helm release.", + "operationId": "Addon_ListHelmReleaseResources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHelmReleaseResourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "helmrelease", + "description": "Name of the helmrelease.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is used to fuzzy search resources which belongs to this helmrelease by resource name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "kind", + "description": "Kind is used to filter resources which belongs to this helmrelease by resource kind.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase is used to filter resources which belongs to this helmrelease by resource phase.\n\n - RESOURCE_PHASE_UNSPECIFIED: ResourcePhase unspecified.\n - InProgress: Resource in progress.\n - Failed: Resource failed.\n - Current: Resource current.\n - Terminating: Resource terminating.\n - Unknown: Resource unknown.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "RESOURCE_PHASE_UNSPECIFIED", + "InProgress", + "Failed", + "Current", + "Terminating", + "Unknown" + ], + "default": "RESOURCE_PHASE_UNSPECIFIED" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the resource list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "SortDir determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{helmrelease}/revisions": { + "get": { + "summary": "ListHelmReleaseRevisions lists revisions of the specified helm release.", + "operationId": "Addon_ListHelmReleaseRevisions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHelmReleaseRevisionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "helmrelease", + "description": "Name of the helmrelease.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name}": { + "get": { + "summary": "GetHelmRelease gets a release in cluster.", + "operationId": "Addon_GetHelmRelease", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1HelmRelease" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the helmrelease.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + }, + "delete": { + "summary": "DeleteHelmRelease delete a release.", + "operationId": "Addon_DeleteHelmRelease", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1DeleteHelmReleaseResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of helmrelease.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "disableHooks": { + "type": "boolean" + }, + "dryRun": { + "type": "boolean" + }, + "keepHistory": { + "type": "boolean" + }, + "timeout": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Addon" + ] + }, + "put": { + "summary": "UpdateHelmRelease updates a release.", + "operationId": "Addon_UpdateHelmRelease", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateHelmReleaseResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of helmrelease.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "repo": { + "type": "string", + "description": "The repo represents for the charts belongs to." + }, + "timeout": { + "type": "string", + "description": "Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)." + }, + "wait": { + "type": "boolean", + "description": "If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout." + }, + "atomic": { + "type": "boolean", + "description": "If set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used." + }, + "debug": { + "type": "boolean", + "description": "Enable verbose output." + }, + "disableHooks": { + "type": "boolean", + "description": "Prevent hooks from running during install." + }, + "disableOpenApiValidation": { + "type": "boolean", + "description": "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema." + }, + "force": { + "type": "boolean", + "description": "Force resource updates through a replacement strategy." + }, + "maxHistory": { + "type": "integer", + "format": "int32", + "description": "Limit the maximum number of revisions saved per release. Use 0 for no limit (default 10)." + }, + "install": { + "type": "boolean", + "description": "If a release by this name doesn't already exist, run an install." + }, + "cleanupOnFail": { + "type": "boolean", + "description": "Allow deletion of new resources created in this upgrade when upgrade fails." + }, + "chart": { + "$ref": "#/definitions/v1alpha1HelmChartUpgrade" + } + } + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name}/json": { + "get": { + "summary": "GetHelmReleaseJSON gets a release in cluster.", + "operationId": "Addon_GetHelmReleaseJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHelmReleaseJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the release belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name}:rollback": { + "post": { + "summary": "RollbackHelmRelease rollbacks a release.", + "operationId": "Addon_RollbackHelmRelease", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RollbackHelmReleaseResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the helmrelease belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of helmrelease.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "revision": { + "type": "integer", + "format": "int32", + "description": "Revision that needs to rollback to." + }, + "timeout": { + "type": "string", + "description": "Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)." + }, + "wait": { + "type": "boolean", + "description": "If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout." + }, + "debug": { + "type": "boolean", + "description": "Enable verbose output." + }, + "disableHooks": { + "type": "boolean", + "description": "Prevent hooks from running during install." + }, + "force": { + "type": "boolean", + "description": "Force resource updates through a replacement strategy." + }, + "maxHistory": { + "type": "integer", + "format": "int32", + "description": "Limit the maximum number of revisions saved per release. Use 0 for no limit (default 10)." + }, + "cleanupOnFail": { + "type": "boolean", + "description": "Allow deletion of new resources created in this upgrade when upgrade fails." + } + }, + "description": "RollbackHelmReleaseRequest rollbacks a release." + } + } + ], + "tags": [ + "Addon" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers": { + "get": { + "summary": "ListHorizontalPodAutoscalers lists hpas in the specified cluster and namespace.", + "operationId": "Autoscaling_ListHorizontalPodAutoscalers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListHorizontalPodAutoscalersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "kind", + "description": "The kind of hpa targetRef.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A hpa which targetRef kind is Deployment.\n - StatefulSet: A hpa which targetRef kind is StatefulSet.\n - ReplicaSet: A hpa which targetRef kind is ReplicaSet.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "ReplicaSet" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "name", + "description": "The workload name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "post": { + "summary": "CreateHorizontalPodAutoscaler creates a hpa by given json.", + "operationId": "Autoscaling_CreateHorizontalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateHorizontalPodAutoscalerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "When the current namespace is named, the priority is higher than that in yaml", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the hpa YAML details" + } + } + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers/{name}": { + "delete": { + "summary": "DeleteHorizontalPodAutoscaler deletes a hpa by given name.", + "operationId": "Autoscaling_DeleteHorizontalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the metadata.name of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "put": { + "summary": "UpdateHorizontalPodAutoscaler updates the specified hpa, the body must\nbe a JSON string.", + "operationId": "Autoscaling_UpdateHorizontalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateHorizontalPodAutoscalerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced hpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the hpa YAML details" + } + } + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers/{name}/json": { + "get": { + "summary": "GetHorizontalPodAutoscalerJSON gets the hpa by namespace and name,\nreturns a string in JSON format.", + "operationId": "Autoscaling_GetHorizontalPodAutoscalerJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetHorizontalPodAutoscalerJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced HorizontalPodAutoscaler.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "HorizontalPodAutoscaler name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "stable", + "description": "If stable is true, the v2 version under the corresponding package will be returned.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses": { + "get": { + "summary": "ListIngresses lists all ingresses in the specified cluster and namespace.", + "operationId": "Networking_ListIngresses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListIngressesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is the number of pages at the beginning.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the number of every page displayed.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy defines sort field, please see message kpanda.io.api.types.SortBy.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy defines the type of sort, default type asc, can also specify desc.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is the name of the ingress.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + }, + "post": { + "summary": "CreateIngress creates a ingress in the specified cluster and namespace.", + "operationId": "Networking_CreateIngress", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateIngressResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the ingress YAML details." + } + }, + "title": "CreateIngressRequest the request of create cluster ingresses" + } + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name}": { + "get": { + "summary": "GetIngress gets the ingress by namespace and name.", + "operationId": "Networking_GetIngress", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Ingress" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of the ingress.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + }, + "delete": { + "summary": "DeleteIngress deletes the ingress by name.", + "operationId": "Networking_DeleteIngress", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of ingress.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + }, + "put": { + "summary": "UpdateIngress updates the specified ingress, the body must be a JSON\nstring.", + "operationId": "Networking_UpdateIngress", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateIngressResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the ingress YAML details." + } + }, + "title": "UpdateIngressRequest the request of update cluster ingresses" + } + } + ], + "tags": [ + "Networking" + ] + }, + "patch": { + "summary": "PatchIngress patches the specified ingress, the body must be a JSON string.", + "operationId": "Networking_PatchIngress", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchIngressResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The data defines the update details of ingress." + } + }, + "title": "PatchIngressRequest the request of patch cluster ingresses" + } + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name}/json": { + "get": { + "summary": "GetIngressJSON gets the ingress by namespace and name, returns a string in JSON\nformat.", + "operationId": "Networking_GetIngressJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetIngressJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the ingress of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of the ingress.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "stable", + "description": "If stable is true, the v1 version under the corresponding package will be returned.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs": { + "get": { + "summary": "ListClusterJobs list cluster jobs under the namespaces of a specific\ncluster", + "operationId": "Batch_ListClusterJobs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterJobsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "phase", + "description": "Status represents the current state of a job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name}": { + "get": { + "summary": "GetJob gets a job under the namespaces of a specific cluster", + "operationId": "Batch_GetJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Job" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + }, + "delete": { + "summary": "DeleteJob deletes a job under the namespaces of a specific cluster", + "operationId": "Batch_DeleteJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name}:restart": { + "post": { + "summary": "RestartJob restarts a job under the namespaces of a specific\ncluster", + "operationId": "Batch_RestartJob", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RestartJobResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified job belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the job.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "resourceVersion": { + "type": "string", + "description": "ResourceVersion of the job." + } + }, + "description": "Get restart job information." + } + } + ], + "tags": [ + "Batch" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges": { + "get": { + "summary": "ListLimitRanges lists all limitranges in the specified cluster and namespace.", + "operationId": "Core_ListLimitRanges", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListLimitRangesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the LimitRanges belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the LimitRanges belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for LimitRange name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the LimitRange list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the LimitRange list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreateLimitRange creates a limitrange in the specified cluster and namespace.", + "operationId": "Core_CreateLimitRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateLimitRangeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the limitRange YAML details." + } + }, + "description": "Create LimitRange in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges/{name}": { + "get": { + "summary": "GetLimitRange gets the limitrange by namespace and name.", + "operationId": "Core_GetLimitRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1LimitRange" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified limitRange.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeleteLimitRange deletes the limitrange by name.", + "operationId": "Core_DeleteLimitRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the LimitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced LimitRange.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the LimitRange name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateLimitRange updates the specified limitrange, the body must be a JSON\nstring.", + "operationId": "Core_UpdateLimitRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateLimitRangeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified limitRange.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the limitRange YAML details." + } + }, + "description": "Update LimitRange in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges/{name}/json": { + "get": { + "summary": "GetLimitRangeJSON gets the limitrange by namespace and name, returns a string in JSON format.", + "operationId": "Core_GetLimitRangeJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetLimitRangeJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified limitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the limitRange name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges:compute": { + "get": { + "summary": "ComputeLimitRange returns the final effective quota detail of multi limit range in specified namespace", + "operationId": "Core_ComputeLimitRange", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1LimitRange" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified LimitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified LimitRange belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/metricvalues": { + "get": { + "summary": "ListMetricValueList returns a list of metrics values for a given\nresource.", + "operationId": "Autoscaling_ListMetricValues", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListMetricValuesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the hpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "The kind of metrics.\n\n - Pod: The custom metrics for service.\n - Service: The custom metrics for service.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Pod", + "Service" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "The exact name of metric.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies": { + "get": { + "summary": "ListNetworkPolicies lists all networkpolicies in the specified cluster and namespace.", + "operationId": "Networking_ListNetworkPolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNetworkPoliciesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, return all the networkpolicies of the cluster\nbe specified.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace of networkpolicy list.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page number.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the number of every page displayed.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy defines sort field, please see message kpanda.io.api.types.SortBy.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy defines the type of sort, default type asc, can also specify desc.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is the name of the networkpolicy.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + }, + "post": { + "summary": "CreateNetworkPolicy creates a networkpolicy in the specified cluster and namespace.", + "operationId": "Networking_CreateNetworkPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateNetworkPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster to request.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the networkpolicy YAML details." + } + }, + "title": "CreateNetworkPolicyRequest the request of create cluster networkpolicies" + } + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies/{name}": { + "get": { + "summary": "GetNetworkPolicy gets the networkpolicy by namespace and name.", + "operationId": "Networking_GetNetworkPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1NetworkPolicy" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster to request.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specifies the namespace of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of the networkpolicy.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + }, + "delete": { + "summary": "DeleteNetworkPolicy deletes the networkpolicy by name.", + "operationId": "Networking_DeleteNetworkPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster to request.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + }, + "put": { + "summary": "UpdateNetworkPolicy updates the specified networkpolicy, the body must be a JSON\nstring.", + "operationId": "Networking_UpdateNetworkPolicy", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateNetworkPolicyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster to request.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the networkpolicy YAML details." + } + }, + "title": "UpdateNetworkPolicyRequest the request of update cluster networkpolicies" + } + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies/{name}/json": { + "get": { + "summary": "GetNetworkPolicyJSON gets the networkpolicy by namespace and name, returns a string in JSON\nformat.", + "operationId": "Networking_GetNetworkPolicyJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetNetworkPolicyJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster to request.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace specified the namespace of networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the name of the networkpolicy.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "stable", + "description": "If stable is true, the v1 version under the corresponding package will be returned.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims": { + "get": { + "summary": "ListPersistentVolumeClaims gets the pvcs from the system", + "operationId": "Core_ListPersistentVolumeClaims", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPersistentVolumeClaimsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for fuzzy search by name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phases is used for fuzzy search by phase.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "accessMode", + "description": " - PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - ReadWriteOnce: ReadWriteOnce can be mounted in read/write mode to exactly 1 host.\n - ReadOnlyMany: ReadOnlyMany can be mounted in read-only mode to many hosts.\n - ReadWriteMany: ReadWriteMany can be mounted in read/write mode to many hosts.\n - ReadWriteOncePod: ReadWriteOncePod can be mounted in read/write mode to exactly 1 pod.\nReadWriteOncePod cannot be used in combination with other access modes.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED", + "ReadWriteOnce", + "ReadOnlyMany", + "ReadWriteMany", + "ReadWriteOncePod" + ], + "default": "PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreatePersistentVolumeClaim create persistent volume claim", + "operationId": "Core_CreatePersistentVolumeClaim", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreatePersistentVolumeClaimResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the pvc YAML details" + } + }, + "description": "CreatePersistentVolumeClaimRequest represents the request of create PVC in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}": { + "get": { + "summary": "GetPersistentVolumeClaim gets a pvc from the system by given pvc-name;", + "operationId": "Core_GetPersistentVolumeClaim", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaim" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of PVC to search", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeletePersistentVolumeClaim delete the specified pvc", + "operationId": "Core_DeletePersistentVolumeClaim", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdatePersistentVolumeClaim update the persistent volume claim", + "operationId": "Core_UpdatePersistentVolumeClaim", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdatePersistentVolumeClaimResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data represents the data of PVC JSON" + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}/annotations": { + "put": { + "summary": "UpdatePersistentVolumeClaimAnnotations puts the specified pvc's annotations", + "operationId": "Core_UpdatePersistentVolumeClaimAnnotations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdatePersistentVolumeClaimAnnotationsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "labels represents the labels of pvc" + } + }, + "title": "UpdatePersistentVolumeClaimAnnotationsRequest represents the request of put pvc's AnnotationsRequest" + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}/json": { + "get": { + "summary": "GetPersistentVolumeClaimJSON get the specified pvc's JSON", + "operationId": "Core_GetPersistentVolumeClaimJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetPersistentVolumeClaimJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of PVC to search", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}/labels": { + "put": { + "summary": "UpdatePersistentVolumeClaimLabels puts the specified pvc's labels", + "operationId": "Core_UpdatePersistentVolumeClaimLabels", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdatePersistentVolumeClaimLabelsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of PVC to search", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "labels represents the labels of pvc" + } + }, + "title": "UpdatePersistentVolumeClaimLabelsRequest represents the request of put pvc's labels" + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}:scale": { + "post": { + "summary": "ScalePersistentVolumeClaim post scale the persistent volume claim capacity", + "operationId": "Core_ScalePersistentVolumeClaim", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ScalePersistentVolumeClaimResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of PVC belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "capacity": { + "type": "string", + "title": "capacity represents the capacity of PVC" + } + }, + "title": "UpdateScalePersistentVolumeClaimRequest represents the request of scale Pvc" + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods": { + "get": { + "summary": "ListPods will list all pod by given cluster and namespace", + "operationId": "Core_ListPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "kind", + "description": "The kind of pod.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A Deployment provides declarative updates for Pods and ReplicaSets.\n - StatefulSet: StatefulSet is the workload API object used to manage stateful\napplications.\n - DaemonSet: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod.\n - Service: Service to expose an application running on a set of Pods.\n - Job: Job is used to express a one-time task.\n - CronJob: CronJob runs repeatedly according to its time schedule.\n - ReplicaSet: ReplicaSet is the workload API object used to manage pods\n - NetworkPolicy: NetworkPolicy uses podSelector to select pods.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet", + "Service", + "Job", + "CronJob", + "ReplicaSet", + "NetworkPolicy" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "description": "Name of kind.\nIf the kind is Deployment,\nthis presents the name of the deployment.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for pod name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phases is used for filter.\n\n - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Unknown: PodUnknown means that for some reason the state of the pod could not be\nobtained, typically due to an error in communicating with the host of the\npod.\n - Pending: PodPending means the pod has been accepted by the system, but one or more\nof the containers has not been started. This includes time before being\nbound to a node, as well as time spent pulling images onto the host.\n - Running: PodRunning means the pod has been bound to a node and all of the\ncontainers have been started. At least one container is still running or\nis in the process of being restarted. PodSucceeded means that all\ncontainers in the pod have voluntarily terminated with a container exit\ncode of 0, and the system is not going to restart any of these\ncontainers.\n - Succeeded: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).\n - Failed: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Unknown", + "Pending", + "Running", + "Succeeded", + "Failed" + ], + "default": "PHASE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "description": "status is filter with pod status ,the status is composite state", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "FILTER_POD_STATUS_UNSPECIFIED", + "FILTER_POD_STATUS_RUNNING", + "FILTER_POD_STATUS_ERROR", + "FILTER_POD_STATUS_COMPLETED", + "FILTER_POD_STATUS_WAITING" + ], + "default": "FILTER_POD_STATUS_UNSPECIFIED" + }, + { + "name": "gpuType", + "description": "gpu_type is filter with pods resources, when value is * search all", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}": { + "get": { + "summary": "GetPods will get a pod under the namespaces of a specific cluster by pods", + "operationId": "Core_GetPod", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Pod" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Pod name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeletePod deletes a pod under the namespaces of a specific cluster", + "operationId": "Core_DeletePod", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Pod name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}/containers": { + "get": { + "summary": "ListContainersByPod lists containers under the namespaces of a specific\ncluster by pods", + "operationId": "Core_ListContainersByPod", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodContainerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of pod to search", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}/log": { + "get": { + "summary": "GetPodContainerLog gets pod contianer log", + "operationId": "insight_GetPodContainerLog", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetPodContainerLogResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Name of the cluster where the Pod is located", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Name of the namespace where the Pod is located", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of pod", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "workload", + "description": "workload refers to the name of a workload", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "container", + "description": "Name of the pod where the container is located", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "startTime", + "description": "Start time of get pod container log", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "endTime", + "description": "End time of get pod container log", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Number of page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Log number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "logSearch", + "description": "for fuzzy query", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "insight" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets": { + "get": { + "summary": "ListReplicaSets lists replicasets in specified namespace of a cluster", + "operationId": "Apps_ListReplicaSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListReplicaSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of replicaset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the replicaset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "Kind stands for what type of replicasets are needed.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "description": "The name of involvedObject.\nIf the kind is Deployment,\nthis presents the name of deployments.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for replicaset name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "SortDir determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "PageSize is size of every page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets/{name}": { + "get": { + "summary": "GetReplicaSet gets replicaset detail in specified namespace of a cluster", + "operationId": "Apps_GetReplicaSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ReplicaSet" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified replicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified replicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified replicaSet.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "delete": { + "summary": "DeleteReplicaSet deletes a replicaset in specified namespace of a cluster", + "operationId": "Apps_DeleteReplicaSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the ReplicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ReplicaSet.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the ReplicaSet name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "put": { + "summary": "UpdateReplicaSet updates a replicaset in specified namespace of a cluster", + "operationId": "Apps_UpdateReplicaSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateReplicaSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified replicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified replicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified replicaSet.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the replicaSet YAML details." + } + }, + "description": "Update ReplicaSet in the cluster." + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets/{name}/json": { + "get": { + "summary": "GetReplicaSetJSON gets replicaset yaml in specified namespace of a cluster", + "operationId": "Apps_GetReplicaSetJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetReplicaSetJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified replicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified replicaSet belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the replicaSet name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas": { + "get": { + "summary": "ListResourceQuotas lists quotas in specified namespace", + "operationId": "Core_ListResourceQuotas", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListResourceQuotasResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the ResourceQuotas belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the ResourceQuotas belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for ResourceQuota name, used for name fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the ResourceQuota list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the ResourceQuota list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreateResourceQuota creates a resourceQuota to the system by given resourceQuota data", + "operationId": "Core_CreateResourceQuota", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateResourceQuotaResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the resourceQuota YAML details." + } + }, + "description": "Create ResourceQuota in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas/{name}": { + "get": { + "summary": "GetResourceQuota gets a resourceQuota from the system by given resourceQuota name", + "operationId": "Core_GetResourceQuota", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ResourceQuota" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified resourceQuota.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateResourceQuota updates a resourceQuota from the system by given resourceQuota name", + "operationId": "Core_UpdateResourceQuota", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateResourceQuotaResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified resourceQuota.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the resourceQuota YAML details." + } + }, + "description": "Update ResourceQuota in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas/{name}/json": { + "get": { + "summary": "GetResourceQuotaJSON gets a resourceQuota json from the system by given resourceQuota name", + "operationId": "Core_GetResourceQuotaJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetResourceQuotaJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified resourceQuota belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the resourceQuota name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas:compute": { + "get": { + "summary": "ComputeResourceQuota returns the final effective quota detail of multi quotas in specified namespace", + "operationId": "Core_ComputeResourceQuota", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ResourceQuota" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified resourceQuotas belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified resourceQuotas belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resources": { + "post": { + "summary": "CreateResource creates a list of resources of a given yaml", + "operationId": "Apiextensions_CreateResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the resources belong to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the resources belong to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The data field is the resource YAML details." + } + }, + "title": "CreateResourceRequest represents create request to create resources from yaml" + } + } + ], + "tags": [ + "Apiextensions" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/rolebindings": { + "post": { + "summary": "CreateRoleBinding creates a RoleBinding", + "operationId": "RBAC_CreateRoleBinding", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RoleBinding" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the roleBinding belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the roleBinding belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "subject": { + "$ref": "#/definitions/v1alpha1Subject", + "description": "Subject holds references to the objects the role applies to." + }, + "roleRef": { + "$ref": "#/definitions/v1alpha1RoleRef", + "description": "RoleRef can reference a Role in the current namespace or a ClusterRole in\nthe global namespace. If the RoleRef cannot be resolved, the Authorizer\nmust return an error." + }, + "name": { + "type": "string", + "description": "the name of RoleBinding." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "ownerReferences": { + "type": "array", + "items": { + "$ref": "#/definitions/typesOwnerReference" + } + } + } + } + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/rolebindings/{name}": { + "delete": { + "summary": "ListRoleBindings lists the clusterrolebidings created by the frontend.", + "operationId": "RBAC_DeleteRoleBinding", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the roleBinding belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the roleBinding belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the rolebinding to delete.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles": { + "get": { + "summary": "ListRoles lists the roles created by frontend.", + "operationId": "RBAC_ListRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of the user", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + }, + "post": { + "summary": "CreateRole creates a Role", + "operationId": "RBAC_CreateRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/rbacv1alpha1Role" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + }, + "name": { + "type": "string", + "description": "the name of role." + } + } + } + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles/{name}": { + "get": { + "summary": "GetRole gets a Role", + "operationId": "RBAC_GetRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/rbacv1alpha1Role" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the role to delete.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + }, + "delete": { + "summary": "DeleteRole deletes the roles created by the frontend.", + "operationId": "RBAC_DeleteRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the role to delete.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + }, + "put": { + "summary": "UpdateRole updates a Role", + "operationId": "RBAC_UpdateRole", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateRoleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the role belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of the role to delete.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + }, + "title": "UpdateRoleRequest the request of update role" + } + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets": { + "get": { + "summary": "ListSecrets lists a secret under the namespaces of a specific cluster", + "operationId": "Core_ListSecrets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListSecretsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced secret.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "The name use to search specific secret", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "type", + "description": "Type is used to filter secrets by type.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "onlyMetadata", + "description": "OnlyMetadata lists only metadata of secrets, default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreateSecret creates a secret under the namespaces of a specific cluster", + "operationId": "Core_CreateSecret", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateSecretResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "When the current namespace is named, the priority is higher than that in yaml", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the Secret YAML details" + } + }, + "description": "Create Secret in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name}": { + "get": { + "summary": "GetClusterSecret gets a secret under the namespaces of a specific cluster", + "operationId": "Core_GetSecret", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Secret" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced secret.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Secret name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeleteSecret deletes a secret under the namespaces of a specific cluster", + "operationId": "Core_DeleteSecret", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced secret.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Secret name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateSecret updates secret under the namespaces of a specific cluster", + "operationId": "Core_UpdateSecret", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateSecretResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced secret.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Secret name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the Secret YAML details" + } + }, + "description": "Update Secret in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name}/json": { + "get": { + "summary": "GetSecretJSON gets a secret json under the namespaces of a specific cluster", + "operationId": "Core_GetSecretJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetSecretJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced secret.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Secret name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "patch": { + "summary": "PatchSecret patchs a Secret under the namespaces of a specific cluster", + "operationId": "Core_PatchSecret", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchSecretResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced secret.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The data is the secret YAML details." + } + }, + "description": "Patches the current secret." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{secret}/related": { + "get": { + "summary": "ListSecretsRelatedWorkloads list all workloads associated with this secret", + "operationId": "Apps_ListSecretsRelatedWorkloads", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListSecretRelatedWorkloadsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "secret", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/serviceaccounts": { + "post": { + "summary": "CreateServiceAccount creates a sa from the system by given sa name", + "operationId": "Core_CreateServiceAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateServiceAccountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents the cluster of ServiceAccount to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the ServiceAccount YAML details" + } + }, + "description": "CreateStorageClassRequest represents the request of create ServiceAccount in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/serviceaccounts/{name}": { + "get": { + "summary": "GetServiceAccount gets a sa from the system by given sa\nname", + "operationId": "Core_GetServiceAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ServiceAccount" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced ServiceAccount.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of ServiceAccount to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeleteServiceAccount deletes a sa from the system by given sa name", + "operationId": "Core_DeleteServiceAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the ServiceAccount belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of StorageClass", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services": { + "get": { + "summary": "ListServices lists services in the specified cluster and namespace", + "operationId": "Core_ListServices", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListServicesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "The kind of service.\nIf the kind is Deployment,\nthis presents the name of the deployment.\n\n - Deployment: A Deployment provides declarative updates for Pods and ReplicaSets.\n - StatefulSet: StatefulSet is the workload API object used to manage stateful\napplications.\n - DaemonSet: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "description": "Name of kind.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for service name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the service list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the service list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "type", + "description": "Type is a array used for frontend filter.\nUse examples: type=CLUSTER_IP&type=NODE_PORT.\n\n - SERVICE_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - ClusterIP: ClusterIP means a service will only be accessible inside the cluster, via\nthe cluster IP.\n - NodePort: NodePort means a service will be exposed on one port of every node, in\naddition to 'ClusterIP' type.\n - LoadBalancer: LoadBalancer means a service will be exposed via an external load balancer\n(if the cloud provider supports it), in addition to 'NodePort' type.\n - ExternalName: ExternalName means a service consists of only a reference to an external\nname that kubedns or equivalent will return as a CNAME record, with no\nexposing or proxying of any pods involved.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SERVICE_TYPE_UNSPECIFIED", + "ClusterIP", + "NodePort", + "LoadBalancer", + "ExternalName" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "ports", + "description": "Ports is used to filter by port.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreateService creates a service to the system by given service data", + "operationId": "Core_CreateService", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateServiceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "When the current namespace is named, the priority is higher than that in\nyaml", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "Data is the Service YAML details" + } + }, + "description": "Create Service in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name}": { + "get": { + "summary": "GetService gets a service from the system by given service name", + "operationId": "Core_GetService", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Service" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the service name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeleteService deletes a service from the system by given service name", + "operationId": "Core_DeleteService", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced service.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the service name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateService updates a service from the system by given service name", + "operationId": "Core_UpdateService", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateServiceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the service name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "Data is the Service YAML details" + } + }, + "description": "Update the Service information." + } + } + ], + "tags": [ + "Core" + ] + }, + "patch": { + "summary": "PatchService patches a service from the system by given service name", + "operationId": "Core_PatchService", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchServiceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The json data of patch." + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name}/json": { + "get": { + "summary": "GetServiceJSON gets a service json from the system by given service name", + "operationId": "Core_GetServiceJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetServiceJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the service name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets": { + "get": { + "operationId": "Apps_ListStatefulSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListStatefulSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}": { + "get": { + "summary": "GetStatefulSet gets a statefulSets under the namespaces of a specific\ncluster", + "operationId": "Apps_GetStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1StatefulSet" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which namespace the workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Cluster represents which namespace the workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "delete": { + "summary": "DeleteStatefulSet deletes a statefulSet under the namespaces of a specific\ncluster", + "operationId": "Apps_DeleteStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of deployment", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + }, + "patch": { + "summary": "PatchStatefulSet update a statefulSet under the namespaces of a specific\ncluster", + "operationId": "Apps_PatchStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchStatefulSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster which the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "The namespace which the deployment belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the deployment.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The json data of patch." + } + }, + "description": "The request of patching deployment." + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:restart": { + "post": { + "summary": "RestartStatefulSet restarts a statefulSet under the namespaces of a\nspecific cluster", + "operationId": "Apps_RestartStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RestartStatefulSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "StatefulSet name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:rollback": { + "post": { + "summary": "RollbackStatefulSet rollbacks a statefulSet under the namespaces of a\nspecific cluster", + "operationId": "Apps_RollbackStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1RollbackStatefulSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace the specified statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "StatefulSet name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "revision": { + "type": "string", + "format": "int64", + "description": "Revision indicates the revision of the state represented by Data." + } + } + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:start": { + "post": { + "summary": "StartStatefulSet starts a statefulset under the namespace of a specific cluster", + "operationId": "Apps_StartStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1StartStatefulSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of statefulset.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:stop": { + "post": { + "summary": "StopStatefulSet starts a statefulset under the namespace of a specific cluster", + "operationId": "Apps_StopStatefulSet", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1StopStatefulSetResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the statefulset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of statefulset.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers": { + "get": { + "summary": "ListVerticalPodAutoscalers lists vpas in the specified cluster and namespace.", + "operationId": "Autoscaling_ListVerticalPodAutoscalers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListVerticalPodAutoscalersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the vpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced vpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "kind", + "description": "The kind of vpa targetRef.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A vpa which targetRef kind is Deployment.\n - StatefulSet: A vpa which targetRef kind is StatefulSet.\n - DaemonSet: A vpa which targetRef kind is DaemonSet.\n - ReplicaSet: A vpa which targetRef kind is ReplicaSet.\n - Job: A vpa which targetRef kind is Job.\n - CronJob: A vpa which targetRef kind is CronJob.\n - ReplicationController: A vpa which targetRef kind is ReplicationController.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet", + "ReplicaSet", + "Job", + "CronJob", + "ReplicationController" + ], + "default": "KIND_UNSPECIFIED" + }, + { + "name": "kindName", + "description": "The name of the targetRef.\nIf the kind is StatefulSet, this presents the name of statefulset.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "post": { + "summary": "CreateVerticalPodAutoscaler creates a vpa by given json.", + "operationId": "Autoscaling_CreateVerticalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateVerticalPodAutoscalerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified vpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace of the vpa.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the vpa YAML details." + } + }, + "description": "CreateVerticalPodAutoscalerRequest requests to create a vpa." + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers/{name}": { + "delete": { + "summary": "DeleteVerticalPodAutoscaler deletes a vpa by given name.", + "operationId": "Autoscaling_DeleteVerticalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the vpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced vpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the metadata.name of the vpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Autoscaling" + ] + }, + "put": { + "summary": "UpdateVerticalPodAutoscaler updates the specified vpa, the body must\nbe a JSON string.", + "operationId": "Autoscaling_UpdateVerticalPodAutoscaler", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateVerticalPodAutoscalerResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified vpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced vpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the vpa YAML details." + } + }, + "description": "UpdateVerticalPodAutoscalerRequest requests to update a vpa." + } + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers/{name}/json": { + "get": { + "summary": "GetVerticalPodAutoscalerJSON gets a vpa by namespace and name, returning a string in JSON format.", + "operationId": "Autoscaling_GetVerticalPodAutoscalerJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetVerticalPodAutoscalerJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the vpa belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace of the vpa.\nThis field is required in all cases.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the vpa.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "stable", + "description": "If stable is true, the v2 version under the corresponding package will be returned.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Autoscaling" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots": { + "get": { + "summary": "ListVolumeSnapshots list volume snapshot in single cluster", + "operationId": "Storage_ListVolumeSnapshots", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListVolumeSnapshotsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the VolumeSnapshot belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + }, + "post": { + "summary": "CreateVolumeSnapshot create volume snapshot in single cluster", + "operationId": "Storage_CreateVolumeSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateVolumeSnapshotResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "name represents the name of VolumeSnapshot to snapshot belongs to." + } + }, + "description": "CreateVolumeSnapshotRequest represents the request of create VolumeSnapshot Snapshot in the cluster." + } + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots/{name}": { + "delete": { + "summary": "DeleteVolumeSnapshot delete volume snapshot in single cluster", + "operationId": "Storage_DeleteVolumeSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + }, + "put": { + "summary": "UpdateVolumeSnapshot update volume snapshot", + "operationId": "Storage_UpdateVolumeSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateVolumeSnapshotResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of Volume snapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "namespace represents the namespace of volume snapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of volume snapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data represents the data of volume snapshot JSON" + } + }, + "description": "UpdateVolumeSnapshotRequest represents the request of update volume snapshot." + } + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots/{name}/json": { + "get": { + "summary": "GetVolumeSnapshotJSON list StorageClass in single cluster", + "operationId": "Storage_GetVolumeSnapshotJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetVolumeSnapshotJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of VolumeSnapshots belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the VolumeSnapshots belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of VolumeSnapshots to search", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/{kind}/json": { + "post": { + "summary": "CreateWorkloadByJSON creates workload by JSON under the namespaces of a\nspecific cluster", + "operationId": "Apps_CreateWorkloadByJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1WorkloadJSON" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the Workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the Workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "WorkloadKind the workload of kind", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "deployments", + "statefulsets", + "daemonsets", + "jobs", + "cronjobs", + "pods", + "replicasets" + ] + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the Workload YAML details" + } + }, + "title": "CreateWorkloadByJSONRequest the request of create workload by JSON request" + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/{kind}/{name}/json": { + "get": { + "summary": "GetWorkloadJSON gets workload by JSON under the namespaces of a specific\ncluster", + "operationId": "Apps_GetWorkloadJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1WorkloadJSON" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the Workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the Workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "WorkloadKind the workload of kind", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "deployments", + "statefulsets", + "daemonsets", + "jobs", + "cronjobs", + "pods", + "replicasets" + ] + }, + { + "name": "name", + "description": "Name represents the name of Workload", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "stable", + "description": "If stable is true, the v1 version under the corresponding package will be returned.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Apps" + ] + }, + "put": { + "summary": "UpdateWorkloadByJSON updates workload by JSON under the namespaces of a\nspecific cluster", + "operationId": "Apps_UpdateWorkloadByJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1WorkloadJSON" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the Workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the Workload belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "kind", + "description": "WorkloadKind the workload of kind", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "deployments", + "statefulsets", + "daemonsets", + "jobs", + "cronjobs", + "pods", + "replicasets" + ] + }, + { + "name": "name", + "description": "Name represents the name of Workload", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the Workload YAML details" + } + }, + "title": "UpdateWorkloadByJSONRequest request of update workload by JSON request" + } + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}": { + "get": { + "summary": "GetNamespace gets a namespace from the system by given namespace\nname", + "operationId": "Core_GetNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Namespace" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the namespace belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeleteNamespace deletes a namespace from the system by given namespace name", + "operationId": "Core_DeleteNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified namespace belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateNamespace updates a namespace from the system by given namespace name", + "operationId": "Core_UpdateNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified namespace belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the namespace YAML details." + } + }, + "description": "Update Namespace information." + } + } + ], + "tags": [ + "Core" + ] + }, + "patch": { + "summary": "PatchNamespace patches a namespace from the system by given namespace name", + "operationId": "Core_PatchNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PatchNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified namespace belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "The data is the namespace YAML details." + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}/json": { + "get": { + "summary": "GetNamespaceJSON gets a namespace json from the system by given namespace\nname", + "operationId": "Core_GetNamespaceJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetNamespaceJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the namespace belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the requested namespace name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}/podsecurity:disable": { + "post": { + "summary": "DisableNamespacePodSecurity enables pod security policy of a namespace", + "operationId": "Core_DisableNamespacePodSecurity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Namespace" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster of the namespace.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "description": "DisableNamespacePodSecurityRequest requests to remove pod security labels of a namespace." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}/podsecurity:enable": { + "post": { + "summary": "EnableNamespacePodSecurity enables pod security policy of a namespace", + "operationId": "Core_EnableNamespacePodSecurity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Namespace" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster of the namespace.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the resource name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "podSecurity": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PodSecurity" + }, + "description": "PodSecurity is a list of label combinations of mode plus level." + } + }, + "description": "EnableNamespacePodSecurityRequest request to enable pod security of a namespace." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}:bind": { + "post": { + "operationId": "Workspace_BindResourceToWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1BindResourceToWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "workspaceAlias": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}:unbind": { + "delete": { + "operationId": "Workspace_UnbindResourceFromWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UnbindResourceFromWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "workspaceAlias": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/namespacesummary": { + "get": { + "summary": "ListClusterNamespaceSummary gets a list of namespace simple information\nfrom the system by given cluster name", + "operationId": "Core_ListClusterNamespaceSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterNamespaceSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the namespace summary list belong to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "phase", + "description": "Phases is used for filter.\n\n - NAMESPACE_PHASE_UNSPECIFIED: The namespace state is unspecified.\n - Active: NamespaceActive means the namespace is available for use in the system\n - Terminating: NamespaceTerminating means the namespace is undergoing graceful termination", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "NAMESPACE_PHASE_UNSPECIFIED", + "Active", + "Terminating" + ], + "default": "NAMESPACE_PHASE_UNSPECIFIED" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/networkpolicies": { + "get": { + "summary": "ListClusterNetworkPolicies lists all networkpolicies in the specified cluster.", + "operationId": "Networking_ListClusterNetworkPolicies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterNetworkPoliciesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the name of the cluster, must be specified,\nwill return all the networkpolicies of the cluster.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page number.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the number of every page displayed.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy defines sort field, please see message kpanda.io.api.types.SortBy.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy defines the type of sort, default type asc, can also specify desc.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is the name of the networkpolicy.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Networking" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes": { + "get": { + "summary": "ListNodes lists the node in specified cluster", + "operationId": "Core_ListNodes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNodesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "phase", + "description": "Phase represents the current phase of node.\n\n - NODE_PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Ready: The node is ready to work.\n - Not_Ready: The node is not ready.\n - Unknown: The node state is unknown.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "NODE_PHASE_UNSPECIFIED", + "Ready", + "Not_Ready", + "Unknown" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "nodeIp", + "description": "nodeIp represents node's ip address", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the job list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the job list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is to filter nodes by node name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "role", + "description": "Role is used for filter by node role.\n\n - NODE_ROLE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - CONTROL_PLANE: The control plane manages the worker nodes and the Pods in the cluster.\n - WORKER: The worker node(s) host the Pods that are the components of the\napplication workload.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "NODE_ROLE_UNSPECIFIED", + "CONTROL_PLANE", + "WORKER" + ], + "default": "NODE_ROLE_UNSPECIFIED" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "excludeMetrics", + "description": "exclude_metrics\nIf false, contains metrics-related information\nIf true, metrics-related information is not included", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name}": { + "get": { + "summary": "GetNode gets a node from the system by given node name", + "operationId": "Core_GetNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Node" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "showPods", + "description": "ShowPods is to control whether returned data contains\nnode.status.PodAllocated. Default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "excludeMetrics", + "description": "exclude_metrics\nIf false, contains metrics-related information\nIf true, metrics-related information is not included", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdateNode updates a node from the system by given node name", + "operationId": "Core_UpdateNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateNodeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name represents for the node name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the node YAML details." + } + }, + "description": "UpdateNodeRequest requests to update a node." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name}/json": { + "get": { + "summary": "GetNodeJSON gets a node's json from the system by given node name", + "operationId": "Core_GetNodeJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetNodeJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the node name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name}:unbindNamespace": { + "post": { + "summary": "UnbindNodeToNamespace makes the specified node to shared.", + "operationId": "Core_UnbindNodeToNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UnbindNodeToNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the cluster for namespace and node.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is the node name for node which needs to\nbe unbound with namespace.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "Namespace is the namespace for node to unbind." + } + }, + "description": "UnbindNodeToNamespaceRequest is the request for node unbind namespace." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/annotations": { + "put": { + "summary": "UpdateNodeAnnotations edits annotations of specified node.", + "operationId": "Core_UpdateNodeAnnotations", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateNodeAnnotationsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations requested." + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/cordon": { + "post": { + "summary": "CordonNode makes the specified node to unschedulable.", + "operationId": "Core_CordonNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Node" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/gpu-mode": { + "put": { + "summary": "UpdateNodeGPUMode updates single the gpu mode with cluster node", + "operationId": "Core_UpdateNodeGPUMode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateNodeGPUModeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/definitions/v1alpha1GPUModel" + }, + "migSpec": { + "$ref": "#/definitions/v1alpha1MIGModeSpec" + } + } + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/gpu-stats": { + "get": { + "summary": "GetNodeGPUStats get node gpu stats", + "operationId": "Core_GetNodeGPUStats", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetNodeGPUStatsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/gpus": { + "get": { + "summary": "listNodeGPU gets all the gpu info with cluster node", + "operationId": "Core_ListNodeGPU", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListNodeGPUResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/labels": { + "put": { + "summary": "PutNodeLabels puts the specified node's labels", + "operationId": "Core_PutNodeLabels", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PutNodeLabelsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "the labels of node." + } + }, + "description": "PutNodeLabels put node's labels." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/pods": { + "get": { + "summary": "ListPodsByNode lists pods info by given node in a specific\ncluster", + "operationId": "Core_ListPodsByNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsByNodeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "description": "Node represents which node the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name is to filter pods by pod name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the job list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the job list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "description": "status is filter with pod status ,the status is composite state", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "FILTER_POD_STATUS_UNSPECIFIED", + "FILTER_POD_STATUS_RUNNING", + "FILTER_POD_STATUS_ERROR", + "FILTER_POD_STATUS_COMPLETED", + "FILTER_POD_STATUS_WAITING" + ], + "default": "FILTER_POD_STATUS_UNSPECIFIED" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/taints": { + "put": { + "summary": "PutNodeTaints puts a node's taints in a specific cluster", + "operationId": "Core_PutNodeTaints", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PutNodeTaintsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "// Cluster the specified node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "taints": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Taint" + }, + "description": "If specified, the node's taints." + } + }, + "description": "PutNodeTaints put node's taints." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/uncordon": { + "post": { + "summary": "UnCordonNode makes the specified node to schedulable.", + "operationId": "Core_UnCordonNode", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Node" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified node belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "node", + "description": "Node name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes:batchBindNamespace": { + "post": { + "summary": "BatchBindNodeToNamespace makes the specified node to exclusive.", + "operationId": "Core_BatchBindNodeToNamespace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1BatchBindNodeToNamespaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the cluster for namespace and node.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "Namespace is the namespace for node to be bound." + }, + "nodeNames": { + "type": "array", + "items": { + "type": "string" + }, + "description": "NodeNames is the list of node name which\nneeds to be bound with namespace." + } + }, + "description": "BatchBindNamespaceRequest is the request for node bind namespaces." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/nodesummary": { + "get": { + "summary": "ListClusterNodeSummary lists the node summary in specified cluster", + "operationId": "Core_ListClusterNodeSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterNodeSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumeclaims": { + "get": { + "summary": "ListPersistentVolumeClaims gets the pvcs from the system", + "operationId": "Core_ListClusterPersistentVolumeClaims", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterPersistentVolumeClaimsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "accessMode", + "description": "AccessMode is used searching PVC by accessMode.\n\n - PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - ReadWriteOnce: ReadWriteOnce can be mounted in read/write mode to exactly 1 host.\n - ReadOnlyMany: ReadOnlyMany can be mounted in read-only mode to many hosts.\n - ReadWriteMany: ReadWriteMany can be mounted in read/write mode to many hosts.\n - ReadWriteOncePod: ReadWriteOncePod can be mounted in read/write mode to exactly 1 pod.\nReadWriteOncePod cannot be used in combination with other access modes.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED", + "ReadWriteOnce", + "ReadOnlyMany", + "ReadWriteMany", + "ReadWriteOncePod" + ], + "default": "PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes": { + "get": { + "summary": "ListPersistentVolumes lists persistentvolumes in the specified cluster", + "operationId": "Core_ListPersistentVolumes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPersistentVolumesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the PersistentVolumes belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name stands for PersistentVolume name, used for fuzzy search.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the PersistentVolume list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the PersistentVolume list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by cluster name or cluster alias name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "post": { + "summary": "CreatePersistentVolume creates a persistentvolume to the system by given persistentvolume data", + "operationId": "Core_CreatePersistentVolume", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreatePersistentVolumeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified persistentVolume belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the persistentVolume YAML details." + } + }, + "description": "Create PersistentVolume in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes/{name}": { + "get": { + "summary": "GetPersistentVolume gets a persistentvolume from the system by given persistentvolume name", + "operationId": "Core_GetPersistentVolume", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1PersistentVolume" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified persistentVolume belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified persistentVolume.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "delete": { + "summary": "DeletePersistentVolume deletes a persistentvolume from the system by given persistentvolume name", + "operationId": "Core_DeletePersistentVolume", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the PersistentVolume belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the PersistentVolume name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + }, + "put": { + "summary": "UpdatePersistentVolume updates a persistentvolume from the system by given persistentvolume name", + "operationId": "Core_UpdatePersistentVolume", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdatePersistentVolumeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified persistentVolume belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name of the specified persistentVolume.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the persistentVolume YAML details." + } + }, + "description": "Update PersistentVolume in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes/{name}/json": { + "get": { + "summary": "GetPersistentVolumeJSON gets a persistentvolume json from the system by given persistentvolume name", + "operationId": "Core_GetPersistentVolumeJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetPersistentVolumeJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified persistentVolume belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents for the persistentVolume name.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/pods": { + "get": { + "summary": "ListClusterPods will list all pod by given cluster and regardless of\nnamespaces", + "operationId": "Core_ListClusterPods", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPodsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the pod belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phases is used for filter.\n\n - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Unknown: PodUnknown means that for some reason the state of the pod could not be\nobtained, typically due to an error in communicating with the host of the\npod.\n - Pending: PodPending means the pod has been accepted by the system, but one or more\nof the containers has not been started. This includes time before being\nbound to a node, as well as time spent pulling images onto the host.\n - Running: PodRunning means the pod has been bound to a node and all of the\ncontainers have been started. At least one container is still running or\nis in the process of being restarted. PodSucceeded means that all\ncontainers in the pod have voluntarily terminated with a container exit\ncode of 0, and the system is not going to restart any of these\ncontainers.\n - Succeeded: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).\n - Failed: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Unknown", + "Pending", + "Running", + "Succeeded", + "Failed" + ], + "default": "PHASE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "status", + "description": "status is filter with pod status ,the status is composite state", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "FILTER_POD_STATUS_UNSPECIFIED", + "FILTER_POD_STATUS_RUNNING", + "FILTER_POD_STATUS_ERROR", + "FILTER_POD_STATUS_COMPLETED", + "FILTER_POD_STATUS_WAITING" + ], + "default": "FILTER_POD_STATUS_UNSPECIFIED" + }, + { + "name": "excludeMetrics", + "description": "exclude_metrics\nIf false, contains metrics-related information\nIf true, metrics-related information is not included", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "gpuType", + "description": "gpu_type is filter with pods resources, when value is * search all", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/preferredresources": { + "get": { + "operationId": "Cluster_ListClusterPreferredResources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterPreferredResourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespaced", + "description": "namespaced indicates whether this resource is cluster or namespace scoped.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/publicmetric": { + "post": { + "operationId": "insight_QueryPublicUsage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1MetricResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Name of the cluster where the workload is located", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "title": "Name of the namespace where the workload is located" + }, + "param": { + "$ref": "#/definitions/v1alpha1BatchQueryRequestParam", + "title": "The parameters of query request" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "queryList": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "insight" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/publicmetricrange": { + "post": { + "operationId": "insight_QueryPublicRangeUsage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1MetricRangeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Name of the cluster where the workload is located", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "title": "Name of the namespace where the workload is located" + }, + "param": { + "$ref": "#/definitions/v1alpha1BatchQueryRangeRequestParam", + "title": "The parameters of query request" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "queryList": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "insight" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/replicasets": { + "get": { + "summary": "ListClusterReplicaSets lists replicasets of a cluster", + "operationId": "Apps_ListClusterReplicaSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterReplicaSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified replicaset belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "PageSize is the data number per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is used for query.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/secrets": { + "get": { + "summary": "ListClusterSecrets lists a secret in a specific cluster", + "operationId": "Core_ListClusterSecrets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterSecretsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the secret belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "The name use to search specific secret", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "type", + "description": "Type is used to filter secrets by type.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "onlyMetadata", + "description": "OnlyMetadata lists only metadata of secrets, default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/serviceaccounts": { + "get": { + "summary": "ListNamespaces gets all the namespaces across clusters", + "operationId": "Core_ListServiceAccounts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListServiceAccountsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of sa to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namesapce", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/serviceaccounts/{name}": { + "put": { + "summary": "UpdateServiceAccount updates a sa from the system by given sa name", + "operationId": "Core_UpdateServiceAccount", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateServiceAccountResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of ServiceAccount to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of ServiceAccount to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "Namespace is the metadata.namespace of the referenced pod.\nThis field is required in all cases." + }, + "data": { + "type": "string", + "title": "The data is the ServiceAccount YAML details" + } + }, + "description": "UpdateServiceAccount represents the request of update ServiceAccount in the cluster." + } + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/services": { + "get": { + "summary": "ListClusterServices lists all services in the specified cluster, regardless\nof namespace", + "operationId": "Core_ListClusterServices", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterServicesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster the specified service belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the service list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the service list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "name", + "description": "Name is used for query.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "type", + "description": "Type is a array used for frontend filter.\nUse examples: type=CLUSTER_IP&type=NODE_PORT\n\n - SERVICE_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - ClusterIP: ClusterIP means a service will only be accessible inside the cluster, via\nthe cluster IP.\n - NodePort: NodePort means a service will be exposed on one port of every node, in\naddition to 'ClusterIP' type.\n - LoadBalancer: LoadBalancer means a service will be exposed via an external load balancer\n(if the cloud provider supports it), in addition to 'NodePort' type.\n - ExternalName: ExternalName means a service consists of only a reference to an external\nname that kubedns or equivalent will return as a CNAME record, with no\nexposing or proxying of any pods involved.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string", + "enum": [ + "SERVICE_TYPE_UNSPECIFIED", + "ClusterIP", + "NodePort", + "LoadBalancer", + "ExternalName" + ] + }, + "collectionFormat": "multi" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "ports", + "description": "Ports is used to filter by port.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "integer", + "format": "int32" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/settings": { + "get": { + "summary": "Gets the setting under a given cluster.", + "operationId": "ClusterSetting_GetClusterSetting", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterSetting" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster name of the clustersetting.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "ClusterSetting" + ] + }, + "put": { + "summary": "UpdateClusterSetting will update the cluster setting and returns the settings\nafter updating.", + "operationId": "ClusterSetting_UpdateClusterSetting", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ClusterSetting" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "one of cluster or kubeSystemID has value", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "settings": { + "$ref": "#/definitions/v1alpha1ClusterSetting" + } + } + } + } + ], + "tags": [ + "ClusterSetting" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/gpu": { + "get": { + "operationId": "ClusterSetting_ListGPUSetting", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListGPUSettingResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster name of the clustersetting.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "availableEnable", + "description": "if available_enable is true will return available gpu number\nif available_enable is false AvailableResource return nil", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "ClusterSetting" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/plugins": { + "get": { + "summary": "Lists plugins under a given cluster.", + "operationId": "ClusterSetting_ListPlugins", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListPluginsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster name of the clustersetting.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "ClusterSetting" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/plugins/{name}:disable": { + "post": { + "summary": "Disable a plugin so that it can be shown by the frontend.", + "operationId": "ClusterSetting_DisablePlugin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Plugin" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster name of the clustersetting.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the plugin which needs to disable.", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "PLUGIN_NAME_UNSPECIFIED", + "HPA", + "Insight", + "GPU", + "METALLB", + "Spiderpool", + "CustomMetrics", + "CronHPA", + "VPA", + "Hwameistor", + "Flannel", + "KubeOvn", + "OLM", + "EgressGateway", + "Snapshot", + "DRA" + ] + } + ], + "tags": [ + "ClusterSetting" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/plugins/{name}:enable": { + "post": { + "summary": "Enable a plugin so that it can be shown by the frontend.", + "operationId": "ClusterSetting_EnablePlugin", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Plugin" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "The cluster name of the clustersetting.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "The name of the plugin which needs to enable.", + "in": "path", + "required": true, + "type": "string", + "enum": [ + "PLUGIN_NAME_UNSPECIFIED", + "HPA", + "Insight", + "GPU", + "METALLB", + "Spiderpool", + "CustomMetrics", + "CronHPA", + "VPA", + "Hwameistor", + "Flannel", + "KubeOvn", + "OLM", + "EgressGateway", + "Snapshot", + "DRA" + ] + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "tags": [ + "ClusterSetting" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/sriovnodesresources": { + "get": { + "operationId": "Core_ListClusterSriovAllocatedResources", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterSriovAllocatedResourcesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Core" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/statefulsets": { + "get": { + "summary": "ListClusterStatefulSets lists one cluster all namespace's statefulsets", + "operationId": "Apps_ListClusterStatefulSets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListStatefulSetsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of Workload to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page is current page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size is the data number shown per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name represents the name of workloads to search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "phase", + "description": "Phase represents the phase of workloads to search\n\n - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED" + }, + { + "name": "sortBy", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Apps" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses": { + "get": { + "summary": "ListStorageClass list StorageClass in single cluster", + "operationId": "Storage_ListStorageClasses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListStorageClassesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "provisioner", + "description": "Provisioner is used for fuzzy search by provisioner.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "reclaimPolicy", + "description": "ReclaimPolicy is used for fuzzy search by reclaimPolicy.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + }, + "post": { + "summary": "CreateStorageClass", + "operationId": "Storage_CreateStorageClass", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateStorageClassResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents the cluster of StorageClass to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "description": "CreateStorageClassRequest represents the request of create StorageClass in the cluster." + } + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses/{name}": { + "get": { + "summary": "GetStorageClass get StorageClass in single cluster", + "operationId": "Storage_GetStorageClass", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1StorageClass" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of StorageClass to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + }, + "delete": { + "summary": "DeleteStorageClass", + "operationId": "Storage_DeleteStorageClass", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the StorageClass belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "Name represents the name of StorageClass", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + }, + "put": { + "summary": "UpdateStorageClass update storage class", + "operationId": "Storage_UpdateStorageClass", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UpdateStorageClassResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the cluster of StorageClass to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of StorageClass to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "description": "UpdateStorageClassRequest represents the request of update StorageClass in the cluster." + } + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses/{name}/json": { + "get": { + "summary": "GetStorageClassJSON get StorageClass json in single cluster", + "operationId": "Storage_GetStorageClassJSON", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetStorageClassJSONResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of PVC to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "description": "name represents the name of StorageClass to belongs to.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}/volumesnapshots": { + "get": { + "summary": "ListClusterVolumeSnapshots will list all VolumeSnapshot by given cluster and regardless of\nnamespaces", + "operationId": "Storage_ListClusterVolumeSnapshots", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterVolumeSnapshotsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents the name of VolumeSnapshot to belongs to.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "name", + "description": "Name is used for filter.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "labelSelector", + "description": "LabelSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fieldSelector", + "description": "FieldSelector is the format after labels.FormatLabels used to filter", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Storage" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}:bind": { + "post": { + "operationId": "Workspace_BindClusterToWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1BindClusterToWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "workspaceAlias": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{cluster}:unbind": { + "delete": { + "operationId": "Workspace_UnBindClusterFromWorkspace", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1UnBindClusterFromWorkspaceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "workspaceId": { + "type": "integer", + "format": "int32" + }, + "workspaceAlias": { + "type": "string" + } + } + } + } + ], + "tags": [ + "Workspace" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{name}": { + "get": { + "summary": "GetCluster gets the details of the specified kpanda cr", + "operationId": "Cluster_GetCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1Cluster" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "Name is the user-specified identifier.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "status", + "description": "Status represents the current state of cluster.", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "sortBy", + "description": "SortBy determines the list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "excludeMetrics", + "description": "exclude_metrics\nIf false, contains metrics-related information\nIf true, metrics-related information is not included", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Cluster" + ] + }, + "delete": { + "summary": "DeleteCluster deletes the specified cluster", + "operationId": "Cluster_DeleteCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "properties": {} + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "deleteKpandaNamespace": { + "type": "boolean", + "description": "DeleteKpandaNamespace represents whether to delete namespace of kpanda." + }, + "deleteInsightAgent": { + "type": "boolean", + "title": "DeleteInsightAgent represents whether to delete insight agent server.``" + } + }, + "description": "DeleteClusterRequest returns clusters information." + } + } + ], + "tags": [ + "Cluster" + ] + }, + "put": { + "summary": "UpdateClusters updates a cluster by cluster name", + "operationId": "Cluster_UpdateClusters", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateOrUpdateClusterResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "aliasName": { + "type": "string", + "description": "It is an alias given by the user and can be changed at will. It cannot be\nempty." + }, + "provider": { + "$ref": "#/definitions/v1alpha1ClusterProvider", + "description": "Provider represents the cloud provider name of the member cluster." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations to attach arbitrary metadata to objects." + }, + "describe": { + "type": "string", + "description": "Describe represents the details of the member cluster." + }, + "region": { + "type": "string", + "description": "Region represents the region of the member cluster locate in." + }, + "zone": { + "type": "string", + "description": "Zone represents the zone of the member cluster locate in." + }, + "kubeConfigString": { + "type": "string", + "description": "KubeConfig of the cluster." + } + }, + "description": "UpdateClusterRequest requests to update a cluster." + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{name}/labels": { + "put": { + "summary": "EditClusterLabels edits the specified cluster's labels", + "operationId": "Cluster_EditClusterLabels", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1EditClusterLabelsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + } + }, + "description": "EditClusterLabelsRequest returns true when pod termination has been\nrequested." + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clusters/{name}/validate": { + "post": { + "summary": "ValidateCluster checks if residuals which affect integrating exist in a cluster", + "operationId": "Cluster_ValidateCluster", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ValidateClusterResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "unjoinCluster": { + "type": "boolean", + "description": "JoinCluster represents whther the request is to join cluster.\nif true, the kube_config_string is required param, otherwise, the name is required." + }, + "kubeConfigString": { + "type": "string", + "description": "KubeConfig of the cluster." + } + }, + "description": "ValidateClusterRequest requests to check if residuals which affect integrating exist in a cluster." + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/clustersummary": { + "get": { + "summary": "listClusterSummary lists cluster summary", + "operationId": "Cluster_ListClusterSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListClusterSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "showVirtualCluster", + "description": "ShowVirtualCluster is used to control whether returned data contains\nvirtualCluster. Default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "filterByStrategy", + "description": "FilterByStrategy is to list all the clusters without strategies if true, default false.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "filterBySnapshot", + "description": "FilterBySnapshot is to list all the clusters which has snapshot if true, default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/etcdbackuprestore/strategies": { + "get": { + "summary": "ListEtcdBackupStrategies list etcd backup strategies.", + "operationId": "EtcdBackupRestore_ListEtcdBackupStrategies", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListEtcdBackupStrategiesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "cluster represents which cluster the repository belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "description": "Name is the user-specified identifier.\nThis field may not be updated.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "sortBy", + "description": "SortBy determines the repository list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED" + }, + { + "name": "sortDir", + "description": "OrderBy determines the repository list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + } + ], + "tags": [ + "EtcdBackupRestore" + ] + } + }, + "/apis/kpanda.io/v1alpha1/featuregates": { + "get": { + "operationId": "FeatureGate_ListFeatureGates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListFeatureGatesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "FeatureGate" + ] + } + }, + "/apis/kpanda.io/v1alpha1/globalroles": { + "get": { + "operationId": "Workspace_ListGlobalRolesForCurrentUser", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListGlobalRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Workspace" + ] + } + }, + "/apis/kpanda.io/v1alpha1/gpus": { + "get": { + "summary": "ListClusters lists kpanda cr resources", + "operationId": "Cluster_ListAllClusterGPU", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAllClusterGPUInfoResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/kubesystemid/{kubeSystemID}/clustercert": { + "post": { + "summary": "CreateOpenAPIClusterCertByKubeSystemID creates openAPI cluster cert by\nkubeSystemID", + "operationId": "Cluster_CreateOpenAPIClusterCertByKubeSystemID", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1CreateOpenAPIClusterCertResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "kubeSystemID", + "description": "kubeSystemID is the cluster system ID.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "title": "one of cluster or kubeSystemID has value" + }, + "expirationSeconds": { + "type": "integer", + "format": "int32", + "description": "ExpirationSeconds is the requested duration of validity of the request." + } + } + } + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registries": { + "get": { + "summary": "ListRegistries returns a list of registries", + "operationId": "Image_ListRegistries", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRegistriesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "global", + "description": "Global is to list all global registries.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "public", + "description": "Public is distinguish public images and private images.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by registry name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registries/kangaroo": { + "get": { + "summary": "DetectKangaroo returns whether the kangaroo is installed.", + "operationId": "Image_DetectKangaroo", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1DetectKangarooResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Image" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registries/{registry}/projects": { + "get": { + "summary": "ListProjects returns a list of projects of specified registry", + "operationId": "Image_ListProjects", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListProjectsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "registry", + "description": "Registry is registry name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "public", + "description": "Public is distinguish public projects and private projects.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by project name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registries/{registry}/repositories": { + "get": { + "summary": "ListRepositories returns a list of image names of specified project", + "operationId": "Image_ListRepositories", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListRepositoriesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "registry", + "description": "Registry is registry name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "project", + "description": "Project is the project to request, \"/\" is a possible value.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "public", + "description": "Public is distinguish public images and private images.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "showArtifacts", + "description": "ShowArtifacts is to list artifacts of per image, default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registries/{registry}/repositories/{repository}/artifacts": { + "get": { + "summary": "ListArtifacts returns a list of tags of specified image", + "operationId": "Image_ListArtifacts", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListArtifactsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "registry", + "description": "Registry is registry name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "repository", + "description": "Repository is image name.", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "project", + "description": "Project is the project to request.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "public", + "description": "Public is distinguish public images and private images.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "fuzzyTagName", + "description": "FuzzyTagName is used to fuzzy search by tag name.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registry/tags": { + "get": { + "operationId": "Registry_ListImageTags", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListImageTagsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster presents the cluster of dockeconfig belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace presents the namespace of dockeconfig belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "secret", + "description": "Secret is the name of dockeconfig.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "image", + "description": "Image is the name of repository which needs verify.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "registryHost", + "description": "The registry host which the repository belongs to.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Registry" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registry/verify": { + "post": { + "operationId": "Registry_VerifyRegistry", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1VerifyRegistryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/v1alpha1VerifyRegistryRequest" + } + } + ], + "tags": [ + "Registry" + ] + } + }, + "/apis/kpanda.io/v1alpha1/registry/verifyImage": { + "get": { + "operationId": "Registry_VerifyImage", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1VerifyImageResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster presents the cluster of dockeconfig belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace presents the namespace of dockeconfig belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "secret", + "description": "Secret is the name of dockeconfig.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "image", + "description": "Image is the name of repository which needs to list tags.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "registryHost", + "description": "The registry host which the repository belongs to.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Registry" + ] + } + }, + "/apis/kpanda.io/v1alpha1/rolesummary": { + "get": { + "summary": "ListAllUserRoleSummary lists user role summary", + "operationId": "RBAC_ListAllUserRoleSummary", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListAllUserRoleSummaryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster represents which cluster the roleBinding belongs to.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace represents which namespace the roleBinding belongs to.", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "RBAC" + ] + } + }, + "/apis/kpanda.io/v1alpha1/settings/gpu": { + "get": { + "operationId": "SettingService_GPUSetting", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GPUSettingResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "SettingService" + ] + } + }, + "/apis/kpanda.io/v1alpha1/workspaces": { + "get": { + "operationId": "Workspace_ListWorkspaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1ListWorkspacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Workspace" + ] + } + }, + "/apis/kpanda.io/v1alpha1/workspaces/{workspaceId}/workspacesharedresourcequota": { + "get": { + "operationId": "Workspace_GetWorkspaceResourceQuotaAllocatable", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1GetWorkspaceSharedResourceQuotaResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "workspaceId", + "in": "path", + "required": true, + "type": "integer", + "format": "int32" + }, + { + "name": "workspaceAlias", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "cluster", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Workspace" + ] + } + } + }, + "definitions": { + "CalicoConfigCalicoIptablesBackendType": { + "type": "string", + "enum": [ + "CALICO_IPTABLES_BACKEND_TYPE_UNSPECIFIED", + "NFT", + "Auto", + "Legacy" + ], + "default": "CALICO_IPTABLES_BACKEND_TYPE_UNSPECIFIED" + }, + "CalicoConfigCalicoTunnel": { + "type": "string", + "enum": [ + "CALICO_TUNNEL_UNSPECIFIED", + "IPIP", + "IPIPCrossSubnet", + "VXLAN", + "VXLANCrossSubnet" + ], + "default": "CALICO_TUNNEL_UNSPECIFIED" + }, + "CommonNetworkConfigKubeProxyMode": { + "type": "string", + "enum": [ + "KUBE_PROXY_MODE_UNSPECIFIED", + "iptables", + "ipvs" + ], + "default": "KUBE_PROXY_MODE_UNSPECIFIED" + }, + "ContainerResourcePolicyContainerScalingMode": { + "type": "string", + "enum": [ + "CONTAINER_SCALING_MODE_UNSPECIFIED", + "Auto", + "Off" + ], + "default": "CONTAINER_SCALING_MODE_UNSPECIFIED", + "description": "ContainerScalingMode controls whether autoscaler is enabled for a specific\ncontainer.\n\n - CONTAINER_SCALING_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Auto: ContainerScalingModeAuto means autoscaling is enabled for a container.\n - Off: ContainerScalingModeOff means autoscaling is disabled for a container." + }, + "CronJobStatusCronJobCondition": { + "type": "object", + "properties": { + "jobName": { + "type": "string", + "description": "The name of job." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current condition of job." + } + }, + "description": "Current condition of cronjob." + }, + "CronJobStatusCronJobState": { + "type": "string", + "enum": [ + "CRONJOB_STATE_UNSPECIFIED", + "Waiting", + "Activated", + "Stopped", + "Deleting" + ], + "default": "CRONJOB_STATE_UNSPECIFIED", + "description": "Current state of a cron job.\n\n - CRONJOB_STATE_UNSPECIFIED: CronJob is unspecified.\n - Waiting: Waiting for cronjob ready.\n - Activated: The number of pending and running pods.\n - Stopped: CronJob has stopped.\n - Deleting: CronJob is being deleted." + }, + "CustomMetricValueDescribedObject": { + "type": "object", + "properties": { + "kind": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "name": { + "type": "string" + }, + "apiVersion": { + "type": "string" + } + }, + "title": "a reference to the described object" + }, + "CustomResourceDefinitionSpecResourceScope": { + "type": "string", + "enum": [ + "RESOURCE_SCOPE_UNSPECIFIED", + "NAMESPACED", + "CLUSTER" + ], + "default": "RESOURCE_SCOPE_UNSPECIFIED", + "description": "- RESOURCE_SCOPE_UNSPECIFIED: ResourceScope is unspecified\n - NAMESPACED: Represents which namespace the belongs to.\n - CLUSTER: Cluster the specified belongs to.", + "title": "ResourceScope is an enum defining the different scopes available to a\ncustom resource" + }, + "EtcdBackupStrategySpecEtcdBackupType": { + "type": "string", + "enum": [ + "BACKUP_TYPE_UNSPECIFIED", + "Manual", + "Timing" + ], + "default": "BACKUP_TYPE_UNSPECIFIED", + "description": " - BACKUP_TYPE_UNSPECIFIED: Backup strategy type is unspecified." + }, + "FlannelConfigBackendType": { + "type": "string", + "enum": [ + "BACKEND_TYPE_UNSPECIFIED", + "VXLAN", + "HostGateway", + "WireGuard" + ], + "default": "BACKEND_TYPE_UNSPECIFIED" + }, + "GetHelmChartResourcesResponseResources": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "image": { + "type": "string" + } + } + }, + "GetPodContainerLogResponseData": { + "type": "object", + "properties": { + "log": { + "type": "string", + "title": "the log of the pod container's log" + }, + "timeStamp": { + "type": "string", + "title": "the time stamp the pod container's log" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "the labels of log" + } + }, + "title": "the data of log" + }, + "KubeOvnConfigNetworkType": { + "type": "string", + "enum": [ + "NETWORK_TYPE_UNSPECIFIED", + "GENEVE", + "VLAN" + ], + "default": "NETWORK_TYPE_UNSPECIFIED", + "title": "- GENEVE: geneve means that the network mode is overlay\n - VLAN: vlan means that the network mode is underlay" + }, + "KubesprayArgsRuntime": { + "type": "string", + "enum": [ + "RUNTIME_UNSPECIFIED", + "containerd", + "docker" + ], + "default": "RUNTIME_UNSPECIFIED", + "description": "Container runtime\ndocker for docker, crio for cri-o and containerd for containerd.\nAdditionally you can set this to kubeadm if you want to install etcd using kubeadm\nKubeadm etcd deployment is experimental and only available for new deployments\nIf this is not set, container manager will be inherited from the Kubespray defaults\nand not from k8s_cluster/k8s-cluster.yml, which might not be what you want.\nAlso this makes possible to use different container manager for etcd nodes." + }, + "ListClusterNamespaceSummaryResponseScope": { + "type": "string", + "enum": [ + "SCOPE_UNSPECIFIED", + "Cluster", + "Namespaced" + ], + "default": "SCOPE_UNSPECIFIED", + "description": "Scope is an enum defining the different scopes available to the namespaces.\nAllowed values are `Cluster` and `Namespaced`." + }, + "ListClusterlcmOpsRequestAction": { + "type": "string", + "enum": [ + "ACTION_UNSPECIFIED", + "CREATE_CLUSTER", + "UPGRADE_CLUSTER", + "RESET_CLUSTER", + "ADD_NODE", + "REMOVE_NODE" + ], + "default": "ACTION_UNSPECIFIED" + }, + "ListHelmChartsResponseCategoryItem": { + "type": "object", + "properties": { + "othersNums": { + "type": "integer", + "format": "int32" + }, + "storageNums": { + "type": "integer", + "format": "int32" + }, + "networkNums": { + "type": "integer", + "format": "int32" + }, + "monitorNums": { + "type": "integer", + "format": "int32" + }, + "databaseNums": { + "type": "integer", + "format": "int32" + }, + "dataServiceNums": { + "type": "integer", + "format": "int32" + }, + "infraNums": { + "type": "integer", + "format": "int32" + }, + "securityNums": { + "type": "integer", + "format": "int32" + }, + "ecoappNums": { + "type": "integer", + "format": "int32" + }, + "bigdataNums": { + "type": "integer", + "format": "int32" + }, + "iotedgeNums": { + "type": "integer", + "format": "int32" + } + } + }, + "ListRuntimeVersionsResponsePreferredVersion": { + "type": "object", + "properties": { + "containerdVersion": { + "type": "string", + "title": "The recommended containerd_version" + }, + "dockerVersion": { + "type": "string", + "title": "The recommended docker_version" + } + } + }, + "NetworkConfigCNI": { + "type": "string", + "enum": [ + "CNI_UNSPECIFIED", + "calico", + "cilium", + "flannel", + "kube_ovn", + "none" + ], + "default": "CNI_UNSPECIFIED" + }, + "NetworkPolicySpecPolicyType": { + "type": "string", + "enum": [ + "POLICY_TYPE_UNSPECIFIED", + "Ingress", + "Egress" + ], + "default": "POLICY_TYPE_UNSPECIFIED", + "description": "- POLICY_TYPE_UNSPECIFIED: Placeholder to avoid zero not return.\n - Ingress: PolicyTypeIngress is a NetworkPolicy that affects ingress traffic on selected pods.\n - Egress: PolicyTypeEgress is a NetworkPolicy that affects egress traffic on selected pods.", + "title": "PolicyType string describes the NetworkPolicy type\nThis type is beta-level in 1.8" + }, + "PatchCustomResourceRequestPatchType": { + "type": "string", + "enum": [ + "PATCH_TYPE_UNSPECIFIED", + "PATCH_TYPE_JSON", + "PATCH_TYPE_MERGE", + "PATCH_TYPE_STRATEGIC_MERGE", + "PATCH_TYPE_APPLY" + ], + "default": "PATCH_TYPE_UNSPECIFIED" + }, + "PersistentVolumeClaimSpecVolumeMode": { + "type": "string", + "enum": [ + "VOLUME_MODE_UNSPECIFIED", + "Block", + "Filesystem" + ], + "default": "VOLUME_MODE_UNSPECIFIED", + "description": " - Block: PersistentVolumeBlock means the volume will not be formatted with a filesystem and will remain a raw block device.\n - Filesystem: PersistentVolumeFilesystem means the volume will be or is formatted with a filesystem." + }, + "PodStatusOwnedBy": { + "type": "object", + "properties": { + "kind": { + "$ref": "#/definitions/PodStatusOwnedByKind", + "description": "The kind of pod." + }, + "name": { + "type": "string", + "title": "Name is the related workload name" + } + }, + "title": "OwnedBy states which workload the pod belongs to" + }, + "PodStatusOwnedByKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "DEPLOYMENT", + "STATEFULSET", + "DAEMONSET", + "REPLICASET", + "JOB", + "CRONJOB" + ], + "default": "KIND_UNSPECIFIED", + "description": "- KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - DEPLOYMENT: A Deployment provides declarative updates for Pods and ReplicaSets.\n - STATEFULSET: StatefulSet is the workload API object used to manage stateful\napplications.\n - DAEMONSET: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod.\n - REPLICASET: A pod's owner replicaSet\n - JOB: A pod's owner job\n - CRONJOB: A pod's owner cronjob", + "title": "Kind includes deployment, statefulset, daemonset" + }, + "RepoSpecSecretReference": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "description": "namespace is the namespace for the resource being referenced." + }, + "name": { + "type": "string", + "description": "name is the name of resource being referenced." + } + } + }, + "SnapStoreConfigSnapStoreProvider": { + "type": "string", + "enum": [ + "SNAP_STORE_PROVIDER_UNSPECIFIED", + "Local", + "S3" + ], + "default": "SNAP_STORE_PROVIDER_UNSPECIFIED", + "description": " - SNAP_STORE_PROVIDER_UNSPECIFIED: Snap Store Provider is unspecified.\n - Local: Local is constant for local disk storage provider.\n - S3: S3 is constant for aws S3 storage provider." + }, + "SnapshotterConfigGarbageCollectingPolicy": { + "type": "string", + "enum": [ + "ETCD_BACKUP_TYPE_UNSPECIFIED", + "Exponential", + "LimitBased" + ], + "default": "ETCD_BACKUP_TYPE_UNSPECIFIED", + "description": "- ETCD_BACKUP_TYPE_UNSPECIFIED: etcd backup type is unspecified.\n - Exponential: Exponential policy stores the snapshots in a condensed manner as mentioned below:\nAll full backups and delta backups for the previous hour.\nLatest full snapshot of each previous hour for the day.\nLatest full snapshot of each previous day for 7 days.\nLatest full snapshot of the previous 4 weeks\n - LimitBased: If using LimitBased policy, the max-backups flag should be provided to indicate the\nnumber of recent-most backups to persist at each garbage collection cycle.", + "title": "garbage_collection_policy Policy for garbage collecting old backups" + }, + "StorageClassReclaimPolicy": { + "type": "string", + "enum": [ + "RECLAIM_AOLICY_UNSPECIFIED", + "Delete", + "Retain" + ], + "default": "RECLAIM_AOLICY_UNSPECIFIED", + "description": " - Delete: PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim.\nThe volume plugin must support Deletion.\n - Retain: PersistentVolumeReclaimRetain means the volume will be left in its current phase (Released) for manual reclamation by the administrator.\nThe default policy is Retain." + }, + "StorageClassVolumeBindingMode": { + "type": "string", + "enum": [ + "VOLUME_BINDING_MODE_UNSPECIFIED", + "Immediate", + "WaitForFirstConsumer" + ], + "default": "VOLUME_BINDING_MODE_UNSPECIFIED", + "description": " - Immediate: VolumeBindingImmediate indicates that PersistentVolumeClaims should be\nimmediately provisioned and bound. This is the default mode.\n - WaitForFirstConsumer: VolumeBindingWaitForFirstConsumer indicates that PersistentVolumeClaims\nshould not be provisioned and bound until the first Pod is created that\nreferences the PeristentVolumeClaim. The volume provisioning and\nbinding will occur during Pod scheduing." + }, + "apicloudshellv1alpha1LocalSecretReference": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name is the name of resource being referenced." + } + }, + "description": "LocalSecretReference is a reference to a secret within the enclosing\nnamespace." + }, + "apiclustersv1alpha1ClusterRole": { + "type": "string", + "enum": [ + "CLUSTER_ROLE_UNSPECIFIED", + "CLUSTER_ROLE_MANAGER", + "CLUSTER_ROLE_GLOBAL_SERVICE", + "CLUSTER_ROLE_WORKER", + "CLUSTER_ROLE_THIRD_PARTY" + ], + "default": "CLUSTER_ROLE_UNSPECIFIED" + }, + "apiclustersv1alpha1LocalSecretReference": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name is the name of resource being referenced." + }, + "namespace": { + "type": "string", + "description": "Namespace is the namespace for the resource being referenced." + }, + "resourceVersion": { + "type": "string", + "description": "ResourceVersion is the version of resource being referenced." + } + }, + "title": "SecretRef represents the secret contains mandatory credentials to access the member cluster.\nThe secret should hold credentials as follows:\n- secret.data.token\n- secret.data.caBundle\n+optional" + }, + "apicorev1alpha1LoadBalancerIngress": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "title": "IP is set for load-balancer ingress points that are IP based\n(typically GCE or OpenStack load-balancers)" + }, + "hostname": { + "type": "string", + "title": "Hostname is set for load-balancer ingress points that are DNS based\n(typically AWS load-balancers)" + }, + "ports": { + "type": "array", + "items": { + "$ref": "#/definitions/apicorev1alpha1PortStatus" + }, + "title": "Ports is a list of records of service ports\nIf used, every port defined in the service should have an entry in it" + } + } + }, + "apicorev1alpha1LoadBalancerStatus": { + "type": "object", + "properties": { + "ingress": { + "type": "array", + "items": { + "$ref": "#/definitions/apicorev1alpha1LoadBalancerIngress" + }, + "description": "Ingress is a list containing ingress points for the load-balancer.\nTraffic intended for the service should be sent to these ingress points." + } + }, + "description": "LoadBalancerStatus represents the status of a load-balancer." + }, + "apicorev1alpha1PortStatus": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "format": "int32", + "title": "Port is the port number of the service port of which status is recorded here" + }, + "protocol": { + "type": "string", + "title": "Protocol is the protocol of the service port of which status is recorded here\nThe supported values are: \"TCP\", \"UDP\", \"SCTP\"" + }, + "error": { + "type": "string", + "description": "Error is to record the problem with the service port\nThe format of the error shall comply with the following rules:\n - built-in error values shall be specified in this file and those shall use\n CamelCase names\n - cloud provider specific error values must have names that comply with the\n format foo.example.com/CamelCase." + } + }, + "title": "PortStatus represents the error condition of a service port" + }, + "apicorev1alpha1TypedLocalObjectReference": { + "type": "object", + "properties": { + "apiGroup": { + "type": "string", + "description": "APIGroup is the group for the resource being referenced.\nIf APIGroup is not specified, the specified Kind must be in the core API group.\nFor any other third-party types, APIGroup is required." + }, + "kind": { + "type": "string", + "description": "Kind is the type of resource being referenced." + }, + "name": { + "type": "string", + "description": "Name is the name of resource being referenced." + } + }, + "description": "TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace." + }, + "apinetworkingv1alpha1LoadBalancerIngress": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "description": "IP is set for load-balancer ingress points that are IP based." + }, + "hostname": { + "type": "string", + "description": "Hostname is set for load-balancer ingress points that are DNS based." + }, + "ports": { + "type": "array", + "items": { + "$ref": "#/definitions/apinetworkingv1alpha1PortStatus" + }, + "description": "Ports is a list of records of service ports.\nIf used, every port defined in the service should have an entry in it." + } + }, + "description": "LoadBalancerIngress represents the status of a load-balancer ingress point:\ntraffic intended for the service should be sent to an ingress point." + }, + "apinetworkingv1alpha1LoadBalancerStatus": { + "type": "object", + "properties": { + "ingress": { + "type": "array", + "items": { + "$ref": "#/definitions/apinetworkingv1alpha1LoadBalancerIngress" + }, + "description": "Ingress is a list containing ingress points for the load-balancer.\nTraffic intended for the service should be sent to these ingress points." + } + }, + "title": "LoadBalancerStatus represents the status of a load-balancer" + }, + "apinetworkingv1alpha1PortStatus": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "format": "int32", + "description": "Port is the port number of the service port of which status is recorded." + }, + "error": { + "type": "string", + "description": "Error is to record the problem with the service port." + }, + "protocol": { + "$ref": "#/definitions/v1alpha1Protocol", + "description": "Protocol is the protocol of the service port of which status is recorded." + } + }, + "title": "PortStatus represents the error condition of a service port" + }, + "apinetworkingv1alpha1TypedLocalObjectReference": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name is the name of resource being referenced." + }, + "kind": { + "type": "string", + "description": "Kind is the type of resource being referenced." + }, + "apiGroup": { + "type": "string", + "description": "APIGroup is the group for the resource being referenced.\nIf APIGroup is not specified, the specified Kind must be in the core API\ngroup. For any other third-party types, APIGroup is required." + } + }, + "description": "TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace." + }, + "apirbacv1alpha1ClusterRole": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PolicyRule" + }, + "title": "Rules holds all the PolicyRules for this ClusterRole" + }, + "aggregationRule": { + "$ref": "#/definitions/v1alpha1AggregationRule", + "title": "AggregationRule is an optional field that describes how to build the Rules for this ClusterRole.\nIf AggregationRule is set, then the Rules are controller managed and direct changes to Rules will be\nstomped by the controller.\n+optional" + } + }, + "description": "ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding." + }, + "clusterlcmv1alpha1Phase": { + "type": "string", + "enum": [ + "STATUS_UNSPECIFIED", + "Running", + "Succeeded", + "Failed", + "Blocked" + ], + "default": "STATUS_UNSPECIFIED" + }, + "googlerpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics." + } + }, + "additionalProperties": {}, + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(&foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := &pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := &pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": ,\n \"lastName\": \n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" + }, + "rbacv1alpha1Role": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PolicyRule" + }, + "title": "Rules holds all the PolicyRules for this Role" + } + }, + "description": "Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding." + }, + "typesCondition": { + "type": "object", + "properties": { + "lastTransitionTime": { + "type": "string", + "title": "Last time the condition transitioned from one status to another.\n+optional" + }, + "lastUpdateTime": { + "type": "string", + "title": "Last time we got an update on a given condition.\n+optional" + }, + "message": { + "type": "string", + "title": "A human readable message indicating details about the transition.\n+optional" + }, + "reason": { + "type": "string", + "title": "The reason for the condition's last transition.\n+optional" + }, + "status": { + "type": "string", + "description": "Status of the condition, one of True, False, Unknown." + }, + "type": { + "type": "string", + "description": "Type of condition." + } + }, + "description": "Condition describes the state of a referent at a certain point." + }, + "typesConditionStatus": { + "type": "string", + "enum": [ + "CONDITION_STATUS_UNSPECIFIED", + "True", + "False", + "Unknown" + ], + "default": "CONDITION_STATUS_UNSPECIFIED", + "description": "These are valid condition statuses.\n\n - CONDITION_STATUS_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - True: True means a resource is in the condition.\n - False: False means a resource is not in the condition.\n - Unknown: Unknown means kubernetes can't decide if a resource is in the condition or\nnot." + }, + "typesLabelSelector": { + "type": "object", + "properties": { + "matchLabels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "matchLabels is a map of {key,value} pairs. A single {key,value} in the\nmatchLabels map is equivalent to an element of matchExpressions, whose key\nfield is \"key\", the operator is \"In\", and the values array contains only\n\"value\". The requirements are ANDed. +optional" + }, + "matchExpressions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesLabelSelectorRequirement" + }, + "title": "matchExpressions is a list of label selector requirements. The requirements\nare ANDed. +optional" + } + }, + "description": "A label selector is a label query over a set of resources. The result of\nmatchLabels and matchExpressions are ANDed. An empty label selector matches\nall objects. A null label selector matches no objects." + }, + "typesLabelSelectorRequirement": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "key is the label key that the selector applies to." + }, + "operator": { + "type": "string", + "description": "operator represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists and DoesNotExist." + }, + "values": { + "type": "array", + "items": { + "type": "string" + }, + "title": "values is an array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or\nDoesNotExist, the values array must be empty. This array is replaced during\na strategic merge patch. +optional" + } + }, + "description": "A label selector requirement is a selector that contains values, a key, and\nan operator that relates the key and values." + }, + "typesObjectMeta": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name must be unique within a namespace. Is required when creating\nresources, although some resources may allow a client to request the\ngeneration of an appropriate name automatically. Name is primarily intended\nfor creation idempotence and configuration definition. Cannot be updated.\nMore info: http://kubernetes.io/docs/identifiers#names\n+optional" + }, + "namespace": { + "type": "string", + "description": "Namespace defines the space within each name must be unique. An empty\nnamespace is equivalent to the \"default\" namespace, but \"default\" is the\ncanonical representation. Not all objects are required to be scoped to a\nnamespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL.\nCannot be updated.\nMore info: http://kubernetes.io/docs/namespaces\n+optional" + }, + "uid": { + "type": "string", + "description": "UID is the unique in time and space value for this object. It is typically\ngenerated by the server on successful creation of a resource and is not\nallowed to change on PUT operations.\n\nPopulated by the system.\nRead-only.\nMore info: http://kubernetes.io/docs/identifiers#uids\n+optional" + }, + "resourceVersion": { + "type": "string", + "description": "An opaque value that represents the internal version of this object that\ncan be used by clients to determine when objects have changed. May be used\nfor optimistic concurrency, change detection, and the watch operation on a\nresource or set of resources. Clients must treat these values as opaque and\npassed unmodified back to the server. They may only be valid for a\nparticular resource or set of resources.\n\nPopulated by the system.\nRead-only.\nValue must be treated as opaque by clients and .\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency" + }, + "creationTimestamp": { + "type": "string", + "format": "int64", + "description": "CreationTimestamp is a timestamp representing the server time when this\nobject was created. It is not guaranteed to be set in happens-before order\nacross separate operations. Clients may not set this value. It is\nrepresented in RFC3339 form and is in UTC.\n\nPopulated by the system.\nRead-only.\nNull for lists.\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n+optional" + }, + "deletionTimestamp": { + "type": "string", + "format": "int64", + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be\ndeleted. This field is set by the server when a graceful deletion is\nrequested by the user, and is not directly settable by a client. The\nresource is expected to be deleted (no longer visible from resource lists,\nand not reachable by name) after the time in this field, once the\nfinalizers list is empty. As long as the finalizers list contains items,\ndeletion is blocked. Once the deletionTimestamp is set, this value may not\nbe unset or be set further into the future, although it may be shortened or\nthe resource may be deleted prior to this time. For example, a user may\nrequest that a pod is deleted in 30 seconds. The kubelet will react by\nsending a graceful termination signal to the containers in the pod. After\nthat 30 seconds, the kubelet will send a hard termination signal (SIGKILL)\nto the container and after cleanup, remove the pod from the API. In the\npresence of network partitions, this object may still exist after this\ntimestamp, until an administrator or automated process can determine the\nresource is fully terminated.\nIf not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested.\nRead-only.\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n+optional" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Map of string keys and values that can be used to organize and categorize\n(scope and select) objects. May match selectors of replication controllers\nand services.\nMore info: http://kubernetes.io/docs/labels\n+optional" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Annotations is an unstructured key value map stored with a resource that\nmay be set by external tools to store and retrieve arbitrary metadata. They\nare not queryable and should be preserved when modifying objects. More\ninfo: http://kubernetes.io/docs/annotations +optional" + }, + "ownerReferences": { + "type": "array", + "items": { + "$ref": "#/definitions/typesOwnerReference" + }, + "title": "List of objects depended by this object. If ALL objects in the list have\nbeen deleted, this object will be garbage collected. If this object is\nmanaged by a controller, then an entry in this list will point to this\ncontroller, with the controller field set to true. There cannot be more\nthan one managing controller. +optional +patchMergeKey=uid\n+patchStrategy=merge" + }, + "cluster": { + "type": "string", + "description": "The name of the cluster which the object belongs to.\nThis is used to distinguish resources with same name and namespace in\ndifferent clusters. This field is not set anywhere right now and apiserver\nis going to ignore it if set in create or update request." + }, + "workspaceAlias": { + "type": "string", + "description": "The name of the workspace which the object belongs to.\nThis is used to distinguish resources with same name and namespace in\ndifferent workspaces. This field is not set anywhere right now and\napiserver is going to ignore it if set in create or update request." + } + }, + "description": "ObjectMeta is metadata that all persisted resources must have, which includes\nall objects users must create." + }, + "typesOwnerReference": { + "type": "object", + "properties": { + "uid": { + "type": "string", + "title": "UID of the referent.\nMore info: http://kubernetes.io/docs/identifiers#uids" + }, + "controller": { + "type": "boolean", + "title": "If true, this reference points to the managing controller.\n+optional" + }, + "name": { + "type": "string", + "description": "Name of the referent." + }, + "kind": { + "type": "string", + "description": "Kind of the referent." + }, + "apiVersion": { + "type": "string", + "description": "API version of the referent." + }, + "blockOwnerDeletion": { + "type": "boolean", + "title": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then\nthe owner cannot be deleted from the key-value store until this\nreference is removed.\n+optional" + } + }, + "description": "OwnerReference contains enough information to let you identify an owning\nobject. An owning object must be in the same namespace as the dependent, or\nbe cluster-scoped, so there is no namespace field." + }, + "typesPagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32", + "description": "Total is the total number of referents." + }, + "page": { + "type": "integer", + "format": "int32", + "description": "Page is current page." + }, + "pageSize": { + "type": "integer", + "format": "int32", + "description": "PageSize is the data number shown per page." + }, + "pages": { + "type": "integer", + "format": "int32", + "description": "Pages is the number of pages." + } + }, + "description": "Pagination is for data paging." + }, + "typesRollingUpdate": { + "type": "object", + "properties": { + "maxSurge": { + "type": "string", + "title": "The maximum number of pods that can be scheduled above the desired number\nof pods. Value can be an absolute number (ex: 5) or a percentage of desired\npods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number\nis calculated from percentage by rounding up. Defaults to 25%. Example:\nwhen this is set to 30%, the new ReplicaSet can be scaled up immediately\nwhen the rolling update starts, such that the total number of old and new\npods do not exceed 130% of desired pods. Once old pods have been killed,\nnew ReplicaSet can be scaled up further, ensuring that total number of pods\nrunning at any time during the update is at most 130% of desired pods.\n+optional" + }, + "maxUnavailable": { + "type": "string", + "title": "The maximum number of pods that can be unavailable during the update.\nValue can be an absolute number (ex: 5) or a percentage of desired pods\n(ex: 10%). Absolute number is calculated from percentage by rounding down.\nThis can not be 0 if MaxSurge is 0.\nDefaults to 25%.\nExample: when this is set to 30%, the old ReplicaSet can be scaled down to\n70% of desired pods immediately when the rolling update starts. Once new\npods are ready, old ReplicaSet can be scaled down further, followed by\nscaling up the new ReplicaSet, ensuring that the total number of pods\navailable at all times during the update is at least 70% of desired pods.\n+optional" + } + }, + "description": "Spec to control the desired behavior of rolling update." + }, + "typesSortBy": { + "type": "string", + "enum": [ + "SORT_BY_UNSPECIFIED", + "field_name", + "state", + "workspace", + "cluster", + "namespace", + "created_at" + ], + "default": "SORT_BY_UNSPECIFIED", + "description": "SortBy determines the data list order reference.\n\n - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting.\n - field_name: Sort result by name.\n - state: TODO: Sort result by state not supported yet.\n - workspace: TODO: Sort result by workspace not supported yet.\n - cluster: Sort result by cluster name.\n - namespace: Sort result by namespace.\n - created_at: Sort result by creationTimestamp." + }, + "typesSortDir": { + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc", + "description": "SortDir determines the data list order.\n\n - desc: Desc stands for descending order.\n - asc: Asc stands for ascending order." + }, + "typesUpdateStrategy": { + "type": "object", + "properties": { + "rollingUpdate": { + "$ref": "#/definitions/typesRollingUpdate", + "title": "RollingUpdate is used to communicate parameters when Type is\nRollingUpdateType. +optional" + }, + "type": { + "type": "string", + "title": "Type indicates the type of the UpdateStrategy.\n+optional" + } + }, + "description": "UpdateStrategy indicates the strategy that the controller\nwill use to perform updates. It includes any additional parameters necessary\nto perform the update for the indicated strategy." + }, + "typesWorkloadState": { + "type": "string", + "enum": [ + "WORKLOAD_STATE_UNSPECIFIED", + "Running", + "Deleting", + "Not_Ready", + "Stopped", + "Waiting" + ], + "default": "WORKLOAD_STATE_UNSPECIFIED", + "description": "- WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return.\n - Running: Running shows the referent is available.\n - Deleting: Deleting is when the referent will be deleted.\n - Not_Ready: NotReady shows the referent is unavailable.\n - Stopped: Stopped indicates that the referent has 0 ready pods.\n - Waiting: Waiting indicates that the referent is paused.", + "title": "WorkloadState describes the state of\nworkload(deployments/daemonsets/statefulsets)" + }, + "v1alpha1APIResource": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "name is the plural name of the resource." + }, + "namespaced": { + "type": "boolean", + "description": "namespaced indicates if a resource is namespaced or not." + }, + "group": { + "type": "string", + "description": "group is the preferred group of the resource. Empty implies the group of the containing resource list.\nFor subresources, this may have a different value, for example: Scale\"." + }, + "version": { + "type": "string", + "description": "version is the preferred version of the resource. Empty implies the version of the containing resource list\nFor subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)\"." + }, + "kind": { + "type": "string", + "title": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')" + } + }, + "description": "Resource specifies the name of a resource and whether it is namespaced." + }, + "v1alpha1APIResourceList": { + "type": "object", + "properties": { + "groupVersion": { + "type": "string", + "description": "groupVersion is the group and version this APIResourceList is for." + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1APIResource" + }, + "description": "resources contains the name of the resources and if they are namespaced." + } + }, + "description": "APIResourceList is a list of APIResource, it is used to expose the name of the\nresources supported in a specific group and version, and if the resource\nis namespaced." + }, + "v1alpha1ActionType": { + "type": "string", + "enum": [ + "ACTION_TYPE_UNSPECIFIED", + "playbook", + "shell" + ], + "default": "ACTION_TYPE_UNSPECIFIED" + }, + "v1alpha1AddonInfo": { + "type": "object", + "properties": { + "repoUrl": { + "type": "string", + "title": "Repository url" + }, + "addons": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CreateHelmReleaseRequest" + }, + "title": "Chart info" + } + } + }, + "v1alpha1AddonSetting": { + "type": "object", + "properties": { + "helmOperationHistoryLimit": { + "type": "integer", + "format": "int32", + "description": "The OperationHistoryLimit info in the cluster." + }, + "helmRepoRefreshInterval": { + "type": "integer", + "format": "int32", + "title": "The frequency of helm repos' auto refresh.(Unit: time.Second)" + }, + "helmOperationBaseImage": { + "type": "string", + "title": "The frequency of helm repos'" + }, + "enableHelmRepoRefresh": { + "type": "boolean", + "description": "EnableHelmRepoRefresh is to control whether to auto refresh all the helm repos in the cluster." + }, + "helmOperationJobTemplateResources": { + "$ref": "#/definitions/v1alpha1ResourceRequirements" + }, + "helmOperationTimeoutSecond": { + "type": "string", + "format": "int64", + "description": "HelmOperationTimeoutSecond is the time limit of installing/uninstalling a helmrelease, unit: second." + } + } + }, + "v1alpha1Affinity": { + "type": "object", + "properties": { + "nodeAffinity": { + "$ref": "#/definitions/v1alpha1NodeAffinity", + "title": "Describes node affinity scheduling rules for the pod.\n+optional" + }, + "podAffinity": { + "$ref": "#/definitions/v1alpha1PodAffinity", + "title": "Describes pod affinity scheduling rules (e.g. co-locate this pod in the\nsame node, zone, etc. as some other pod(s)). +optional" + }, + "podAntiAffinity": { + "$ref": "#/definitions/v1alpha1PodAffinity", + "title": "Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod\nin the same node, zone, etc. as some other pod(s)). +optional" + } + }, + "description": "Affinity is a group of affinity scheduling rules." + }, + "v1alpha1AggregationRule": { + "type": "object", + "properties": { + "clusterRoleSelectors": { + "type": "array", + "items": { + "$ref": "#/definitions/typesLabelSelector" + }, + "title": "ClusterRoleSelectors holds a list of selectors which will be used to find ClusterRoles and create the rules.\nIf any of the selectors match, then the ClusterRole's permissions will be added" + } + }, + "title": "AggregationRule describes how to locate ClusterRoles to aggregate into the ClusterRole" + }, + "v1alpha1AllocatedResource": { + "type": "object", + "properties": { + "resourceName": { + "type": "string", + "title": "the name of the node sriov resource" + }, + "value": { + "type": "string", + "title": "the maximum allocation for this resource" + } + } + }, + "v1alpha1Artifact": { + "type": "object", + "properties": { + "digest": { + "type": "string", + "description": "Digest is artifact digest." + }, + "tags": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Tag" + }, + "description": "Tags is a list of tags." + }, + "imageSize": { + "type": "string", + "format": "int64", + "description": "Size of artifact. Unit: byte. 1024 GenericBinary." + }, + "pushTime": { + "type": "string", + "format": "int64", + "description": "First push time." + } + }, + "title": "Artifact is the concept of harbor artifact" + }, + "v1alpha1AvailableResource": { + "type": "object", + "properties": { + "available": { + "type": "string", + "format": "int64", + "title": "if error_message is not null, available is -1" + }, + "errorMessage": { + "type": "string" + } + } + }, + "v1alpha1BatchBindNodeToNamespaceResponse": { + "type": "object", + "properties": { + "successfulResults": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1BindNodeToNamespaceResult" + }, + "description": "SuccessfulResults is the node list which\nsuccessfully bound with the namespace." + }, + "failedResults": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1BindNodeToNamespaceResult" + }, + "description": "FailedResults is the node list which\nbound with the namespace failed." + }, + "nsError": { + "type": "string", + "description": "NsError is the error message for the namespace update at the end." + } + }, + "description": "BatchBindNodeToNamespaceResponse is the response for node batch bind namespaces." + }, + "v1alpha1BatchQueryRangeRequestParam": { + "type": "object", + "properties": { + "start": { + "type": "string", + "format": "int64", + "title": "Time of start of query" + }, + "end": { + "type": "string", + "format": "int64", + "title": "Time of end of query" + }, + "step": { + "type": "number", + "format": "double", + "title": "Interval of query" + } + }, + "title": "The parameters of batch queryRangeRequest" + }, + "v1alpha1BatchQueryRangeResult": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1PrometheusQueryRangeResult", + "title": "The dat of prometheus query range result" + }, + "status": { + "$ref": "#/definitions/v1alpha1requestStatus", + "title": "The request status" + }, + "errorMessage": { + "type": "string", + "title": "The error message returned" + } + }, + "title": "The result of batch query range" + }, + "v1alpha1BatchQueryRequestParam": { + "type": "object", + "properties": { + "time": { + "type": "string", + "format": "int64", + "title": "Time of query" + } + }, + "title": "The parameters of batch query request" + }, + "v1alpha1BatchQueryResult": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/v1alpha1PrometheusQueryResult", + "title": "The data of prometheus query result" + }, + "status": { + "$ref": "#/definitions/v1alpha1requestStatus", + "title": "The status of request" + }, + "errorMessage": { + "type": "string", + "title": "The error message returned" + } + }, + "title": "The result of batch query" + }, + "v1alpha1BindClusterToWorkspaceResponse": { + "type": "object" + }, + "v1alpha1BindNodeToNamespaceResult": { + "type": "object", + "properties": { + "nodeName": { + "type": "string", + "description": "NodeName is the name of the node." + }, + "error": { + "type": "string", + "description": "Error is the error detail for binding,\nIf there are no mistakes, the error message will be empty." + } + }, + "description": "BindNodeToNamespaceResult is the result for node batch bind namespaces." + }, + "v1alpha1BindResourceToWorkspaceResponse": { + "type": "object" + }, + "v1alpha1CalicoAutoDetectionMethod": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1CalicoAutoDetectionMethodType" + }, + "value": { + "type": "string" + } + } + }, + "v1alpha1CalicoAutoDetectionMethodType": { + "type": "string", + "enum": [ + "TYPE_UNSPECIFIED", + "FIRST_FOUND", + "KUBERNETES_INTERNAL_IP", + "CAN_REACH", + "INTERFACE_REGEX", + "SKIP_INTERFACE" + ], + "default": "TYPE_UNSPECIFIED" + }, + "v1alpha1CalicoConfig": { + "type": "object", + "properties": { + "autoDetectionMethod": { + "$ref": "#/definitions/v1alpha1CalicoAutoDetectionMethod" + }, + "ipv4Tunnel": { + "$ref": "#/definitions/CalicoConfigCalicoTunnel" + }, + "ipv6Tunnel": { + "$ref": "#/definitions/CalicoConfigCalicoTunnel" + }, + "iptablesBackend": { + "$ref": "#/definitions/CalicoConfigCalicoIptablesBackendType" + } + } + }, + "v1alpha1Category": { + "type": "string", + "enum": [ + "CATEGORY_UNSPECIFIED", + "CATEGORY_OTHERS", + "CATEGORY_STORAGE", + "CATEGORY_NETWORKING", + "CATEGORY_MONITORING", + "CATEGORY_DATABASE", + "CATEGORY_DATASERVICE", + "CATEGORY_ECOAPP", + "CATEGORY_BIGDATA", + "CATEGORY_SECURITY", + "CATEGORY_IOTEDGE", + "CATEGORY_INFRA" + ], + "default": "CATEGORY_UNSPECIFIED", + "description": " - CATEGORY_UNSPECIFIED: The Category is unspecified." + }, + "v1alpha1CheckClusterResponse": { + "type": "object", + "properties": { + "available": { + "type": "boolean" + }, + "errMsg": { + "type": "string" + } + } + }, + "v1alpha1CiliumConfig": { + "type": "object", + "properties": { + "extraVars": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "var1: \"value1\"\n var2: \"value2\"", + "title": "A dictionary of extra config variables to add to cilium-config, formatted like:\ncilium_config_extra_vars:" + } + } + }, + "v1alpha1CloudShell": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1CloudShellSpec", + "description": "CloudShellSpec defines the desired state of CloudShell." + }, + "status": { + "$ref": "#/definitions/v1alpha1CloudShellStatus", + "description": "CloudShellStatus defines the observed state of CloudShell." + } + }, + "description": "CloudShell is the Schema for the cloudshells API." + }, + "v1alpha1CloudShellSpec": { + "type": "object", + "properties": { + "secretRef": { + "$ref": "#/definitions/apicloudshellv1alpha1LocalSecretReference", + "title": "SecretRef represents the secret contains mandatory credentials to access the target cluster.\nThe secret should hold credentials as follows:\n- secret.data.token\n- secret.data.caBundle\nThe field is alpha phase, please open the featuregate AllowSecretStoreKubeconfig to use it.\n+optional" + }, + "once": { + "type": "boolean", + "title": "accept only one client and exit on disconnection" + }, + "commandAction": { + "type": "string", + "description": "command action specified a initialized command to cloudshell server." + }, + "ttl": { + "type": "integer", + "format": "int32", + "description": "ttl specified a period time that the cloudshell server pod is\nstop. if not to set, default 500s." + }, + "cleanup": { + "type": "boolean", + "description": "cleanup specified whether to delete cloudshell resources when\ncorresponding job status is completed." + } + }, + "description": "CloudShellSpec defines the desired state of CloudShell." + }, + "v1alpha1CloudShellStatus": { + "type": "object", + "properties": { + "phase": { + "type": "string", + "description": "phase specified status of cloudshell server." + }, + "accessUrl": { + "type": "string", + "description": "access url is be set to expose cloudshell server." + } + }, + "title": "CloudShellStatus defines the observed state of CloudShell.enum" + }, + "v1alpha1CloudShellType": { + "type": "string", + "enum": [ + "CLOUD_SHELL_TYPE_UNSPECIFIED", + "bash", + "exec", + "logs", + "upload", + "download" + ], + "default": "CLOUD_SHELL_TYPE_UNSPECIFIED", + "description": "CloudShellType defines the cloudshell command type (exec, logs, bash)." + }, + "v1alpha1Cluster": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1ClusterSpec", + "description": "ClusterSpec describes how the cluster execution will look like and when it\nwill actually run." + }, + "status": { + "$ref": "#/definitions/v1alpha1ClusterStatus", + "description": "ClusterStatus contains the cluster status. The ClusterStatus will be stored\nin the kubeadm-config ConfigMap in the cluster, and then updated by kubeadm\nwhen additional control plane instance joins or leaves the cluster." + } + } + }, + "v1alpha1ClusterKubeConfigSetting": { + "type": "object", + "properties": { + "expireWarningThreshold": { + "type": "string", + "format": "int64", + "title": "Set the expire warning threshold for cluster kubeConfig.(Unit: day)" + } + } + }, + "v1alpha1ClusterPhase": { + "type": "string", + "enum": [ + "CLUSTER_PHASE_UNSPECIFIED", + "Unknown", + "Creating", + "Running", + "Updating", + "Deleting", + "Failed", + "DeleteFailed" + ], + "default": "CLUSTER_PHASE_UNSPECIFIED", + "description": " - CLUSTER_PHASE_UNSPECIFIED: The cluster state is unspecified.\n - Unknown: The cluster state is unknown.\n - Creating: The cluster is being created.\n - Running: The cluster is running.\n - Updating: The cluster is updating.\n - Deleting: The cluster is being deleted.\n - Failed: The cluster create failed.\n - DeleteFailed: The cluster delete failed." + }, + "v1alpha1ClusterProvider": { + "type": "string", + "enum": [ + "GENERIC", + "DAOCLOUD_KUBESPRAY", + "DAOCLOUD_CLUSTER_API", + "DAOCLOUD_DCE4", + "REDHAT_OPENSHIFT4", + "SUSE_RANCHER", + "VMWARE_TANZU", + "AWS_EKS", + "ALIYUN_ACK", + "TENCENT_TKE", + "HUAWEI_CCE", + "MICROSOFT_AZURE", + "K3S", + "Oracle_OKE" + ], + "default": "GENERIC", + "description": " - GENERIC: Generic\nGENERIC indicates other providers\n - DAOCLOUD_KUBESPRAY: DaoCloud\nDAOCLOUD_KUBESPRAY indicates a provider of DaoCloud's KubeSpray Engine\n - DAOCLOUD_CLUSTER_API: DAOCLOUD_CLUSTER_API indicates a provider of DaoCloud's Cluster API Engine\n - DAOCLOUD_DCE4: DAOCLOUD_DCE4 indicates a provider of DaoCloud's DCE4 Engine\n - REDHAT_OPENSHIFT4: OverSea Distribtion\nREDHAT_OPENSHIFT4 indicates a provider of RedHat Openshift4\n - SUSE_RANCHER: SUSE_RANCHER indicates a provider of SUSE Rancher\n - VMWARE_TANZU: VMWARE_TANZU indicates a provider of VMware Tanzu\n - AWS_EKS: Public Cloud\nAWS_EKS indicates a provider of AWS EKS\n - ALIYUN_ACK: ALIYUN_ACK indicates a provider of Aliyun ACK\n - TENCENT_TKE: TENCENT_TKE indicates a provider of Tencent TKE.\n - HUAWEI_CCE: TENCENT_TKE indicates a provider of Huawei CCE.\n - MICROSOFT_AZURE: MICROSOFT_AZURE=11; indicates a provider of Microsoft Azure.\n - K3S: RANCHER_K3S=12; indicates a provider of k3s.\n - Oracle_OKE: Oracle_OKE=13; indicates a provider of Oracle OKE." + }, + "v1alpha1ClusterResourceOverride": { + "type": "object", + "properties": { + "memoryRequestToLimitPercent": { + "type": "integer", + "format": "int32", + "description": "MemoryRequestToLimitPercent (if > 0) overrides memory request to a percentage of memory limit." + }, + "cpuRequestToLimitPercent": { + "type": "integer", + "format": "int32", + "description": "CPURequestToLimitPercent (if > 0) overrides CPU request to a percentage of CPU limit." + } + }, + "description": "ClusterResourceOverride is the Schema for the ClusterResourceOverride API." + }, + "v1alpha1ClusterResourceSummary": { + "type": "object", + "properties": { + "allocatable": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Allocatable represents the resources of a cluster that are available for scheduling.\nTotal amount of allocatable resources on all nodes.\n+optional" + }, + "allocated": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Allocated represents the resources of a cluster that have been scheduled.\nTotal amount of required resources of all Pods that have been scheduled to nodes.\n+optional" + } + } + }, + "v1alpha1ClusterRoleBinding": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "subjects": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Subject" + }, + "description": "Subjects holds references to the objects the role applies to." + }, + "roleRef": { + "$ref": "#/definitions/v1alpha1RoleRef", + "description": "RoleRef can reference a Role in the current namespace or a ClusterRole in\nthe global namespace." + } + } + }, + "v1alpha1ClusterSetting": { + "type": "object", + "properties": { + "plugins": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Plugin" + }, + "description": "The plugins info in the cluster." + }, + "network": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Plugin" + }, + "description": "The network plugins info in the cluster." + }, + "addonSetting": { + "$ref": "#/definitions/v1alpha1AddonSetting", + "description": "The settings of addon." + }, + "clusterlcmSetting": { + "$ref": "#/definitions/v1alpha1ClusterlcmSetting", + "description": "The settings of cl." + }, + "etcdBackupRestoreSetting": { + "$ref": "#/definitions/v1alpha1EtcdBackupRestoreSetting", + "description": "The setting for etcdbackuprestore." + }, + "kubeanSetting": { + "$ref": "#/definitions/v1alpha1KubeanSetting", + "description": "The setting for kubean." + }, + "clusterKubeconfigSetting": { + "$ref": "#/definitions/v1alpha1ClusterKubeConfigSetting", + "title": "The setting for ClusterKubeConfig" + } + }, + "title": "setting of the cluster" + }, + "v1alpha1ClusterSettings": { + "type": "object", + "properties": { + "dkgClusterName": { + "type": "string", + "description": "The name of the manger cluster." + }, + "clusterName": { + "type": "string", + "description": "The name of the cluster which needs to be create." + }, + "aliasName": { + "type": "string", + "description": "It is an alias given by the user and can be changed at will." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations to attach arbitrary metadata to objects." + }, + "describe": { + "type": "string", + "description": "describe represents the details of the cluster." + }, + "region": { + "type": "string" + }, + "zone": { + "type": "string" + }, + "kubesprayArgs": { + "$ref": "#/definitions/v1alpha1KubesprayArgs", + "description": "The Parameters for creating a cluster by kubespray." + }, + "preinstallAddons": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1AddonInfo" + }, + "title": "addon info selected by the user" + } + } + }, + "v1alpha1ClusterSpec": { + "type": "object", + "properties": { + "provider": { + "$ref": "#/definitions/v1alpha1ClusterProvider", + "description": "Provider represents the cloud provider name of the member cluster." + }, + "apiEndpoint": { + "type": "string", + "description": "The API endpoint of the member cluster. This can be a hostname,\nhostname:port, IP or IP:port." + }, + "region": { + "type": "string", + "description": "Region represents the region of the member cluster locate in." + }, + "zone": { + "type": "string", + "description": "Zone represents the zone of the member cluster locate in." + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/apiclustersv1alpha1ClusterRole" + }, + "description": "Roles represents the roles of cluster." + }, + "managedBy": { + "type": "string", + "description": "ManagedBy is used for worker cluster to show\ncluster is controlled by." + }, + "aliasName": { + "type": "string", + "description": "AliasName represents the alias of the cluster." + }, + "secretRef": { + "$ref": "#/definitions/apiclustersv1alpha1LocalSecretReference", + "description": "SecretRef represents the secret contains mandatory credentials to access the member cluster." + }, + "proxyUrl": { + "type": "string", + "description": "ProxyURL is the proxy URL for the cluster.\nIf not empty, the kpanda control plane will use this proxy to talk to the cluster." + } + } + }, + "v1alpha1ClusterStatus": { + "type": "object", + "properties": { + "kubernetesVersion": { + "type": "string", + "description": "KubernetesVersion represents version of the member cluster." + }, + "kubeSystemID": { + "type": "string", + "description": "KubeSystemId represents the uuid of sub cluster kube-system namespace." + }, + "clusterVersion": { + "type": "string", + "description": "ClusterVersion represents the version of the member cluster." + }, + "serviceCIDR": { + "type": "string", + "description": "ServiceCIDR represents the service network CIDR." + }, + "clusterCIDR": { + "type": "string", + "description": "ClusterCIDR represents the Cluster CIDR." + }, + "phase": { + "$ref": "#/definitions/v1alpha1ClusterPhase", + "description": "Condition represents the status of the member cluster." + }, + "proxyMode": { + "type": "string", + "description": "ProxyMode represents the kube-proxy mode of the member cluster." + }, + "deploymentSummary": { + "$ref": "#/definitions/v1alpha1ResourceSummary", + "description": "ResourceSummary represents the deployment of the member cluster." + }, + "daemonsetSummary": { + "$ref": "#/definitions/v1alpha1ResourceSummary", + "description": "ResourceSummary represents the daemonset of the member cluster." + }, + "statefulsetSummary": { + "$ref": "#/definitions/v1alpha1ResourceSummary", + "description": "ResourceSummary represents the statefulset of the member cluster." + }, + "nodeSummary": { + "$ref": "#/definitions/v1alpha1ResourceSummary", + "description": "ResourceSummary represents the node of the member cluster." + }, + "podSummary": { + "$ref": "#/definitions/v1alpha1ResourceSummary", + "description": "ResourceSummary represents the pod of the member cluster." + }, + "resourceSummary": { + "$ref": "#/definitions/v1alpha1ClusterResourceSummary", + "description": "ResourceSummary represents the resource of the member cluster." + }, + "cpuUsage": { + "type": "number", + "format": "double", + "description": "The cpu usage of the member cluster." + }, + "memoryUsage": { + "type": "number", + "format": "double", + "description": "The memory usage of the member cluster." + }, + "gpuTotal": { + "type": "integer", + "format": "int32" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current condition of cluster." + }, + "settings": { + "$ref": "#/definitions/v1alpha1ClusterSetting" + }, + "networkMode": { + "type": "array", + "items": { + "type": "string" + }, + "title": "NetworkMode represents the cluster's network mode" + }, + "maxSigningDuration": { + "type": "number", + "format": "double" + }, + "kubeconfigExpireWarnning": { + "type": "boolean" + }, + "kubeconfigExpireTime": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1ClusterStreamResponse": { + "type": "object", + "properties": { + "message": { + "$ref": "#/definitions/v1alpha1Message" + }, + "cluster": { + "$ref": "#/definitions/v1alpha1Cluster" + } + } + }, + "v1alpha1ClusterSummary": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of cluster." + }, + "phase": { + "$ref": "#/definitions/v1alpha1ClusterPhase" + }, + "kubeSystemID": { + "type": "string", + "description": "kubeSystemID is the cluster system ID." + } + } + }, + "v1alpha1ClusterlcmOps": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1ClusterlcmOpsSpec", + "description": "ClusterSpec defines the desired state of a member cluster." + }, + "status": { + "$ref": "#/definitions/v1alpha1ClusterlcmOpsStatus" + } + } + }, + "v1alpha1ClusterlcmOpsSpec": { + "type": "object", + "properties": { + "kuBeanCluster": { + "type": "string", + "title": "KuBeanCluster the name of KuBeanCluster.\n+required" + }, + "actionType": { + "$ref": "#/definitions/v1alpha1ActionType" + }, + "action": { + "type": "string" + }, + "image": { + "type": "string" + } + }, + "description": "ClusterSpec defines the desired state of a member cluster." + }, + "v1alpha1ClusterlcmOpsStatus": { + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "jobRef": { + "$ref": "#/definitions/v1alpha1JobRef" + }, + "phase": { + "$ref": "#/definitions/clusterlcmv1alpha1Phase" + }, + "startTime": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1ClusterlcmResponse": { + "type": "object", + "properties": { + "clusterName": { + "type": "string" + }, + "dkgClusterName": { + "type": "string" + }, + "opsRef": { + "$ref": "#/definitions/v1alpha1ClusterlcmOps" + } + }, + "description": "KuBeanClusterOps is the result of the operation after the cluster changes." + }, + "v1alpha1ClusterlcmSetting": { + "type": "object", + "properties": { + "enableLocalService": { + "type": "boolean", + "description": "enable_local_service controlled whether to use the\nlocal repo source when creating the cluster." + }, + "enableDeletionProtection": { + "type": "boolean", + "description": "enable_deletion_protection controlled whether the cluster\ncan use the reset function." + } + } + }, + "v1alpha1CommonNetworkConfig": { + "type": "object", + "properties": { + "podIPv4CIDR": { + "type": "string", + "title": "podIPv4CIDR is the pod ipv4 CIDR.s" + }, + "serviceIPv4CIDR": { + "type": "string" + }, + "kubeProxyMode": { + "$ref": "#/definitions/CommonNetworkConfigKubeProxyMode" + }, + "enableVip": { + "type": "boolean" + }, + "kubeVipAddr": { + "type": "string" + }, + "kubeVipLbEnable": { + "type": "boolean" + }, + "podIPv6CIDR": { + "type": "string" + }, + "serviceIPv6CIDR": { + "type": "string" + }, + "enableDualStack": { + "type": "boolean" + } + } + }, + "v1alpha1ConfigMap": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "immutable": { + "type": "boolean", + "title": "Immutable, if set to true, ensures that data stored in the ConfigMap cannot\nbe updated (only object metadata can be modified).\nIf not set to true, the field can be modified at any time.\nDefaulted to nil.\n+optional" + }, + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Data contains the configuration data.\nEach key must consist of alphanumeric characters, '-', '_' or '.'.\nValues with non-UTF-8 byte sequences must use the BinaryData field.\nThe keys stored in Data must not overlap with the keys in\nthe BinaryData field, this is enforced during validation process.\n+optional" + }, + "binaryData": { + "type": "object", + "additionalProperties": { + "type": "string", + "format": "byte" + }, + "title": "BinaryData contains the binary data.\nEach key must consist of alphanumeric characters, '-', '_' or '.'.\nBinaryData can contain byte sequences that are not in the UTF-8 range.\nThe keys stored in BinaryData must not overlap with the ones in\nthe Data field, this is enforced during validation process.\nUsing this field will require 1.10+ apiserver and\nkubelet.\n+optional" + } + }, + "description": "ConfigMap holds configuration data for pods to consume." + }, + "v1alpha1ConfigMapEnvSource": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This must match the Name of a Volume." + }, + "optional": { + "type": "boolean" + } + }, + "description": "ConfigMapEnvSource selects a ConfigMap to populate the environment\nvariables with.\nThe contents of the target ConfigMap's Data field will represent the\nkey-value pairs as environment variables." + }, + "v1alpha1ConfigMapKeySelector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The ConfigMap to select from." + }, + "key": { + "type": "string", + "description": "The key to select." + }, + "optional": { + "type": "boolean", + "title": "Specify whether the ConfigMap or its key must be defined\n+optional" + } + }, + "description": "ConfigMapKeySelector selects a key from a ConfigMap." + }, + "v1alpha1ConfigMapVolumeSource": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1KeyToPath" + }, + "title": "If unspecified, each key-value pair in the Data field of the referenced\nConfigMap will be projected into the volume as a file whose name is the\nkey and content is the value. If specified, the listed keys will be\nprojected into the specified paths, and unlisted keys will not be\npresent. If a key is specified which is not present in the ConfigMap,\nthe volume setup will error unless it is marked optional. Paths must be\nrelative and may not contain the '..' path or start with '..'.\n+optional" + }, + "defaultMode": { + "type": "integer", + "format": "int32", + "title": "Optional: mode bits used to set permissions on created files by default.\nMust be an octal value between 0000 and 0777 or a decimal value between 0\nand 511. YAML accepts both octal and decimal values, JSON requires decimal\nvalues for mode bits. Defaults to 0644. Directories within the path are not\naffected by this setting. This might be in conflict with other options that\naffect the file mode, like fsGroup, and the result can be other mode bits\nset. +optional" + }, + "optional": { + "type": "boolean", + "title": "Specify whether the ConfigMap or its keys must be defined\n+optional" + } + }, + "description": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a\nvolume as files using the keys in the Data field as the file names, unless\nthe items element is populated with specific mappings of keys to paths.\nConfigMap volumes support ownership management and SELinux relabeling." + }, + "v1alpha1Container": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of Container." + }, + "image": { + "type": "string", + "description": "The used image of Container." + }, + "command": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The container command." + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "workingDir": { + "type": "string" + }, + "ports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Ports" + } + }, + "envFrom": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1EnvFromSource" + }, + "title": "EnvFromSource represents the source of a set of ConfigMaps" + }, + "env": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1EnvVar" + }, + "description": "EnvVar represents an environment variable present in a Container." + }, + "resources": { + "$ref": "#/definitions/v1alpha1ResourceRequirements", + "description": "Source represents a source for the value of an EnvVar." + }, + "volumeMounts": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VolumeMount" + }, + "description": "VolumeMount describes a mounting of a Volume within a container." + }, + "livenessProbe": { + "$ref": "#/definitions/v1alpha1Probe", + "description": "Liveness probe is aimed to help in situarions where fluentd\nsilently hangs for no apparent reasons until manual restart.\nThe idea of this probe is that if fluentd is not queueing or\nflushing chunks for 5 minutes, something is not right. If\nyou want to change the fluentd configuration, reducing amount of\nlogs fluentd collects, consider changing the threshold or turning\nliveness probe off completely." + }, + "readinessProbe": { + "$ref": "#/definitions/v1alpha1Probe", + "description": "Readiness updates the cached pod status with the given readiness, and\ntriggers a status update." + }, + "startupProbe": { + "$ref": "#/definitions/v1alpha1Probe", + "description": "Startup updates the cached container status with the given startup, and\ntriggers a status update." + }, + "lifecycle": { + "$ref": "#/definitions/v1alpha1Lifecycle", + "description": "The life cycle of a Container." + }, + "imagePullPolicy": { + "type": "string", + "description": "Pull image policy." + }, + "securityContext": { + "$ref": "#/definitions/v1alpha1SecurityContext", + "description": "SecurityContext holds security attributes." + } + } + }, + "v1alpha1ContainerControlledValues": { + "type": "string", + "enum": [ + "CONTAINER_CONTROLLED_VALUES_UNSPECIFIED", + "RequestsAndLimits", + "RequestsOnly" + ], + "default": "CONTAINER_CONTROLLED_VALUES_UNSPECIFIED", + "description": "ContainerControlledValues controls which resource value should be autoscaled.\n\n - CONTAINER_CONTROLLED_VALUES_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - RequestsAndLimits: ContainerControlledValuesRequestsAndLimits means resource request and limits\nare scaled automatically. The limit is scaled proportionally to the request.\n - RequestsOnly: ContainerControlledValuesRequestsOnly means only requested resource is autoscaled." + }, + "v1alpha1ContainerResourcePolicy": { + "type": "object", + "properties": { + "containerName": { + "type": "string", + "description": "Name of the container or DefaultContainerResourcePolicy, in which\ncase the policy is used by the containers that don't have their own\npolicy specified." + }, + "mode": { + "$ref": "#/definitions/ContainerResourcePolicyContainerScalingMode", + "description": "Whether autoscaler is enabled for the container. The default is \"Auto\"." + }, + "minAllowed": { + "$ref": "#/definitions/v1alpha1ResourceList", + "description": "Specifies the minimal amount of resources that will be recommended\nfor the container. The default is no minimum." + }, + "maxAllowed": { + "$ref": "#/definitions/v1alpha1ResourceList", + "description": "Specifies the maximum amount of resources that will be recommended\nfor the container. The default is no maximum." + }, + "controlledResources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceName" + }, + "description": "Specifies the type of recommendations that will be computed\n(and possibly applied) by VPA.\nIf not specified, the default of [ResourceCPU, ResourceMemory] will be used." + }, + "controlleValues": { + "$ref": "#/definitions/v1alpha1ContainerControlledValues", + "description": "Specifies which resource values should be controlled.\nThe default is \"RequestsAndLimits\"." + } + }, + "description": "ContainerResourcePolicy controls how autoscaler computes the recommended\nresources for a specific container." + }, + "v1alpha1ContainerState": { + "type": "object", + "properties": { + "waiting": { + "$ref": "#/definitions/v1alpha1ContainerStateWaiting", + "description": "ContainerStateWaiting is a waiting state of a container." + }, + "running": { + "$ref": "#/definitions/v1alpha1ContainerStateRunning", + "description": "ContainerStateRunning indicates a currently running container." + }, + "terminated": { + "$ref": "#/definitions/v1alpha1ContainerStateTerminated", + "description": "ContainerStateTerminated indicates a container that ran and completed\n(\"stopped\" in other contexts, although a created container is technically\nalso \"stopped\")." + } + } + }, + "v1alpha1ContainerStateRunning": { + "type": "object", + "properties": { + "startedAt": { + "type": "string", + "format": "int64" + } + }, + "description": "ContainerStateRunning indicates a currently running container." + }, + "v1alpha1ContainerStateTerminated": { + "type": "object", + "properties": { + "exitCode": { + "type": "integer", + "format": "int32", + "description": "Container exit code." + }, + "signal": { + "type": "integer", + "format": "int32", + "description": "Signal defines a signal that can trigger eviction of pods on a node." + }, + "reason": { + "type": "string", + "description": "The reason for the condition's last transition." + }, + "message": { + "type": "string", + "description": "The container terminated information." + }, + "startedAt": { + "type": "string", + "format": "int64", + "description": "The container created time." + }, + "finishedAt": { + "type": "string", + "format": "int64", + "description": "The container terminated time." + } + }, + "description": "ContainerStateExited indicates a container that ran\nand completed (\"stopped\" in other contexts, although a created container is\ntechnically also \"stopped\")." + }, + "v1alpha1ContainerStateWaiting": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "title": "(brief) reason the container is not yet running.\n+optional" + }, + "message": { + "type": "string", + "title": "Message regarding why the container is not yet running.\n+optional" + } + }, + "description": "ContainerStateWaiting represents 'Waiting' container state." + }, + "v1alpha1ContainerStatus": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This must be a DNS_LABEL. Each container in a pod must have a unique name.\nCannot be updated." + }, + "state": { + "$ref": "#/definitions/v1alpha1ContainerState", + "title": "Details about the container's current condition.\n+optional" + }, + "ready": { + "type": "boolean", + "description": "Specifies whether the container has passed its readiness probe." + }, + "restartCount": { + "type": "integer", + "format": "int32", + "description": "The number of times the container has been restarted, currently based on\nthe number of dead containers that have not yet been removed.\nNote that this is calculated from dead containers. But those containers are\nsubject to garbage collection. This value will get capped at 5 by GC." + }, + "image": { + "type": "string", + "title": "The image the container is running.\nMore info: https://kubernetes.io/docs/concepts/containers/images" + }, + "started": { + "type": "boolean", + "title": "Specifies whether the container has passed its startup probe.\nInitialized as false, becomes true after startupProbe is considered\nsuccessful. Resets to false when the container is restarted, or if kubelet\nloses state temporarily. Is always true when no startupProbe is defined.\n+optional" + }, + "phase": { + "$ref": "#/definitions/v1alpha1ContainerStatusPhase", + "description": "Phase represents the phase to search." + } + }, + "description": "ContainerStatus represents the container status." + }, + "v1alpha1ContainerStatusPhase": { + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Waiting", + "Running", + "Terminated" + ], + "default": "PHASE_UNSPECIFIED", + "description": "Phase represents the phase of the container.\n\n - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Waiting: Waiting is a waiting state of a pod.\n - Running: PodRunning means the pod has been bound to a node and all of the\ncontainers have been started. At least one container is still running or\nis in the process of being restarted. PodSucceeded means that all\ncontainers in the pod have voluntarily terminated with a container exit\ncode of 0, and the system is not going to restart any of these\ncontainers.\n - Terminated: Terminated indicates a pod that ran and completed\n(\"stopped\" in other contexts, although a created container is technically\nalso \"stopped\")." + }, + "v1alpha1ControlleRrevision": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "data": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "Data is the serialized representation of the state." + }, + "revision": { + "type": "string", + "format": "int64", + "description": "Revision indicates the revision of the state represented by Data." + } + } + }, + "v1alpha1CreateCloudShellRequest": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1CloudShellType", + "description": "type specified the cloudshell command type (exec, logs, bash)." + }, + "cluster": { + "type": "string", + "description": "cluster specified the cluster name for cloudshell." + }, + "namespace": { + "type": "string", + "description": "namespace defines the namespace of the specified pod." + }, + "podName": { + "type": "string", + "description": "pod_name defines the name of the specified pod." + }, + "filePath": { + "type": "string", + "description": "file_path defines the file path." + }, + "container": { + "type": "string", + "description": "container defines which container or init container to create cloud shell." + }, + "logCount": { + "type": "integer", + "format": "int32", + "description": "log_count defines the count of display logs." + }, + "data": { + "$ref": "#/definitions/v1alpha1CloudShell", + "description": "cloud_shell defines the data of cloud shell." + } + }, + "title": "CreateIngressResponse the response of create cluster ingresses" + }, + "v1alpha1CreateClusterCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "CreateClusterCustomResourceResponse represents response of creating one\nCustomResource of cluster scope" + }, + "v1alpha1CreateClusterRequest": { + "type": "object", + "properties": { + "dkgClusterName": { + "type": "string", + "description": "The name of the manger cluster." + }, + "clusterName": { + "type": "string", + "description": "The name of the cluster which needs to be create." + }, + "aliasName": { + "type": "string", + "description": "It is an alias given by the user and can be changed at will." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations to attach arbitrary metadata to objects." + }, + "describe": { + "type": "string", + "description": "describe represents the details of the cluster." + }, + "region": { + "type": "string" + }, + "zone": { + "type": "string" + }, + "kubesprayArgs": { + "$ref": "#/definitions/v1alpha1KubesprayArgs", + "description": "The Parameters for creating a cluster by kubespray." + }, + "preinstallAddons": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1AddonInfo" + }, + "title": "addon info selected by the user" + }, + "retry": { + "type": "boolean", + "title": "retry defines the flag to retry" + } + } + }, + "v1alpha1CreateConfigMapResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the ConfigMap YAML details" + } + } + }, + "v1alpha1CreateCronHorizontalPodAutoscalerResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the cron hpa json details" + } + } + }, + "v1alpha1CreateCustomResourceDefinitionResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the customResourceDefinition YAML details." + } + }, + "title": "CreateCustomResourceDefinitionResponse represents response of creating\na createCustomResourceDefinition" + }, + "v1alpha1CreateCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "CreateCustomResourceResponse represents response of creating one\nCustomResource of namespaced scope" + }, + "v1alpha1CreateHelmReleaseRequest": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "description": "cluster represents which cluster the chart belongs to." + }, + "namespace": { + "type": "string", + "description": "Namespace represents which namespace the helm release belongs to." + }, + "repo": { + "type": "string", + "description": "The repo represents for the charts belongs to." + }, + "timeout": { + "type": "string", + "description": "Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s)." + }, + "wait": { + "type": "boolean", + "description": "If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout." + }, + "atomic": { + "type": "boolean", + "description": "If set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used." + }, + "debug": { + "type": "boolean", + "description": "Enable verbose output." + }, + "disableHooks": { + "type": "boolean", + "description": "Prevent hooks from running during install." + }, + "disableOpenApiValidation": { + "type": "boolean", + "description": "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema." + }, + "createNamespace": { + "type": "boolean", + "description": "Create the release namespace if not present." + }, + "checkReleaseName": { + "type": "boolean", + "description": "Check whether the release name entered during installation matches the release name in charts annotations." + }, + "chart": { + "$ref": "#/definitions/v1alpha1HelmChartInstall" + } + } + }, + "v1alpha1CreateHelmReleaseResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "description": "cluster represents which cluster the helmrelease belongs to." + }, + "namespace": { + "type": "string", + "description": "Namespace represents which namespace the helmrelease belongs to." + }, + "releaseName": { + "type": "string" + } + } + }, + "v1alpha1CreateHorizontalPodAutoscalerResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the hpa YAML details" + } + } + }, + "v1alpha1CreateIngressResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the ingress YAML details." + } + }, + "title": "CreateIngressResponse the response of create cluster ingresses" + }, + "v1alpha1CreateLimitRangeResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the LimitRange YAML details." + } + }, + "description": "CreateLimitRangeResponse returns the created LimitRange data information." + }, + "v1alpha1CreateNamespaceResponse": { + "type": "object", + "properties": { + "namespace": { + "$ref": "#/definitions/v1alpha1Namespace" + } + }, + "description": "Create Namespace information." + }, + "v1alpha1CreateNetworkPolicyResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the networkpolicy YAML details." + } + }, + "title": "CreateNetworkPolicyResponse the response of create cluster networkpolicies" + }, + "v1alpha1CreateOpenAPIClusterCertResponse": { + "type": "object", + "properties": { + "kubeConfigString": { + "type": "string", + "description": "one of cluster or kubeSystemID has value." + }, + "cluster": { + "type": "string", + "description": "Cluster represents which cluster belongs to." + } + }, + "description": "CreateOpenAPIClusterCertResponse returns a openapi cert information." + }, + "v1alpha1CreateOrUpdateClusterResponse": { + "type": "object", + "properties": { + "cluster": { + "$ref": "#/definitions/v1alpha1Cluster", + "description": "Cluster the specified job belongs to." + } + }, + "description": "CreateOrUpdateCluster creates a Cluster if the target resource doesn't exist.\nIf the resource exists already, this function will update the resource\ninstead." + }, + "v1alpha1CreatePersistentVolumeClaimResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the pvc YAML details" + } + }, + "title": "CreatePersistentVolumeClaimResponse represents the response of create Pvc" + }, + "v1alpha1CreatePersistentVolumeResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the PersistentVolume YAML details." + } + }, + "description": "CreatePersistentVolumeResponse returns the created PersistentVolume data information." + }, + "v1alpha1CreateResourceQuotaResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the ResourceQuota YAML details." + } + }, + "description": "CreateResourceQuotaResponse returns the created ResourceQuota data information." + }, + "v1alpha1CreateResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The data field is the resources YAML details." + } + }, + "title": "CreateResourceResponse represents response of creating resources from yaml" + }, + "v1alpha1CreateSecretResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the Secret YAML details" + } + }, + "description": "It returns the created Secret data information." + }, + "v1alpha1CreateServiceAccountResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "title": "CreateServiceAccount represents the response of create sa" + }, + "v1alpha1CreateServiceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "Data is the Service YAML details" + } + }, + "description": "It returns the created Service data information." + }, + "v1alpha1CreateStorageClassResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "title": "CreateStorageClassResponse represents the response of create Pvc" + }, + "v1alpha1CreateVerticalPodAutoscalerResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the cron vpa json details" + } + }, + "description": "CreateVerticalPodAutoscalerResponse returns the yaml of the created vpa." + }, + "v1alpha1CreateVolumeSnapshotResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the VolumeSnapshot YAML details" + } + }, + "title": "CreateVolumeSnapshotResponse represents the response of create VolumeSnapshot snapshot" + }, + "v1alpha1CronHPACondition": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Type of job condition, Complete or Failed." + }, + "jobId": { + "type": "string", + "description": "The execution job id." + }, + "schedule": { + "type": "string", + "description": "The schedule of cron hpa job." + }, + "targetSize": { + "type": "integer", + "format": "int32", + "description": "The target replicas size of target workload." + }, + "runOnce": { + "type": "boolean", + "description": "RunOnce indicates whether to scale workload once." + }, + "jobState": { + "$ref": "#/definitions/v1alpha1CronHPAConditionJobState", + "description": "The state of corn hpa job." + }, + "lastProbeTime": { + "type": "string", + "format": "int64", + "description": "Last probe time for cron hpa job." + }, + "message": { + "type": "string", + "title": "Human readable message indicating details about last transition.\n+optional" + } + } + }, + "v1alpha1CronHPAConditionJobState": { + "type": "string", + "enum": [ + "JOB_STATE_UNSPECIFIED", + "Succeed", + "Failed", + "Submitted" + ], + "default": "JOB_STATE_UNSPECIFIED", + "description": "The enum for cron hpa job." + }, + "v1alpha1CronHPAJob": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name for cron hoa job." + }, + "schedule": { + "type": "string", + "description": "The rule for cron hoa job." + }, + "runOnce": { + "type": "boolean", + "description": "RunOnce indicates whether to scale workload once." + }, + "targetSize": { + "type": "integer", + "format": "int32", + "description": "The target replicas size of target workload." + } + }, + "description": "CronHPAJob is the rule for cron hpa." + }, + "v1alpha1CronHorizontalPodAutoscaler": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1CronHorizontalPodAutoscalerSpec", + "description": "CronHorizontalPodAutoscalerSpec defines the desired state of CronHorizontalPodAutoscaler." + }, + "status": { + "$ref": "#/definitions/v1alpha1CronHorizontalPodAutoscalerStatus", + "description": "current information about the autoscaler." + } + }, + "description": "configuration of a horizontal pod autoscaler." + }, + "v1alpha1CronHorizontalPodAutoscalerSpec": { + "type": "object", + "properties": { + "excludeDates": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ExcludeDates is the special period to exclude cronHPA execution." + }, + "scaleTargetRef": { + "$ref": "#/definitions/v1alpha1CrossVersionObjectReference", + "description": "reference to scaled resource; cron horizontal pod autoscaler will\nset the desired number of pods by given jobs." + }, + "jobs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CronHPAJob" + }, + "description": "The execution job details." + } + }, + "title": "CronHorizontalPodAutoscalerSpec defines the desired state of CronHorizontalPodAutoscaler" + }, + "v1alpha1CronHorizontalPodAutoscalerStatus": { + "type": "object", + "properties": { + "excludeDates": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ExcludeDates is the special period to exclude cronHPA execution." + }, + "scaleTargetRef": { + "$ref": "#/definitions/v1alpha1CrossVersionObjectReference", + "title": "Reference to scaled resource;" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CronHPACondition" + }, + "description": "Current service state of cron hpa." + } + } + }, + "v1alpha1CronJob": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "title": "Standard object's metadata.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n+optiona" + }, + "spec": { + "$ref": "#/definitions/v1alpha1CronJobSpec", + "description": "CronJobSpec describes how the job execution will look like and when it will actually run." + }, + "status": { + "$ref": "#/definitions/v1alpha1CronJobStatus", + "description": "CronJobStatus represents the current state of a cron job." + }, + "availed": { + "type": "integer", + "format": "int32", + "description": "The number of available cronjob." + }, + "total": { + "type": "integer", + "format": "int32", + "description": "The number of totally cronjob." + }, + "executionTimestamp": { + "type": "string", + "format": "int64", + "description": "Information when was the time the cronjob was successfully executed." + }, + "images": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Images the cronjob use." + } + }, + "description": "CronJob represents the configuration of a single cron job." + }, + "v1alpha1CronJobSpec": { + "type": "object", + "properties": { + "schedule": { + "type": "string", + "description": "The schedule in Cron format." + }, + "paused": { + "type": "boolean", + "description": "Indicates that the cronjob is paused." + } + }, + "description": "Specification of the desired behavior of a cron job, including the schedule." + }, + "v1alpha1CronJobStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/CronJobStatusCronJobState", + "description": "State of a cron job." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/CronJobStatusCronJobCondition" + }, + "description": "Current condition of cronjob." + } + }, + "description": "Current status of a cron job." + }, + "v1alpha1CrossVersionObjectReference": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "title": "Kind of the referent; More info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\"" + }, + "name": { + "type": "string", + "title": "Name of the referent; More info:\nhttp://kubernetes.io/docs/identifiers#names" + }, + "apiVersion": { + "type": "string", + "title": "API version of the referent" + } + }, + "description": "CrossVersionObjectReference contains enough information to let you identify\nthe referred resource." + }, + "v1alpha1CustomMetricValue": { + "type": "object", + "properties": { + "metricName": { + "type": "string", + "title": "the name of the metric" + }, + "value": { + "type": "string", + "title": "the value of the metric for this" + }, + "timestamp": { + "type": "string", + "format": "int64", + "title": "indicates the time at which the metrics were produced" + }, + "describedObject": { + "$ref": "#/definitions/CustomMetricValueDescribedObject", + "title": "a reference to the described object" + } + } + }, + "v1alpha1CustomResource": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "description": "Kind represents the kind of CustomResource." + }, + "apiVersion": { + "type": "string", + "description": "APIVersion represents the apiVersion of CustomResource." + }, + "name": { + "type": "string", + "description": "Name represents the name of CustomResource." + }, + "namespace": { + "type": "string", + "description": "Namespace represents which namespace the CustomResource belongs to." + }, + "creationTimestamp": { + "type": "string", + "format": "int64", + "description": "CreationTimestamp represents the creationTime of the CustomResource." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Map of string keys and values that can be used to organize and categorize\n(scope and select) objects. May match selectors of replication controllers\nand services.\nMore info: http://kubernetes.io/docs/labels\n+optional" + }, + "data": { + "type": "string", + "description": "The Data field is the CustomResource YAML details." + } + }, + "title": "CustomResource represents the CustomResource message" + }, + "v1alpha1CustomResourceDefinition": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "title": "Metadata is that all persisted resources must have, which includes all\nobjects" + }, + "spec": { + "$ref": "#/definitions/v1alpha1CustomResourceDefinitionSpec", + "description": "Spec is the desired behavior of the CustomResource." + }, + "status": { + "$ref": "#/definitions/v1alpha1CustomResourceDefinitionStatus", + "description": "status is the status information of the CustomResource." + } + }, + "title": "CustomResourceDefinition message of CustomResource definition" + }, + "v1alpha1CustomResourceDefinitionNames": { + "type": "object", + "properties": { + "plural": { + "type": "string", + "description": "Plural is the plural name of the resource to serve. It must match the name\nof the CustomResourceDefinition-registration too: plural.group and it must\nbe all lowercase." + }, + "singular": { + "type": "string", + "title": "Singular is the singular name of the resource. It must be all lowercase\nDefaults to lowercased " + }, + "shortNames": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ShortNames are short names for the resource. It must be all lowercase." + }, + "kind": { + "type": "string", + "description": "Kind is the serialized kind of the resource. It is normally CamelCase and\nsingular." + }, + "listKind": { + "type": "string", + "description": "ListKind is the serialized kind of the list for this resource. Defaults to\nList." + }, + "categories": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Categories is a list of grouped resources custom resources belong to (e.g.\n'all') +optional" + } + }, + "title": "CustomResourceDefinitionNames message of CustomResource definition names" + }, + "v1alpha1CustomResourceDefinitionSpec": { + "type": "object", + "properties": { + "group": { + "type": "string", + "title": "Group is the group this resource belongs in" + }, + "names": { + "$ref": "#/definitions/v1alpha1CustomResourceDefinitionNames", + "title": "Names are the names used to describe this custom resource" + }, + "scope": { + "$ref": "#/definitions/CustomResourceDefinitionSpecResourceScope", + "title": "Scope indicates whether this resource is cluster or namespace scoped.\nDefault is namespaced" + }, + "versions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CustomResourceDefinitionVersion" + }, + "description": "Versions is the list of all supported versions for this resource.\nIf Version field is provided, this field is optional.\nValidation: All versions must use the same validation schema for now. i.e.,\ntop level Validation field is applied to all of these versions. Order: The\nversion name will be used to compute the order. If the version string is\n\"kube-like\", it will sort above non \"kube-like\" version strings, which are\nordered lexicographically. \"Kube-like\" versions start with a \"v\", then are\nfollowed by a number (the major version), then optionally the string\n\"alpha\" or \"beta\" and another number (the minor version). These are sorted\nfirst by GA > beta > alpha (where GA is a version with no suffix such as\nbeta or alpha), and then by comparing major version, then minor version. An\nexample sorted list of versions: v10, v2, v1, v11beta2, v10beta3, v3beta1,\nv12alpha1, v11alpha2, foo1, foo10." + } + }, + "title": "CustomResourceDefinitionSpec message of CustomResource definition spec" + }, + "v1alpha1CustomResourceDefinitionStatus": { + "type": "object", + "properties": { + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current condition of cluster." + } + }, + "title": "CustomResourceDefinitionStatus represents custom resource definition status" + }, + "v1alpha1CustomResourceDefinitionVersion": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name is the version name, e.g. “v1”, “v2beta1”, etc." + }, + "served": { + "type": "boolean", + "title": "Served is a flag enabling/disabling this version from being served via REST\nAPIs" + }, + "storage": { + "type": "boolean", + "description": "Storage flags the version as storage version. There must be exactly one\nflagged as storage version." + }, + "deprecated": { + "type": "boolean", + "description": "deprecated indicates this version of the custom resource API is deprecated.\nWhen set to true, API requests to this version receive a warning header in\nthe server response. Defaults to false." + } + }, + "title": "CustomResourceDefinitionVersion message of CustomResource definition version" + }, + "v1alpha1DNSConfig": { + "type": "object", + "properties": { + "enableNodeLocalDns": { + "type": "boolean" + }, + "upstreamDnsServers": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1DaemonSet": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "title": "Standard object's metadata.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata\n+optional" + }, + "spec": { + "$ref": "#/definitions/v1alpha1DaemonSetSpec", + "title": "The desired behavior of this daemon set.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n+optional" + }, + "status": { + "$ref": "#/definitions/v1alpha1DaemonSetStatus", + "title": "The current status of this daemon set. This data may be\nout of date by some window of time.\nPopulated by the system.\nRead-only.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n+optional" + }, + "revision": { + "type": "string", + "format": "int64", + "title": "The revision to rollback to. If set to 0, rollback to the last revision.\n+optional" + } + }, + "description": "DaemonSet represents the configuration of a daemonSet." + }, + "v1alpha1DaemonSetSpec": { + "type": "object", + "properties": { + "template": { + "$ref": "#/definitions/v1alpha1PodTemplateSpec", + "title": "An object that describes the pod that will be created.\nThe DaemonSet will create exactly one copy of this pod on every node\nthat matches the template's node selector (or on every node if no node\nselector is specified).\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template" + }, + "updateStrategy": { + "$ref": "#/definitions/typesUpdateStrategy", + "title": "An update strategy to replace existing DaemonSet pods with new pods.\n+optional" + } + }, + "description": "DaemonSetSpec is the specification of a daemonSet." + }, + "v1alpha1DaemonSetStatus": { + "type": "object", + "properties": { + "desiredNumberScheduled": { + "type": "integer", + "format": "int32", + "description": "The total number of nodes that should be running the daemon\npod (including nodes correctly running the daemon pod)." + }, + "numberAvailable": { + "type": "integer", + "format": "int32", + "title": "The number of nodes that should be running the\ndaemon pod and have one or more of the daemon pod running and\navailable (ready for at least spec.minReadySeconds)\n+optional" + }, + "state": { + "$ref": "#/definitions/typesWorkloadState", + "title": "WorkloadState describes the state of daemonsets" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current service state of daemonSet." + } + }, + "description": "DaemonSetStatus represents the current status of a daemon set." + }, + "v1alpha1DeleteHelmReleaseResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "description": "cluster represents which cluster the helmrelease belongs to." + }, + "namespace": { + "type": "string", + "description": "Namespace represents which namespace the helmrelease belongs to." + }, + "releaseName": { + "type": "string" + } + } + }, + "v1alpha1DeletionPropagation": { + "type": "string", + "enum": [ + "DELETION_PROPAGATION_UNSPECIFIED", + "DELETION_PROPAGATION_ORPHAN", + "DELETION_PROPAGATION_BACKGROUND", + "DELETION_PROPAGATION_FOREGROUND" + ], + "default": "DELETION_PROPAGATION_UNSPECIFIED", + "description": " - DELETION_PROPAGATION_ORPHAN: Orphans the dependents.\n - DELETION_PROPAGATION_BACKGROUND: Deletes the object from the key-value store, the garbage collector will\ndelete the dependents in the background.\n - DELETION_PROPAGATION_FOREGROUND: The object exists in the key-value store until the garbage collector\ndeletes all the dependents whose ownerReference.blockOwnerDeletion=true\nfrom the key-value store. API sever will put the \"foregroundDeletion\"\nfinalizer on the object, and sets its deletionTimestamp. This policy is\ncascading, i.e., the dependents will be deleted with Foreground." + }, + "v1alpha1Dependency": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "name is the name of the dependency.\nThis must mach the name in the dependency's Chart.yaml." + }, + "version": { + "type": "string", + "description": "version is the version (range) of this chart.\nA lock file will always produce a single version, while a dependency\nmay contain a semantic version range." + }, + "repository": { + "type": "string", + "description": "The URL to the repository.\nAppending `index.yaml` to this string should result in a URL that can be\nused to fetch the repository index." + }, + "condition": { + "type": "string", + "title": "A yaml path that resolves to a boolean, used for enabling/disabling charts (e.g. subchart1.enabled )" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "title": "tags can be used to group charts for enabling/disabling together" + }, + "enabled": { + "type": "boolean", + "title": "enabled bool determines if chart should be loaded" + }, + "importValues": { + "type": "array", + "items": { + "type": "string" + }, + "description": "import_values holds the mapping of source values to parent key to be imported. Each item can be a\nstring or pair of child/parent sublist items." + }, + "alias": { + "type": "string", + "title": "alias usable alias to be used for the chart" + } + }, + "description": "Dependencies can be used to express developer intent, or to capture the state\nof a chart." + }, + "v1alpha1Deployment": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Metadata is that all persisted resources must have, which includes all objects\nusers must create." + }, + "spec": { + "$ref": "#/definitions/v1alpha1DeploymentSpec", + "title": "Specification of the desired behavior of the Deployment.\n+optional" + }, + "status": { + "$ref": "#/definitions/v1alpha1DeploymentStatus", + "title": "Most recently observed status of the Deployment.\n+optional" + }, + "revision": { + "type": "string", + "format": "int64", + "title": "The revision to rollback to. If set to 0, rollback to the last revision.\n+optional" + } + }, + "description": "Deployment provides declarative updates for Pods and ReplicaSets." + }, + "v1alpha1DeploymentSpec": { + "type": "object", + "properties": { + "template": { + "$ref": "#/definitions/v1alpha1PodTemplateSpec", + "title": "Template describes the data a pod should have when created from a template" + }, + "strategy": { + "$ref": "#/definitions/typesUpdateStrategy", + "description": "Strategy indicates the strategy that the controller\nwill use to perform updates. It includes any additional parameters necessary\nto perform the update for the indicated strategy." + }, + "paused": { + "type": "boolean", + "description": "Indicates that the deployment is paused." + } + }, + "description": "DeploymentSpec specifies the state of a Deployment." + }, + "v1alpha1DeploymentStatus": { + "type": "object", + "properties": { + "availableReplicas": { + "type": "integer", + "format": "int32", + "title": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.\n+optional" + }, + "readyReplicas": { + "type": "integer", + "format": "int32", + "title": "Total number of ready pods targeted by this deployment.\n+optional" + }, + "replicas": { + "type": "integer", + "format": "int32", + "title": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).\n+optional" + }, + "state": { + "$ref": "#/definitions/typesWorkloadState", + "title": "state describes the state of deployments" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current service state of deployments." + } + }, + "description": "DeploymentStatus holds information about the observed status of a deployment." + }, + "v1alpha1DetectKangarooResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "The kangaroo_enable indicates whether the kangaroo is installed" + } + } + }, + "v1alpha1DownwardAPIVolumeFile": { + "type": "object", + "properties": { + "path": { + "type": "string", + "title": "Required: Path is the relative path name of the file to be created. Must\nnot be absolute or contain the '..' path. Must be utf-8 encoded. The first\nitem of the relative path must not start with '..'" + }, + "fieldRef": { + "$ref": "#/definitions/v1alpha1ObjectFieldSelector", + "title": "Required: Selects a field of the pod: only annotations, labels, name and\nnamespace are supported. +optional" + }, + "resourceFieldRef": { + "$ref": "#/definitions/v1alpha1ResourceFieldSelector", + "title": "Selects a resource of the container: only resources limits and requests\n(limits.cpu, limits.memory, requests.cpu and requests.memory) are currently\nsupported. +optional" + }, + "mode": { + "type": "integer", + "format": "int32", + "title": "Optional: mode bits used to set permissions on this file, must be an octal\nvalue between 0000 and 0777 or a decimal value between 0 and 511. YAML\naccepts both octal and decimal values, JSON requires decimal values for\nmode bits. If not specified, the volume defaultMode will be used. This\nmight be in conflict with other options that affect the file mode, like\nfsGroup, and the result can be other mode bits set. +optional" + } + }, + "description": "DownwardAPIVolumeFile represents information to create the file containing\nthe pod field." + }, + "v1alpha1DownwardAPIVolumeSource": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1DownwardAPIVolumeFile" + }, + "title": "Items is a list of downward API volume file\n+optional" + }, + "DefaultMode": { + "type": "integer", + "format": "int32", + "title": "Optional: mode bits to use on created files by default. Must be a\nOptional: mode bits used to set permissions on created files by default.\nMust be an octal value between 0000 and 0777 or a decimal value between 0\nand 511. YAML accepts both octal and decimal values, JSON requires decimal\nvalues for mode bits. Defaults to 0644. Directories within the path are not\naffected by this setting. This might be in conflict with other options that\naffect the file mode, like fsGroup, and the result can be other mode bits\nset. +optional" + } + }, + "description": "DownwardAPIVolumeSource represents a volume containing downward API info.\nDownward API volumes support ownership management and SELinux relabeling." + }, + "v1alpha1EditClusterLabelsResponse": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "description": "EditClusterLabelsRequest returns true when pod termination has been\nrequested." + }, + "v1alpha1EmptyDirVolumeSource": { + "type": "object", + "properties": { + "medium": { + "type": "string", + "title": "What type of storage medium should back this directory.\nThe default is \"\" which means to use the node's default medium.\nMust be an empty string (default) or Memory.\nMore info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n+optional" + }, + "sizeLimit": { + "type": "string", + "format": "int64", + "title": "Total amount of local storage required for this EmptyDir volume.\nThe size limit is also applicable for memory medium.\nThe maximum usage on memory medium EmptyDir would be the minimum value\nbetween the SizeLimit specified here and the sum of memory limits of all\ncontainers in a pod. The default is nil which means that the limit is\nundefined. More info: http://kubernetes.io/docs/volumes#emptydir\n+optional" + } + }, + "description": "Represents an empty directory for a pod.\nEmpty directory volumes support ownership management and SELinux relabeling." + }, + "v1alpha1EnvFromSource": { + "type": "object", + "properties": { + "prefix": { + "type": "string", + "title": "An optional identifier to prepend to each key in the ConfigMap.\n+optional" + }, + "configMapRef": { + "$ref": "#/definitions/v1alpha1ConfigMapEnvSource", + "title": "The ConfigMap to select from.\n+optional" + }, + "secretRef": { + "$ref": "#/definitions/v1alpha1SecretEnvSource", + "title": "The Secret to select from.\n+optional" + } + }, + "title": "EnvFromSource represents the source of a set of ConfigMaps" + }, + "v1alpha1EnvVar": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of EnvVar." + }, + "value": { + "type": "string", + "description": "The value of EnvVar." + }, + "valueFrom": { + "$ref": "#/definitions/v1alpha1EnvVarSource", + "title": "List of sources to populate environment variables in the container.\nThe keys defined within a source must be a C_IDENTIFIER. All invalid keys\nwill be reported as an event when the container is starting. When a key\nexists in multiple sources, the value associated with the last source will\ntake precedence. Values defined by an Env with a duplicate key will take\nprecedence. Cannot be updated.\"," + } + }, + "description": "Environment variable information." + }, + "v1alpha1EnvVarSource": { + "type": "object", + "properties": { + "fieldRef": { + "$ref": "#/definitions/v1alpha1ObjectFieldSelector", + "title": "Selects a field of the pod: supports metadata.name, metadata.namespace,\n`metadata.labels['']`, `metadata.annotations['']`, spec.nodeName,\nspec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n+optional" + }, + "resourceFieldRef": { + "$ref": "#/definitions/v1alpha1ResourceFieldSelector", + "title": "Selects a resource of the container: only resources limits and requests\n(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,\nrequests.memory and requests.ephemeral-storage) are currently supported.\n+optional" + }, + "ConfigMapKeyRef": { + "$ref": "#/definitions/v1alpha1ConfigMapKeySelector", + "title": "Selects a key of a ConfigMap.\n+optional" + }, + "secretKeyRef": { + "$ref": "#/definitions/v1alpha1SecretKeySelector", + "title": "Selects a key of a secret in the pod's namespace\n+optional" + } + }, + "description": "EnvVarSource represents a source for the value of an EnvVar.\nOnly one of its fields may be set." + }, + "v1alpha1EphemeralContainer": { + "type": "object", + "properties": { + "ephemeralContainerCommon": { + "$ref": "#/definitions/v1alpha1Container", + "description": "Ephemeral containers have all of the fields of Container, plus additional fields\nspecific to ephemeral containers. Fields in common with Container are in the\nfollowing inlined struct so than an EphemeralContainer may easily be converted\nto a Container." + }, + "targetContainerName": { + "type": "string", + "description": "If set, the name of the container from PodSpec that this ephemeral container targets.\nThe ephemeral container will be run in the namespaces (IPC, PID, etc) of this container.\nIf not set then the ephemeral container uses the namespaces configured in the Pod spec.\n\nThe container runtime must implement support for this feature. If the runtime does not\nsupport namespace targeting then the result of setting this field is undefined." + } + }, + "description": "An EphemeralContainer is a temporary container that you may add to an existing Pod for\nuser-initiated activities such as debugging. Ephemeral containers have no resource or\nscheduling guarantees, and they will not be restarted when they exit or when a Pod is\nremoved or restarted. The kubelet may evict a Pod if an ephemeral container causes the\nPod to exceed its resource allocation." + }, + "v1alpha1EtcdBackupRestoreSetting": { + "type": "object", + "properties": { + "baseImage": { + "type": "string", + "description": "The base image for the etcdbackuprestore deployment." + } + }, + "description": "setting of the etcdbackuprestore for every cluster." + }, + "v1alpha1EtcdBackupStrategy": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategySpec", + "description": "EtcdBackupStrategySpec describes how the etcd backup strategy will look like." + }, + "status": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategyStatus", + "description": "EtcdBackupStrategyStatus represents the current state of a etcd backup strategy." + } + } + }, + "v1alpha1EtcdBackupStrategyConfig": { + "type": "object", + "properties": { + "etcdConnectionConfig": { + "$ref": "#/definitions/v1alpha1EtcdConnectionConfig", + "description": "config for etcd connection." + }, + "snapshotterConfig": { + "$ref": "#/definitions/v1alpha1SnapshotterConfig", + "description": "config for Snapshotter.\nSnapshotter should parse from the deploy." + }, + "snapStoreConfig": { + "$ref": "#/definitions/v1alpha1SnapStoreConfig", + "description": "config for SnapStore." + } + }, + "description": "all configs for EtcdBackupStrategy." + }, + "v1alpha1EtcdBackupStrategySpec": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/EtcdBackupStrategySpecEtcdBackupType" + }, + "maxBackups": { + "type": "integer", + "format": "int64", + "description": "max_backups maximum number of previous backups to keep." + }, + "storeLocation": { + "type": "string", + "description": "console address for etcd backup strategy." + }, + "config": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategyConfig" + } + }, + "description": "EtcdBackupStrategySpec describes etcd backup strategy." + }, + "v1alpha1EtcdBackupStrategyStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/typesWorkloadState", + "description": "Current state of a etcd backup strategy." + } + }, + "description": "EtcdBackupStrategyStatus represents the current state of a etcd backup strategy." + }, + "v1alpha1EtcdConnectionConfig": { + "type": "object", + "properties": { + "endpoints": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Endpoints are the endpoints from which the backup will be take or defragmentation will be called.\nThis need not be necessary match the entire etcd cluster.\nendpoints comma separated list of etcd endpoints." + }, + "serviceEndpoints": { + "type": "array", + "items": { + "type": "string" + }, + "description": "service_endpoints comma separated list of etcd endpoints that are used for etcd-backup-restore to connect to etcd through a (Kubernetes) service." + }, + "connectionTimeout": { + "type": "string", + "format": "int64", + "description": "connection_timeout etcd client connection timeout." + }, + "snapshotTimeout": { + "type": "string", + "format": "int64", + "description": "snapshot_timeout timeout duration for taking etcd snapshots." + }, + "insecureTransport": { + "type": "boolean", + "description": "insecure_transport disable transport security for client connections." + }, + "insecureSkipVerify": { + "type": "boolean", + "description": "insecure_skip_verify skip server certificate verification." + }, + "certData": { + "type": "string", + "description": "cert_data identify secure client using this TLS certificate file." + }, + "keyData": { + "type": "string", + "description": "key_data identify secure client using this TLS key file." + }, + "caData": { + "type": "string", + "description": "ca_date verify certificates of TLS-enabled secure servers using this CA bundle." + } + } + }, + "v1alpha1Event": { + "type": "object", + "properties": { + "involvedObject": { + "$ref": "#/definitions/v1alpha1ObjectReference", + "description": "The object that this event is about." + }, + "reason": { + "type": "string", + "description": "reason is why the action was taken. It is human-readable.\nThis field cannot be empty for new Events and it can have at most 128\ncharacters." + }, + "message": { + "type": "string", + "description": "A human-readable description of the status of this operation." + }, + "source": { + "$ref": "#/definitions/v1alpha1EventSource", + "description": "The component reporting this event. Should be a short machine\nunderstandable string." + }, + "lastTimestamp": { + "type": "string", + "format": "int64", + "description": "The time at which the most recent occurrence of this event was recorded." + }, + "type": { + "$ref": "#/definitions/v1alpha1EventType", + "description": "Type of this event (Normal, Warning), new types could be added in the\nfuture." + }, + "firstTimestamp": { + "type": "string", + "format": "int64" + } + }, + "description": "Event is a report of an event somewhere in the cluster. Events\nhave a limited retention time and triggers and messages may evolve\nwith time. Event consumers should not rely on the timing of an event\nwith a given Reason reflecting a consistent underlying trigger, or the\ncontinued existence of events with that Reason. Events should be\ntreated as informative, best-effort, supplemental data." + }, + "v1alpha1EventSource": { + "type": "object", + "properties": { + "component": { + "type": "string", + "title": "Component from which the event is generated.\n+optional" + }, + "host": { + "type": "string", + "title": "Node name on which the event is generated.\n+optional" + } + }, + "description": "EventSource contains information for an event." + }, + "v1alpha1EventType": { + "type": "string", + "enum": [ + "EVENT_TYPE_UNSPECIFIED", + "Normal", + "Warning" + ], + "default": "EVENT_TYPE_UNSPECIFIED", + "description": "Type of event (Normal, Warning), new types could be added in the\nfuture.\n\n - EVENT_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Normal: Normal is a normal event type.\n - Warning: Warning is a warning event type." + }, + "v1alpha1ExecAction": { + "type": "object", + "properties": { + "command": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "ExecAction describes a \"run in container\" action." + }, + "v1alpha1ExecuteEtcdBackupStrategyResponse": { + "type": "object", + "properties": { + "strategy": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy", + "description": "The new state of the etcd backup strategy after resuming." + } + }, + "description": "Response message for the `ExecuteEtcdBackupStrategyResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1ExternalMetricSource": { + "type": "object", + "properties": { + "metric": { + "$ref": "#/definitions/v1alpha1MetricIdentifier", + "title": "metric identifies the target metric by name and selector" + }, + "target": { + "$ref": "#/definitions/v1alpha1MetricTarget", + "title": "target specifies the target value for the given metric" + } + }, + "description": "ExternalMetricSource indicates how to scale on a metric not associated with\nany Kubernetes object (for example length of queue in cloud\nmessaging service, or QPS from loadbalancer running outside of cluster)." + }, + "v1alpha1ExternalMetricStatus": { + "type": "object", + "properties": { + "metric": { + "$ref": "#/definitions/v1alpha1MetricIdentifier", + "title": "metric identifies the target metric by name and selector" + }, + "current": { + "$ref": "#/definitions/v1alpha1MetricValueStatus", + "title": "current contains the current value for the given metric" + } + }, + "description": "ExternalMetricStatus indicates the current value of a global metric\nnot associated with any Kubernetes object." + }, + "v1alpha1FeatureGate": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1alpha1FeatureGateName", + "title": "name is the name of the feature gate" + }, + "enabled": { + "type": "boolean", + "title": "default is the default enablement state for the feature" + }, + "lockToDefault": { + "type": "boolean", + "title": "LockToDefault indicates that the feature is locked to its default and cannot be changed" + }, + "preRelease": { + "$ref": "#/definitions/v1alpha1PreRelease", + "title": "PreRelease indicates the maturity level of the feature" + } + } + }, + "v1alpha1FeatureGateName": { + "type": "string", + "enum": [ + "FEATURE_GATE_NAME_TYPE_UNSPECIFIED", + "DownloadClusterKubeConfig" + ], + "default": "FEATURE_GATE_NAME_TYPE_UNSPECIFIED", + "title": "- FEATURE_GATE_NAME_TYPE_UNSPECIFIED: feature gate name type is unspecified.\n - DownloadClusterKubeConfig: DownloadClusterKubeConfig indicates whether the cluster can download kubeconfig" + }, + "v1alpha1FilterPodStatus": { + "type": "string", + "enum": [ + "FILTER_POD_STATUS_UNSPECIFIED", + "FILTER_POD_STATUS_RUNNING", + "FILTER_POD_STATUS_ERROR", + "FILTER_POD_STATUS_COMPLETED", + "FILTER_POD_STATUS_WAITING" + ], + "default": "FILTER_POD_STATUS_UNSPECIFIED" + }, + "v1alpha1FlannelConfig": { + "type": "object", + "properties": { + "backendType": { + "$ref": "#/definitions/FlannelConfigBackendType" + } + } + }, + "v1alpha1FullGPUNodeStats": { + "type": "object", + "properties": { + "totalGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of physical Gpus" + }, + "allocatedGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of allocated Gpus" + } + } + }, + "v1alpha1GPU": { + "type": "object", + "properties": { + "uid": { + "type": "string", + "title": "uid is gpu unique id" + }, + "name": { + "type": "string", + "title": "name is gpu name" + }, + "gpuMode": { + "$ref": "#/definitions/v1alpha1GPUModel", + "title": "gpu_mode is gpu model" + }, + "gpuInfo": { + "$ref": "#/definitions/v1alpha1GPUInfo", + "title": "gpu_info is some gpu metadata" + }, + "migSpecList": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1MigSpec" + }, + "title": "if GPU model is mig mig_spec_list will have values" + } + } + }, + "v1alpha1GPUInfo": { + "type": "object", + "properties": { + "modelName": { + "type": "string", + "title": "gpu model\ne.g. NVIDIA A800 80GB PCIe" + }, + "device": { + "type": "string", + "title": "e.g. nvidia0" + }, + "gpuMemory": { + "type": "string", + "format": "int64", + "title": "gpu memory unit: Mi" + } + } + }, + "v1alpha1GPUModel": { + "type": "string", + "enum": [ + "GPU_MODEL_UNSPECIFIED", + "GPU_MODEL_MIG", + "GPU_MODEL_GPU", + "GPU_MODEL_VGPU" + ], + "default": "GPU_MODEL_UNSPECIFIED", + "title": "- GPU_MODEL_MIG: gpu_model_mig gpu model is mig\n - GPU_MODEL_GPU: gpu_model_gpu gpu model is whole\n - GPU_MODEL_VGPU: gpu_model_gpu gpu model is vgpu" + }, + "v1alpha1GPUResourceSetting": { + "type": "object", + "properties": { + "key": { + "type": "string", + "title": "gpu workload type resources key" + }, + "alias": { + "type": "string", + "title": "gpu workload type resources alias" + }, + "isAllocatable": { + "type": "boolean", + "title": "Resource quota can be allocated" + }, + "description": { + "type": "string", + "title": "gpu workload type resources description" + }, + "aliasZh": { + "type": "string", + "title": "gpu workload type resources zh alias" + }, + "range": { + "$ref": "#/definitions/v1alpha1ResourceRange", + "title": "gpu resource range" + }, + "available": { + "$ref": "#/definitions/v1alpha1AvailableResource", + "title": "available gpu resource number\nif we don't need it\nwill return nil" + } + } + }, + "v1alpha1GPUSetting": { + "type": "object", + "properties": { + "type": { + "type": "string", + "title": "type is gpu card type" + }, + "alias": { + "type": "string", + "title": "alias is gpu card alias" + }, + "resource": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPUResourceSetting" + }, + "title": "gpu card resource setting" + }, + "resourceTemplate": { + "$ref": "#/definitions/v1alpha1GPUResourceSetting", + "title": "when is_dynamic is true, user setting resource template" + }, + "isDynamic": { + "type": "boolean", + "title": "is_dynamic is check gpu resource whether dynamic, eg: nvidia.com/mig-1c.10gb" + } + } + }, + "v1alpha1GPUSettingResponse": { + "type": "object", + "properties": { + "gpuSetting": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPUSetting" + } + } + }, + "title": "GPUSettingResponse is the response message for GPUSetting" + }, + "v1alpha1GPUSpec": { + "type": "object", + "properties": { + "modelName": { + "type": "string", + "title": "ref gpu metrics modelName" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "gpu memory" + }, + "uuid": { + "type": "string", + "title": "gpu uuid" + } + } + }, + "v1alpha1GPUSummary": { + "type": "object", + "properties": { + "node": { + "type": "string", + "description": "node defines the cluster node name." + }, + "vgpuTypes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "vgpu_types defines a array restore vGPU types of the node." + } + } + }, + "v1alpha1GetClusterAdminKubeConfigResponse": { + "type": "object", + "properties": { + "kubeConfigString": { + "type": "string", + "description": "The kubeconfig of the cluster." + }, + "cluster": { + "type": "string", + "description": "Cluster represents which cluster belongs to." + }, + "expireTime": { + "type": "string", + "format": "int64" + } + }, + "description": "GetClusterAdminKubeConfigResponse returns a openapi cert information." + }, + "v1alpha1GetClusterCustomResourceJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the CustomResource YAML details" + } + }, + "title": "GetClusterCustomResourceJSONResponse represents response of get one\nCustomResource'json of cluster scope" + }, + "v1alpha1GetClusterKubeConfigResponse": { + "type": "object", + "properties": { + "kubeConfigString": { + "type": "string" + } + } + }, + "v1alpha1GetClusterlcmOpsJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the tKuBeanClusterOps YAML details" + } + } + }, + "v1alpha1GetConfigMapJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the ConfigMap YAML details" + } + }, + "description": "ConfigMap data information in json format." + }, + "v1alpha1GetCronHorizontalPodAutoscalerJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the hpa YAML details." + } + }, + "description": "HorizontalPodAutoscalerJSON responses the messages of hap YAML details." + }, + "v1alpha1GetCustomResourceDefinitionJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the CustomResourceDefinition YAML details" + } + }, + "title": "GetCustomResourceDefinitionJSONResponse represents response of get one\nCustomResourceDefinition'json" + }, + "v1alpha1GetCustomResourceJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the CustomResource YAML details" + } + }, + "title": "GetCustomResourceJSONResponse represents response of get one\nCustomResource'json of namespaced scope" + }, + "v1alpha1GetEtcdBackupStrategyJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the etcd backup strategy YAML details." + } + }, + "description": "GetEtcdBackupStrategyJSONResponse returns etcd backup strategy data information in json format." + }, + "v1alpha1GetHelmChartDisplayResponse": { + "type": "object", + "properties": { + "readme": { + "type": "string", + "title": "The readme represents for the helm charts readme file contents" + }, + "appReadme": { + "type": "string", + "title": "The app_readme represents for the helm charts app_readme file contents" + }, + "values": { + "type": "string", + "title": "The values represents for the helm charts values file contents" + }, + "questions": { + "type": "string", + "title": "The questions represents for the helm charts questions file contents" + }, + "chart": { + "type": "string", + "title": "The chart represents for the helm charts chart file contents" + }, + "schemaJson": { + "type": "string", + "title": "The schema_json represents for the helm charts schema_json file contents" + } + } + }, + "v1alpha1GetHelmChartFilesResponse": { + "type": "object", + "properties": { + "files": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1GetHelmChartManifestResponse": { + "type": "object", + "properties": { + "manifest": { + "type": "string" + } + } + }, + "v1alpha1GetHelmChartResourcesResponse": { + "type": "object", + "properties": { + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/GetHelmChartResourcesResponseResources" + } + } + } + }, + "v1alpha1GetHelmChartResponse": { + "type": "object", + "properties": { + "entries": { + "$ref": "#/definitions/v1alpha1HelmChartVersions" + } + } + }, + "v1alpha1GetHelmOperationJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the repository YAML details" + } + } + }, + "v1alpha1GetHelmReleaseJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the release YAML details" + } + } + }, + "v1alpha1GetHelmRepoJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the repository YAML details" + } + } + }, + "v1alpha1GetHorizontalPodAutoscalerJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the hpa YAML details." + } + }, + "description": "HorizontalPodAutoscalerJSON responses the messages of hap YAML details." + }, + "v1alpha1GetIngressJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the ingress YAML details." + } + }, + "title": "GetIngressJSONResponse the response of get cluster ingresses json" + }, + "v1alpha1GetLimitRangeJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the limitRange YAML details." + } + }, + "description": "GetLimitRangeJSONResponse returns limitRange data information in json format." + }, + "v1alpha1GetNamespaceJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the Namespace YAML details" + } + } + }, + "v1alpha1GetNetworkPolicyJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the networkpolicy YAML details." + } + }, + "title": "GetNetworkPolicyJSONResponse the response of get cluster networkpolicies json" + }, + "v1alpha1GetNodeGPUStatsResponse": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/definitions/v1alpha1GPUModel", + "title": "cluster node gpu mode" + }, + "fullGpuStats": { + "$ref": "#/definitions/v1alpha1FullGPUNodeStats", + "title": "full gpu stats" + }, + "vgpuStats": { + "$ref": "#/definitions/v1alpha1VGPUNodeStats", + "title": "vgpu stats" + }, + "migStats": { + "$ref": "#/definitions/v1alpha1MIGNodeStats", + "title": "mig stats" + } + } + }, + "v1alpha1GetNodeJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the node YAML details." + } + }, + "description": "GetNodeJSONResponse returns a node's json." + }, + "v1alpha1GetPersistentVolumeClaimJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data represents the data of PVC JSON" + } + }, + "title": "GetPersistentVolumeClaimSnapshotJSONResponse represents the response of get PVC JSON" + }, + "v1alpha1GetPersistentVolumeJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the persistentVolume YAML details." + } + }, + "description": "GetPersistentVolumeJSONResponse returns persistentVolume data information in json format." + }, + "v1alpha1GetPodContainerLogResponse": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "format": "int32", + "title": "the total of log" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/GetPodContainerLogResponseData" + }, + "title": "the data of los" + } + }, + "title": "GetPodContainerLogResponse represents the response of get pod container log" + }, + "v1alpha1GetPreCheckClusterInfoResponse": { + "type": "object", + "properties": { + "nodes": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1PreCheckNodeInfo" + }, + "description": "nodes defines all nodes of cluster." + }, + "yumRepoInfo": { + "$ref": "#/definitions/v1alpha1PreCheckYumRepoInfo" + } + } + }, + "v1alpha1GetReplicaSetJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the replicaSet YAML details." + } + }, + "description": "GetReplicaSetJSONResponse returns replicaSet data information in json format." + }, + "v1alpha1GetResourceQuotaJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the resourceQuota YAML details." + } + }, + "description": "GetResourceQuotaJSONResponse returns resourceQuota data information in json format." + }, + "v1alpha1GetSecretJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the Secret YAML details" + } + }, + "description": "It returns Secret data information in json format." + }, + "v1alpha1GetServiceJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the Service YAML details." + } + }, + "description": "It returns Service data information in json format." + }, + "v1alpha1GetStorageClassJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "title": "GetStorageClassJSONResponse represents the response of get storage class" + }, + "v1alpha1GetVerticalPodAutoscalerJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the vpa YAML details." + } + }, + "description": "GetVerticalPodAutoscalerJSONResponse returns the YAML details of a vpa." + }, + "v1alpha1GetVolumeSnapshotJSONResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data represents the data of VolumeSnapshots JSON" + } + }, + "title": "GetVolumeSnapshotJSONResponse represents the response of get VolumeSnapshots JSON" + }, + "v1alpha1GetWorkspaceSharedResourceQuotaResponse": { + "type": "object", + "properties": { + "setting": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "allocatable": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1Group": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "id is the unique identification of the group." + }, + "name": { + "type": "string", + "description": "the name of the group." + } + } + }, + "v1alpha1HPAScalingRules": { + "type": "object", + "properties": { + "stabilizationWindowSeconds": { + "type": "integer", + "format": "int32", + "title": "StabilizationWindowSeconds is the number of seconds for which past recommendations should be\nconsidered while scaling up or scaling down.\nStabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour).\nIf not set, use the default values:\n- For scale up: 0 (i.e. no stabilization is done).\n- For scale down: 300 (i.e. the stabilization window is 300 seconds long).\n+optional" + } + } + }, + "v1alpha1HTTPGetAction": { + "type": "object", + "properties": { + "path": { + "type": "string", + "title": "Path to access on the HTTP server.\n+optional" + }, + "port": { + "type": "string", + "description": "Name or number of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME." + }, + "host": { + "type": "string", + "title": "Host name to connect to, defaults to the pod IP. You probably want to set\n\"Host\" in httpHeaders instead.\n+optional" + }, + "scheme": { + "type": "string", + "title": "Scheme to use for connecting to the host.\nDefaults to HTTP.\n+optional" + } + }, + "description": "HTTPGetAction describes an action based on HTTP Get requests." + }, + "v1alpha1HTTPIngressPath": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path is matched against the path of an incoming request." + }, + "pathType": { + "type": "string", + "description": "PathType determines the interpretation of the Path matching." + }, + "backend": { + "$ref": "#/definitions/v1alpha1IngressBackend", + "description": "Backend defines the referenced service endpoint to which the traffic will\nbe forwarded to." + } + }, + "description": "HTTPIngressPath associates a path with a backend. Incoming urls matching the\npath are forwarded to the backend." + }, + "v1alpha1HTTPIngressRuleValue": { + "type": "object", + "properties": { + "paths": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HTTPIngressPath" + }, + "description": "A collection of paths that map requests to backends." + } + }, + "description": "HTTPIngressRuleValue is a list of http selectors pointing to backends.\nIn the example: http:///? -> backend where\nwhere parts of the url correspond to RFC 3986, this resource will be used\nto match against everything after the last '/' and before the first '?'\nor '#'." + }, + "v1alpha1Handler": { + "type": "object", + "properties": { + "exec": { + "$ref": "#/definitions/v1alpha1ExecAction", + "title": "Exec specifies the action to take.\n+optional" + }, + "httpGet": { + "$ref": "#/definitions/v1alpha1HTTPGetAction", + "title": "HTTPGet specifies the http request to perform.\n+optional" + }, + "TCPSocket": { + "$ref": "#/definitions/v1alpha1TCPSocketAction", + "title": "TCPSocket specifies an action involving a TCP port.\n+optional" + } + } + }, + "v1alpha1HelmChart": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/v1alpha1Metadata" + }, + "values": { + "type": "string" + } + } + }, + "v1alpha1HelmChartInstall": { + "type": "object", + "properties": { + "chartName": { + "type": "string" + }, + "version": { + "type": "string" + }, + "releaseName": { + "type": "string" + }, + "description": { + "type": "string" + }, + "values": { + "type": "string" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1HelmChartUpgrade": { + "type": "object", + "properties": { + "chartName": { + "type": "string" + }, + "version": { + "type": "string" + }, + "releaseName": { + "type": "string" + }, + "force": { + "type": "boolean" + }, + "resetValues": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "values": { + "type": "string" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1HelmChartVersion": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/v1alpha1Metadata" + }, + "urls": { + "type": "array", + "items": { + "type": "string" + } + }, + "created": { + "type": "string", + "format": "int64" + }, + "removed": { + "type": "boolean" + } + } + }, + "v1alpha1HelmChartVersions": { + "type": "object", + "properties": { + "chartVersion": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmChartVersion" + } + } + } + }, + "v1alpha1HelmInstallConfig": { + "type": "object", + "properties": { + "values": { + "type": "string" + } + } + }, + "v1alpha1HelmOperation": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "status": { + "$ref": "#/definitions/v1alpha1HelmOperationStatus", + "description": "OperationStatus contains the operation status." + } + } + }, + "v1alpha1HelmOperationStatus": { + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "chart": { + "type": "string" + }, + "version": { + "type": "string" + }, + "release": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "token": { + "type": "string" + }, + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "jobName": { + "type": "string", + "description": "Related job's name." + }, + "jobNamespace": { + "type": "string", + "description": "Related job's namespace." + }, + "jobCreated": { + "type": "boolean", + "description": "Job created or not." + }, + "phase": { + "$ref": "#/definitions/v1alpha1HelmOperationStatusPhase", + "description": "Current state of the helm operation (job)." + }, + "podCreated": { + "type": "boolean", + "description": "Pod created or not." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current service state of helmOperation." + } + } + }, + "v1alpha1HelmOperationStatusPhase": { + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Running", + "Succeeded", + "Failed", + "Blocked" + ], + "default": "PHASE_UNSPECIFIED", + "description": "Current phase of the helm operation (job).\n\n - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Running: Job running, consistent with kubean ClusterOpsStatus \"Running\".\n - Succeeded: Job succeeded, consistent with kubean ClusterOpsStatus \"Succeeded\".\n - Failed: Job failed or deleted, consistent with kubean ClusterOpsStatus \"Failed\".\n - Blocked: Job waiting, consistent with kubean ClusterOpsStatus \"Blocked\"." + }, + "v1alpha1HelmRelease": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1ReleaseSpec", + "description": "ReleaseSpec describes how the release execution will look like and when it\nwill actually run." + }, + "status": { + "$ref": "#/definitions/v1alpha1ReleaseStatus", + "description": "ReleaseStatus contains the release status." + } + } + }, + "v1alpha1HelmRepo": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1RepoSpec", + "description": "RepoSpec describes how the repository execution will look like and when it\nwill actually run." + }, + "status": { + "$ref": "#/definitions/v1alpha1RepoStatus", + "description": "RepoStatus contains the repository status." + } + } + }, + "v1alpha1HorizontalPodAutoscaler": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1HorizontalPodAutoscalerSpec", + "description": "behaviour of autoscaler. More info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status." + }, + "status": { + "$ref": "#/definitions/v1alpha1HorizontalPodAutoscalerStatus", + "description": "current information about the autoscaler." + } + }, + "description": "configuration of a horizontal pod autoscaler." + }, + "v1alpha1HorizontalPodAutoscalerBehavior": { + "type": "object", + "properties": { + "scaleUp": { + "$ref": "#/definitions/v1alpha1HPAScalingRules", + "description": "No stabilization is used.\n+optional", + "title": "scaleUp is scaling policy for scaling Up.\nIf not set, the default value is the higher of:\n - increase no more than 4 pods per 60 seconds\n - double the number of pods per 60 seconds" + }, + "scaleDown": { + "$ref": "#/definitions/v1alpha1HPAScalingRules", + "title": "scaleDown is scaling policy for scaling Down.\nIf not set, the default value is to allow to scale down to minReplicas pods, with a\n300 second stabilization window (i.e., the highest recommendation for\nthe last 300sec is used).\n+optional" + } + } + }, + "v1alpha1HorizontalPodAutoscalerSpec": { + "type": "object", + "properties": { + "scaleTargetRef": { + "$ref": "#/definitions/v1alpha1CrossVersionObjectReference", + "description": "reference to scaled resource; horizontal pod autoscaler will learn the\ncurrent resource consumption and will set the desired number of pods by\nusing its Scale subresource." + }, + "minReplicas": { + "type": "integer", + "format": "int32", + "title": "minReplicas is the lower limit for the number of replicas to which the\nautoscaler can scale down. It defaults to 1 pod. minReplicas is allowed\nto be 0 if the alpha feature gate HPAScaleToZero is enabled and at least\none Object or External metric is configured. Scaling is active as long as\nat least one metric value is available. +optional" + }, + "maxReplicas": { + "type": "integer", + "format": "int32", + "description": "upper limit for the number of pods that can be set by the autoscaler;\ncannot be smaller than MinReplicas." + }, + "metrics": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1MetricSpec" + }, + "title": "metrics contains the specifications for which to use to calculate the\ndesired replica count (the maximum replica count across all metrics will\nbe used). The desired replica count is calculated multiplying the\nratio between the target value and the current value by the current\nnumber of pods. Ergo, metrics used must decrease as the pod count is\nincreased, and vice-versa. See the individual metric source types for\nmore information about how each type of metric must respond.\nIf not set, the default metric will be set to 80% average CPU utilization.\n+listType=atomic\n+optional" + }, + "behavior": { + "$ref": "#/definitions/v1alpha1HorizontalPodAutoscalerBehavior", + "title": "behavior configures the scaling behavior of the target\nin both Up and Down directions (scaleUp and scaleDown fields respectively).\nIf not set, the default HPAScalingRules for scale up and scale down are used.\n+optional\ntodo: add HorizontalPodAutoscalerBehavior" + } + }, + "description": "specification of a horizontal pod autoscaler." + }, + "v1alpha1HorizontalPodAutoscalerStatus": { + "type": "object", + "properties": { + "lastScaleTime": { + "type": "string", + "format": "int64", + "title": "last time the HorizontalPodAutoscaler scaled the number of pods;\nused by the autoscaler to control how often the number of pods is changed.\n+optional" + }, + "currentReplicas": { + "type": "integer", + "format": "int32", + "description": "current number of replicas of pods managed by this autoscaler." + }, + "desiredReplicas": { + "type": "integer", + "format": "int32", + "description": "desired number of replicas of pods managed by this autoscaler." + }, + "currentMetrics": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1MetricStatus" + }, + "title": "currentMetrics is the last read state of the metrics used by this autoscaler.\n+listType=atomic\n+optional" + }, + "phase": { + "$ref": "#/definitions/v1alpha1HorizontalPodAutoscalerStatusPhase", + "description": "The phase of hpa." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current service state of HPA." + } + } + }, + "v1alpha1HorizontalPodAutoscalerStatusPhase": { + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Ready", + "NotReady" + ], + "default": "PHASE_UNSPECIFIED", + "description": "- Ready: The Ready phase which means the hpa is normal.\n - NotReady: The NotReady phase which means some error occur.", + "title": "The list of HPA phase;" + }, + "v1alpha1HostPathVolumeSource": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path of the directory on the host.\nIf the path is a symlink, it will follow the link to the real path." + }, + "type": { + "type": "string", + "title": "Type for HostPath Volume\nDefaults to \"\"\n+optional" + } + }, + "description": "HostPathVolumeSource Represents a host path mapped into a pod.\nHost path volumes do not support ownership management or SELinux relabeling." + }, + "v1alpha1IPBlock": { + "type": "object", + "properties": { + "cidr": { + "type": "string", + "title": "CIDR is a string representing the IP Block\nValid examples are \"192.168.1.1/24\" or \"2001:db9::/64\"" + }, + "except": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Except is a slice of CIDRs that should not be included within an IP Block\nValid examples are \"192.168.1.1/24\" or \"2001:db9::/64\"\nExcept values will be rejected if they are outside the CIDR range\n+optional" + } + }, + "description": "IPBlock describes a particular CIDR (Ex. \"192.168.1.1/24\",\"2001:db9::/64\") that is allowed\nto the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs\nthat should not be included within this rule." + }, + "v1alpha1Ingress": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1IngressSpec", + "description": "Spec is the desired state of the Ingress." + }, + "status": { + "$ref": "#/definitions/v1alpha1IngressStatus", + "description": "Status is the current state of the Ingress." + } + }, + "description": "Ingress is a collection of rules that allow inbound connections to reach the\nendpoints defined by a backend. An Ingress can be configured to give services\nexternally-reachable urls, load balance traffic, terminate SSL, offer name\nbased virtual hosting etc." + }, + "v1alpha1IngressBackend": { + "type": "object", + "properties": { + "service": { + "$ref": "#/definitions/v1alpha1IngressServiceBackend", + "description": "Service references a Service as a Backend.\nThis is a mutually exclusive setting with \"Resource\"." + }, + "resource": { + "$ref": "#/definitions/apinetworkingv1alpha1TypedLocalObjectReference", + "description": "Resource is an ObjectRef to another Kubernetes resource in the namespace\nof the Ingress object. If resource is specified, a service.Name and\nservice.Port must not be specified.\nThis is a mutually exclusive setting with \"Service\"." + } + }, + "description": "IngressBackend describes all endpoints for a given service and port." + }, + "v1alpha1IngressClassSummary": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name is the name of ingress class" + }, + "isDefaultClass": { + "type": "boolean", + "description": "IsDefaultClass is used to indicate that an IngressClass should be considered default." + }, + "kind": { + "type": "string", + "description": "Kind field is an implementation identifier of ingress, e.g. k8s.io/ingress-nginx." + } + } + }, + "v1alpha1IngressRule": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "Host is the fully qualified domain name of a network host, as defined by\nRFC 3986." + }, + "http": { + "$ref": "#/definitions/v1alpha1HTTPIngressRuleValue", + "description": "HTTPIngressRuleValue is a list of http selectors pointing to backends." + } + }, + "description": "IngressRule represents the rules mapping the paths under a specified host to\nthe related backend services. Incoming requests are first evaluated for a host\nmatch, then routed to the backend associated with the matching IngressRuleValue." + }, + "v1alpha1IngressServiceBackend": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name is the referenced service. The service must exist in" + }, + "port": { + "$ref": "#/definitions/v1alpha1IngressServiceBackendPort", + "title": "Port of the referenced service. A port name or port number" + } + }, + "description": "IngressServiceBackend references a Kubernetes Service as a Backend." + }, + "v1alpha1IngressServiceBackendPort": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name is the name of the port on the Service.\nThis is a mutually exclusive setting with \"Number\"." + }, + "number": { + "type": "integer", + "format": "int32", + "description": "Number is the numerical port number (e.g. 80) on the Service.\nThis is a mutually exclusive setting with \"Name\"." + } + }, + "description": "ServiceBackendPort is the service port being referenced." + }, + "v1alpha1IngressSpec": { + "type": "object", + "properties": { + "ingressClassName": { + "type": "string", + "title": "IngressClassName is the name of the IngressClass cluster resource.\nThe associated IngressClass defines which controller will implement the\nresource. This replaces the deprecated `kubernetes.io/ingress.class`\nannotation. For backwards compatibility, when that annotation is set, it\nmust be given precedence over this field. The controller may emit a\nwarning if the field and annotation have different values.\nImplementations of this API should ignore Ingresses without a class\nspecified. An IngressClass resource may be marked as default, which can\nbe used to set a default value for this field" + }, + "tls": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1IngressTLS" + }, + "description": "TLS configuration.\nCurrently the Ingress only supports a single TLS\nport, 443. If multiple members of this list specify different hosts, they\nwill be multiplexed on the same port according to the hostname specified\nthrough the SNI TLS extension, if the ingress controller fulfilling the\ningress supports SNI." + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1IngressRule" + }, + "description": "A list of host rules used to configure the Ingress. If unspecified, or\nno rule matches, all traffic is sent to the default backend." + } + }, + "description": "IngressSpec is the desired state of the Ingress." + }, + "v1alpha1IngressStatus": { + "type": "object", + "properties": { + "loadBalancer": { + "$ref": "#/definitions/apinetworkingv1alpha1LoadBalancerStatus", + "description": "LoadBalancer contains the current status of the load-balancer." + } + }, + "description": "IngressStatus is the current state of the Ingress." + }, + "v1alpha1IngressTLS": { + "type": "object", + "properties": { + "hosts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Hosts are a list of hosts included in the TLS certificate.\nThe values in this list must match the name/s used in the tlsSecret. Defaults to the\nwildcard host setting for the loadbalancer controller fulfilling this\nIngress, if left unspecified." + }, + "secretName": { + "type": "string", + "description": "SecretName is the name of the secret used to terminate TLS traffic on port\n443.\nField is left optional to allow TLS routing based on SNI\nhostname alone. If the SNI host in a listener conflicts with the \"Host\"\nheader field used by an IngressRule, the SNI host is used for termination\nand value of the Host header is used for routing." + } + }, + "description": "IngressTLS describes the transport layer security associated with an Ingress." + }, + "v1alpha1IntegrateClusterRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name is the user-specified identifier.\nThis field may not be updated." + }, + "aliasName": { + "type": "string", + "description": "It is an alias given by the user and can be changed at will. It cannot be\nempty." + }, + "provider": { + "$ref": "#/definitions/v1alpha1ClusterProvider", + "description": "Provider represents the cloud provider name of the member cluster." + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Labels are key/value pairs that are attached to objects." + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations to attach arbitrary metadata to objects." + }, + "describe": { + "type": "string", + "description": "describe represents the details of the member cluster." + }, + "region": { + "type": "string", + "description": "Region represents the region of the member cluster locate in." + }, + "zone": { + "type": "string", + "description": "Zone represents the zone of the member cluster locate in." + }, + "kubeConfigString": { + "type": "string", + "description": "kubeConfig of the cluster." + }, + "direct": { + "type": "boolean", + "description": "direct Indicates whether the egress agent is created for the sub cluster, if true the egress agent is not created for the sub cluster." + } + }, + "description": "IntegrateClusterRequest requests to integrates a cluster." + }, + "v1alpha1Job": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1JobSpec", + "description": "JobSpec describes how the job execution will look like." + }, + "status": { + "$ref": "#/definitions/v1alpha1JobStatus", + "description": "JobStatus represents the current state of a Job." + }, + "executionTimestamp": { + "type": "string", + "format": "int64", + "description": "Information when was the time the job was successfully executed." + } + }, + "description": "Job represents the details information." + }, + "v1alpha1JobRef": { + "type": "object", + "properties": { + "namesapce": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1JobSpec": { + "type": "object", + "properties": { + "template": { + "$ref": "#/definitions/v1alpha1PodTemplateSpec", + "description": "Describes the pod that will be created when executing a job." + } + }, + "description": "JobSpec describes how the job execution will look like and when it will\nactually run." + }, + "v1alpha1JobStatus": { + "type": "object", + "properties": { + "active": { + "type": "integer", + "format": "int32", + "title": "The number of pending and running pods.\n+optional" + }, + "succeed": { + "type": "integer", + "format": "int32", + "title": "The number of pods which reached phase Succeeded.\n+optional" + }, + "failed": { + "type": "integer", + "format": "int32", + "title": "The number of pods which reached phase Failed.\n+optional" + }, + "phase": { + "$ref": "#/definitions/v1alpha1JobStatusJobState", + "description": "State of a job." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current service state of job." + } + }, + "description": "JobStatus represents the current state of a cron job." + }, + "v1alpha1JobStatusJobState": { + "type": "string", + "enum": [ + "JOB_STATE_UNSPECIFIED", + "Waiting", + "Running", + "Completed", + "Deleting", + "Failed" + ], + "default": "JOB_STATE_UNSPECIFIED", + "description": "Current state of a job.\n\n - JOB_STATE_UNSPECIFIED: Job is unspecified.\n - Waiting: Waiting for job ready.\n - Running: Job is working.\n - Completed: Jobs has completed.\n - Deleting: Jobs is being deleted.\n - Failed: Jobs is not ready to work ." + }, + "v1alpha1KeyToPath": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "The key to project." + }, + "path": { + "type": "string", + "description": "The relative path of the file to map the key to.\nMay not be an absolute path.\nMay not contain the path element '..'.\nMay not start with the string '..'." + }, + "mode": { + "type": "integer", + "format": "int32", + "title": "Optional: mode bits to use on this file, should be a value between 0\nand 0777. If not specified, the volume defaultMode will be used.\nThis might be in conflict with other options that affect the file\nmode, like fsGroup, and the result can be other mode bits set.\n+optional" + } + }, + "description": "KeyToPath maps a string key to a path within a volume." + }, + "v1alpha1KubeOvnConfig": { + "type": "object", + "properties": { + "networkType": { + "$ref": "#/definitions/KubeOvnConfigNetworkType" + }, + "defaultInterfaceName": { + "type": "string", + "title": "The following configuration takes effect only when the network mode is vlan" + }, + "defaultVlanId": { + "type": "string" + }, + "defaultGatewayIpv4": { + "type": "string" + }, + "defaultGatewayIpv6": { + "type": "string" + } + } + }, + "v1alpha1KubeanSetting": { + "type": "object", + "properties": { + "clusterOperationsBackEndLimit": { + "type": "string", + "description": "Set the maximum number of cluster ops reserved for each kubean cluster." + } + } + }, + "v1alpha1KubesprayArgs": { + "type": "object", + "properties": { + "runtime": { + "$ref": "#/definitions/KubesprayArgsRuntime", + "title": "Container runtime" + }, + "runtimeVersion": { + "type": "string", + "title": "Change this to use another runtime version, e.g. a current beta release" + }, + "kubernetesVersion": { + "type": "string", + "title": "Change this to use another Kubernetes version, e.g. a current beta release" + }, + "ntpConfig": { + "$ref": "#/definitions/v1alpha1NTPConfig" + }, + "nodeConfig": { + "$ref": "#/definitions/v1alpha1NodeConfig" + }, + "networkConfig": { + "$ref": "#/definitions/v1alpha1NetworkConfig" + }, + "dnsConfig": { + "$ref": "#/definitions/v1alpha1DNSConfig" + }, + "params": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "containerdInsecureRegistries": { + "type": "array", + "items": { + "type": "string" + }, + "title": "An obvious use case is allowing insecure-registry access to self hosted registries.\nCan be ipaddress and domain_name.\nexample define mirror.registry.io or 172.19.16.11:5000\nset \"name\": \"url\". insecure url must be started http://\nPort number is also needed if the default HTTPS port is not used.\n# containerd_insecure_registries:\n# \"localhost\": \"http://127.0.0.1\"\n# \"172.19.16.11:5000\": \"http://172.19.16.11:5000\"" + }, + "dockerInsecureRegistries": { + "type": "array", + "items": { + "type": "string" + }, + "title": "An obvious use case is allowing insecure-registry access to self hosted registries.\nCan be ipaddress and domain_name.\nexample define 172.19.16.11 or mirror.registry.io\n# docker_insecure_registries:\n# - mirror.registry.io\n# - 172.19.16.11" + }, + "yumRepos": { + "type": "array", + "items": { + "type": "string" + }, + "description": "YumRepos is the yum repository for echo node to be added." + }, + "enableNodeSysctlTuning": { + "type": "boolean", + "description": "EnableNodeSysctlTuning enable systcl tunning variables." + }, + "sysctlParams": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "SysctlParams is work when enabel NodeSysctlTunning." + }, + "enableVerboseLogging": { + "type": "boolean", + "description": "EnableVerboseLogging represents if print more detail logging when installing cluster.\nIt's true by default." + }, + "highLevelParams": { + "type": "string", + "description": "params filled in by the user." + }, + "skipDocker": { + "type": "boolean", + "description": "True means using the docker already exists on the node." + } + } + }, + "v1alpha1Level": { + "type": "string", + "enum": [ + "LEVEL_UNSPECIFIED", + "privileged", + "baseline", + "restricted" + ], + "default": "LEVEL_UNSPECIFIED", + "description": "The Level of Pod Security Standards to broadly cover the security spectrum.\n\n - LEVEL_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - privileged: Privileged is the unrestricted policy, providing the widest possible level of permissions. This policy allows for known privilege escalations.\n - baseline: Baseline is the minimally restrictive policy which prevents known privilege escalations. Allows the default (minimally specified) Pod configuration.\n - restricted: Restricted is the heavily restricted policy, following current Pod hardening best practices." + }, + "v1alpha1Lifecycle": { + "type": "object", + "properties": { + "PostStart": { + "$ref": "#/definitions/v1alpha1Handler", + "title": "PostStart is called immediately after a container is created. If the\nhandler fails, the container is terminated and restarted according to its\nrestart policy. Other management of the container blocks until the hook\ncompletes. More info:\nhttps://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n+optional" + }, + "preStop": { + "$ref": "#/definitions/v1alpha1Handler", + "title": "PreStop is called immediately before a container is terminated due to an\nAPI request or management event such as liveness/startup probe failure,\npreemption, resource contention, etc. The handler is not called if the\ncontainer crashes or exits. The Pod's termination grace period countdown\nbegins before the PreStop hook is executed. Regardless of the outcome of\nthe handler, the container will eventually terminate within the Pod's\ntermination grace period (unless delayed by finalizers). Other management\nof the container blocks until the hook completes or until the termination\ngrace period is reached. More info:\nhttps://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n+optional" + } + }, + "description": "Lifecycle describes actions that the management system should take in\nresponse to container lifecycle events. For the PostStart and PreStop\nlifecycle handlers, management of the container blocks until the action is\ncomplete, unless the container process fails, in which case the handler is\naborted." + }, + "v1alpha1LimitRange": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1LimitRangeSpec", + "description": "Spec defines the limits enforced." + } + }, + "description": "LimitRange sets resource usage limits for each kind of resource in a Namespace." + }, + "v1alpha1LimitRangeItem": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type is a type of object that is limited. It can be Pod, Container, PersistentVolumeClaim or a fully qualified resource name." + }, + "max": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Max usage constraints on this kind by resource name. Format: a map of (resource name, quantity) pairs." + }, + "min": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Min usage constraints on this kind by resource name. Format: a map of (resource name, quantity) pairs." + }, + "default": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Default resource requirement limit value by resource name if resource limit is omitted. Format: a map of (resource name, quantity) pairs." + }, + "defaultRequest": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "DefaultRequest is the default resource requirement request value by resource name if resource request is omitted. Format: a map of (resource name, quantity) pairs." + }, + "maxLimitRequestRatio": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource. Format: a map of (resource name, quantity) pairs." + } + }, + "description": "LimitRangeItem defines a min/max usage limit for any resource that matches on kind." + }, + "v1alpha1LimitRangeSpec": { + "type": "object", + "properties": { + "limits": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1LimitRangeItem" + }, + "description": "Limits is the list of LimitRangeItem objects that are enforced." + } + }, + "description": "LimitRangeSpec defines a min/max usage limit for resources that match on kind." + }, + "v1alpha1ListAdminClusterSummaryResponse": { + "type": "object", + "properties": { + "clusters": { + "type": "array", + "items": { + "type": "string" + }, + "title": "clusters is the cluster summary" + } + } + }, + "v1alpha1ListAllClusterGPUInfoResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPUSpec" + } + } + } + }, + "v1alpha1ListAllStorageClassesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1StorageClass" + }, + "title": "Data describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListPersistentVolumeClaimsRequest represents the response of list storage class" + }, + "v1alpha1ListAllUserRoleSummaryResponse": { + "type": "object", + "properties": { + "items": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1RoleSummary" + } + } + } + }, + "v1alpha1ListArtifactsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Artifact" + }, + "description": "Items is a list of tag names." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, page size, and total." + } + }, + "title": "ListArtifactsResponse returns a list of tags of specified image" + }, + "v1alpha1ListClusterConfigMapsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ConfigMap" + }, + "title": "The data is the ConfigMap YAML details" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "the list of Cluster ConfigMaps." + }, + "v1alpha1ListClusterCronJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CronJob" + }, + "description": "The data field is the cronjob YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "Cluster CronJob information List." + }, + "v1alpha1ListClusterCustomResourcesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CustomResource" + }, + "title": "Data represents the response of CustomResource" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListClusterCustomResourcesResponse represents list all CustomResources of\ncluster scope in cluster" + }, + "v1alpha1ListClusterEventKindsResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Data is the list of involvedObject'kinds of events." + } + }, + "description": "ListClusterEventKindsResponse returns the list of involvedObject's kinds of\nevents." + }, + "v1alpha1ListClusterEventsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Event" + }, + "description": "Data represents the returned event list." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination is for data paging." + } + }, + "description": "ListClusterEventsResponse returns the list and pagination of events." + }, + "v1alpha1ListClusterGPUSummaryResponese": { + "type": "object", + "properties": { + "summary": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPUSummary" + }, + "description": "summary defines a array restore GUP type summary of all nodes." + } + } + }, + "v1alpha1ListClusterHelmOperationsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmOperation" + }, + "description": "A list of operation sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListClusterHelmReleasesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmRelease" + }, + "description": "A list of release sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListClusterIngressesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Ingress" + }, + "description": "Data is the ingress details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Page defines the pagination detail be return." + } + }, + "title": "ListClusterIngressesResponse the response of list all cluster ingresses" + }, + "v1alpha1ListClusterInstalledHelmChartResponse": { + "type": "object", + "properties": { + "entries": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1HelmChartVersions" + }, + "title": "The built in helm repo which helm chart install" + } + } + }, + "v1alpha1ListClusterJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Job" + }, + "description": "The data is the job YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "Cluster Jobs information List." + }, + "v1alpha1ListClusterLimitRangesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1LimitRange" + }, + "description": "Items of LimitRange." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "List of cluster LimitRanges." + }, + "v1alpha1ListClusterNamespaceSummaryResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NamespaceSummary" + }, + "title": "Data is the returned namespace summary list" + }, + "accessScope": { + "$ref": "#/definitions/ListClusterNamespaceSummaryResponseScope", + "description": "AccessScope indicates whether the user has the cluster right." + } + } + }, + "v1alpha1ListClusterNamespacesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Namespace" + }, + "title": "Data is the returned namespace list" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListClusterNetworkPoliciesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicy" + }, + "description": "Items is the networkpolicy list." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination defines the pagination detail to return." + } + }, + "description": "ListClusterNetworkPoliciesResponse returns a list of all networkpolicies in the cluster." + }, + "v1alpha1ListClusterNodeSummaryResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeSummary" + } + } + }, + "description": "It returns node list in the cluster." + }, + "v1alpha1ListClusterPersistentVolumeClaimsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaim" + }, + "title": "Data describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListClusterPersistentVolumeClaimRequest represents the response of list all namespace PVC" + }, + "v1alpha1ListClusterPreferredResourcesResponse": { + "type": "object", + "properties": { + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1APIResourceList" + }, + "description": "resources contains the name of the resources and if they are namespaced." + } + }, + "description": "ListClusterPreferredResourcesResponse returns a list of cluster." + }, + "v1alpha1ListClusterReplicaSetsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ReplicaSet" + }, + "description": "Items is the list of replicasets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, page size, and total." + } + }, + "description": "ListClusterReplicaSetsResponse returns a list of replicasets in specified cluster." + }, + "v1alpha1ListClusterRoleBindingsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ClusterRoleBinding" + }, + "description": "Data represents the data of roleBindings." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + } + }, + "v1alpha1ListClusterRolesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/apirbacv1alpha1ClusterRole" + }, + "description": "Data represents the data of roles." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListClusterRolesResponse the response of list clusterrole" + }, + "v1alpha1ListClusterSecretsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Secret" + }, + "description": "Secret name." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "List of Cluster Secrets information." + }, + "v1alpha1ListClusterServicesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Service" + }, + "description": "Items is the list of services." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, page size, and total." + } + }, + "description": "List of cluster services." + }, + "v1alpha1ListClusterSriovAllocatedResourcesResponse": { + "type": "object", + "properties": { + "allocatedResources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1AllocatedResource" + } + } + }, + "title": "ListClusterSriovAllocatedResourcesResponse is a response for node sriov-related resources" + }, + "v1alpha1ListClusterSummaryResponse": { + "type": "object", + "properties": { + "clusterSummary": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ClusterSummary" + } + } + }, + "description": "ClusterSummaryResponse returns a list of cluster." + }, + "v1alpha1ListClusterVolumeSnapshotsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VolumeSnapshot" + }, + "title": "Data describes the common attributes of volumeSnapshot" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListClusterVolumeSnapshotRequest represents the response of list all namespace VolumeSnapshot" + }, + "v1alpha1ListClusterlcmOpsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ClusterlcmOps" + }, + "description": "The data of clusterclmOps." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + } + }, + "v1alpha1ListClustersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Cluster" + }, + "title": "data The data field is the YAML details" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "Clusters information List." + }, + "v1alpha1ListConfigMapRelatedWorkloadsResponse": { + "type": "object", + "properties": { + "pods": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Pod" + } + }, + "daemonsets": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1DaemonSet" + } + }, + "deployments": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Deployment" + } + }, + "statefulsets": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1StatefulSet" + } + }, + "jobs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Job" + } + } + } + }, + "v1alpha1ListConfigMapsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ConfigMap" + }, + "description": "Standard object's data." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListControllerRevisionsRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "StatefulSet", + "DaemonSet" + ], + "default": "KIND_UNSPECIFIED" + }, + "v1alpha1ListControllerRevisionsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ControlleRrevision" + }, + "description": "Data is the revision list related to the specified statefulset." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListCronHorizontalPodAutoscalersRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "ReplicaSet" + ], + "default": "KIND_UNSPECIFIED", + "description": "The list of hpa kind enums.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A hpa which targetRef kind is Deployment.\n - StatefulSet: A hpa which targetRef kind is StatefulSet.\n - ReplicaSet: A hpa which targetRef kind is ReplicaSet." + }, + "v1alpha1ListCronHorizontalPodAutoscalersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CronHorizontalPodAutoscaler" + }, + "description": "The data is the job YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "HorizontalPodAutoscalers information list." + }, + "v1alpha1ListCronJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CronJob" + }, + "description": "The data field is the cronjob YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "CronJob information List." + }, + "v1alpha1ListCustomMetricSummaryResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The data is the array of metric." + } + }, + "description": "The response of listing ListCustomMetricsSummary." + }, + "v1alpha1ListCustomResourceDefinitionGroupsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Items represents groups of customResourceDefinitions." + } + }, + "title": "ListCustomResourceDefinitionGroupsResponse represents a list of all groups of customResourceDefinitions" + }, + "v1alpha1ListCustomResourceDefinitionsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CustomResourceDefinition" + }, + "description": "CustomResourceDefinition represents all custom resource definitions." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListCustomResourceDefinitionsResponse represents response of list all\nCustomResourceDefinitions" + }, + "v1alpha1ListCustomResourcesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CustomResource" + }, + "title": "Data represents the response of CustomResource" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListCustomResourcesResponse represents list all of the CustomResources of\nnamespaced scope in cluster" + }, + "v1alpha1ListDaemonSetsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1DaemonSet" + }, + "title": "Data represents the kpanda's workload types of inclusion" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "description": "Response message for the `ListDaemonSets` method." + }, + "v1alpha1ListDeploymentsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Deployment" + }, + "title": "Data represents the kpanda's workload types of inclusion" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "description": "Response message for the `ListDeployments` method." + }, + "v1alpha1ListEtcdBackupStrategiesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy" + }, + "description": "EtcdBackupStrategy A list of etcd backup strategy sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListEtcdSnapshotsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Snapshot" + } + } + } + }, + "v1alpha1ListEventsRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet", + "Pod", + "Service", + "Ingress", + "Job", + "CronJob", + "HorizontalPodAutoscaler", + "ReplicaSet", + "CronHPA", + "PersistentVolumeClaim", + "GroupVersionResource" + ], + "default": "KIND_UNSPECIFIED", + "description": " - KIND_UNSPECIFIED: KIND_UNSPECIFIED is only a meaningless placeholder, to avoid zero not\nreturn.\n - Deployment: ListEvents by deployment.\n - StatefulSet: ListEvents by statefulSet.\n - DaemonSet: ListEvents by daemonSet.\n - Pod: ListEvents by pod.\n - Service: ListEvents by service.\n - Ingress: ListEvents by ingress.\n - Job: ListEvents by job.\n - CronJob: ListEvents by cronJob.\n - HorizontalPodAutoscaler: ListEvents by HorizontalPodAutoscaler.\n - ReplicaSet: ListEvents by replicaset.\n - CronHPA: ListEvents by CronHPA.\n - PersistentVolumeClaim: ListEvents by PersistentVolumeClaim.\n - GroupVersionResource: ListEvents by GroupVersionResource. If kind is set to GroupVersionResource,\nyou must specify the value of group version resource." + }, + "v1alpha1ListEventsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Event" + }, + "title": "Data response of the workload's event" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListEventsByWorkloadNameResponse the response of listEvents by workload name" + }, + "v1alpha1ListFeatureGatesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1FeatureGate" + } + } + } + }, + "v1alpha1ListGPUSettingResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPUSetting" + }, + "description": "The plugins in the specific cluster." + } + } + }, + "v1alpha1ListGlobalRolesResponse": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1ListGroupsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Group" + } + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination is for data paging." + } + } + }, + "v1alpha1ListHelmChartsResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmChartVersion" + } + }, + "categories": { + "$ref": "#/definitions/ListHelmChartsResponseCategoryItem" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListHelmOperationsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmOperation" + }, + "description": "A list of operation sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListHelmReleaseResourcesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Resource" + }, + "description": "A list of resources sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "ListHelmReleaseResourcesResponse returns resources of a helmrelease." + }, + "v1alpha1ListHelmReleaseRevisionsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Revision" + }, + "description": "A list of revisions sets." + } + }, + "description": "ListHelmReleaseRevisionsResponse returns revisions of a helmrelease." + }, + "v1alpha1ListHelmReleasesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmRelease" + }, + "description": "A list of release sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListHelmReposResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HelmRepo" + }, + "description": "HelmRepo A list of repo sets." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + } + }, + "v1alpha1ListHorizontalPodAutoscalersRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "ReplicaSet" + ], + "default": "KIND_UNSPECIFIED", + "description": "The list of hpa kind enums.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A hpa which targetRef kind is Deployment.\n - StatefulSet: A hpa which targetRef kind is StatefulSet.\n - ReplicaSet: A hpa which targetRef kind is ReplicaSet." + }, + "v1alpha1ListHorizontalPodAutoscalersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1HorizontalPodAutoscaler" + }, + "description": "The data is the job YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "HorizontalPodAutoscalers information list." + }, + "v1alpha1ListImageTagsResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "The response of list image tags." + }, + "v1alpha1ListIngressClassSummaryResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1IngressClassSummary" + } + } + } + }, + "v1alpha1ListIngressesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Ingress" + }, + "description": "Data is the ingress details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Page defines the pagination detail be return." + } + }, + "title": "ListIngressesResponse the response of list one cluster ingresses" + }, + "v1alpha1ListJobsByCronJobNameResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Job" + }, + "description": "The data field is the cronjob YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "CronJob Name information List" + }, + "v1alpha1ListJobsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Job" + }, + "description": "The data is the job YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "Jobs information List." + }, + "v1alpha1ListKubeVersionsResponse": { + "type": "object", + "properties": { + "kubernetesVersions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "The available k8s version list." + }, + "preferredVersion": { + "type": "string" + }, + "useLocalService": { + "type": "boolean" + } + } + }, + "v1alpha1ListLimitRangesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1LimitRange" + }, + "description": "Items of LimitRanges." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "ListLimitRangesResponse returns LimitRange list." + }, + "v1alpha1ListMetallbIPPoolResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1MetallbIPPool" + }, + "description": "List of MetallbIPPool." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Page defines the pagination detail be return." + } + } + }, + "v1alpha1ListMetricValuesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1CustomMetricValue" + } + } + } + }, + "v1alpha1ListNamespacesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Namespace" + }, + "title": "Data is the returned namespace list" + }, + "pagination": { + "$ref": "#/definitions/typesPagination" + } + }, + "description": "ListNamespaceResponse is a list of Namespaces." + }, + "v1alpha1ListNetworkPoliciesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicy" + }, + "description": "Items is the networkpolicy list." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination defines the pagination detail to return." + } + }, + "description": "ListNetworkPoliciesResponse returns a list of networkpolicies in a namespace." + }, + "v1alpha1ListNodeGPUResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1GPU" + } + } + } + }, + "v1alpha1ListNodesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Node" + }, + "description": "Node name." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "List of Nodes information." + }, + "v1alpha1ListPersistentVolumeClaimsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaim" + }, + "title": "Data describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListPersistentVolumeClaimRequest represents the response of list PVC" + }, + "v1alpha1ListPersistentVolumesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolume" + }, + "description": "Items of PersistentVolumes." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "ListPersistentVolumesResponse returns PersistentVolume list." + }, + "v1alpha1ListPluginsResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Plugin" + }, + "description": "The plugins in the specific cluster." + } + } + }, + "v1alpha1ListPodContainerResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ContainerStatus" + }, + "title": "Data represents the container status" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListPodContainerResponse represents the response of list pod container" + }, + "v1alpha1ListPodsByNodeResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Pod" + }, + "description": "The data field is the YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "Pod list belong to the node." + }, + "v1alpha1ListPodsRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet", + "Service", + "Job", + "CronJob", + "ReplicaSet", + "NetworkPolicy" + ], + "default": "KIND_UNSPECIFIED", + "description": " - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A Deployment provides declarative updates for Pods and ReplicaSets.\n - StatefulSet: StatefulSet is the workload API object used to manage stateful\napplications.\n - DaemonSet: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod.\n - Service: Service to expose an application running on a set of Pods.\n - Job: Job is used to express a one-time task.\n - CronJob: CronJob runs repeatedly according to its time schedule.\n - ReplicaSet: ReplicaSet is the workload API object used to manage pods\n - NetworkPolicy: NetworkPolicy uses podSelector to select pods." + }, + "v1alpha1ListPodsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Pod" + }, + "description": "Standard object's data." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "List of pod information." + }, + "v1alpha1ListProjectsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Items is a list of project names." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, page size, and total." + } + }, + "title": "ListProjectsResponse returns a list of projects of a registry" + }, + "v1alpha1ListRegistriesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Registry" + }, + "title": "items is registry host" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, page size, and total." + } + }, + "title": "ListRegistriesResponse returns a list of registries" + }, + "v1alpha1ListReplicaSetsRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment" + ], + "default": "KIND_UNSPECIFIED" + }, + "v1alpha1ListReplicaSetsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ReplicaSet" + }, + "description": "data replicaSet ensures that a specified number of pod replicas are running\nat any given time." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListReplicaSetsByDeploymentResponse the response of list replicaSets by\ndeployment name" + }, + "v1alpha1ListRepositoriesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Repository" + }, + "description": "Items is a list of repositories." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, page size, and total." + } + }, + "title": "ListRepositoriesResponse returns a list of projects of a registry" + }, + "v1alpha1ListResourceQuotasResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ResourceQuota" + }, + "description": "Items of ResourceQuotas." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "ListResourceQuotasResponse returns ResourceQuota list." + }, + "v1alpha1ListRoleBindingsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1RoleBinding" + }, + "description": "Data represents the data of roleBindings." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListRoleBindingsResponse the response of list role bindings" + }, + "v1alpha1ListRolesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/rbacv1alpha1Role" + }, + "description": "Data represents the data of roles." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "title": "ListRolesResponse the response of list role" + }, + "v1alpha1ListRuntimeVersionsResponse": { + "type": "object", + "properties": { + "containerdVersions": { + "type": "array", + "items": { + "type": "string" + }, + "title": "The available containerd version list" + }, + "dockerVersions": { + "type": "array", + "items": { + "type": "string" + }, + "title": "The available docker version list" + }, + "preferredVersion": { + "$ref": "#/definitions/ListRuntimeVersionsResponsePreferredVersion", + "description": "The preferred version recommend by system." + } + } + }, + "v1alpha1ListSecretRelatedWorkloadsResponse": { + "type": "object", + "properties": { + "pods": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Pod" + } + }, + "daemonsets": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1DaemonSet" + } + }, + "deployments": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Deployment" + } + }, + "statefulsets": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1StatefulSet" + } + }, + "jobs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Job" + } + } + } + }, + "v1alpha1ListSecretsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Secret" + }, + "description": "Secret name." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "List of Secrets data details." + }, + "v1alpha1ListServiceAccountsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ServiceAccount" + }, + "title": "Data describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListPersistentVolumeClaimsRequest represents the response of list storage class" + }, + "v1alpha1ListServicesRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet" + ], + "default": "KIND_UNSPECIFIED", + "description": " - Deployment: A Deployment provides declarative updates for Pods and ReplicaSets.\n - StatefulSet: StatefulSet is the workload API object used to manage stateful\napplications.\n - DaemonSet: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod." + }, + "v1alpha1ListServicesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Service" + }, + "description": "The data field is the service YAML details." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "The Service list for the given namespace and name if it exists in the\ncluster." + }, + "v1alpha1ListStatefulSetsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1StatefulSet" + }, + "title": "Data represents the kpanda's workload types of inclusion" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "title": "Pagination is for data paging" + } + }, + "description": "Response message for the `ListStatefulSets` method." + }, + "v1alpha1ListStorageClassesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1StorageClass" + }, + "title": "Data describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListPersistentVolumeClaimsRequest represents the response of list storage class" + }, + "v1alpha1ListUsersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1User" + } + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination is for data paging." + } + } + }, + "v1alpha1ListVerticalPodAutoscalersRequestKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Deployment", + "StatefulSet", + "DaemonSet", + "ReplicaSet", + "Job", + "CronJob", + "ReplicationController" + ], + "default": "KIND_UNSPECIFIED", + "description": "The list of vpa kind enums.\n\n - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Deployment: A vpa which targetRef kind is Deployment.\n - StatefulSet: A vpa which targetRef kind is StatefulSet.\n - DaemonSet: A vpa which targetRef kind is DaemonSet.\n - ReplicaSet: A vpa which targetRef kind is ReplicaSet.\n - Job: A vpa which targetRef kind is Job.\n - CronJob: A vpa which targetRef kind is CronJob.\n - ReplicationController: A vpa which targetRef kind is ReplicationController." + }, + "v1alpha1ListVerticalPodAutoscalersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VerticalPodAutoscaler" + }, + "description": "Items is the vpa list." + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "description": "ListVerticalPodAutoscalersResponse returns a list of vpas." + }, + "v1alpha1ListVolumeSnapshotsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VolumeSnapshot" + }, + "title": "Data describes the common attributes of volumeSnapshot" + }, + "pagination": { + "$ref": "#/definitions/typesPagination", + "description": "Pagination returned contains current page, size, and total." + } + }, + "title": "ListVolumeSnapshotRequest represents the response of list VolumeSnapshot" + }, + "v1alpha1ListWorkspacesResponse": { + "type": "object", + "properties": { + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1WorkspaceInfo" + } + } + } + }, + "v1alpha1MIGModeSpec": { + "type": "object", + "properties": { + "config": { + "type": "string" + }, + "strategy": { + "$ref": "#/definitions/v1alpha1MIGStrategy", + "title": "single or mixed" + } + } + }, + "v1alpha1MIGNodeStats": { + "type": "object", + "properties": { + "totalGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of physical Gpus" + }, + "allocatedGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of allocated Gpus" + }, + "totalMigNumber": { + "type": "integer", + "format": "int32", + "title": "Number of mig" + } + } + }, + "v1alpha1MIGStrategy": { + "type": "string", + "enum": [ + "MIG_STRATEGY_UNSPECIFIED", + "MIG_STRATEGY_SINGLE", + "MIG_STRATEGY_MIXED" + ], + "default": "MIG_STRATEGY_UNSPECIFIED", + "title": "- MIG_STRATEGY_UNSPECIFIED: mig_strategy_unspecified unspecified mig strategy\n - MIG_STRATEGY_SINGLE: mig_strategy_single single mig strategy\n - MIG_STRATEGY_MIXED: mig_strategy_mixed mixed mig strategy" + }, + "v1alpha1Maintainer": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "name is a user name or organization name" + }, + "email": { + "type": "string", + "title": "email is an optional email address to contact the named maintainer" + }, + "url": { + "type": "string", + "title": "url is an optional URL to an address for the named maintainer" + } + }, + "description": "Maintainer describes a Chart maintainer." + }, + "v1alpha1Message": { + "type": "string", + "enum": [ + "MESSAGE_UNSPECIFIED", + "MESSAGE_CREATE", + "MESSAGE_UPDATE", + "MESSAGE_DELETE" + ], + "default": "MESSAGE_UNSPECIFIED" + }, + "v1alpha1Metadata": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the chart. Required." + }, + "home": { + "type": "string", + "title": "The URL to a relevant project page, git repo, or contact person" + }, + "sources": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Source is the URL to the source code of this chart" + }, + "version": { + "type": "string", + "description": "A SemVer 2 conformant version string of the chart. Required." + }, + "description": { + "type": "string", + "title": "A one-sentence description of the chart" + }, + "keywords": { + "type": "array", + "items": { + "type": "string" + }, + "title": "A list of string keywords" + }, + "maintainers": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Maintainer" + }, + "title": "A list of name and URL/email address combinations for the maintainer(s)" + }, + "icon": { + "type": "string", + "description": "The URL to an icon file." + }, + "apiVersion": { + "type": "string", + "description": "The API Version of this chart. Required." + }, + "condition": { + "type": "string", + "title": "The condition to check to enable chart" + }, + "tags": { + "type": "string", + "title": "The tags to check to enable chart" + }, + "appVersion": { + "type": "string", + "description": "The version of the application enclosed inside of this chart." + }, + "deprecated": { + "type": "boolean", + "title": "Whether or not this chart is deprecated" + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations are additional mappings uninterpreted by Helm,\nmade available for inspection by other applications." + }, + "kubeVersion": { + "type": "string", + "description": "KubeVersion is a SemVer constraint specifying the version of Kubernetes required." + }, + "dependencies": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Dependency" + }, + "description": "Dependencies are a list of dependencies for a chart." + }, + "type": { + "type": "string", + "title": "Specifies the chart type: application or library" + }, + "repo": { + "type": "string", + "description": "The repo name which the charts belongs to." + } + }, + "description": "Metadata for a Chart file. This models the structure of a Chart.yaml file." + }, + "v1alpha1MetallbIPPool": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1MetallbIPPoolSpec", + "description": "Spec is the desired state of the SpiderIPPool." + } + }, + "description": "Ingress is a collection of rules that allow inbound connections to reach the\nendpoints defined by a backend. An Ingress can be configured to give services\nexternally-reachable urls, load balance traffic, terminate SSL, offer name\nbased virtual hosting etc." + }, + "v1alpha1MetallbIPPoolSpec": { + "type": "object", + "properties": { + "addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "A list of IP address ranges over which MetalLB has authority.\nYou can list multiple ranges in a single pool, they will all share the\nsame settings. Each range can be either a CIDR prefix, or an explicit\nstart-end range of IPs." + }, + "autoAssign": { + "type": "boolean", + "title": "AutoAssign flag used to prevent MetallB from automatic allocation\nfor a pool.\n+optional\n+kubebuilder:default:=true" + }, + "avoidBuggyIPs": { + "type": "boolean", + "title": "AvoidBuggyIPs prevents addresses ending with .0 and .255\nto be used by a pool.\n+optional\n+kubebuilder:default:=false" + } + } + }, + "v1alpha1MetricIdentifier": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "name is the name of the given metric" + } + } + }, + "v1alpha1MetricRangeResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1BatchQueryRangeResult" + }, + "title": "The metric range data" + } + }, + "title": "MetricRangeResponse represents the response of metric range" + }, + "v1alpha1MetricResourceKind": { + "type": "string", + "enum": [ + "KIND_UNSPECIFIED", + "Pod", + "Service" + ], + "default": "KIND_UNSPECIFIED", + "description": " - Pod: The custom metrics for service.\n - Service: The custom metrics for service." + }, + "v1alpha1MetricResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1BatchQueryResult" + }, + "title": "the metric data" + } + }, + "title": "MetricResponse represents the response of metric" + }, + "v1alpha1MetricSourceType": { + "type": "string", + "enum": [ + "METRICS_SOURCE_TYPE_UNSPECIFIED", + "Object", + "Pods", + "Resource", + "External" + ], + "default": "METRICS_SOURCE_TYPE_UNSPECIFIED", + "title": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\",\n\"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object.\nNote: \"ContainerResource\" type is available on when the feature-gate\nHPAContainerMetrics is enabled" + }, + "v1alpha1MetricSpec": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1MetricSourceType", + "title": "type is the type of metric source. It should be one of \"ContainerResource\", \"External\",\n\"Object\", \"Pods\" or \"Resource\", each mapping to a matching field in the object.\nNote: \"ContainerResource\" type is available on when the feature-gate\nHPAContainerMetrics is enabled" + }, + "object": { + "$ref": "#/definitions/v1alpha1ObjectMetricSource", + "title": "object refers to a metric describing a single kubernetes object\n(for example, hits-per-second on an Ingress object).\n+optional" + }, + "pods": { + "$ref": "#/definitions/v1alpha1PodsMetricSource", + "title": "pods refers to a metric describing each pod in the current scale target\n(for example, transactions-processed-per-second). The values will be\naveraged together before being compared to the target value.\n+optional" + }, + "resource": { + "$ref": "#/definitions/v1alpha1ResourceMetricSource", + "title": "resource refers to a resource metric (such as those specified in\nrequests and limits) known to Kubernetes describing each pod in the\ncurrent scale target (e.g. CPU or memory). Such metrics are built in to\nKubernetes, and have special scaling options on top of those available\nto normal per-pod metrics using the \"pods\" source.\n+optional" + }, + "external": { + "$ref": "#/definitions/v1alpha1ExternalMetricSource", + "title": "external refers to a global metric that is not associated\nwith any Kubernetes object. It allows autoscaling based on information\ncoming from components running outside of cluster\n(for example length of queue in cloud messaging service, or\nQPS from loadbalancer running outside of cluster).\n+optional" + } + } + }, + "v1alpha1MetricStatus": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1MetricSourceType", + "title": "type is the type of metric source. It will be one of \"ContainerResource\", \"External\",\n\"Object\", \"Pods\" or \"Resource\", each corresponds to a matching field in the object.\nNote: \"ContainerResource\" type is available on when the feature-gate\nHPAContainerMetrics is enabled" + }, + "object": { + "$ref": "#/definitions/v1alpha1ObjectMetricStatus", + "title": "object refers to a metric describing a single kubernetes object\n(for example, hits-per-second on an Ingress object).\n+optional" + }, + "pods": { + "$ref": "#/definitions/v1alpha1PodsMetricStatus", + "title": "pods refers to a metric describing each pod in the current scale target\n(for example, transactions-processed-per-second). The values will be\naveraged together before being compared to the target value.\n+optional" + }, + "resource": { + "$ref": "#/definitions/v1alpha1ResourceMetricStatus", + "title": "resource refers to a resource metric (such as those specified in\nrequests and limits) known to Kubernetes describing each pod in the\ncurrent scale target (e.g. CPU or memory). Such metrics are built in to\nKubernetes, and have special scaling options on top of those available\nto normal per-pod metrics using the \"pods\" source.\n+optional" + }, + "external": { + "$ref": "#/definitions/v1alpha1ExternalMetricStatus", + "title": "external refers to a global metric that is not associated\nwith any Kubernetes object. It allows autoscaling based on information\ncoming from components running outside of cluster\n(for example length of queue in cloud messaging service, or\nQPS from loadbalancer running outside of cluster).\n+optional" + } + }, + "description": "MetricStatus describes the last-read state of a single metric." + }, + "v1alpha1MetricTarget": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1MetricTargetType", + "title": "type represents whether the metric type is Utilization, Value, or AverageValue" + }, + "value": { + "type": "string", + "title": "value is the target value of the metric (as a quantity).\n+optional" + }, + "averageValue": { + "type": "string", + "title": "averageValue is the target value of the average of the\nmetric across all relevant pods (as a quantity)\n+optional" + }, + "averageUtilization": { + "type": "integer", + "format": "int32", + "title": "averageUtilization is the target value of the average of the\nresource metric across all relevant pods, represented as a percentage of\nthe requested value of the resource for the pods.\nCurrently only valid for Resource metric source type\n+optional" + } + } + }, + "v1alpha1MetricTargetType": { + "type": "string", + "enum": [ + "MetricTargetType_UNSPECIFIED", + "Utilization", + "Value", + "AverageValue" + ], + "default": "MetricTargetType_UNSPECIFIED", + "title": "type represents whether the metric type is Utilization, Value, or AverageValue" + }, + "v1alpha1MetricValueStatus": { + "type": "object", + "properties": { + "value": { + "type": "string", + "title": "value is the current value of the metric (as a quantity).\n+optional" + }, + "averageValue": { + "type": "string", + "title": "averageValue is the current value of the average of the\nmetric across all relevant pods (as a quantity)\n+optional" + }, + "averageUtilization": { + "type": "integer", + "format": "int32", + "title": "currentAverageUtilization is the current value of the average of the\nresource metric across all relevant pods, represented as a percentage of\nthe requested value of the resource for the pods.\n+optional" + } + }, + "title": "MetricValueStatus holds the current value for a metric" + }, + "v1alpha1MigSpec": { + "type": "object", + "properties": { + "gpuIId": { + "type": "string", + "title": "gpu_i_id is the id of each mig instance after the gpu is in mig mode" + }, + "gpuIProfile": { + "type": "string", + "title": "gpu_i_profile is the specification of each mig instance after the gpu is in mig mode" + } + } + }, + "v1alpha1Mode": { + "type": "string", + "enum": [ + "MODE_UNSPECIFIED", + "enforce", + "audit", + "warn" + ], + "default": "MODE_UNSPECIFIED", + "description": "The mode of Pod Security Standards. A namespace can configure any or all modes, or even set a different level for different modes.\n\n - MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - enforce: Enforce policy violations will cause the pod to be rejected.\n - audit: Audit Policy violations will trigger the addition of an audit annotation to the event recorded in the audit log, but are otherwise allowed.\n - warn: Warn policy violations will trigger a user-facing warning, but are otherwise allowed." + }, + "v1alpha1NTPConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean", + "description": "Start the ntpd or chrony service and enable it at system boot." + }, + "servers": { + "type": "array", + "items": { + "type": "string" + } + }, + "timezone": { + "type": "string" + } + }, + "title": "NTP Settings" + }, + "v1alpha1Namespace": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1NamespaceSpec", + "description": "NamespaceSpec describes how the namespace execution will look like and when\nit will actually run." + }, + "status": { + "$ref": "#/definitions/v1alpha1NamespaceStatus", + "title": "Status describes the current status of a Namespace.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n+optional" + } + }, + "description": "Namespace provides a scope for Names." + }, + "v1alpha1NamespacePhase": { + "type": "string", + "enum": [ + "NAMESPACE_PHASE_UNSPECIFIED", + "Active", + "Terminating" + ], + "default": "NAMESPACE_PHASE_UNSPECIFIED", + "title": "- NAMESPACE_PHASE_UNSPECIFIED: The namespace state is unspecified.\n - Active: NamespaceActive means the namespace is available for use in the system\n - Terminating: NamespaceTerminating means the namespace is undergoing graceful termination" + }, + "v1alpha1NamespaceSpec": { + "type": "object", + "properties": { + "Finalizers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "NamespaceSpec describes the attributes on a Namespace." + }, + "v1alpha1NamespaceStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1NamespacePhase", + "description": "Phase represents the phase of namespace." + }, + "readyPodNumber": { + "type": "integer", + "format": "int32", + "description": "ReadyPodNumber is the ready pod number on the namespace." + }, + "totalPodNumber": { + "type": "integer", + "format": "int32", + "description": "TotalPodNumber is the total pod number on the namespace." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Represents the latest available observations of a namespace's current state." + }, + "podSecurityEnabled": { + "type": "boolean", + "description": "PodSecurityEnabled shows if the namespace has enabled pod security policy." + }, + "cpuUsage": { + "type": "number", + "format": "double", + "description": "The cpu usage of the member namespace." + }, + "memoryUsage": { + "type": "number", + "format": "double", + "description": "The memory usage of the member namespace." + }, + "quotaStatus": { + "$ref": "#/definitions/v1alpha1ResourceQuotaStatus" + } + }, + "description": "NamespaceStatus is information about the current status of a Namespace." + }, + "v1alpha1NamespaceSummary": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name must be unique within a cluster." + }, + "cluster": { + "type": "string", + "description": "Cluster the namespace belongs to." + }, + "phase": { + "$ref": "#/definitions/v1alpha1NamespacePhase", + "description": "Phases is used for filter." + } + } + }, + "v1alpha1NetworkConfig": { + "type": "object", + "properties": { + "cni": { + "$ref": "#/definitions/NetworkConfigCNI" + }, + "ciliumConfig": { + "$ref": "#/definitions/v1alpha1CiliumConfig" + }, + "calicoConfig": { + "$ref": "#/definitions/v1alpha1CalicoConfig" + }, + "flannelConfig": { + "$ref": "#/definitions/v1alpha1FlannelConfig" + }, + "kubeOvnConfig": { + "$ref": "#/definitions/v1alpha1KubeOvnConfig" + }, + "commonNetworkConfig": { + "$ref": "#/definitions/v1alpha1CommonNetworkConfig" + } + } + }, + "v1alpha1NetworkPolicy": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1NetworkPolicySpec", + "description": "Specification of the desired behavior for this NetworkPolicy." + } + }, + "description": "NetworkPolicy describes what network traffic is allowed for a set of Pods." + }, + "v1alpha1NetworkPolicyEgressRule": { + "type": "object", + "properties": { + "ports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicyPort" + }, + "title": "List of destination ports for outgoing traffic.\nEach item in this list is combined using a logical OR. If this field is\nempty or missing, this rule matches all ports (traffic not restricted by port).\nIf this field is present and contains at least one item, then this rule allows\ntraffic only if the traffic matches at least one port in the list.\n+optional" + }, + "to": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicyPeer" + }, + "title": "List of destinations for outgoing traffic of pods selected for this rule.\nItems in this list are combined using a logical OR operation. If this field is\nempty or missing, this rule matches all destinations (traffic not restricted by\ndestination). If this field is present and contains at least one item, this rule\nallows traffic only if the traffic matches at least one item in the to list.\n+optional" + } + }, + "title": "NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods\nmatched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to.\nThis type is beta-level in 1.8" + }, + "v1alpha1NetworkPolicyIngressRule": { + "type": "object", + "properties": { + "ports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicyPort" + }, + "title": "List of ports which should be made accessible on the pods selected for this\nrule. Each item in this list is combined using a logical OR. If this field is\nempty or missing, this rule matches all ports (traffic not restricted by port).\nIf this field is present and contains at least one item, then this rule allows\ntraffic only if the traffic matches at least one port in the list.\n+optional" + }, + "from": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicyPeer" + }, + "title": "List of sources which should be able to access the pods selected for this rule.\nItems in this list are combined using a logical OR operation. If this field is\nempty or missing, this rule matches all sources (traffic not restricted by\nsource). If this field is present and contains at least one item, this rule\nallows traffic only if the traffic matches at least one item in the from list.\n+optional" + } + }, + "description": "NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods\nmatched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from." + }, + "v1alpha1NetworkPolicyPeer": { + "type": "object", + "properties": { + "podSelector": { + "$ref": "#/definitions/typesLabelSelector", + "description": "This is a label selector which selects Pods. This field follows standard label\nselector semantics; if present but empty, it selects all pods.\n\nIf NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects\nthe Pods matching PodSelector in the Namespaces selected by NamespaceSelector.\nOtherwise it selects the Pods matching PodSelector in the policy's own Namespace.\n+optional" + }, + "namespaceSelector": { + "$ref": "#/definitions/typesLabelSelector", + "description": "Selects Namespaces using cluster-scoped labels. This field follows standard label\nselector semantics; if present but empty, it selects all namespaces.\n\nIf PodSelector is also set, then the NetworkPolicyPeer as a whole selects\nthe Pods matching PodSelector in the Namespaces selected by NamespaceSelector.\nOtherwise it selects all Pods in the Namespaces selected by NamespaceSelector.\n+optional" + }, + "ipBlock": { + "$ref": "#/definitions/v1alpha1IPBlock", + "title": "IPBlock defines policy on a particular IPBlock. If this field is set then\nneither of the other fields can be.\n+optional" + } + }, + "title": "NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of\nfields are allowed" + }, + "v1alpha1NetworkPolicyPort": { + "type": "object", + "properties": { + "protocol": { + "$ref": "#/definitions/v1alpha1Protocol", + "title": "The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this\nfield defaults to TCP.\n+optional" + }, + "port": { + "type": "string", + "title": "The port on the given protocol. This can either be a numerical or named\nport on a pod. If this field is not provided, this matches all port names and\nnumbers.\nIf present, only traffic on the specified protocol AND port will be matched.\n+optional" + }, + "endPort": { + "type": "integer", + "format": "int32", + "title": "If set, indicates that the range of ports from port to endPort, inclusive,\nshould be allowed by the policy. This field cannot be defined if the port field\nis not defined or if the port field is defined as a named (string) port.\nThe endPort must be equal or greater than port.\nThis feature is in Beta state and is enabled by default.\nIt can be disabled using the Feature Gate \"NetworkPolicyEndPort\".\n+optional" + } + }, + "title": "NetworkPolicyPort describes a port to allow traffic on" + }, + "v1alpha1NetworkPolicySpec": { + "type": "object", + "properties": { + "podSelector": { + "$ref": "#/definitions/typesLabelSelector", + "description": "Selects the pods to which this NetworkPolicy object applies. The array of\ningress rules is applied to any pods selected by this field. Multiple network\npolicies can select the same set of pods. In this case, the ingress rules for\neach are combined additively. This field is NOT optional and follows standard\nlabel selector semantics. An empty podSelector matches all pods in this\nnamespace." + }, + "ingress": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicyIngressRule" + }, + "title": "List of ingress rules to be applied to the selected pods. Traffic is allowed to\na pod if there are no NetworkPolicies selecting the pod\n(and cluster policy otherwise allows the traffic), OR if the traffic source is\nthe pod's local node, OR if the traffic matches at least one ingress rule\nacross all of the NetworkPolicy objects whose podSelector matches the pod. If\nthis field is empty then this NetworkPolicy does not allow any traffic (and serves\nsolely to ensure that the pods it selects are isolated by default)\n+optional" + }, + "egress": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NetworkPolicyEgressRule" + }, + "title": "List of egress rules to be applied to the selected pods. Outgoing traffic is\nallowed if there are no NetworkPolicies selecting the pod (and cluster policy\notherwise allows the traffic), OR if the traffic matches at least one egress rule\nacross all of the NetworkPolicy objects whose podSelector matches the pod. If\nthis field is empty then this NetworkPolicy limits all outgoing traffic (and serves\nsolely to ensure that the pods it selects are isolated by default).\nThis field is beta-level in 1.8\n+optional" + }, + "policyTypes": { + "type": "array", + "items": { + "$ref": "#/definitions/NetworkPolicySpecPolicyType" + }, + "title": "List of rule types that the NetworkPolicy relates to.\nValid options are [\"Ingress\"], [\"Egress\"], or [\"Ingress\", \"Egress\"].\nIf this field is not specified, it will default based on the existence of Ingress or Egress rules;\npolicies that contain an Egress section are assumed to affect Egress, and all policies\n(whether or not they contain an Ingress section) are assumed to affect Ingress.\nIf you want to write an egress-only policy, you must explicitly specify policyTypes [ \"Egress\" ].\nLikewise, if you want to write a policy that specifies that no egress is allowed,\nyou must specify a policyTypes value that include \"Egress\" (since such a policy would not include\nan Egress section and would otherwise default to just [ \"Ingress\" ]).\nThis field is beta-level in 1.8\n+optional" + } + }, + "description": "NetworkPolicySpec provides the specification of a NetworkPolicy." + }, + "v1alpha1Node": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1NodeSpec", + "description": "NodeSpec defines the behavior of a node." + }, + "status": { + "$ref": "#/definitions/v1alpha1NodeStatus", + "description": "Most recently observed status of the node.\nPopulated by the system." + } + } + }, + "v1alpha1NodeAddress": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type is a array used for frontend filter." + }, + "address": { + "type": "string", + "description": "IP Address reachable to the node." + } + }, + "description": "NodeAddress contains information for the instance's address.\nThe node addresses returned here will be set on the node's status.addresses\nfield." + }, + "v1alpha1NodeAffinity": { + "type": "object", + "properties": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "$ref": "#/definitions/v1alpha1NodeSelector", + "title": "If the affinity requirements specified by this field are not met at\nscheduling time, the pod will not be scheduled onto the node.\nIf the affinity requirements specified by this field cease to be met\nat some point during pod execution (e.g. due to an update), the system\nmay or may not try to eventually evict the pod from its node.\n+optional" + }, + "preferredDuringSchedulingIgnoredDuringExecution": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PreferredSchedulingTerm" + }, + "title": "The scheduler will prefer to schedule pods to nodes that satisfy\nthe affinity expressions specified by this field, but it may choose\na node that violates one or more of the expressions. The node that is\nmost preferred is the one with the greatest sum of weights, i.e.\nfor each node that meets all of the scheduling requirements (resource\nrequest, requiredDuringScheduling affinity expressions, etc.),\ncompute a sum by iterating through the elements of this field and adding\n\"weight\" to the sum if the node matches the corresponding matchExpressions;\nthe node(s) with the highest sum are the most preferred. +optional" + } + }, + "description": "Node affinity is a group of node affinity scheduling rules." + }, + "v1alpha1NodeCondition": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of node condition. The built-in set of conditions are: Ready,\nMemoryPressure, DiskPressure, PIDPressure,\nNetworkUnavailable, and SchedulingDisabled." + }, + "status": { + "$ref": "#/definitions/typesConditionStatus", + "description": "Status of the condition, one of True, False, Unknown." + }, + "reason": { + "type": "string", + "description": "(brief) reason for the condition's last transition." + }, + "message": { + "type": "string", + "description": "Human readable message indicating details about last transition." + } + }, + "description": "NodeCondition contains condition information for a node." + }, + "v1alpha1NodeConfig": { + "type": "object", + "properties": { + "nodeInfo": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeInfo" + } + }, + "sshInfo": { + "$ref": "#/definitions/v1alpha1SSHInfo" + }, + "ansibleExtraArgs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1NodeInfo": { + "type": "object", + "properties": { + "hostName": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "role": { + "$ref": "#/definitions/v1alpha1NodeInfoRole" + }, + "user": { + "type": "string" + }, + "pass": { + "type": "string" + } + } + }, + "v1alpha1NodeInfoRole": { + "type": "string", + "enum": [ + "ROlE_UNSPECIFIED", + "Worker", + "Controller" + ], + "default": "ROlE_UNSPECIFIED" + }, + "v1alpha1NodeKubesprayArgs": { + "type": "object", + "properties": { + "params": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "containerdInsecureRegistries": { + "type": "array", + "items": { + "type": "string" + }, + "title": "An obvious use case is allowing insecure-registry access to self hosted registries.\nCan be ipaddress and domain_name.\nexample define mirror.registry.io or 172.19.16.11:5000\nset \"name\": \"url\". insecure url must be started http://\nPort number is also needed if the default HTTPS port is not used.\n# containerd_insecure_registries:\n# \"localhost\": \"http://127.0.0.1\"\n# \"172.19.16.11:5000\": \"http://172.19.16.11:5000\"" + }, + "dockerInsecureRegistries": { + "type": "array", + "items": { + "type": "string" + }, + "title": "An obvious use case is allowing insecure-registry access to self hosted registries.\nCan be ipaddress and domain_name.\nexample define 172.19.16.11 or mirror.registry.io\n# docker_insecure_registries:\n# - mirror.registry.io\n# - 172.19.16.11" + }, + "yumRepos": { + "type": "array", + "items": { + "type": "string" + }, + "description": "YumRepos is the yum repository for echo node to be added." + }, + "enableNodeSysctlTuning": { + "type": "boolean", + "description": "EnableNodeSysctlTuning enable systcl tunning variables." + }, + "sysctlParams": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "SysctlParams is work when enabel NodeSysctlTunning." + }, + "sshSecretName": { + "type": "string", + "title": "SSHSecretName means secret name for ssh private key" + } + } + }, + "v1alpha1NodePhase": { + "type": "string", + "enum": [ + "NODE_PHASE_UNSPECIFIED", + "Ready", + "Not_Ready", + "Unknown" + ], + "default": "NODE_PHASE_UNSPECIFIED", + "description": "Phase includes Ready, NotReady, and Unknown.\n\n - NODE_PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Ready: The node is ready to work.\n - Not_Ready: The node is not ready.\n - Unknown: The node state is unknown." + }, + "v1alpha1NodeSelector": { + "type": "object", + "properties": { + "nodeSelectorTerms": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeSelectorTerm" + } + } + }, + "title": "A node selector represents the union of the results of one or more label\nqueries over a set of nodes; that is, it represents the OR of the selectors\nrepresented by the node selector terms. +structType=atomic" + }, + "v1alpha1NodeSelectorRequirement": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "The label key that the selector applies to." + }, + "operator": { + "type": "string", + "description": "Represents a key's relationship to a set of values.\nValid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt." + }, + "values": { + "type": "array", + "items": { + "type": "string" + }, + "title": "An array of string values. If the operator is In or NotIn,\nthe values array must be non-empty. If the operator is Exists or\nDoesNotExist, the values array must be empty. If the operator is Gt or Lt,\nthe values array must have a single element, which will be interpreted as\nan integer. This array is replaced during a strategic merge patch.\n+optional" + } + }, + "description": "A node selector requirement is a selector that contains values, a key, and an\noperator that relates the key and values." + }, + "v1alpha1NodeSelectorTerm": { + "type": "object", + "properties": { + "matchExpressions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeSelectorRequirement" + }, + "title": "A list of node selector requirements by node's labels.\n+optional" + }, + "matchFields": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeSelectorRequirement" + }, + "title": "A list of node selector requirements by node's fields.\n+optional" + } + }, + "title": "A null or empty node selector term matches no objects. The requirements of\nthem are ANDed.\nThe TopologySelectorTerm type implements a subset of the NodeSelectorTerm.\n+structType=atomic" + }, + "v1alpha1NodeSpec": { + "type": "object", + "properties": { + "podCIDR": { + "type": "string", + "description": "PodCIDR represents the pod IP range assigned to the node." + }, + "unschedulable": { + "type": "boolean", + "description": "Unschedulable controls node schedulability of new pods. By default, node is\nschedulable." + }, + "taints": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Taint" + }, + "description": "If specified, the node's taints." + } + } + }, + "v1alpha1NodeStatus": { + "type": "object", + "properties": { + "status": { + "$ref": "#/definitions/v1alpha1NodeStatusStatus", + "description": "Status represents the current information/status of node." + }, + "addresses": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeAddress" + }, + "description": "IP Address reachable to the node." + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeStatusRole" + }, + "description": "The roles of current node." + }, + "cpuCapacity": { + "type": "string", + "format": "int64", + "description": "CpuCapacity is the total cpu of the node. Unit: m." + }, + "cpuAllocated": { + "type": "number", + "format": "double", + "description": "CpuAllocated is the total pod cpu request on the node. Unit: %." + }, + "cpuUsage": { + "type": "number", + "format": "double", + "description": "CpuUsage is the cpu usage on the node. Unit: %." + }, + "memoryCapacity": { + "type": "string", + "format": "int64", + "description": "MemoryCapacity is the total memory of the node. Unit: byte." + }, + "memoryAllocated": { + "type": "number", + "format": "double", + "description": "MemoryAllocated is the total pod memory request on the node. Unit: %." + }, + "memoryUsage": { + "type": "number", + "format": "double", + "description": "MemoryUsage is the memory usage on the node. Unit: %." + }, + "systemInfo": { + "$ref": "#/definitions/v1alpha1NodeSystemInfo", + "description": "Set of ids/uuids to uniquely identify the node." + }, + "allowedPodNumber": { + "type": "integer", + "format": "int32", + "description": "AllowedPodNumber is the max pod number allowed on the node." + }, + "podAllocated": { + "type": "integer", + "format": "int32", + "description": "PodAllocated is the pod number already allocated on the node." + }, + "readyPodNumber": { + "type": "integer", + "format": "int32", + "description": "ReadyPodNumber is the ready pod number on the node." + }, + "storageCapacity": { + "type": "string", + "format": "int64", + "description": "StorageCapacity is the total storage of the node. Unit: byte." + }, + "storageAllocated": { + "type": "string", + "format": "int64", + "description": "StorageAllocated is the total pod storage request on the node. Unit: byte." + }, + "storageUsage": { + "type": "number", + "format": "double", + "description": "StorageUsage is the usage of storage space on the node. Unit: %." + }, + "storageDriver": { + "type": "string", + "description": "StorageDriver is the docker storage driver (e.g. overlay2)." + }, + "gpuTotal": { + "type": "string", + "format": "int64", + "description": "gpu_total is gpu total number." + }, + "gpuAllocated": { + "type": "string", + "format": "int64", + "description": "gpu_allocated is gpu allocated number." + }, + "gpuMemoryTotal": { + "type": "string", + "format": "int64", + "description": "gpu_memory_total is all gpu memory number with node. Unit: byte." + }, + "gpuMemoryAllocated": { + "type": "string", + "format": "int64", + "title": "gpu_memory_allocated is allocated gpu memory number with node. Unit: byte" + }, + "gpuCoreUsage": { + "type": "number", + "format": "double", + "title": "gpu_core_usage is the usage rate of gpu" + }, + "gpuMemoryUsage": { + "type": "number", + "format": "double", + "title": "gpu_memory_usage is the usage rate of gpu video memory" + } + }, + "description": "NodeStatus is information about the current status of a node." + }, + "v1alpha1NodeStatusRole": { + "type": "string", + "enum": [ + "NODE_ROLE_UNSPECIFIED", + "CONTROL_PLANE", + "WORKER" + ], + "default": "NODE_ROLE_UNSPECIFIED", + "description": "Role includes control-plane and worker.\n\n - NODE_ROLE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - CONTROL_PLANE: The control plane manages the worker nodes and the Pods in the cluster.\n - WORKER: The worker node(s) host the Pods that are the components of the\napplication workload." + }, + "v1alpha1NodeStatusStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1NodePhase" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1NodeCondition" + }, + "description": "NodeCondition contains condition information for a node." + } + }, + "description": "Status is the current observed node condition." + }, + "v1alpha1NodeSummary": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of node." + }, + "uid": { + "type": "string", + "description": "UID is the unique in time and space value for this object." + }, + "creationTimestamp": { + "type": "string", + "format": "int64", + "description": "CreationTimestamp represents the creationTime of the node." + }, + "podCIDR": { + "type": "string", + "description": "PodCIDR represents the pod IP range assigned to the node." + }, + "unschedulable": { + "type": "boolean", + "description": "Unschedulable controls node schedulability of new pods. By default, node is\nschedulable." + }, + "phase": { + "$ref": "#/definitions/v1alpha1NodePhase", + "description": "Phase represents the phase of nodes to search." + } + }, + "description": "Node information Details Summary." + }, + "v1alpha1NodeSystemInfo": { + "type": "object", + "properties": { + "kernelVersion": { + "type": "string", + "description": "Kernel Version reported by the node from 'uname -r'\n(e.g. 3.16.0-0.bpo.4-amd64)." + }, + "osImage": { + "type": "string", + "description": "OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7\n(wheezy))." + }, + "containerRuntimeVersion": { + "type": "string", + "description": "ContainerRuntime Version reported by the node through runtime remote API\n(e.g. docker://1.5.0)." + }, + "kubeletVersion": { + "type": "string", + "description": "Kubelet Version reported by the node." + }, + "kubeProxyVersion": { + "type": "string", + "description": "KubeProxy Version reported by the node." + }, + "operatingSystem": { + "type": "string", + "description": "The Operating System reported by the node." + }, + "architecture": { + "type": "string", + "description": "The Architecture reported by the node." + } + } + }, + "v1alpha1ObjectFieldSelector": { + "type": "object", + "properties": { + "apiVersion": { + "type": "string", + "title": "Version of the schema the FieldPath is written in terms of, defaults to\n\"v1\". +optional" + }, + "fieldPath": { + "type": "string", + "description": "Path of the field to select in the specified API version." + } + }, + "description": "ObjectFieldSelector selects an APIVersioned field of an object." + }, + "v1alpha1ObjectMetricSource": { + "type": "object", + "properties": { + "describedObject": { + "$ref": "#/definitions/v1alpha1CrossVersionObjectReference", + "title": "describedObject specifies the descriptions of a object,such as kind,name apiVersion" + }, + "target": { + "$ref": "#/definitions/v1alpha1MetricTarget", + "title": "target specifies the target value for the given metric" + }, + "metric": { + "$ref": "#/definitions/v1alpha1MetricIdentifier", + "title": "metric identifies the target metric by name and selector" + } + } + }, + "v1alpha1ObjectMetricStatus": { + "type": "object", + "properties": { + "metric": { + "$ref": "#/definitions/v1alpha1MetricIdentifier", + "title": "metric identifies the target metric by name and selector" + }, + "current": { + "$ref": "#/definitions/v1alpha1MetricValueStatus", + "title": "current contains the current value for the given metric" + }, + "describedObject": { + "$ref": "#/definitions/v1alpha1CrossVersionObjectReference", + "title": "DescribedObject specifies the descriptions of a object,such as kind,name apiVersion" + } + }, + "description": "ObjectMetricStatus indicates the current value of a metric describing a\nkubernetes object (for example, hits-per-second on an Ingress object)." + }, + "v1alpha1ObjectReference": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "title": "Kind of the referent.\nMore info:\nhttps://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n+optional" + }, + "name": { + "type": "string", + "title": "Name of the referent.\nMore info:\nhttps://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names" + }, + "namespace": { + "type": "string", + "title": "Namespace of the referent.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\n+optional" + }, + "uid": { + "type": "string", + "title": "UID of the referent.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids\n+optional" + }, + "apiVersion": { + "type": "string", + "title": "API version of the referent.\n+optional" + }, + "resourceVersion": { + "type": "string", + "title": "Specific resourceVersion to which this reference is made, if any.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency\n+optional" + } + }, + "description": "ObjectReference contains enough information to let you inspect or modify the\nreferred object." + }, + "v1alpha1OsRepoType": { + "type": "string", + "enum": [ + "OsRepoNone", + "BuiltIn", + "External" + ], + "default": "OsRepoNone" + }, + "v1alpha1PatchConfigMapResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the ConfigMap YAML details" + } + } + }, + "v1alpha1PatchCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "PatchClusterCustomResourceResponse represents response of updating one\nCustomResource of cluster scope" + }, + "v1alpha1PatchDaemonSetResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the json data of deployment after patching." + } + } + }, + "v1alpha1PatchDeploymentResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the json data of deployment after patching." + } + } + }, + "v1alpha1PatchIngressResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the ingress YAML details," + } + }, + "title": "UpdateIngressRequest the response of patch cluster ingresses" + }, + "v1alpha1PatchNamespaceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the service YAML details." + } + } + }, + "v1alpha1PatchSecretResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the secret YAML details" + } + }, + "description": "It returns patches the current secret details." + }, + "v1alpha1PatchServiceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the service YAML details." + } + } + }, + "v1alpha1PatchStatefulSetResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the json data of deployment after patching." + } + } + }, + "v1alpha1PauseCronJobResponse": { + "type": "object", + "properties": { + "cronjob": { + "$ref": "#/definitions/v1alpha1CronJob", + "description": "The new state of the cronjob after pausing." + } + }, + "description": "Response message for the `PauseCronJobResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1PauseDeploymentResponse": { + "type": "object", + "properties": { + "deployment": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "The new state of the deployment after pausing." + } + }, + "description": "Response message for the `PauseDeploymentRequest` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1PauseEtcdBackupStrategyResponse": { + "type": "object", + "properties": { + "strategy": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy", + "description": "The new state of the etcd backup strategy after pausing." + } + }, + "description": "Response message for the `PauseEtcdBackupStrategyResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1PersistentVolume": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1PersistentVolumeSpec", + "description": "Spec defines a specification of a persistent volume owned by the cluster." + }, + "status": { + "$ref": "#/definitions/v1alpha1PersistentVolumeStatus", + "title": "PersistentVolumeClaimStatus represents the status of PV claim" + } + }, + "title": "PersistentVolume (PV) is a storage resource provisioned by an administrator.\nIt is analogous to a node.\nMore info: https://kubernetes.io/docs/concepts/storage/persistent-volumes" + }, + "v1alpha1PersistentVolumeAccessMode": { + "type": "string", + "enum": [ + "PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED", + "ReadWriteOnce", + "ReadOnlyMany", + "ReadWriteMany", + "ReadWriteOncePod" + ], + "default": "PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED", + "description": "PersistentVolumeAccessMode are the ways the volume can be mounted.\n\n - PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - ReadWriteOnce: ReadWriteOnce can be mounted in read/write mode to exactly 1 host.\n - ReadOnlyMany: ReadOnlyMany can be mounted in read-only mode to many hosts.\n - ReadWriteMany: ReadWriteMany can be mounted in read/write mode to many hosts.\n - ReadWriteOncePod: ReadWriteOncePod can be mounted in read/write mode to exactly 1 pod.\nReadWriteOncePod cannot be used in combination with other access modes." + }, + "v1alpha1PersistentVolumeClaim": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaimSpec", + "title": "PersistentVolumeClaimSpec describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "status": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaimStatus", + "title": "PersistentVolumeClaimStatus represents the status of PV claim" + } + }, + "description": "PersistentVolumeClaim represents a reference to a PersistentVolume in the same namespace." + }, + "v1alpha1PersistentVolumeClaimCondition": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of this PersistentVolumeClaimCondition." + }, + "status": { + "type": "string", + "description": "Status is the current status of PersistentVolumeClaim." + }, + "lastProbeTime": { + "type": "string", + "format": "int64", + "description": "Last time we probed the condition." + }, + "lastTransitionTime": { + "type": "string", + "format": "int64", + "description": "Last time the condition transitioned from one status to another." + }, + "reason": { + "type": "string", + "description": "The reason of PersistentVolumeClaimCondition." + }, + "message": { + "type": "string", + "description": "The message of PersistentVolumeClaimCondition." + } + }, + "description": "PersistentVolumeClaimConditionType defines the condition of PV claim." + }, + "v1alpha1PersistentVolumeClaimSpec": { + "type": "object", + "properties": { + "accessModes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeAccessMode" + }, + "title": "Contains the types of access modes required\n+optional" + }, + "selector": { + "$ref": "#/definitions/typesLabelSelector", + "title": "A label query over volumes to consider for binding. This selector is\nignored when VolumeName is set\n+optional" + }, + "resources": { + "$ref": "#/definitions/v1alpha1ResourceRequirements", + "title": "Resources represents the minimum resources required\nIf RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\nthat are lower than previous value but must still be higher than capacity recorded in the\nstatus field of the claim.\n+optional" + }, + "volumeName": { + "type": "string", + "title": "VolumeName is the binding reference to the PersistentVolume backing this\nclaim. When set to non-empty value Selector is not evaluated\n+optional" + }, + "storageClassName": { + "type": "string", + "title": "Name of the StorageClass required by the claim.\nMore info: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#class-1\n+optional" + }, + "volumeMode": { + "$ref": "#/definitions/PersistentVolumeClaimSpecVolumeMode", + "title": "volumeMode defines what type of volume is required by the claim.\nValue of Filesystem is implied when not included in claim spec.\n+optional" + }, + "dataSource": { + "$ref": "#/definitions/apicorev1alpha1TypedLocalObjectReference", + "description": "TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace." + }, + "dataSourceRef": { + "$ref": "#/definitions/v1alpha1TypedObjectReference", + "description": "dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\nvolume is desired. This may be any object from a non-empty API group (non\ncore object) or a PersistentVolumeClaim object.\nWhen this field is specified, volume binding will only succeed if the type of\nthe specified object matches some installed volume populator or dynamic\nprovisioner.\nThis field will replace the functionality of the dataSource field and as such\nif both fields are non-empty, they must have the same value. For backwards\ncompatibility, when namespace isn't specified in dataSourceRef,\nboth fields (dataSource and dataSourceRef) will be set to the same\nvalue automatically if one of them is empty and the other is non-empty.\nWhen namespace is specified in dataSourceRef,\ndataSource isn't set to the same value and must be empty.\nThere are three important differences between dataSource and dataSourceRef:\n - While dataSource only allows two specific types of objects, dataSourceRef\n allows any non-core object, as well as PersistentVolumeClaim objects.\n - While dataSource ignores disallowed values (dropping them), dataSourceRef\n preserves all values, and generates an error if a disallowed value is\n specified.\n - While dataSource only allows local objects, dataSourceRef allows objects\n in any namespaces.\n\n(Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n(Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n+optional" + }, + "supportExpansion": { + "type": "boolean", + "title": "The support expansion represents this pvc weather support expansion" + }, + "supportSnapshot": { + "type": "boolean", + "title": "The support snapshot represents this pvc weather support snapshot" + } + }, + "title": "PersistentVolumeClaimSpec describes the common attributes of storage devices\nand allows a Source for provider-specific attributes" + }, + "v1alpha1PersistentVolumeClaimStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaimStatusPhase", + "title": "Phase represents the current phase of PersistentVolumeClaim\n+optional" + }, + "accessModes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeAccessMode" + }, + "title": "AccessModes contains all ways the volume backing the PVC can be mounted\n+optional" + }, + "capacity": { + "$ref": "#/definitions/v1alpha1ResourceList", + "title": "Represents the actual resources of the underlying volume\n+optional" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaimCondition" + }, + "title": "+optional" + }, + "podName": { + "type": "array", + "items": { + "type": "string" + }, + "title": "PodName represents the pod to which the PVC belongs" + }, + "snapshotCount": { + "type": "integer", + "format": "int32", + "title": "snapshotCount represents how many snapshot the PVC has" + } + }, + "title": "PersistentVolumeClaimStatus represents the status of PV claim" + }, + "v1alpha1PersistentVolumeClaimStatusPhase": { + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Pending", + "Bound", + "Lost" + ], + "default": "PHASE_UNSPECIFIED", + "description": " - Pending: used for PersistentVolumeClaims that are not yet bound\n - Bound: used for PersistentVolumeClaims that are bound\n - Lost: used for PersistentVolumeClaims that lost their underlying\nPersistentVolume. The claim was bound to a PersistentVolume and this\nvolume does not exist any longer and all data on it was lost." + }, + "v1alpha1PersistentVolumeClaimVolumeSource": { + "type": "object", + "properties": { + "claimName": { + "type": "string", + "title": "ClaimName is the name of a PersistentVolumeClaim in the same namespace as\nthe pod using this volume. More info:\nhttps://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims" + }, + "readOnly": { + "type": "boolean", + "title": "Will force the ReadOnly setting in VolumeMounts.\nDefault false.\n+optional" + } + }, + "description": "PersistentVolumeClaimVolumeSource references the user's PVC in the same\nnamespace. This volume finds the bound PV and mounts that volume for the pod.\nA PersistentVolumeClaimVolumeSource is, essentially, a wrapper around another\ntype of volume that is owned by someone else (the system)." + }, + "v1alpha1PersistentVolumeMode": { + "type": "string", + "enum": [ + "PERSISTENT_VOLUME_MODE_UNSPECIFIED", + "Block", + "Filesystem" + ], + "default": "PERSISTENT_VOLUME_MODE_UNSPECIFIED", + "description": "PersistentVolumeMode defines if a volume is intended to be used with a formatted filesystem or to remain in raw block state.\n\n - PERSISTENT_VOLUME_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Block: Block means the volume will not be formatted with a filesystem and will remain a raw block device.\n - Filesystem: Filesystem means the volume will be or is formatted with a filesystem." + }, + "v1alpha1PersistentVolumeReclaimPolicy": { + "type": "string", + "enum": [ + "PERSISTENT_VOLUME_RECLAIM_POLICY_UNSPECIFIED", + "Recycle", + "Delete", + "Retain" + ], + "default": "PERSISTENT_VOLUME_RECLAIM_POLICY_UNSPECIFIED", + "description": "PersistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim.\n\n - PERSISTENT_VOLUME_RECLAIM_POLICY_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Recycle: Recycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim.\nThe volume plugin must support Recycling.\n - Delete: Delete means the volume will be deleted from Kubernetes on release from its claim.\nThe volume plugin must support Deletion.\n - Retain: Retain means the volume will be left in its current phase (Released) for manual reclamation by the administrator.\nThe default policy is Retain." + }, + "v1alpha1PersistentVolumeSpec": { + "type": "object", + "properties": { + "capacity": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Capacity is the description of the persistent volume's resources and capacity." + }, + "accessModes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeAccessMode" + }, + "description": "AccessModes contains all ways the volume can be mounted." + }, + "claimRef": { + "$ref": "#/definitions/v1alpha1ObjectReference", + "description": "ClaimRef is part of a bi-directional binding between PersistentVolume and PersistentVolumeClaim.\nExpected to be non-nil when bound.\nclaim.VolumeName is the authoritative bind between PV and PVC." + }, + "persistentVolumeReclaimPolicy": { + "$ref": "#/definitions/v1alpha1PersistentVolumeReclaimPolicy", + "description": "PersistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim.\nValid options are Retain (default for manually created PersistentVolumes), Delete (default\nfor dynamically provisioned PersistentVolumes), and Recycle (deprecated).\nRecycle must be supported by the volume plugin underlying this PersistentVolume." + }, + "storageClassName": { + "type": "string", + "description": "StorageClassName is the name of StorageClass to which this persistent volume belongs. Empty value\nmeans that this volume does not belong to any StorageClass." + }, + "mountOptions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "MountOptions is the list of mount options, e.g. [\"ro\", \"soft\"]. Not validated - mount will\nsimply fail if one is invalid." + }, + "volumeMode": { + "$ref": "#/definitions/v1alpha1PersistentVolumeMode", + "description": "VolumeMode defines if a volume is intended to be used with a formatted filesystem\nor to remain in raw block state. Value of Filesystem is implied when not included in spec." + }, + "nodeAffinity": { + "$ref": "#/definitions/v1alpha1VolumeNodeAffinity", + "description": "NodeAffinity defines constraints that limit what nodes this volume can be accessed from.\nThis field influences the scheduling of pods that use this volume." + } + }, + "description": "PersistentVolumeSpec is the specification of a persistent volume." + }, + "v1alpha1PersistentVolumeStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1PersistentVolumeStatusPhase", + "title": "Phase indicates if a volume is available, bound to a claim, or released by a claim\n+optional" + }, + "message": { + "type": "string", + "title": "A human-readable message indicating details about why the volume is in this state.\n+optional" + }, + "reason": { + "type": "string", + "title": "Reason is a brief CamelCase string that describes any failure and is meant for machine parsing and tidy display in the CLI\n+optional" + } + } + }, + "v1alpha1PersistentVolumeStatusPhase": { + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Pending", + "Available", + "Bound", + "Released", + "Failed" + ], + "default": "PHASE_UNSPECIFIED", + "title": "- Pending: used for PersistentVolumes that are not available\n - Available: used for PersistentVolumes that are not yet bound\nAvailable volumes are held by the binder and matched to PersistentVolumeClaims\n - Bound: used for PersistentVolumes that are bound\n - Released: used for PersistentVolumes where the bound PersistentVolumeClaim was deleted\nreleased volumes must be recycled before becoming available again\nthis phase is used by the persistent volume claim binder to signal to another process to reclaim the resource\n - Failed: used for PersistentVolumes that failed to be correctly recycled or deleted after being released from a claim" + }, + "v1alpha1Plugin": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1alpha1PluginName", + "description": "The name of the plugin." + }, + "enabled": { + "type": "boolean", + "description": "The user has activated the application for this plugin." + }, + "intelligentDetection": { + "type": "boolean", + "description": "IntelligentDetection indicate the plugin is whether intelligent." + }, + "externalAddress": { + "type": "string", + "description": "ExternalAddress is a address which access the plugin from outside the cluster." + }, + "setting": { + "type": "string", + "description": "The setting of the plugin. every plugin encode the setting to json string." + }, + "healthy": { + "type": "boolean", + "description": "Healthy is to show a plugin state when installed." + } + } + }, + "v1alpha1PluginName": { + "type": "string", + "enum": [ + "PLUGIN_NAME_UNSPECIFIED", + "HPA", + "Insight", + "GPU", + "METALLB", + "Spiderpool", + "CustomMetrics", + "CronHPA", + "VPA", + "Hwameistor", + "Flannel", + "KubeOvn", + "OLM", + "EgressGateway", + "Snapshot", + "DRA" + ], + "default": "PLUGIN_NAME_UNSPECIFIED", + "description": "PluginName for enum describing possible enum name.\n\n - PLUGIN_NAME_UNSPECIFIED: Enum unspecified.\n - HPA: The plugin name is HPA.\n - Insight: The plugin name is Insight.\n - GPU: The plugin name is GPU.\n - METALLB: The plugin name is METALLAB.\n - Spiderpool: The plugin name is Spiderpool.\n - CustomMetrics: The plugin name is CustomMetrics.\n - CronHPA: The plugin name is CronHPA.\n - VPA: The plugin name is VPA.\n - Hwameistor: The plugin name is Hwameistor\n - Flannel: The plugin name is Flannel\n - KubeOvn: The plugin name is Kube-ovn\n - OLM: The plugin name is olm\n - EgressGateway: The plugin name is egressgateway\n - Snapshot: The plugin name is snapshot controller\n - DRA: The plugin name is DRA(dynamic resources allcated)" + }, + "v1alpha1Pod": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1PodSpec", + "description": "Spec describes the attributes that a pod is created with." + }, + "status": { + "$ref": "#/definitions/v1alpha1PodStatus", + "description": "Status represents the current information/status of node." + } + } + }, + "v1alpha1PodAffinity": { + "type": "object", + "properties": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PodAffinityTerm" + }, + "title": "If the affinity requirements specified by this field are not met at\nscheduling time, the pod will not be scheduled onto the node.\nIf the affinity requirements specified by this field cease to be met\nat some point during pod execution (e.g. due to a pod label update), the\nsystem may or may not try to eventually evict the pod from its node.\nWhen there are multiple elements, the lists of nodes corresponding to each\npodAffinityTerm are intersected, i.e. all terms must be satisfied.\n+optional" + }, + "preferredDuringSchedulingIgnoredDuringExecution": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1WeightedPodAffinityTerm" + }, + "title": "The scheduler will prefer to schedule pods to nodes that satisfy\nthe affinity expressions specified by this field, but it may choose\na node that violates one or more of the expressions. The node that is\nmost preferred is the one with the greatest sum of weights, i.e.\nfor each node that meets all of the scheduling requirements (resource\nrequest, requiredDuringScheduling affinity expressions, etc.),\ncompute a sum by iterating through the elements of this field and adding\n\"weight\" to the sum if the node has pods which matches the corresponding\npodAffinityTerm; the node(s) with the highest sum are the most preferred.\n+optional" + } + }, + "description": "Pod affinity is a group of inter pod affinity scheduling rules." + }, + "v1alpha1PodAffinityTerm": { + "type": "object", + "properties": { + "labelSelector": { + "$ref": "#/definitions/typesLabelSelector", + "title": "A label query over a set of resources, in this case pods.\n+optional" + }, + "namespaces": { + "type": "array", + "items": { + "type": "string" + }, + "title": "namespaces specifies a static list of namespace names that the term applies\nto. The term is applied to the union of the namespaces listed in this field\nand the ones selected by namespaceSelector.\nnull or empty namespaces list and null namespaceSelector means \"this pod's\nnamespace\" +optional" + }, + "topologyKey": { + "type": "string", + "description": "This pod should be co-located (affinity) or not co-located (anti-affinity)\nwith the pods matching the labelSelector in the specified namespaces, where\nco-located is defined as running on a node whose value of the label with\nkey topologyKey matches that of any node on which any of the selected pods\nis running. Empty topologyKey is not allowed." + }, + "namespaceSelector": { + "$ref": "#/definitions/typesLabelSelector", + "title": "A label query over the set of namespaces that the term applies to.\nThe term is applied to the union of the namespaces selected by this field\nand the ones listed in the namespaces field.\nnull selector and null or empty namespaces list means \"this pod's\nnamespace\". An empty selector ({}) matches all namespaces. This field is\nbeta-level and is only honored when PodAffinityNamespaceSelector feature is\nenabled. +optional" + } + }, + "title": "Defines a set of pods (namely those matching the labelSelector\nrelative to the given namespace(s)) that this pod should be\nco-located (affinity) or not co-located (anti-affinity) with,\nwhere co-located is defined as running on a node whose value of\nthe label with key matches that of any node on which\na pod of the set of pods is running" + }, + "v1alpha1PodIp": { + "type": "object", + "properties": { + "ip": { + "type": "string" + } + }, + "description": "IP: An IP address allocated to the pod. Routable at least within\n the cluster.", + "title": "PodIP represents the IP address of a pod.\nIP address information. Each entry includes:" + }, + "v1alpha1PodResourcePolicy": { + "type": "object", + "properties": { + "containerPolicies": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ContainerResourcePolicy" + }, + "description": "Per-container resource policies." + } + }, + "description": "PodResourcePolicy controls how autoscaler computes the recommended resources\nfor containers belonging to the pod. There can be at most one entry for every\nnamed container and optionally a single wildcard entry with `containerName` = '*',\nwhich handles all containers that don't have individual policies." + }, + "v1alpha1PodSecurity": { + "type": "object", + "properties": { + "level": { + "$ref": "#/definitions/v1alpha1Level", + "description": "Level of Pod Security Standards to broadly cover the security spectrum." + }, + "mode": { + "$ref": "#/definitions/v1alpha1Mode", + "description": "Mode of Pod Security Standards." + } + }, + "description": "PodSecurity is the label combination of mode plus level." + }, + "v1alpha1PodSpec": { + "type": "object", + "properties": { + "volumes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Volume" + } + }, + "initContainers": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Container" + }, + "title": "init containers" + }, + "containers": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Container" + }, + "description": "Containers name." + }, + "ephemeralContainers": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1EphemeralContainer" + }, + "description": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing\npod to perform user-initiated actions such as debugging. This list cannot be specified when\ncreating a pod, and it cannot be modified by updating the pod spec. In order to add an\nephemeral container to an existing pod, use the pod's ephemeralcontainers subresource." + }, + "restartPolicy": { + "type": "string" + }, + "nodeName": { + "type": "string", + "description": "NodeName is a request to schedule this pod onto a specific node.\nIf it is non-empty, the scheduler simply schedules this pod onto that node,\nassuming that it fits resource requirements." + }, + "hostNetwork": { + "type": "boolean" + }, + "affinity": { + "$ref": "#/definitions/v1alpha1Affinity", + "title": "bool hostPID = 15;\nbool hostIPC = 16;\nbool shareProcessNamespace = 17;\nPodSecurityContext SecurityContext = 18;\nrepeated LocalObjectReference imagePullSecrets = 19;\nstring hostname = 20;\nstring subdomain = 21;" + }, + "tolerations": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Toleration" + }, + "title": "string schedulerName = 23;" + } + }, + "description": "PodSpec describes the attributes that a pod is created with." + }, + "v1alpha1PodStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1PodStatusPhase", + "description": "Phase represents the phase to search." + }, + "hostIP": { + "type": "string", + "title": "repeated types.Condition conditions = 2;\nstring message = 3;\nstring reason = 4;\nstring nominatedNodeName = 5;" + }, + "podIP": { + "type": "string", + "description": "IP: An IP address allocated to the pod. Routable at least within\n the cluster.", + "title": "PodIP represents the IP address of a pod.\nIP address information. Each entry includes:" + }, + "podIPs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PodIp" + }, + "title": "PodIPs is same as PodIP" + }, + "startTime": { + "type": "string", + "format": "int64", + "description": "Required. Start time of the operation." + }, + "cpuRequest": { + "type": "string", + "format": "int64", + "description": "Pod cpu request." + }, + "cpuLimit": { + "type": "string", + "format": "int64", + "description": "Pod cpu limit." + }, + "memoryRequest": { + "type": "string", + "format": "int64", + "description": "Pod memory request." + }, + "memoryLimit": { + "type": "string", + "format": "int64", + "description": "Pod memory limit." + }, + "cpuUsageRate": { + "type": "number", + "format": "double", + "description": "cpuUsage_rate is the actual total pod cpu usage. Unit: m." + }, + "memoryUsageRate": { + "type": "number", + "format": "double", + "description": "memoryUsage_rate the total pod memory usage. Unit: byte." + }, + "restartCount": { + "type": "integer", + "format": "int32", + "description": "restart_count the total pod restart count." + }, + "ownedBy": { + "$ref": "#/definitions/PodStatusOwnedBy" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "title": "Current service state of pod.\nMore info:\nhttps://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions" + }, + "containerTotalCount": { + "type": "integer", + "format": "int32", + "description": "Container_total_count represents pod's container total count." + }, + "containerReadyCount": { + "type": "integer", + "format": "int32", + "description": "Container_ready_count represents pod's container ready count." + }, + "initContainerStatuses": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ContainerStatus" + }, + "title": "The list has one entry per init container in the manifest. The most recent successful\ninit container will have ready = true, the most recently started container will have\nstartTime set.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status" + }, + "containerStatuses": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ContainerStatus" + }, + "title": "The list has one entry per container in the manifest.\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status\n+optional" + }, + "ephemeralContainerStatuses": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ContainerStatus" + }, + "title": "Status for any ephemeral containers that have run in this pod.\n+optional" + }, + "podStatus": { + "type": "string", + "description": "pod_status refer to `kubectl get po` result." + }, + "cpuUsage": { + "type": "number", + "format": "double", + "description": "cpu_usage is the actual total pod cpu usage. Unit: m." + }, + "memoryUsage": { + "type": "number", + "format": "double", + "description": "memory_usage the total pod memory usage. Unit: byte." + }, + "podFilterStatus": { + "$ref": "#/definitions/v1alpha1FilterPodStatus" + } + }, + "description": "PodStatus constructs an declarative configuration of the Pod type for use\nwith apply." + }, + "v1alpha1PodStatusPhase": { + "type": "string", + "enum": [ + "PHASE_UNSPECIFIED", + "Unknown", + "Pending", + "Running", + "Succeeded", + "Failed" + ], + "default": "PHASE_UNSPECIFIED", + "description": " - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Unknown: PodUnknown means that for some reason the state of the pod could not be\nobtained, typically due to an error in communicating with the host of the\npod.\n - Pending: PodPending means the pod has been accepted by the system, but one or more\nof the containers has not been started. This includes time before being\nbound to a node, as well as time spent pulling images onto the host.\n - Running: PodRunning means the pod has been bound to a node and all of the\ncontainers have been started. At least one container is still running or\nis in the process of being restarted. PodSucceeded means that all\ncontainers in the pod have voluntarily terminated with a container exit\ncode of 0, and the system is not going to restart any of these\ncontainers.\n - Succeeded: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system).\n - Failed: PodFailed means that all containers in the pod have terminated, and at\nleast one container has terminated in a failure (exited with a non-zero\nexit code or was stopped by the system)." + }, + "v1alpha1PodTemplateSpec": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1PodSpec", + "description": "Spec describes the attributes that a pod is created with." + } + }, + "description": "template is the object that describes the pod that will be created if\ninsufficient replicas are detected. Each pod stamped out by the StatefulSet\nwill fulfill this Template, but have a unique identity from the rest\nof the StatefulSet." + }, + "v1alpha1PodUpdatePolicy": { + "type": "object", + "properties": { + "updateMode": { + "$ref": "#/definitions/v1alpha1UpdateMode", + "description": "Controls when autoscaler applies changes to the pod resources.\nThe default is 'Auto'." + }, + "minReplicas": { + "type": "integer", + "format": "int32", + "description": "Minimal number of replicas which need to be alive for Updater to attempt\npod eviction (pending other checks like PDB). Only positive values are\nallowed. Overrides global '--min-replicas' flag." + } + }, + "description": "PodUpdatePolicy describes the rules on how changes are applied to the pods." + }, + "v1alpha1PodsMetricSource": { + "type": "object", + "properties": { + "metric": { + "$ref": "#/definitions/v1alpha1MetricIdentifier", + "title": "metric identifies the target metric by name and selector" + }, + "target": { + "$ref": "#/definitions/v1alpha1MetricTarget", + "title": "target specifies the target value for the given metric" + } + }, + "title": "MetricValueStatus holds the current value for a metric" + }, + "v1alpha1PodsMetricStatus": { + "type": "object", + "properties": { + "metric": { + "$ref": "#/definitions/v1alpha1MetricIdentifier", + "title": "metric identifies the target metric by name and selector" + }, + "current": { + "$ref": "#/definitions/v1alpha1MetricValueStatus", + "title": "current contains the current value for the given metric" + } + }, + "description": "PodsMetricStatus indicates the current value of a metric describing each pod in\nthe current scale target (for example, transactions-processed-per-second)." + }, + "v1alpha1PolicyRule": { + "type": "object", + "properties": { + "verbs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs." + }, + "apiGroups": { + "type": "array", + "items": { + "type": "string" + }, + "description": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of\nthe enumerated resources in any API group will be allowed. \"\" represents the core API group and \"*\" represents all API groups." + }, + "resources": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Resources is a list of resources this rule applies to. '*' represents all resources." + }, + "resourceNames": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed." + }, + "nonResourceUrls": { + "type": "array", + "items": { + "type": "string" + }, + "description": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path\nSince non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.\nRules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both." + } + }, + "description": "PolicyRule holds information that describes a policy rule, but does not contain information\nabout who the rule applies to or which namespace the rule applies to." + }, + "v1alpha1Ports": { + "type": "object", + "properties": { + "containerPort": { + "type": "integer", + "format": "int32", + "description": "ContainerPort connects to a certain container port in a pod." + }, + "hostPort": { + "type": "integer", + "format": "int32", + "title": "Number of port to expose on the host.\nIf specified, this must be a valid port number, 0 < x < 65536.\nIf HostNetwork is specified, this must match ContainerPort.\nMost containers do not need this.\n+optional" + }, + "name": { + "type": "string", + "title": "If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\nnamed port in a pod must have a unique name. Name for the port that can be\nreferred to by services.\n+optional" + }, + "protocol": { + "type": "string", + "title": "Protocol for port. Must be UDP, TCP, or SCTP.\nDefaults to \"TCP\".\n+optional\n+default=\"TCP\"" + } + }, + "title": "Ports are not allowed for ephemeral containers.\n+optional\n+patchMergeKey=containerPort\n+patchStrategy=merge\n+listType=map\n+listMapKey=containerPort\n+listMapKey=protocol" + }, + "v1alpha1PreCheckNodeInfo": { + "type": "object", + "properties": { + "pingConnection": { + "type": "string", + "description": "ping_connection represents whether the node is connective." + }, + "existingKubernetesService": { + "type": "string", + "description": "existing_kubernetes_service represents whether exist k8s service." + }, + "dualStackNetwork": { + "type": "string", + "description": "dual_stack_network represents whether enable dual-stack network." + }, + "osKernelVersionOutput": { + "type": "string", + "description": "os_kernel_version_output defines os kernel detail informations." + }, + "osKernelVersion": { + "type": "string", + "description": "os_kernel_version defines os kernel version." + }, + "osFamily": { + "type": "string", + "description": "os_family represents the what the os family of host is." + }, + "osType": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "os_type includes all of os informations." + }, + "timeZone": { + "type": "string", + "description": "time_zone represents the time zone of host." + }, + "nodeTimestamp": { + "type": "string", + "description": "node_timestamp represents the node timestamp when running precheck." + } + } + }, + "v1alpha1PreCheckYumRepoInfo": { + "type": "object", + "properties": { + "osRepoType": { + "$ref": "#/definitions/v1alpha1OsRepoType", + "title": "os_repo_type represents what the os repo type is, none, builtin or external" + }, + "yumRepos": { + "type": "array", + "items": { + "type": "string" + }, + "description": "yum_repos is yum repo list." + }, + "dockerRhRepoBaseUrl": { + "type": "string", + "description": "docker_rh_repo_base_url is docker repo base url." + } + } + }, + "v1alpha1PreRelease": { + "type": "string", + "enum": [ + "PRE_RELEASE_TYPE_UNSPECIFIED", + "ALPHA", + "BETA", + "GA", + "DEPRECATED" + ], + "default": "PRE_RELEASE_TYPE_UNSPECIFIED", + "description": " - PRE_RELEASE_TYPE_UNSPECIFIED: pre release type is unspecified." + }, + "v1alpha1PreferredSchedulingTerm": { + "type": "object", + "properties": { + "weight": { + "type": "integer", + "format": "int32", + "description": "Weight associated with matching the corresponding nodeSelectorTerm, in the\nrange 1-100." + }, + "preference": { + "$ref": "#/definitions/v1alpha1NodeSelectorTerm", + "description": "A node selector term, associated with the corresponding weight." + } + }, + "description": "An empty preferred scheduling term matches all objects with implicit weight 0\n(i.e. it's a no-op). A null preferred scheduling term matches no objects\n(i.e. is also a no-op)." + }, + "v1alpha1Probe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer", + "format": "int32", + "title": "Minimum consecutive failures for the probe to be considered failed after\nhaving succeeded. Defaults to 3. Minimum value is 1. +optional" + }, + "periodSeconds": { + "type": "integer", + "format": "int32", + "description": "Probe describes a health check to be performed against a container to\ndetermine whether it is alive or ready to receive traffic." + }, + "successThreshold": { + "type": "integer", + "format": "int32", + "title": "Minimum consecutive successes for the probe to be considered successful\nafter having failed. Defaults to 1. Must be 1 for liveness and startup.\nMinimum value is 1. +optional" + }, + "timeoutSeconds": { + "type": "integer", + "format": "int32", + "title": "Number of seconds after which the probe times out.\nDefaults to 1 second. Minimum value is 1.\nMore info:\nhttps://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n+optional" + }, + "initialDelaySeconds": { + "type": "integer", + "format": "int32", + "title": "Number of seconds after the container has started before liveness probes\nare initiated. More info:\nhttps://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n+optional" + }, + "terminationGracePeriodSeconds": { + "type": "string", + "format": "int64", + "title": "Optional duration in seconds the pod needs to terminate gracefully upon\nprobe failure. The grace period is the duration in seconds after the\nprocesses running in the pod are sent a termination signal and the time\nwhen the processes are forcibly halted with a kill signal. Set this value\nlonger than the expected cleanup time for your process. If this value is\nnil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\nvalue overrides the value provided by the pod spec.\nValue must be non-negative integer. The value zero indicates stop\nimmediately via the kill signal (no opportunity to shut down). This is a\nbeta field and requires enabling ProbeTerminationGracePeriod feature gate.\nMinimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n+optional" + }, + "httpGet": { + "$ref": "#/definitions/v1alpha1HTTPGetAction", + "title": "handler\nHTTPGet specifies the http request to perform.\n+optional" + }, + "exec": { + "$ref": "#/definitions/v1alpha1ExecAction", + "title": "Exec specifies the action to take.\n+optional" + }, + "tcpSocket": { + "$ref": "#/definitions/v1alpha1TCPSocketAction", + "title": "TCPSocket specifies an action involving a TCP port.\n+optional" + } + }, + "description": "Probe describes a health check to be performed against a container to\ndetermine whether it is alive or ready to receive traffic." + }, + "v1alpha1PrometheusQueryRangeResult": { + "type": "object", + "properties": { + "matrix": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1SampleStream" + }, + "title": "the matrix of sample stream" + } + }, + "title": "The result of prometheus query range" + }, + "v1alpha1PrometheusQueryResult": { + "type": "object", + "properties": { + "vector": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Sample" + }, + "title": "the vector of sample" + } + }, + "title": "The result of prometheus query result" + }, + "v1alpha1Protocol": { + "type": "string", + "enum": [ + "PROTOCOL_UNSPECIFIED", + "TCP", + "UDP", + "SCTP" + ], + "default": "PROTOCOL_UNSPECIFIED", + "description": "Protocol defines network protocols supported for things like container ports.\n\n - PROTOCOL_UNSPECIFIED: Placeholder to avoid zero not return.\n - TCP: ProtocolTCP is the TCP protocol.\n - UDP: ProtocolUDP is the UDP protocol.\n - SCTP: ProtocolSCTP is the SCTP protocol." + }, + "v1alpha1PutNodeLabelsResponse": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "v1alpha1PutNodeTaintsResponse": { + "type": "object", + "properties": { + "taints": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Taint" + } + } + }, + "description": "PutNodeTaintsResponse returns node's taints." + }, + "v1alpha1RecommendedContainerResources": { + "type": "object", + "properties": { + "containerName": { + "type": "string", + "description": "Name of the container." + }, + "target": { + "$ref": "#/definitions/v1alpha1ResourceList", + "description": "Recommended amount of resources. Observes ContainerResourcePolicy." + }, + "lowerBound": { + "$ref": "#/definitions/v1alpha1ResourceList", + "description": "Minimum recommended amount of resources. Observes ContainerResourcePolicy.\nThis amount is not guaranteed to be sufficient for the application to operate in a stable way, however\nrunning with less resources is likely to have significant impact on performance/availability." + }, + "upperBound": { + "$ref": "#/definitions/v1alpha1ResourceList", + "description": "Maximum recommended amount of resources. Observes ContainerResourcePolicy.\nAny resources allocated beyond this value are likely wasted. This value may be larger than the maximum\namount of application is actually capable of consuming." + }, + "uncappedTarget": { + "$ref": "#/definitions/v1alpha1ResourceList", + "description": "The most recent recommended resources target computed by the autoscaler\nfor the controlled pods, based only on actual resource usage, not taking\ninto account the ContainerResourcePolicy.\nMay differ from the Recommendation if the actual resource usage causes\nthe target to violate the ContainerResourcePolicy (lower than MinAllowed\nor higher that MaxAllowed).\nUsed only as status indication, will not affect actual resource assignment." + } + }, + "description": "RecommendedContainerResources is the recommendation of resources computed by\nautoscaler for a specific container. Respects the container resource policy\nif present in the spec. In particular the recommendation is not produced for\ncontainers with `ContainerScalingMode` set to 'Off'." + }, + "v1alpha1RecommendedPodResources": { + "type": "object", + "properties": { + "containerRecommendations": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1RecommendedContainerResources" + }, + "description": "Resources recommended by the autoscaler for each container." + } + }, + "description": "RecommendedPodResources is the recommendation of resources computed by\nautoscaler. It contains a recommendation for each container in the pod\n(except for those with `ContainerScalingMode` set to 'Off')." + }, + "v1alpha1Registry": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "description": "Alias is an alias for the registry, showed in list." + }, + "host": { + "type": "string", + "description": "Host is registry host." + }, + "name": { + "type": "string", + "description": "Name is registry name, use to query project lists." + } + }, + "title": "Registry contains necessary info" + }, + "v1alpha1ReleaseInfo": { + "type": "object", + "properties": { + "firstDeployed": { + "type": "string", + "format": "int64", + "description": "FirstDeployed is when the release was first deployed." + }, + "lastDeployed": { + "type": "string", + "format": "int64", + "description": "LastDeployed is when the release was last deployed." + }, + "deleted": { + "type": "string", + "format": "int64", + "description": "Deleted tracks when this object was deleted." + }, + "description": { + "type": "string", + "description": "Description is human-friendly \"log entry\" about this release." + }, + "status": { + "$ref": "#/definitions/v1alpha1ReleasePhase", + "description": "Status is the current state of the release." + }, + "notes": { + "type": "string", + "description": "Contains the rendered templates/NOTES.txt if available." + }, + "readme": { + "type": "string" + } + } + }, + "v1alpha1ReleasePhase": { + "type": "string", + "enum": [ + "RELEASE_PHASE_UNSPECIFIED", + "unknown", + "deployed", + "uninstalled", + "superseded", + "failed", + "uninstalling", + "pending_install", + "pending_upgrade", + "pending_rollback" + ], + "default": "RELEASE_PHASE_UNSPECIFIED", + "description": " - RELEASE_PHASE_UNSPECIFIED: The release state is unspecified.\n - unknown: unknown indicates that a release is in an uncertain state.\n - deployed: deployed indicates that the release has been pushed to Kubernetes.\n - uninstalled: uninstalled indicates that a release has been uninstalled from Kubernetes.\n - superseded: superseded indicates that this release object is outdated and a newer one exists.\n - failed: failed indicates that the release was not successfully deployed.\n - uninstalling: uninstalling indicates that a uninstall operation is underway.\n - pending_install: pending_install indicates that an install operation is underway.\n - pending_upgrade: pending_upgrade indicates that an upgrade operation is underway.\n - pending_rollback: pending_rollback indicates that an rollback operation is underway." + }, + "v1alpha1ReleaseResource": { + "type": "object", + "properties": { + "apiVersion": { + "type": "string", + "description": "ApiVersion of the resource." + }, + "kind": { + "type": "string", + "description": "Kind of the resource." + }, + "name": { + "type": "string", + "description": "Name of the resource." + }, + "namespace": { + "type": "string", + "description": "Namespace of the resource." + } + }, + "title": "ReleaseResource belongs to ReleaseSpec" + }, + "v1alpha1ReleaseSpec": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Name is the name of the release" + }, + "info": { + "$ref": "#/definitions/v1alpha1ReleaseInfo", + "title": "Info provides information about a release" + }, + "chart": { + "$ref": "#/definitions/v1alpha1HelmChart", + "description": "HelmChart is the chart that was released." + }, + "values": { + "type": "string", + "description": "Config is the set of extra Values added to the chart.\nThese values override the default values inside of the chart." + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ReleaseResource" + }, + "description": "Manifest is the string representation of the rendered template." + }, + "version": { + "type": "integer", + "format": "int32", + "description": "Version is an int which represents the version of the release." + }, + "namespace": { + "type": "string", + "description": "Namespace is the kubernetes namespace of the release." + }, + "helmMajorVersion": { + "type": "integer", + "format": "int32", + "title": "HelmMajorVersion is the helm major version" + }, + "operationName": { + "type": "string", + "description": "OperationName is to find related job and pods to check the helm operation log." + } + } + }, + "v1alpha1ReleaseStatus": { + "type": "object", + "properties": { + "summary": { + "$ref": "#/definitions/v1alpha1Summary" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current condition of the helmrelease." + } + } + }, + "v1alpha1ReplicaSet": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Metadata is that all persisted resources must have, which includes all objects\nusers must create." + }, + "spec": { + "$ref": "#/definitions/v1alpha1ReplicaSetSpec", + "description": "ReplicaSetSpec is the specification of a ReplicaSet." + }, + "status": { + "$ref": "#/definitions/v1alpha1ReplicaSetStatus", + "description": "ReplicaSetStatus represents the current status of a ReplicaSet." + } + }, + "description": "ReplicaSet ensures that a specified number of pod replicas are running at any given time." + }, + "v1alpha1ReplicaSetCondition": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of replica set condition." + }, + "status": { + "type": "string", + "description": "Status of the condition, one of True, False, Unknown." + }, + "lastTransitionTime": { + "type": "string", + "format": "int64", + "title": "The last time the condition transitioned from one status to another.\n+optional" + }, + "reason": { + "type": "string", + "title": "The reason for the condition's last transition.\n+optional" + }, + "message": { + "type": "string", + "title": "A human readable message indicating details about the transition.\n+optional" + } + }, + "title": "kubernetes.io/change-cause\ndeployment.kubernetes.io/revision" + }, + "v1alpha1ReplicaSetSpec": { + "type": "object", + "properties": { + "replicas": { + "type": "integer", + "format": "int32", + "description": "Represents the replicas of the deployment." + }, + "revision": { + "type": "string", + "format": "int64", + "description": "Represents the version of the deployment." + }, + "selector": { + "$ref": "#/definitions/typesLabelSelector", + "description": "Selector a label selector is a label query over a set of resources. The result of matchLabels and\nmatchExpressions are ANDed. An empty label selector matches all objects. A null\nlabel selector matches no objects." + }, + "template": { + "$ref": "#/definitions/v1alpha1PodTemplateSpec", + "title": "Template an object that describes the pod that will be created.\nThe ReplicaSet will create exactly one copy of this pod on every node\nthat matches the template's node selector (or on every node if no node\nselector is specified).\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template" + } + }, + "description": "ReplicaSetSpec is the specification of a ReplicaSet." + }, + "v1alpha1ReplicaSetStatus": { + "type": "object", + "properties": { + "replicas": { + "type": "integer", + "format": "int32", + "title": "Replicas is the most recently oberved number of replicas.\nMore info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller" + }, + "fullyLabeledReplicas": { + "type": "integer", + "format": "int32", + "title": "The number of pods that have labels matching the labels of the pod template of the replicaset.\n+optional" + }, + "readyReplicas": { + "type": "integer", + "format": "int32", + "title": "readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition.\n+optional" + }, + "availableReplicas": { + "type": "integer", + "format": "int32", + "title": "The number of available replicas (ready for at least minReadySeconds) for this replica set.\n+optional" + }, + "observedGeneration": { + "type": "string", + "format": "int64", + "title": "ObservedGeneration reflects the generation of the most recently observed ReplicaSet.\n+optional" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ReplicaSetCondition" + }, + "title": "Represents the latest available observations of a replica set's current state.\n+optional\n+patchMergeKey=type\n+patchStrategy=merge" + } + }, + "description": "ReplicaSetStatus represents the current status of a ReplicaSet." + }, + "v1alpha1RepoPhase": { + "type": "string", + "enum": [ + "REPOSITORY_PHASE_UNSPECIFIED", + "UNKNOWN", + "ACTIVE" + ], + "default": "REPOSITORY_PHASE_UNSPECIFIED", + "description": " - REPOSITORY_PHASE_UNSPECIFIED: The repository state is unspecified.\n - UNKNOWN: The repository state is unknown.\n - ACTIVE: The repository is active." + }, + "v1alpha1RepoSpec": { + "type": "object", + "properties": { + "url": { + "type": "string", + "title": "URL A http URL of the repo to connect to" + }, + "clientSecret": { + "$ref": "#/definitions/RepoSpecSecretReference", + "description": "client_secret a reference to a secret object." + }, + "insecureSkipTLSVerify": { + "type": "boolean", + "description": "InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index." + } + } + }, + "v1alpha1RepoStatus": { + "type": "object", + "properties": { + "phase": { + "$ref": "#/definitions/v1alpha1RepoPhase", + "description": "phase represents the status of the repository." + }, + "indexConfigMapName": { + "type": "string", + "title": "index_config_map_name is the configmap with the store index in it" + }, + "indexConfigMapNamespace": { + "type": "string", + "title": "index_config_map_namespace is the configmap with the store index in it" + }, + "downloadTime": { + "type": "string", + "format": "int64", + "title": "download_time the time when the index was last downloaded" + }, + "url": { + "type": "string", + "title": "The url used for the last successful index" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current service state of helmrepo." + } + } + }, + "v1alpha1Repository": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of repository." + }, + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Artifact" + }, + "description": "Artifacts of repository." + } + }, + "title": "Repository concept from Harbor" + }, + "v1alpha1Resource": { + "type": "object", + "properties": { + "apiVersion": { + "type": "string", + "description": "ApiVersion of the resource." + }, + "kind": { + "type": "string", + "description": "Kind of the resource." + }, + "name": { + "type": "string", + "description": "Name of the resource." + }, + "namespace": { + "type": "string", + "description": "Namespace of the resource." + }, + "phase": { + "$ref": "#/definitions/v1alpha1ResourcePhase", + "description": "Phase stands for the resource phase." + } + }, + "title": "Resource belongs to ReleaseStatus" + }, + "v1alpha1ResourceFieldSelector": { + "type": "object", + "properties": { + "containerName": { + "type": "string", + "title": "Container name: required for volumes,\nfor env vars\n+optional" + }, + "resource": { + "type": "string", + "title": "Required: resource to select" + } + }, + "title": "ResourceFieldSelector represents container resources (cpu, memory) and their\noutput format" + }, + "v1alpha1ResourceList": { + "type": "object", + "properties": { + "cpu": { + "type": "string", + "description": "Cpu is the total pod cpu resource. Unit: m." + }, + "memory": { + "type": "string", + "description": "Memory is the total memory resource. Unit: byte." + }, + "storage": { + "type": "string", + "description": "Storage is the total storage resource. Unit: byte." + }, + "resources": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Resources contains all resources include cpu, memory, storage." + } + }, + "description": "ResourceList returns a string representation of a resource list in a human\nreadable format." + }, + "v1alpha1ResourceMetricSource": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1alpha1ResourceName", + "description": "name is the name of the resource in question." + }, + "target": { + "$ref": "#/definitions/v1alpha1MetricTarget", + "title": "target specifies the target value for the given metric" + } + }, + "description": "ResourceMetricSource indicates how to scale on a resource metric known to\nKubernetes, as specified in requests and limits, describing each pod in the\ncurrent scale target (e.g. CPU or memory). The values will be averaged\ntogether before being compared to the target. Such metrics are built in to\nKubernetes, and have special scaling options on top of those available to\nnormal per-pod metrics using the \"pods\" source. Only one \"target\" type\nshould be set." + }, + "v1alpha1ResourceMetricStatus": { + "type": "object", + "properties": { + "name": { + "$ref": "#/definitions/v1alpha1ResourceName", + "description": "Name is the name of the resource in question." + }, + "current": { + "$ref": "#/definitions/v1alpha1MetricValueStatus", + "title": "current contains the current value for the given metric" + } + }, + "description": "ResourceMetricStatus indicates the current value of a resource metric known to\nKubernetes, as specified in requests and limits, describing each pod in the\ncurrent scale target (e.g. CPU or memory). Such metrics are built in to\nKubernetes, and have special scaling options on top of those available to\nnormal per-pod metrics using the \"pods\" source." + }, + "v1alpha1ResourceName": { + "type": "string", + "enum": [ + "RESOURCE_NAME_UNSPECIFIED", + "cpu", + "memory" + ], + "default": "RESOURCE_NAME_UNSPECIFIED", + "description": "ResourceName is the name identifying various resources in a ResourceList." + }, + "v1alpha1ResourcePhase": { + "type": "string", + "enum": [ + "RESOURCE_PHASE_UNSPECIFIED", + "InProgress", + "Failed", + "Current", + "Terminating", + "Unknown" + ], + "default": "RESOURCE_PHASE_UNSPECIFIED", + "description": "The set of status conditions which can be assigned to resources.\n\n - RESOURCE_PHASE_UNSPECIFIED: ResourcePhase unspecified.\n - InProgress: Resource in progress.\n - Failed: Resource failed.\n - Current: Resource current.\n - Terminating: Resource terminating.\n - Unknown: Resource unknown." + }, + "v1alpha1ResourceQuota": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1ResourceQuotaSpec", + "description": "Spec defines the desired quota." + }, + "status": { + "$ref": "#/definitions/v1alpha1ResourceQuotaStatus", + "description": "Status defines the actual enforced quota and its current usage." + } + }, + "description": "ResourceQuota sets aggregate quota restrictions enforced per namespace." + }, + "v1alpha1ResourceQuotaSpec": { + "type": "object", + "properties": { + "hard": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Hard is the set of desired hard limits for each named resource." + } + }, + "description": "ResourceQuotaSpec defines the desired hard limits to enforce for Quota." + }, + "v1alpha1ResourceQuotaStatus": { + "type": "object", + "properties": { + "hard": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Hard is the set of enforced hard limits for each named resource." + }, + "used": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Used is used for each named resource." + } + }, + "description": "ResourceQuotaStatus defines the enforced hard limits and observed use." + }, + "v1alpha1ResourceRange": { + "type": "object", + "properties": { + "min": { + "type": "integer", + "format": "int32", + "title": "resource min value" + }, + "minDesc": { + "type": "string", + "title": "min resource description" + }, + "max": { + "type": "integer", + "format": "int32", + "title": "resource max value" + }, + "maxDesc": { + "type": "string", + "title": "max resource description" + } + } + }, + "v1alpha1ResourceRequirements": { + "type": "object", + "properties": { + "limits": { + "$ref": "#/definitions/v1alpha1ResourceList", + "title": "Limits describes the maximum amount of compute resources allowed.\nMore info:\nhttps://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n+optional" + }, + "requests": { + "$ref": "#/definitions/v1alpha1ResourceList", + "title": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is\nexplicitly specified, otherwise to an implementation-defined value. More\ninfo:\nhttps://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n+optional" + } + }, + "description": "ResourceRequirements describes the compute resource requirements." + }, + "v1alpha1ResourceSummary": { + "type": "object", + "properties": { + "totalNum": { + "type": "integer", + "format": "int32", + "description": "Refers to a resource totally." + }, + "readyNum": { + "type": "integer", + "format": "int32", + "description": "Refers to a resource has been ready." + } + }, + "description": "ResourceSummary refers to a resource totally." + }, + "v1alpha1RestartDaemonSetResponse": { + "type": "object", + "properties": { + "daemonSet": { + "$ref": "#/definitions/v1alpha1DaemonSet", + "description": "The new state of the daemonSet after restarting." + } + }, + "description": "Response message for the `RestartDaemonSetResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1RestartDeploymentResponse": { + "type": "object", + "properties": { + "deployment": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "The new state of the deployment after restarting." + } + }, + "description": "Response message for the `RestartDeploymentResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1RestartJobResponse": { + "type": "object", + "properties": { + "job": { + "$ref": "#/definitions/v1alpha1Job", + "description": "The new state of the job after restarting." + } + }, + "description": "Response message for the `RestartJobResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1RestartStatefulSetResponse": { + "type": "object", + "properties": { + "statefulSet": { + "$ref": "#/definitions/v1alpha1StatefulSet", + "description": "The new state of the statefulSet after restarting." + } + }, + "description": "Response message for the `RestartStatefulSetResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1ResumeCronJobResponse": { + "type": "object", + "properties": { + "cronjob": { + "$ref": "#/definitions/v1alpha1CronJob", + "description": "The new state of the cronjob after resuming." + } + }, + "description": "Response message for the `ResumeCronJobResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1ResumeDeploymentResponse": { + "type": "object", + "properties": { + "deployment": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "The new state of the deployment after resuming." + } + }, + "description": "Response message for the `ResumeDeploymentResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1ResumeEtcdBackupStrategyResponse": { + "type": "object", + "properties": { + "strategy": { + "$ref": "#/definitions/v1alpha1EtcdBackupStrategy", + "description": "The new state of the etcd backup strategy after resuming." + } + }, + "description": "Response message for the `ResumeEtcdBackupStrategyResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1Revision": { + "type": "object", + "properties": { + "version": { + "type": "integer", + "format": "int32", + "description": "Version is an int which represents the revision of the release." + }, + "updated": { + "type": "string", + "format": "int64", + "description": "Revision update time." + }, + "status": { + "$ref": "#/definitions/v1alpha1ReleasePhase", + "description": "Status is the status of the helm release." + }, + "chart": { + "type": "string", + "description": "Chart is the chart name of the helm release." + }, + "appVersion": { + "type": "string", + "description": "AppVersion is the app version of the helm release." + }, + "manifest": { + "type": "string", + "description": "Manifest is the chart yaml of the helm release revision." + } + } + }, + "v1alpha1RoleBinding": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "subjects": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1Subject" + }, + "description": "Subjects holds references to the objects the role applies to." + }, + "roleRef": { + "$ref": "#/definitions/v1alpha1RoleRef", + "description": "RoleRef can reference a Role in the current namespace or a ClusterRole in\nthe global namespace." + } + }, + "description": "RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace.\nIt adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given\nnamespace only have effect in that namespace." + }, + "v1alpha1RoleNames": { + "type": "object", + "properties": { + "names": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "v1alpha1RoleRef": { + "type": "object", + "properties": { + "APIGroup": { + "type": "string", + "title": "APIGroup is the group for the resource being referenced" + }, + "kind": { + "type": "string", + "title": "Kind is the type of resource being referenced" + }, + "name": { + "type": "string", + "title": "Name is the name of resource being referenced" + } + } + }, + "v1alpha1RoleSummary": { + "type": "object", + "properties": { + "clusterRoles": { + "type": "array", + "items": { + "type": "string" + } + }, + "roles": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/v1alpha1RoleNames" + } + } + } + }, + "v1alpha1RollbackDaemonSetResponse": { + "type": "object", + "properties": { + "daemonSet": { + "$ref": "#/definitions/v1alpha1DaemonSet", + "description": "The new state of the daemonSet after rollBacking." + } + }, + "description": "Response message for the `RollbackDaemonSetResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1RollbackDeploymentResponse": { + "type": "object", + "properties": { + "deployment": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "The new state of the deployment after restarting." + } + }, + "description": "Response message for the `RestartDeploymentResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1RollbackHelmReleaseResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "description": "Cluster represents which cluster the helmrelease belongs to." + }, + "namespace": { + "type": "string", + "description": "Namespace represents which namespace the helmrelease belongs to." + }, + "releaseName": { + "type": "string", + "description": "ReleaseName represents the helmrelease name." + } + } + }, + "v1alpha1RollbackStatefulSetResponse": { + "type": "object", + "properties": { + "statefulSet": { + "$ref": "#/definitions/v1alpha1StatefulSet", + "description": "The new state of the statefulSet after rollBacking." + } + }, + "description": "Response message for the `RollbackStatefulSetResponse` method.\nThis response message is assigned to the `response` field of the returned\nOperation when that operation is done." + }, + "v1alpha1S3Config": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string", + "description": "username or access key id for minio." + }, + "region": { + "type": "string" + }, + "secretAccessKey": { + "type": "string", + "description": "password or secret key for minio." + }, + "bucket": { + "type": "string", + "description": "the bucket name for minio." + }, + "endpoint": { + "type": "string", + "description": "endpoint for minio." + }, + "storePrefix": { + "type": "string", + "description": "equal to SnapStoreConfig.prefix." + }, + "consoleAddress": { + "type": "string", + "description": "the front-end address for minio." + } + } + }, + "v1alpha1SSHInfo": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1SSHInfoType" + }, + "pass": { + "type": "string" + }, + "secretName": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, + "v1alpha1SSHInfoType": { + "type": "string", + "enum": [ + "TYPE_UNSPECIFIED", + "Password", + "PrivateKey" + ], + "default": "TYPE_UNSPECIFIED", + "description": " - PrivateKey: If you choose this mode, the type of secret should be filled in. The key of data should be \"kubernetes.io/ssh-auth\".\nThe key of data should be \"ssh-privatekey\"." + }, + "v1alpha1Sample": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "The labels of match" + }, + "values": { + "$ref": "#/definitions/v1alpha1samplePair", + "title": "The time stamp" + } + }, + "title": "The metric of sample" + }, + "v1alpha1SampleStream": { + "type": "object", + "properties": { + "metric": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "The labels of match" + }, + "values": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1samplePair" + }, + "title": "The time stamp" + } + }, + "title": "The time stamp stream" + }, + "v1alpha1ScalePersistentVolumeClaimResponse": { + "type": "object", + "properties": { + "capacity": { + "type": "string", + "title": "capacity represents the capacity of PVC" + } + }, + "title": "UpdateScalePersistentVolumeClaimResponse represents the request of scale Pvc" + }, + "v1alpha1Secret": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "immutable": { + "type": "boolean", + "title": "Immutable, if set to true, ensures that data stored in the Secret cannot\nbe updated (only object metadata can be modified).\nIf not set to true, the field can be modified at any time.\nDefaulted to nil.\n+optional" + }, + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Data contains the secret data. Each key must consist of alphanumeric\ncharacters, '-', '_' or '.'. The serialized form of the secret data is a\nbase64 encoded string, representing the arbitrary (possibly non-string)\ndata value here. Described in https://tools.ietf.org/html/rfc4648#section-4\n+optional" + }, + "stringData": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "stringData allows specifying non-binary secret data in string form.\nIt is provided as a write-only input field for convenience.\nAll keys and values are merged into the data field on write, overwriting any existing values.\nThe stringData field is never output when reading from the API.\n+k8s:conversion-gen=false\n+optional" + }, + "type": { + "type": "string", + "title": "Used to facilitate programmatic handling of secret data.\n+optional" + } + } + }, + "v1alpha1SecretEnvSource": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of SecretEnvSource." + }, + "optional": { + "type": "boolean" + } + }, + "description": "SecretEnvSource selects a Secret to populate the environment\nvariables with.\nThe contents of the target Secret's Data field will represent the\nkey-value pairs as environment variables." + }, + "v1alpha1SecretKeySelector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of Secret." + }, + "key": { + "type": "string", + "description": "Required. The secret key to be applied to a pod." + }, + "optional": { + "type": "boolean", + "title": "Specify whether the Secret or its key must be defined\n+optional" + } + }, + "description": "SecretKeySelector selects a key of a Secret." + }, + "v1alpha1SecretVolumeSource": { + "type": "object", + "properties": { + "secretName": { + "type": "string", + "title": "Name of the secret in the pod's namespace to use.\nMore info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n+optional" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1KeyToPath" + }, + "title": "If unspecified, each key-value pair in the Data field of the referenced\nSecret will be projected into the volume as a file whose name is the\nkey and content is the value. If specified, the listed keys will be\nprojected into the specified paths, and unlisted keys will not be\npresent. If a key is specified which is not present in the Secret,\nthe volume setup will error unless it is marked optional. Paths must be\nrelative and may not contain the '..' path or start with '..'.\n+optional" + }, + "defaultMode": { + "type": "integer", + "format": "int32", + "title": "Optional: mode bits used to set permissions on created files by default.\nMust be an octal value between 0000 and 0777 or a decimal value between 0\nand 511. YAML accepts both octal and decimal values, JSON requires decimal\nvalues for mode bits. Defaults to 0644. Directories within the path are not\naffected by this setting. This might be in conflict with other options that\naffect the file mode, like fsGroup, and the result can be other mode bits\nset. +optional" + }, + "optional": { + "type": "boolean", + "title": "Specify whether the Secret or its keys must be defined\n+optional" + } + }, + "description": "Adapts a Secret into a volume.\nThe contents of the target Secret's Data field will be presented in a volume\nas files using the keys in the Data field as the file names.\nSecret volumes support ownership management and SELinux relabeling." + }, + "v1alpha1SecurityContext": { + "type": "object", + "properties": { + "privileged": { + "type": "boolean", + "title": "Capabilities capabilities = 1;" + }, + "runAsUser": { + "type": "string", + "format": "int64", + "title": "SELinuxOptions seLinuxOptions = 3;\nWindowsSecurityContextOptions WindowsOptions = 4;" + } + }, + "title": "SecretKeySelector selects a key of a Secret.\n+structType=atomic" + }, + "v1alpha1Service": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1ServiceSpec", + "description": "It describes the attributes that a user creates on a service." + }, + "status": { + "$ref": "#/definitions/v1alpha1ServiceStatus" + } + } + }, + "v1alpha1ServiceAccount": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + } + } + }, + "v1alpha1ServicePort": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of this port within the service. This must be a DNS_LABEL." + }, + "protocol": { + "type": "string", + "description": "Protocol is IP protocol for this port. Supports \"TCP\", \"UDP\", and \"SCTP\"." + }, + "appProtocol": { + "type": "string", + "description": "AppProtocol is the application protocol for this port." + }, + "port": { + "type": "integer", + "format": "int32", + "description": "Port will be exposed by this service." + }, + "targetPort": { + "type": "string", + "description": "TargetPort is the number or name of the port to access on the pods targeted\nby the service." + }, + "nodePort": { + "type": "integer", + "format": "int32", + "description": "NodePort is the port on each node on which this service is exposed when\ntype is NodePort or LoadBalancer." + } + } + }, + "v1alpha1ServiceSpec": { + "type": "object", + "properties": { + "ports": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1ServicePort" + }, + "description": "Ports is the list of ports that are exposed by this service." + }, + "selector": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Selector is to route service traffic to pods with label keys and values\nmatching this selector." + }, + "clusterIP": { + "type": "string", + "description": "ClusterIP is the IP address of the service and is usually assigned\nrandomly." + }, + "clusterIPs": { + "type": "array", + "items": { + "type": "string" + }, + "title": "ClusterIPs is a list of IP addresses assigned to this service, and are\nusually assigned randomly.\nThis field came out since kubernetes version 1.20.\nTODO: Make it compatible\nMore info:\nhttps://v1-20.docs.kubernetes.io/zh/docs/concepts/services-networking/dual-stack/\nhttps://v1-19.docs.kubernetes.io/zh/docs/concepts/services-networking/dual-stack/" + }, + "type": { + "$ref": "#/definitions/v1alpha1ServiceType", + "title": "ServiceType string describes ingress methods for a service" + }, + "externalIPs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "ExternalIPs is a list of IP addresses for which nodes in the cluster\nwill also accept traffic for this service." + }, + "sessionAffinity": { + "type": "string", + "description": "SessionAffinity supports \"ClientIP\" and \"None\". Used to maintain session\naffinity." + }, + "loadBalancerIP": { + "type": "string", + "description": "LoadBalancerIP only applies to Service Type: LoadBalancer." + }, + "IPFamilies": { + "type": "array", + "items": { + "type": "string" + }, + "title": "IPFamilies is a list of IP families (e.g. IPv4, IPv6) assigned to this\nservice, and is gated by the \"IPv6DualStack\" feature gate.\nThis field has changed from ipFamily (string) to ipFamilies (array) since\nkubernetes version 1.20.\nTODO: Make it compatible\nMore info:\nhttps://v1-20.docs.kubernetes.io/zh/docs/concepts/services-networking/dual-stack/\nhttps://v1-19.docs.kubernetes.io/zh/docs/concepts/services-networking/dual-stack/" + } + }, + "description": "ServiceSpec describes the attributes that a user creates on a service." + }, + "v1alpha1ServiceStatus": { + "type": "object", + "properties": { + "loadBalancer": { + "$ref": "#/definitions/apicorev1alpha1LoadBalancerStatus", + "description": "LoadBalancer contains the current status of the load-balancer,\nif one is present." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "title": "Current service state" + } + }, + "description": "ServiceStatus represents the current status of a service." + }, + "v1alpha1ServiceType": { + "type": "string", + "enum": [ + "SERVICE_TYPE_UNSPECIFIED", + "ClusterIP", + "NodePort", + "LoadBalancer", + "ExternalName" + ], + "default": "SERVICE_TYPE_UNSPECIFIED", + "description": "- SERVICE_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - ClusterIP: ClusterIP means a service will only be accessible inside the cluster, via\nthe cluster IP.\n - NodePort: NodePort means a service will be exposed on one port of every node, in\naddition to 'ClusterIP' type.\n - LoadBalancer: LoadBalancer means a service will be exposed via an external load balancer\n(if the cloud provider supports it), in addition to 'NodePort' type.\n - ExternalName: ExternalName means a service consists of only a reference to an external\nname that kubedns or equivalent will return as a CNAME record, with no\nexposing or proxying of any pods involved.", + "title": "ServiceType string describes ingress methods for a service" + }, + "v1alpha1SnapStoreConfig": { + "type": "object", + "properties": { + "provider": { + "$ref": "#/definitions/SnapStoreConfigSnapStoreProvider", + "description": "provider indicated the cloud provider." + }, + "container": { + "type": "string", + "description": "container holds the name of bucket or container to which snapshot will be stored." + }, + "prefix": { + "type": "string", + "description": "prefix holds the prefix or directory under StorageContainer under which snapshot will be stored." + }, + "s3Config": { + "$ref": "#/definitions/v1alpha1S3Config" + }, + "tempDir": { + "type": "string", + "title": "temp_dir Directory" + } + } + }, + "v1alpha1Snapshot": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "lastModified": { + "type": "string", + "format": "int64" + }, + "key": { + "type": "string" + }, + "size": { + "type": "string", + "format": "int64" + }, + "externalUrl": { + "type": "string" + } + } + }, + "v1alpha1SnapshotterConfig": { + "type": "object", + "properties": { + "fullSnapshotSchedule": { + "type": "string", + "title": "full_snapshot_schedule schedule for snapshots" + }, + "deltaSnapshotPeriod": { + "type": "string", + "format": "int64", + "description": "delta_snapshot_period Period after which delta snapshot will be persisted. If this value is set to be lesser\nthan 1, delta snapshotting will be disabled." + }, + "deltaSnapshotMemoryLimit": { + "type": "integer", + "format": "int64", + "title": "delta_snapshot_memory_limit memory limit after which delta snapshots will be taken" + }, + "garbageCollectionPeriod": { + "type": "string", + "format": "int64", + "title": "garbage_collection_period Period for garbage collecting old backups" + }, + "garbageCollectionPolicy": { + "$ref": "#/definitions/SnapshotterConfigGarbageCollectingPolicy" + }, + "maxBackups": { + "type": "integer", + "format": "int64", + "title": "max_backups maximum number of previous backups to keep" + } + } + }, + "v1alpha1StartDeploymentResponse": { + "type": "object", + "properties": { + "deployment": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "The new state of the deployment after starting." + } + }, + "description": "StartDeploymentResponse returns the deployment after being started." + }, + "v1alpha1StartStatefulSetResponse": { + "type": "object", + "properties": { + "statefulSet": { + "$ref": "#/definitions/v1alpha1StatefulSet", + "description": "The new state of the statefulset after starting." + } + }, + "description": "StartStatefulSetResponse returns the statefulset after being started." + }, + "v1alpha1StatefulSet": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1StatefulSetSpec", + "description": "Spec defines the desired identities of pods in this set." + }, + "status": { + "$ref": "#/definitions/v1alpha1StatefulSetStatus", + "description": "Status is the current status of Pods in this StatefulSet. This data\nmay be out of date by some window of time." + }, + "revision": { + "type": "string", + "format": "int64", + "description": "Revision indicates the revision of the state represented by Data." + } + }, + "description": "StatefulSet represents a set of pods with consistent identities.\nIdentities are defined as:\n - Network: A single stable DNS and hostname.\n - Storage: As many VolumeClaims as requested.\n\nThe StatefulSet guarantees that a given network identity will always\nmap to the same storage identity." + }, + "v1alpha1StatefulSetSpec": { + "type": "object", + "properties": { + "replicas": { + "type": "integer", + "format": "int32", + "description": "replicas is the desired number of replicas of the given Template.\nThese are replicas in the sense that they are instantiations of the\nsame Template, but individual replicas also have a consistent identity.\nIf unspecified, defaults to 1." + }, + "podManagementPolicy": { + "type": "string", + "description": "podManagementPolicy controls how pods are created during initial scale up,\nwhen replacing pods on nodes, or when scaling down. The default policy is\n`OrderedReady`, where pods are created in increasing order (pod-0, then\npod-1, etc) and the controller will wait until each pod is ready before\ncontinuing. When scaling down, the pods are removed in the opposite order.\nThe alternative policy is `Parallel` which will create pods in parallel\nto match the desired scale without waiting, and on scale down will delete\nall pods at once." + }, + "revisionHistoryLimit": { + "type": "integer", + "format": "int32", + "description": "revisionHistoryLimit is the maximum number of revisions that will\nbe maintained in the StatefulSet's revision history. The revision history\nconsists of all revisions not represented by a currently applied\nStatefulSetSpec version. The default value is 10." + }, + "selector": { + "$ref": "#/definitions/typesLabelSelector", + "description": "selector is a label query over pods that should match the replica count.\nIt must match the pod template's labels." + }, + "serviceName": { + "type": "string", + "description": "serviceName is the name of the service that governs this StatefulSet.\nThis service must exist before the StatefulSet, and is responsible for\nthe network identity of the set. Pods get DNS/hostnames that follow the\npattern: pod-specific-string.serviceName.default.svc.cluster.local\nwhere \"pod-specific-string\" is managed by the StatefulSet controller." + }, + "template": { + "$ref": "#/definitions/v1alpha1PodTemplateSpec", + "description": "template is the object that describes the pod that will be created if\ninsufficient replicas are detected. Each pod stamped out by the StatefulSet\nwill fulfill this Template, but have a unique identity from the rest\nof the StatefulSet." + }, + "updateStrategy": { + "$ref": "#/definitions/v1alpha1StatefulSetUpdateStrategy", + "description": "updateStrategy indicates the StatefulSetUpdateStrategy that will be\nemployed to update Pods in the StatefulSet when a revision is made to\nTemplate." + }, + "volumeClaimTemplates": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaim" + }, + "description": "volumeClaimTemplates is a list of claims that pods are allowed to\nreference. The StatefulSet controller is responsible for mapping network\nidentities to claims in a way that maintains the identity of a pod. Every\nclaim in this list must have at least one matching (by name) volumeMount in\none container in the template. A claim in this list takes precedence over\nany volumes in the template, with the same name." + } + }, + "description": "A StatefulSetSpec is the specification of a StatefulSet." + }, + "v1alpha1StatefulSetStatus": { + "type": "object", + "properties": { + "replicas": { + "type": "integer", + "format": "int32", + "description": "replicas is the number of Pods created by the StatefulSet controller." + }, + "readyReplicas": { + "type": "integer", + "format": "int32", + "description": "readyReplicas is the number of Pods created by the StatefulSet controller\nthat have a Ready Condition." + }, + "state": { + "$ref": "#/definitions/typesWorkloadState", + "title": "WorkloadState describes the state of statefulsets" + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/typesCondition" + }, + "description": "Current condition of StatefulSet." + } + }, + "description": "StatefulSetStatus represents the current state of a StatefulSet." + }, + "v1alpha1StatefulSetUpdateStrategy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type indicates the type of the StatefulSetUpdateStrategy." + } + }, + "title": "add StatefulSet to make be not defined in common.proto" + }, + "v1alpha1StopDeploymentResponse": { + "type": "object", + "properties": { + "deployment": { + "$ref": "#/definitions/v1alpha1Deployment", + "description": "The new state of the deployment after stopping." + } + }, + "description": "StopDeploymentResponse returns the deployment after being stopped." + }, + "v1alpha1StopStatefulSetResponse": { + "type": "object", + "properties": { + "statefulSet": { + "$ref": "#/definitions/v1alpha1StatefulSet", + "description": "The new state of the statefulset after stopping." + } + }, + "description": "StopStatefulSetResponse returns the statefulset after being stopped." + }, + "v1alpha1StorageClass": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "provisioner": { + "type": "string", + "description": "Provisioner indicates the type of the provisioner." + }, + "reclaimPolicy": { + "$ref": "#/definitions/StorageClassReclaimPolicy", + "title": "persistentVolumeReclaimPolicy defines what happens to a persistent volume when released from its claim.\nValid options are Retain (default for manually created PersistentVolumes), Delete (default\nfor dynamically provisioned PersistentVolumes), and Recycle (deprecated).\nRecycle must be supported by the volume plugin underlying this PersistentVolume.\nMore info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming\n+optional" + }, + "storageClassName": { + "type": "string", + "title": "storageClassName is the name of StorageClass to which this persistent volume belongs. Empty value\nmeans that this volume does not belong to any StorageClass.\n+optional" + }, + "volumeBindingMode": { + "$ref": "#/definitions/StorageClassVolumeBindingMode", + "title": "VolumeBindingMode indicates how PersistentVolumeClaims should be\nprovisioned and bound. When unset, VolumeBindingImmediate is used.\nThis field is only honored by servers that enable the VolumeScheduling feature.\n+optional" + }, + "mountOptions": { + "type": "array", + "items": { + "type": "string" + }, + "title": "Dynamically provisioned PersistentVolumes of this storage class are\ncreated with these mountOptions, e.g. [\"ro\", \"soft\"]. Not validated -\nmount of the PVs will simply fail if one is invalid.\n+optional" + }, + "parameters": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "Parameters holds the parameters for the provisioner that should\ncreate volumes of this storage class.\n+optional" + }, + "allowVolumeExpansion": { + "type": "boolean", + "title": "AllowVolumeExpansion shows whether the storage class allow volume expand\n+optional" + } + }, + "description": "StorageClass describes the parameters for a class of storage for\nwhich PersistentVolumes can be dynamically provisioned.\n\nStorageClasses are non-namespaced; the name of the storage class\naccording to etcd is in ObjectMeta.Name." + }, + "v1alpha1Subject": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "description": "Kind of object being referenced. Values defined by this API group are\n\"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not\nrecognized the kind value, the Authorizer should report an error." + }, + "APIGroup": { + "type": "string", + "description": "APIGroup holds the API group of the referenced subject.\nDefaults to \"\" for ServiceAccount subjects.\nDefaults to \"rbac.authorization.k8s.io\" for User and Group subjects." + }, + "name": { + "type": "string", + "description": "Name of the object being referenced." + }, + "namespace": { + "type": "string", + "title": "Namespace of the referenced object. If the object kind is non-namespace,\nsuch as \"User\" or \"Group\", and this value is not empty the Authorizer\nshould report an error. +optional" + } + } + }, + "v1alpha1Summary": { + "type": "object", + "properties": { + "state": { + "$ref": "#/definitions/v1alpha1ReleasePhase" + }, + "transitioning": { + "type": "boolean" + }, + "error": { + "type": "boolean" + } + } + }, + "v1alpha1TCPSocketAction": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "format": "int32", + "description": "Number or name of the port to access on the container.\nNumber must be in the range 1 to 65535.\nName must be an IANA_SVC_NAME." + }, + "host": { + "type": "string", + "title": "Optional: Host name to connect to, defaults to the pod IP.\n+optional" + } + }, + "description": "TCPSocketAction describes an action based on opening a socket." + }, + "v1alpha1Tag": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the tag." + }, + "pushTime": { + "type": "string", + "format": "int64", + "description": "Tag push time." + } + }, + "description": "Tag of an image." + }, + "v1alpha1Taint": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Required. The taint key to be applied to a node." + }, + "value": { + "type": "string", + "description": "The taint value corresponding to the taint key." + }, + "effect": { + "$ref": "#/definitions/v1alpha1TaintEffect", + "description": "Valid effects are NoSchedule, PreferNoSchedule, and NoExecute." + } + } + }, + "v1alpha1TaintEffect": { + "type": "string", + "enum": [ + "TAINT_EFFECT_UNSPECIFIED", + "NoSchedule", + "PreferNoSchedule", + "NoExecute" + ], + "default": "TAINT_EFFECT_UNSPECIFIED", + "description": "Valid effects are NoSchedule, PreferNoSchedule, and NoExecute.\n\n - TAINT_EFFECT_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - NoSchedule: NoSchedule tries to avoid scheduling pods to nodes where they can't\ntolerate taints.\n - PreferNoSchedule: This is not mandatory tries to avoid scheduling pods to nodes.\n - NoExecute: NoExecute is not assign pod to or evicted pod from the node." + }, + "v1alpha1Toleration": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "The key to project." + }, + "operator": { + "type": "string", + "description": "Represents a key's relationship to a set of values." + }, + "value": { + "type": "string", + "description": "An array of string values." + }, + "effect": { + "type": "string", + "description": "Valid effects are NoSchedule, PreferNoSchedule, and NoExecute." + }, + "tolerationSeconds": { + "type": "string", + "format": "int64" + } + }, + "description": "Taint tolerations to static pods,\nso they are not evicted when there are node problems." + }, + "v1alpha1TypedObjectReference": { + "type": "object", + "properties": { + "apiGroup": { + "type": "string", + "title": "APIGroup is the group for the resource being referenced.\nIf APIGroup is not specified, the specified Kind must be in the core API group.\nFor any other third-party types, APIGroup is required.\n+optional" + }, + "kind": { + "type": "string", + "title": "Kind is the type of resource being referenced" + }, + "name": { + "type": "string", + "title": "Name is the name of resource being referenced" + }, + "namespace": { + "type": "string", + "title": "Namespace is the namespace of resource being referenced\nNote that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n(Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n+featureGate=CrossNamespaceVolumeDataSource\n+optional" + } + } + }, + "v1alpha1UnBindClusterFromWorkspaceResponse": { + "type": "object" + }, + "v1alpha1UnbindNodeToNamespaceResponse": { + "type": "object", + "title": "UnbindNodeToNamespaceResponse is unbind result" + }, + "v1alpha1UnbindResourceFromWorkspaceResponse": { + "type": "object" + }, + "v1alpha1UpdateClusterCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateClusterCustomResourceResponse represents response of updating one\nCustomResource of cluster scope" + }, + "v1alpha1UpdateClusterCustomResourceStatusResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateClusterCustomResourceStatusResponse represents response of updating the status of a CustomResource of cluster scope" + }, + "v1alpha1UpdateClusterRoleResponse": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + }, + "title": "UpdateClusterRoleRequest the response of update clusterrole" + }, + "v1alpha1UpdateConfigMapResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the ConfigMap YAML details" + } + } + }, + "v1alpha1UpdateCronHorizontalPodAutoscalerResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the hpa YAML details" + } + } + }, + "v1alpha1UpdateCustomResourceDefinitionResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the customResourceDefinition YAML details" + } + }, + "title": "UpdateCustomResourceDefinitionResponse represents response of updating\na createCustomResourceDefinition" + }, + "v1alpha1UpdateCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateCustomResourceResponse represents response of updating one\nCustomResource of namespaced scope" + }, + "v1alpha1UpdateCustomResourceStatusResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data field is the CustomResource YAML details." + } + }, + "title": "UpdateCustomResourceStatusResponse returns the response of updating the status of a\nCustomResource of namespaced scope" + }, + "v1alpha1UpdateHelmReleaseResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string", + "description": "Cluster represents which cluster the helmrelease belongs to." + }, + "namespace": { + "type": "string", + "description": "Namespace represents which namespace the helmrelease belongs to." + }, + "releaseName": { + "type": "string" + } + } + }, + "v1alpha1UpdateHorizontalPodAutoscalerResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the hpa YAML details" + } + } + }, + "v1alpha1UpdateIngressResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the ingress YAML details." + } + }, + "title": "UpdateIngressRequest the response of update cluster ingresses" + }, + "v1alpha1UpdateLimitRangeResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the LimitRange YAML details." + } + }, + "description": "UpdateLimitRangeResponse returns the created LimitRange data information." + }, + "v1alpha1UpdateMode": { + "type": "string", + "enum": [ + "UPDATE_MODE_UNSPECIFIED", + "Off", + "Initial", + "Recreate", + "Auto" + ], + "default": "UPDATE_MODE_UNSPECIFIED", + "description": "UpdateMode controls when autoscaler applies changes to the pod resoures.\n\n - UPDATE_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - Off: UpdateModeOff means that autoscaler never changes Pod resources.\nThe recommender still sets the recommended resources in the\nVerticalPodAutoscaler object. This can be used for a \"dry run\".\n - Initial: UpdateModeInitial means that autoscaler only assigns resources on pod\ncreation and does not change them during the lifetime of the pod.\n - Recreate: UpdateModeRecreate means that autoscaler assigns resources on pod\ncreation and additionally can update them during the lifetime of the\npod by deleting and recreating the pod.\n - Auto: UpdateModeAuto means that autoscaler assigns resources on pod creation\nand additionally can update them during the lifetime of the pod,\nusing any available update method. Currently this is equivalent to\nRecreate, which is the only available update method." + }, + "v1alpha1UpdateNamespaceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + }, + "description": "Update Namespace data." + }, + "v1alpha1UpdateNetworkPolicyResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the networkpolicy YAML details." + } + }, + "title": "UpdateNetworkPolicyResponse the response of update cluster networkpolicies" + }, + "v1alpha1UpdateNodeAnnotationsResponse": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Annotations returned." + } + } + }, + "v1alpha1UpdateNodeGPUModeResponse": { + "type": "object", + "properties": { + "mode": { + "$ref": "#/definitions/v1alpha1GPUModel" + } + } + }, + "v1alpha1UpdateNodeResponse": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + }, + "description": "UpdateNodeResponse return's a node's json." + }, + "v1alpha1UpdatePersistentVolumeClaimAnnotationsResponse": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "labels represents the Annotations of pvc" + } + }, + "title": "UpdatePersistentVolumeClaimLabelsResponse represents the response of put PVC annotations Response" + }, + "v1alpha1UpdatePersistentVolumeClaimLabelsResponse": { + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "title": "labels represents the labels of pvc" + } + }, + "title": "UpdateNodeLabelsResponse represents the response of put pvc's labels" + }, + "v1alpha1UpdatePersistentVolumeClaimResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data represents the data of PVC JSON" + } + } + }, + "v1alpha1UpdatePersistentVolumeResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the PersistentVolume YAML details." + } + }, + "description": "UpdatePersistentVolumeResponse returns the created PersistentVolume data information." + }, + "v1alpha1UpdateReplicaSetResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the ReplicaSet YAML details." + } + }, + "description": "UpdateReplicaSetResponse returns the created ReplicaSet data information." + }, + "v1alpha1UpdateResourceQuotaResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Data is the ResourceQuota YAML details." + } + }, + "description": "UpdateResourceQuotaResponse returns the created ResourceQuota data information." + }, + "v1alpha1UpdateRoleResponse": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + }, + "title": "UpdateRoleResponse the response of update role" + }, + "v1alpha1UpdateSecretResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data field is the Secret YAML details" + } + }, + "description": "It returns updated secret information." + }, + "v1alpha1UpdateServiceAccountResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "description": "UpdateServiceAccount represents the response of delete sa." + }, + "v1alpha1UpdateServiceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "Data is the Service YAML details" + } + }, + "description": "It returns the Updated Service data information." + }, + "v1alpha1UpdateStorageClassResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "The data is the StorageClass YAML details" + } + }, + "title": "UpdateStorageClassResponse represents the response of delete storage class" + }, + "v1alpha1UpdateVerticalPodAutoscalerResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "The data is the vpa YAML details." + } + }, + "description": "UpdateVerticalPodAutoscalerResponse returns the updated json data." + }, + "v1alpha1UpdateVolumeSnapshotResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data represents the data of volume snapshot JSON" + } + }, + "description": "UpdateVolumeSnapshotResponse represents the response of update volume snapshot." + }, + "v1alpha1User": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "id is the unique identification of the user." + }, + "name": { + "type": "string", + "description": "the name of the user." + } + } + }, + "v1alpha1VGPUNodeStats": { + "type": "object", + "properties": { + "physicalGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of physical Gpus" + }, + "totalVirtualGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of virtual Gpus" + }, + "allocatedVirtualGpuNumber": { + "type": "integer", + "format": "int32", + "title": "Number of allocated virtual Gpus" + }, + "allocatedComputePower": { + "type": "string", + "format": "int64" + }, + "totalComputePower": { + "type": "string", + "format": "int64", + "title": "total compute power" + }, + "totalGpuMemory": { + "type": "string", + "format": "int64", + "title": "Number of gpu memory" + }, + "allocatedGpuMemory": { + "type": "string", + "format": "int64", + "title": "Number of allocated gpu memory" + } + } + }, + "v1alpha1ValidateClusterResponse": { + "type": "object", + "properties": { + "dceComponents": { + "type": "object", + "additionalProperties": { + "type": "boolean" + }, + "description": "Components is to show if components exist in target cluster, e.g. kpanda-system namespace, insight-system namespace, and mspider mesh." + } + }, + "description": "ValidateClusterResponse returns the result of residuals existence." + }, + "v1alpha1ValidateHelmRepoResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "description": "Successfully connected to the repo." + }, + "error": { + "type": "string", + "description": "If connecting to the repo failed, return the reason." + } + }, + "title": "ValidateHelmRepoResponse returns the result of connecting to a helm repo" + }, + "v1alpha1ValidateKubeConfigRequest": { + "type": "object", + "properties": { + "kubeConfigString": { + "type": "string", + "description": "KubeConfig of the cluster." + } + } + }, + "v1alpha1ValidateKubeConfigResponse": { + "type": "object", + "properties": { + "validateResult": { + "type": "boolean" + }, + "errMsg": { + "type": "string", + "description": "err_msg if validate_result is false , err_msg will has no-empty value." + }, + "kubeconfigExpireTime": { + "type": "string", + "format": "int64" + } + } + }, + "v1alpha1VerificationMethod": { + "type": "string", + "enum": [ + "VERIFICATION_METHOD_UNSPECIFIED", + "None", + "BasicAuth" + ], + "default": "VERIFICATION_METHOD_UNSPECIFIED", + "description": "- VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified.\n - None: The repository is public and does not require authentication.\n - BasicAuth: BasicAuth contains data needed for basic authentication.", + "title": "Repository verification method" + }, + "v1alpha1VerifyEtcdConnectionResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "description": "This field indicates whether or not the verification operation for\nverifying etcd connection successful." + }, + "errMsg": { + "type": "string", + "description": "err_msg if validate_result is false , err_msg will has no-empty value." + } + } + }, + "v1alpha1VerifyImageResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "description": "This field indicates whether or not the verification operation for\nverifying image successful." + } + } + }, + "v1alpha1VerifyRegistryRequest": { + "type": "object", + "properties": { + "registryHost": { + "type": "string", + "description": "The registry host which needs to verify." + }, + "username": { + "type": "string", + "description": "The username of the registry." + }, + "password": { + "type": "string", + "description": "The password of the registry." + } + } + }, + "v1alpha1VerifyRegistryResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "description": "This field indicates whether or not the verification operation for\nverifying registery successful." + } + } + }, + "v1alpha1VerifySnapStoreConfigResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "description": "This field indicates whether or not the verification operation for\nverifying SnapStore successful." + }, + "errMsg": { + "type": "string", + "description": "err_msg if validate_result is false , err_msg will has no-empty value." + } + } + }, + "v1alpha1VerticalPodAutoscaler": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1VerticalPodAutoscalerSpec", + "description": "Specification of the behavior of the autoscaler." + }, + "status": { + "$ref": "#/definitions/v1alpha1VerticalPodAutoscalerStatus", + "description": "Current information about the autoscaler." + } + }, + "description": "VerticalPodAutoscaler is the configuration for a vertical pod autoscaler, which automatically manages pod resources based on historical and real time resource utilization." + }, + "v1alpha1VerticalPodAutoscalerCondition": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1VerticalPodAutoscalerConditionType", + "description": "Type describes the current condition." + }, + "status": { + "$ref": "#/definitions/typesConditionStatus", + "description": "status is the status of the condition (True, False, Unknown)." + }, + "lastTransitionTime": { + "type": "string", + "format": "int64", + "description": "LastTransitionTime is the last time the condition transitioned from one status to another." + }, + "reason": { + "type": "string", + "description": "Reason is the reason for the condition's last transition." + }, + "message": { + "type": "string", + "description": "message is a human-readable explanation containing details about the transition." + } + }, + "description": "VerticalPodAutoscalerCondition describes the state of a VerticalPodAutoscaler at a certain point." + }, + "v1alpha1VerticalPodAutoscalerConditionType": { + "type": "string", + "enum": [ + "VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED", + "RecommendationProvided", + "LowConfidence", + "NoPodsMatched", + "FetchingHistory", + "ConfigDeprecated", + "ConfigUnsupported" + ], + "default": "VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED", + "description": "VerticalPodAutoscalerConditionType is the valid conditions of a VerticalPodAutoscaler.\n\n - VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.\n - RecommendationProvided: RecommendationProvided indicates whether the VPA recommender was able to calculate a recommendation.\n - LowConfidence: LowConfidence indicates whether the VPA recommender has low confidence in the recommendation for some of containers.\n - NoPodsMatched: NoPodsMatched indicates that label selector used with VPA object didn't match any pods.\n - FetchingHistory: FetchingHistory indicates that VPA recommender is in the process of loading additional history samples.\n - ConfigDeprecated: ConfigDeprecated indicates that this VPA configuration is deprecated and will stop being supported soon.\n - ConfigUnsupported: ConfigUnsupported indicates that this VPA configuration is unsupported and recommendations will not be provided for it." + }, + "v1alpha1VerticalPodAutoscalerRecommenderSelector": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the recommender responsible for generating recommendation for this object." + } + }, + "description": "VerticalPodAutoscalerRecommenderSelector points to a specific Vertical Pod Autoscaler recommender.\nIn the future it might pass parameters to the recommender." + }, + "v1alpha1VerticalPodAutoscalerSpec": { + "type": "object", + "properties": { + "targetRef": { + "$ref": "#/definitions/v1alpha1CrossVersionObjectReference", + "description": "TargetRef points to the controller managing the set of pods for the autoscaler to control - e.g. Deployment, StatefulSet." + }, + "updatePolicy": { + "$ref": "#/definitions/v1alpha1PodUpdatePolicy", + "description": "Describes the rules on how changes are applied to the pods.\nIf not specified, all fields in the `PodUpdatePolicy` are set to their\ndefault values." + }, + "resourcePolicy": { + "$ref": "#/definitions/v1alpha1PodResourcePolicy", + "description": "Controls how the autoscaler computes recommended resources.\nThe resource policy may be used to set constraints on the recommendations\nfor individual containers. If not specified, the autoscaler computes recommended\nresources for all containers in the pod, without additional constraints." + }, + "recommenders": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VerticalPodAutoscalerRecommenderSelector" + }, + "description": "Recommender responsible for generating recommendation for this object.\nList should be empty (then the default recommender will generate the recommendation) or contain exactly one recommender." + } + }, + "description": "VerticalPodAutoscalerSpec is the specification of the behavior of the autoscaler." + }, + "v1alpha1VerticalPodAutoscalerStatus": { + "type": "object", + "properties": { + "recommendation": { + "$ref": "#/definitions/v1alpha1RecommendedPodResources", + "description": "The most recently computed amount of resources recommended by the\nautoscaler for the controlled pods." + }, + "conditions": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1VerticalPodAutoscalerCondition" + }, + "description": "Conditions is the set of conditions required for this autoscaler to scale its target,\nand indicates whether or not those conditions are met." + } + }, + "description": "VerticalPodAutoscalerStatus describes the runtime state of the autoscaler." + }, + "v1alpha1Volume": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "hostPath": { + "$ref": "#/definitions/v1alpha1HostPathVolumeSource", + "description": "HostPathVolumeSource represents a host path mapped into a pod.\nHost path volumes do not support ownership management or SELinux\nrelabeling." + }, + "emptyDir": { + "$ref": "#/definitions/v1alpha1EmptyDirVolumeSource", + "description": "EmptyDirVolumeSource represents an empty directory for a pod.\nEmpty directory volumes support ownership management and SELinux\nrelabeling." + }, + "secret": { + "$ref": "#/definitions/v1alpha1SecretVolumeSource", + "description": "SecretVolumeSource adapts a Secret into a volume.\nThe contents of the target Secret's Data field will be presented in a\nvolume as files using the keys in the Data field as the file names. Secret\nvolumes support ownership management and SELinux relabeling." + }, + "persistentVolumeClaim": { + "$ref": "#/definitions/v1alpha1PersistentVolumeClaimVolumeSource", + "title": "PersistentVolumeClaimVolumeSource represents a reference to a\nPersistentVolumeClaim in the same namespace" + }, + "downwardAPI": { + "$ref": "#/definitions/v1alpha1DownwardAPIVolumeSource", + "description": "DownwardAPIVolumeSource represents a volume containing downward API info.\nDownward API volumes support ownership management and SELinux relabeling." + }, + "configMap": { + "$ref": "#/definitions/v1alpha1ConfigMapVolumeSource", + "description": "ConfigMapVolumeSource adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a\nvolume as files using the keys in the Data field as the file names, unless\nthe items element is populated with specific mappings of keys to paths.\nConfigMap volumes support ownership management and SELinux relabeling." + } + }, + "description": "Volume represents a named volume in a pod that may be accessed by any\ncontainer in the pod." + }, + "v1alpha1VolumeMount": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "This must match the Name of a Volume." + }, + "readOnly": { + "type": "boolean", + "title": "Mounted read-only if true, read-write otherwise (false or unspecified).\nDefaults to false.\n+optional" + }, + "mountPath": { + "type": "string", + "description": "Full path to the mount volume path." + }, + "subPath": { + "type": "string", + "title": "Path within the volume from which the container's volume should be mounted.\nDefaults to \"\" (volume's root).\n+optional" + }, + "mountPropagation": { + "type": "string", + "title": "mountPropagation determines how mounts are propagated from the host\nto container and the other way around.\nWhen not set, MountPropagationNone is used.\nThis field is beta in 1.10.\n+optional" + }, + "subPathExpr": { + "type": "string", + "title": "Expanded path within the volume from which the container's volume should be\nmounted. Behaves similarly to SubPath but environment variable references\n$(VAR_NAME) are expanded using the container's environment. Defaults to \"\"\n(volume's root). SubPathExpr and SubPath are mutually exclusive. +optional" + } + }, + "description": "VolumeMount for this container." + }, + "v1alpha1VolumeNodeAffinity": { + "type": "object", + "properties": { + "required": { + "$ref": "#/definitions/v1alpha1NodeSelector", + "description": "Required specifies hard node constraints that must be met." + } + }, + "description": "VolumeNodeAffinity defines constraints that limit what nodes this volume can be accessed from." + }, + "v1alpha1VolumeSnapshot": { + "type": "object", + "properties": { + "metadata": { + "$ref": "#/definitions/typesObjectMeta", + "description": "Standard object's metadata." + }, + "spec": { + "$ref": "#/definitions/v1alpha1VolumeSnapshotSpec", + "description": "spec defines the desired characteristics of a snapshot requested by a user.\nMore info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots\nRequired." + }, + "status": { + "$ref": "#/definitions/v1alpha1VolumeSnapshotStatus", + "title": "status represents the current information of a snapshot.\nConsumers must verify binding between VolumeSnapshot and\nVolumeSnapshotContent objects is successful (by validating that both\nVolumeSnapshot and VolumeSnapshotContent point at each other) before\nusing this object.\n+optional" + } + } + }, + "v1alpha1VolumeSnapshotSource": { + "type": "object", + "properties": { + "persistentVolumeClaimName": { + "type": "string", + "title": "persistentVolumeClaimName specifies the name of the PersistentVolumeClaim\nobject representing the volume from which a snapshot should be created.\nThis PVC is assumed to be in the same namespace as the VolumeSnapshot\nobject.\nThis field should be set if the snapshot does not exists, and needs to be\ncreated.\nThis field is immutable.\n+optional" + }, + "volumeSnapshotContentName": { + "type": "string", + "title": "volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent\nobject representing an existing volume snapshot.\nThis field should be set if the snapshot already exists and only needs a representation in Kubernetes.\nThis field is immutable.\n+optional" + } + } + }, + "v1alpha1VolumeSnapshotSpec": { + "type": "object", + "properties": { + "source": { + "$ref": "#/definitions/v1alpha1VolumeSnapshotSource", + "description": "source specifies where a snapshot will be created from.\nThis field is immutable after creation.\nRequired." + }, + "volumeSnapshotClassName": { + "type": "string", + "title": "VolumeSnapshotClassName is the name of the VolumeSnapshotClass\nrequested by the VolumeSnapshot.\nVolumeSnapshotClassName may be left nil to indicate that the default\nSnapshotClass should be used.\nA given cluster may have multiple default Volume SnapshotClasses: one\ndefault per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass,\nVolumeSnapshotSource will be checked to figure out what the associated\nCSI Driver is, and the default VolumeSnapshotClass associated with that\nCSI Driver will be used. If more than one VolumeSnapshotClass exist for\na given CSI Driver and more than one have been marked as default,\nCreateSnapshot will fail and generate an event.\nEmpty string is not allowed for this field.\n+optional" + } + } + }, + "v1alpha1VolumeSnapshotStatus": { + "type": "object", + "properties": { + "creationTime": { + "type": "string", + "format": "int64", + "title": "creationTime is the timestamp when the point-in-time snapshot is taken\nby the underlying storage system.\nIn dynamic snapshot creation case, this field will be filled in by the\nsnapshot controller with the \"creation_time\" value returned from CSI\n\"CreateSnapshot\" gRPC call.\nFor a pre-existing snapshot, this field will be filled with the \"creation_time\"\nvalue returned from the CSI \"ListSnapshots\" gRPC call if the driver supports it.\nIf not specified, it may indicate that the creation time of the snapshot is unknown.\n+optional" + }, + "readyToUse": { + "type": "boolean", + "title": "readyToUse indicates if the snapshot is ready to be used to restore a volume.\nIn dynamic snapshot creation case, this field will be filled in by the\nsnapshot controller with the \"ready_to_use\" value returned from CSI\n\"CreateSnapshot\" gRPC call.\nFor a pre-existing snapshot, this field will be filled with the \"ready_to_use\"\nvalue returned from the CSI \"ListSnapshots\" gRPC call if the driver supports it,\notherwise, this field will be set to \"True\".\nIf not specified, it means the readiness of a snapshot is unknown.\n+optional" + }, + "restoreSize": { + "type": "string", + "title": "restoreSize represents the minimum size of volume required to create a volume\nfrom this snapshot.\nIn dynamic snapshot creation case, this field will be filled in by the\nsnapshot controller with the \"size_bytes\" value returned from CSI\n\"CreateSnapshot\" gRPC call.\nFor a pre-existing snapshot, this field will be filled with the \"size_bytes\"\nvalue returned from the CSI \"ListSnapshots\" gRPC call if the driver supports it.\nWhen restoring a volume from this snapshot, the size of the volume MUST NOT\nbe smaller than the restoreSize if it is specified, otherwise the restoration will fail.\nIf not specified, it indicates that the size is unknown.\n+optional" + } + }, + "description": "VolumeSnapshotStatus is the status of the VolumeSnapshot\nNote that CreationTime, RestoreSize, ReadyToUse, and Error are in both\nVolumeSnapshotStatus and VolumeSnapshotContentStatus. Fields in VolumeSnapshotStatus\nare updated based on fields in VolumeSnapshotContentStatus. They are eventual\nconsistency. These fields are duplicate in both objects due to the following reasons:\n - Fields in VolumeSnapshotContentStatus can be used for filtering when importing a\n volumesnapshot.\n - VolumsnapshotStatus is used by end users because they cannot see VolumeSnapshotContent.\n - CSI snapshotter sidecar is light weight as it only watches VolumeSnapshotContent\n object, not VolumeSnapshot object." + }, + "v1alpha1WeightedPodAffinityTerm": { + "type": "object", + "properties": { + "weight": { + "type": "integer", + "format": "int32", + "description": "weight associated with matching the corresponding podAffinityTerm,\nin the range 1-100." + }, + "podAffinityTerm": { + "$ref": "#/definitions/v1alpha1PodAffinityTerm", + "description": "Required. A pod affinity term, associated with the corresponding weight." + } + }, + "title": "The weights of all of the matched WeightedPodAffinityTerm fields are added\nper-node to find the most preferred node(s)" + }, + "v1alpha1WorkloadJSON": { + "type": "object", + "properties": { + "data": { + "type": "string", + "title": "data The data field is the Workload YAML details" + } + }, + "title": "WorkloadJSON messages of workload YAML details" + }, + "v1alpha1WorkloadKind": { + "type": "string", + "enum": [ + "deployments", + "statefulsets", + "daemonsets", + "jobs", + "cronjobs", + "pods", + "replicasets" + ], + "default": "deployments", + "description": "- deployments: A Deployment provides declarative updates for Pods and ReplicaSets.\n - statefulsets: StatefulSet is the workload API object used to manage stateful\napplications.\n - daemonsets: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod.\n - jobs: Jobs based on a common template. You can use this approach to process\nbatches of work in parallel.\n - cronjobs: CronJob object is like one line of a crontab (cron table) file. It runs a\njob periodically on a given schedule, written in Cron format.", + "title": "workloadKind represents the kpanda's workload types of inclusion" + }, + "v1alpha1WorkspaceInfo": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "alias": { + "type": "string" + } + } + }, + "v1alpha1requestStatus": { + "type": "string", + "enum": [ + "STATUS_UNSPECIFIED", + "SUCCESS", + "FAIL" + ], + "default": "STATUS_UNSPECIFIED", + "title": "The request of status" + }, + "v1alpha1samplePair": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "int64", + "title": "Timestamp of the query" + }, + "value": { + "type": "string", + "title": "Value of the query" + } + }, + "title": "The sample pair" + } + } +} diff --git a/docs/zh/docs/openapi/virtnest/index.md b/docs/zh/docs/openapi/virtnest/index.md new file mode 100644 index 0000000..c39515d --- /dev/null +++ b/docs/zh/docs/openapi/virtnest/index.md @@ -0,0 +1 @@ +# diff --git a/docs/zh/docs/openapi/virtnest/v0.13.0.json b/docs/zh/docs/openapi/virtnest/v0.13.0.json new file mode 100644 index 0000000..d6aa7aa --- /dev/null +++ b/docs/zh/docs/openapi/virtnest/v0.13.0.json @@ -0,0 +1,3971 @@ +{ + "swagger": "2.0", + "info": { + "title": "云主机", + "version": "v0.13.0" + }, + "tags": [ + { + "name": "Cluster" + }, + { + "name": "FeatureGate" + }, + { + "name": "Image" + }, + { + "name": "Role" + }, + { + "name": "VM" + }, + { + "name": "VMTemplate" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/apis/virtnest.io/v1alpha1/clusters": { + "get": { + "operationId": "Cluster_ListClusters", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clusterListClustersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/custom-resource": { + "post": { + "operationId": "VM_CreateCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmCreateCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces": { + "get": { + "operationId": "Cluster_ListClusterNamespaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clusterListClusterNamespacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets": { + "get": { + "operationId": "Image_ListSecrets", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/imageListSecretsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name}/check": { + "get": { + "operationId": "Image_CheckSecret", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/imageCheckSecretResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vm": { + "post": { + "operationId": "VM_CreateVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmCreateVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "aliasName": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "imageSource": { + "$ref": "#/definitions/v1alpha1vmImageSource" + }, + "imageUrl": { + "type": "string" + }, + "disks": { + "$ref": "#/definitions/v1alpha1vmVMDisks" + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "ssh": { + "$ref": "#/definitions/vmSSH" + }, + "osFamily": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "secret": { + "type": "string" + }, + "network": { + "$ref": "#/definitions/vmMultusNetwork" + }, + "createPowerOn": { + "type": "boolean" + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmGPU" + } + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vm-with-vmtemplate/{vmtemplateName}": { + "post": { + "operationId": "VM_CreateVMWithVMTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmCreateVMWithVMTemplateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "vmtemplateName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "aliasName": { + "type": "string" + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "disks": { + "$ref": "#/definitions/v1alpha1vmVMDisks" + }, + "ssh": { + "$ref": "#/definitions/vmSSH" + }, + "imageSource": { + "$ref": "#/definitions/v1alpha1vmImageSource" + }, + "imageUrl": { + "type": "string" + }, + "osFamily": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "secret": { + "type": "string" + }, + "network": { + "$ref": "#/definitions/vmMultusNetwork" + }, + "createPowerOn": { + "type": "boolean" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}": { + "get": { + "operationId": "VM_GetVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmGetVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + }, + "delete": { + "operationId": "VM_DeleteVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmDeleteVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + }, + "put": { + "operationId": "VM_UpdateVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmUpdateVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "aliasName": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "disks": { + "$ref": "#/definitions/v1alpha1vmVMDisks" + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmGPU" + } + }, + "network": { + "$ref": "#/definitions/vmMultusNetwork" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/clone": { + "post": { + "operationId": "VM_CloneVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmCloneVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "cloneName": { + "type": "string" + }, + "aliasName": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/cold-migration": { + "post": { + "operationId": "VM_ColdMigration", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmColdMigrationResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "targetNode": { + "type": "string", + "title": "空值表示随机选择节点" + }, + "disks": { + "$ref": "#/definitions/v1alpha1vmVMDisks" + }, + "powerOn": { + "type": "boolean" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/custom-resource": { + "get": { + "operationId": "VM_GetCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1vmGetCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + }, + "put": { + "operationId": "VM_UpdateCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1vmUpdateCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/disk-volume": { + "post": { + "operationId": "VM_AddDiskVolumeToVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmAddDiskVolumeToVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "diskVolumes": { + "$ref": "#/definitions/v1alpha1vmDiskVolume" + }, + "hotplug": { + "type": "boolean" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/disk-volume/{diskName}": { + "delete": { + "operationId": "VM_RemoveVMDiskVolume", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmRemoveVMDiskVolumeResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "diskName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/disk-volume/{diskName}/expand-capacity": { + "put": { + "operationId": "VM_ExpandVMDiskCapacity", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmExpandVMDiskCapacityResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "diskName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "capacity": { + "type": "string", + "format": "int64" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/events": { + "get": { + "operationId": "VM_ListVMEvents", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListVMEventsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/live-migration": { + "post": { + "operationId": "VM_LiveMigrateVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmLiveMigrateVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "targetNode": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/networks": { + "get": { + "operationId": "VM_ListVMNetworks", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListVMNetworksResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/restore": { + "post": { + "operationId": "VM_RestoreVMSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmRestoreVMSnapshotResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "snapshotName": { + "type": "string" + }, + "restoreName": { + "type": "string" + }, + "restoreDescription": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/restores/{restoreName}": { + "delete": { + "operationId": "VM_DeleteVMRestore", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmDeleteVMRestoreResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "restoreName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/running-status": { + "put": { + "operationId": "VM_UpdateVMRunningStatus", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmUpdateVMRunningStatusResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "vmOperation": { + "$ref": "#/definitions/vmVMOperation" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshot": { + "post": { + "operationId": "VM_CreateVMSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmCreateVMSnapshotResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "snapshotName": { + "type": "string" + }, + "snapshotDescription": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots": { + "get": { + "operationId": "VM_ListVMSnapshots", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListVMSnapshotsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots/{snapshotName}": { + "delete": { + "operationId": "VM_DeleteVMSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmDeleteVMSnapshotResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "snapshotName", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + }, + "put": { + "operationId": "VM_UpdateVMSnapshot", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmUpdateVMSnapshotResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "snapshotName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "snapshotDescription": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots/{snapshotName}/restores": { + "get": { + "operationId": "VM_ListVMRestores", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListVMRestoresResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "snapshotName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/storages": { + "get": { + "operationId": "VM_ListVMStorages", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListVMStoragesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/network-interfaces": { + "get": { + "operationId": "VM_ListNetworkInterfaces", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListNetworkInterfacesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/nodes": { + "get": { + "operationId": "VM_ListClusterNodes", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListClusterNodesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/storageclasses": { + "get": { + "operationId": "VM_ListClusterStorageClasses", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListClusterStorageClassesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/system-images": { + "get": { + "operationId": "VM_ListSystemImages", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListSystemImagesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/vm-monitor/ready": { + "get": { + "operationId": "Cluster_IsVMMonitorReady", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/clusterIsVMMonitorReadyResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "Cluster" + ] + } + }, + "/apis/virtnest.io/v1alpha1/clusters/{cluster}/vms": { + "get": { + "operationId": "VM_ListClusterVMs", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmListClusterVmsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "created_at", + "field_name" + ], + "default": "created_at" + }, + { + "name": "sortDir", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + { + "name": "namespace", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "VM" + ] + } + }, + "/apis/virtnest.io/v1alpha1/feature-gate": { + "get": { + "operationId": "FeatureGate_ListFeatureGates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/feature_gateListFeatureGatesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "FeatureGate" + ] + } + }, + "/apis/virtnest.io/v1alpha1/projects": { + "get": { + "operationId": "Image_ListProjects", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/imageListProjectsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "registry", + "description": "Registry is registry name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "public", + "description": "Public is distinguish public projects and private projects.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/virtnest.io/v1alpha1/registries": { + "get": { + "operationId": "Image_ListRegistries", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/imageListRegistriesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "public", + "description": "Public is distinguish public images and private images.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/virtnest.io/v1alpha1/repositories": { + "get": { + "operationId": "Image_ListRepositories", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/imageListRepositoriesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "cluster", + "description": "Cluster is the current cluster.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "namespace", + "description": "Namespace is the current namespace.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "registry", + "description": "Registry is registry name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "project", + "description": "Project is the project to request, \"/\" is a possible value.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fuzzyName", + "description": "FuzzyName is used to fuzzy search by multiple parameters including name.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "description": "Page requested.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "pageSize", + "description": "Size per page.", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "public", + "description": "Public is distinguish public images and private images.", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "showArtifacts", + "description": "ShowArtifacts is to list artifacts of per image, default false.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "Image" + ] + } + }, + "/apis/virtnest.io/v1alpha1/roles": { + "get": { + "operationId": "Role_GetUserRoles", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/roleGetUserRolesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "tags": [ + "Role" + ] + } + }, + "/apis/virtnest.io/v1alpha1/vmtemplate-by-vm": { + "post": { + "summary": "rpc UpdateVMTemplate(UpdateVMTemplateRequest) returns (UpdateVMTemplateResponse) {\n option (google.api.http) = {\n put: \"/apis/virtnest.io/v1alpha1/vmtemplates/{name}\"\n body: \"*\"\n };\n }", + "operationId": "VMTemplate_CreateVMTemplateByVM", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmtemplateCreateVMTemplateByVMResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/vmtemplateCreateVMTemplateByVMRequest" + } + } + ], + "tags": [ + "VMTemplate" + ] + } + }, + "/apis/virtnest.io/v1alpha1/vmtemplates": { + "get": { + "operationId": "VMTemplate_ListVMTemplates", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmtemplateListVMTemplatesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "pageSize", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "search", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "sortBy", + "description": " - UNSPECIFIED: Unspecified is default, no sorting.\n - created_at: Sort result by creationTimestamp.\n - field_name: Sort result by name.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "UNSPECIFIED", + "created_at", + "field_name" + ], + "default": "UNSPECIFIED" + }, + { + "name": "sortDir", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + } + ], + "tags": [ + "VMTemplate" + ] + } + }, + "/apis/virtnest.io/v1alpha1/vmtemplates/{name}": { + "get": { + "operationId": "VMTemplate_GetVMTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmtemplateGetVMTemplateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VMTemplate" + ] + }, + "delete": { + "summary": "rpc CreateVMTemplate(CreateVMTemplateRequest) returns (CreateVMTemplateResponse) {\n option (google.api.http) = {\n post: \"/apis/virtnest.io/v1alpha1/vmtemplates\"\n body: \"*\"\n };\n }", + "operationId": "VMTemplate_DeleteVMTemplate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/vmtemplateDeleteVMTemplateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VMTemplate" + ] + } + }, + "/apis/virtnest.io/v1alpha1/vmtemplates/{name}/custom-resource": { + "get": { + "operationId": "VMTemplate_GetCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1vmtemplateGetCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "VMTemplate" + ] + }, + "put": { + "operationId": "VMTemplate_UpdateCustomResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1alpha1vmtemplateUpdateCustomResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/googlerpcStatus" + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + } + } + ], + "tags": [ + "VMTemplate" + ] + } + } + }, + "definitions": { + "clusterClusterInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v1alpha1clusterStatus" + }, + "isKubevirtInstalled": { + "type": "boolean" + }, + "isInsightAgentReady": { + "type": "boolean" + }, + "spiderpool": { + "$ref": "#/definitions/clusterSpiderPool" + }, + "gpuInfo": { + "$ref": "#/definitions/clusterGPUInfo" + } + } + }, + "clusterGPUInfo": { + "type": "object", + "properties": { + "type": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1clusterGPUType" + } + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1clusterGPU" + } + } + } + }, + "clusterIsVMMonitorReadyResponse": { + "type": "object", + "properties": { + "ready": { + "type": "boolean" + } + } + }, + "clusterListClusterNamespacesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "clusterListClustersResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/clusterClusterInfo" + } + } + } + }, + "clusterSpiderPool": { + "type": "object", + "properties": { + "isInstalled": { + "type": "boolean" + }, + "enableIpv4": { + "type": "boolean" + }, + "enableIpv6": { + "type": "boolean" + } + } + }, + "feature_gateFeatureGateID": { + "type": "string", + "enum": [ + "VirtualMachineSnapshot", + "VirtualMachineClone" + ], + "default": "VirtualMachineSnapshot" + }, + "feature_gateFeatureGateInfo": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/feature_gateFeatureGateID", + "title": "唯一标志符" + }, + "description": { + "type": "string", + "title": "关于此 FeatureGate 的描述" + }, + "enabled": { + "type": "boolean", + "title": "是否启用" + } + } + }, + "feature_gateListFeatureGatesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/feature_gateFeatureGateInfo" + } + } + } + }, + "googlerpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "imageArtifact": { + "type": "object", + "properties": { + "digest": { + "type": "string", + "description": "Digest is artifact digest." + }, + "tags": { + "type": "array", + "items": { + "$ref": "#/definitions/imageTag" + }, + "description": "Tags is a list of tags." + }, + "imageSize": { + "type": "string", + "format": "int64", + "description": "Size of artifact. Unit: byte. 1024 GenericBinary." + }, + "pushTime": { + "type": "string", + "format": "int64", + "description": "First push time." + } + }, + "title": "Artifact is the concept of harbor artifact" + }, + "imageCheckSecretResponse": { + "type": "object", + "properties": { + "canUse": { + "type": "boolean" + }, + "message": { + "type": "string" + } + } + }, + "imageListProjectsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Items is a list of project names." + } + }, + "title": "ListProjectsResponse returns a list of projects of a registry" + }, + "imageListRegistriesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/imageRegistry" + }, + "title": "items is registry host" + } + }, + "title": "ListRegistriesResponse returns a list of registries" + }, + "imageListRepositoriesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/imageRepository" + }, + "description": "Items is a list of repositories." + }, + "pagination": { + "$ref": "#/definitions/v1alpha1imagePagination" + } + }, + "title": "ListRepositoriesResponse returns a list of projects of a registry" + }, + "imageListSecretsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/imageSecret" + } + } + } + }, + "imageRegistry": { + "type": "object", + "properties": { + "alias": { + "type": "string", + "description": "Alias is an alias for the registry, showed in list." + }, + "host": { + "type": "string", + "description": "Host is registry host." + }, + "name": { + "type": "string", + "description": "Name is registry name, use to query project lists." + } + }, + "title": "Registry contains necessary info" + }, + "imageRepository": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of repository." + }, + "artifacts": { + "type": "array", + "items": { + "$ref": "#/definitions/imageArtifact" + }, + "description": "Artifacts of repository." + } + }, + "title": "Repository concept from Harbor" + }, + "imageSecret": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "imageTag": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the tag." + }, + "pushTime": { + "type": "string", + "format": "int64", + "description": "Tag push time." + } + }, + "description": "Tag of an image." + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "roleClusterRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/roleRoleEnum" + } + }, + "nsRoles": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/roleNSRoles" + } + } + } + }, + "roleGetUserRolesResponse": { + "type": "object", + "properties": { + "platformRoles": { + "type": "array", + "items": { + "$ref": "#/definitions/roleRoleEnum" + } + }, + "clusterRoles": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/roleClusterRoles" + } + } + } + }, + "roleNSRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/roleRoleEnum" + } + } + } + }, + "roleRoleEnum": { + "type": "string", + "enum": [ + "admin", + "cluster_admin", + "cluster_edit", + "cluster_view", + "ns_admin", + "ns_edit", + "ns_view" + ], + "default": "admin" + }, + "v1alpha1clusterGPU": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1clusterGPUType" + }, + "deviceName": { + "type": "string" + } + } + }, + "v1alpha1clusterGPUType": { + "type": "string", + "enum": [ + "Nvidia_GPU", + "Nvidia_vGPU" + ], + "default": "Nvidia_GPU" + }, + "v1alpha1clusterStatus": { + "type": "string", + "enum": [ + "running", + "failed" + ], + "default": "running" + }, + "v1alpha1imagePagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1vmDiskVolume": { + "type": "object", + "properties": { + "storageClass": { + "type": "string" + }, + "capacity": { + "type": "string", + "format": "int64" + }, + "pvAccessMode": { + "$ref": "#/definitions/v1alpha1vmPersistentVolumeAccessMode" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1vmGPU": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1vmGPUType" + }, + "deviceName": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1vmGPUType": { + "type": "string", + "enum": [ + "Nvidia_GPU", + "Nvidia_vGPU" + ], + "default": "Nvidia_GPU" + }, + "v1alpha1vmGetCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + }, + "v1alpha1vmImageSource": { + "type": "string", + "enum": [ + "docker", + "http", + "s3" + ], + "default": "docker", + "title": "TODO:" + }, + "v1alpha1vmMultusConfigInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "cniType": { + "type": "string" + }, + "hasDefaultIppool": { + "type": "boolean" + } + } + }, + "v1alpha1vmMultusNetworkInfo": { + "type": "object", + "properties": { + "networkMode": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmMultusNetworkInfoItem" + } + } + } + }, + "v1alpha1vmMultusNetworkInfoItem": { + "type": "object", + "properties": { + "multusConfig": { + "$ref": "#/definitions/v1alpha1vmMultusConfigInfo" + }, + "interface": { + "type": "string" + }, + "ips": { + "type": "array", + "items": { + "type": "string" + } + }, + "mac": { + "type": "string" + }, + "subnet": { + "type": "string" + }, + "gateway": { + "type": "string" + }, + "vlanId": { + "type": "string" + } + } + }, + "v1alpha1vmNetworkInterfaceInfo": { + "type": "object", + "properties": { + "networkInterface": { + "type": "string" + }, + "multusConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmMultusConfigInfo" + } + } + } + }, + "v1alpha1vmPagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1vmPersistentVolumeAccessMode": { + "type": "string", + "enum": [ + "ReadWriteOnce", + "ReadOnlyMany", + "ReadWriteMany", + "ReadWriteOncePod" + ], + "default": "ReadWriteOnce" + }, + "v1alpha1vmSortBy": { + "type": "string", + "enum": [ + "created_at", + "field_name" + ], + "default": "created_at" + }, + "v1alpha1vmSortDir": { + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + "v1alpha1vmUpdateCustomResourceResponse": { + "type": "object" + }, + "v1alpha1vmVMDisks": { + "type": "object", + "properties": { + "systemVolume": { + "$ref": "#/definitions/v1alpha1vmDiskVolume" + }, + "dataVolumes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmDiskVolume" + } + } + } + }, + "v1alpha1vmtemplateDiskVolume": { + "type": "object", + "properties": { + "storageClass": { + "type": "string" + }, + "capacity": { + "type": "string", + "format": "int64" + }, + "pvAccessMode": { + "$ref": "#/definitions/v1alpha1vmtemplatePersistentVolumeAccessMode" + }, + "name": { + "type": "string" + } + } + }, + "v1alpha1vmtemplateGPU": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/v1alpha1vmtemplateGPUType" + }, + "deviceName": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1vmtemplateGPUType": { + "type": "string", + "enum": [ + "Nvidia_GPU", + "Nvidia_vGPU" + ], + "default": "Nvidia_GPU" + }, + "v1alpha1vmtemplateGetCustomResourceResponse": { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + }, + "v1alpha1vmtemplateImageSource": { + "type": "string", + "enum": [ + "docker", + "http", + "s3" + ], + "default": "docker" + }, + "v1alpha1vmtemplateMultusConfigInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "cniType": { + "type": "string" + }, + "hasDefaultIppool": { + "type": "boolean" + } + } + }, + "v1alpha1vmtemplateMultusNetworkInfo": { + "type": "object", + "properties": { + "networkMode": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmtemplateMultusNetworkInfoItem" + } + } + } + }, + "v1alpha1vmtemplateMultusNetworkInfoItem": { + "type": "object", + "properties": { + "multusConfig": { + "$ref": "#/definitions/v1alpha1vmtemplateMultusConfigInfo" + }, + "interface": { + "type": "string" + }, + "ips": { + "type": "array", + "items": { + "type": "string" + } + }, + "mac": { + "type": "string" + }, + "subnet": { + "type": "string" + }, + "gateway": { + "type": "string" + }, + "vlanId": { + "type": "string" + }, + "ipPool": { + "$ref": "#/definitions/vmtemplateIPPool" + } + } + }, + "v1alpha1vmtemplatePagination": { + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "total": { + "type": "integer", + "format": "int32" + } + } + }, + "v1alpha1vmtemplatePersistentVolumeAccessMode": { + "type": "string", + "enum": [ + "ReadWriteOnce", + "ReadOnlyMany", + "ReadWriteMany", + "ReadWriteOncePod" + ], + "default": "ReadWriteOnce" + }, + "v1alpha1vmtemplateSortBy": { + "type": "string", + "enum": [ + "UNSPECIFIED", + "created_at", + "field_name" + ], + "default": "UNSPECIFIED", + "description": " - UNSPECIFIED: Unspecified is default, no sorting.\n - created_at: Sort result by creationTimestamp.\n - field_name: Sort result by name." + }, + "v1alpha1vmtemplateSortDir": { + "type": "string", + "enum": [ + "desc", + "asc" + ], + "default": "desc" + }, + "v1alpha1vmtemplateUpdateCustomResourceResponse": { + "type": "object" + }, + "v1alpha1vmtemplateVMDisks": { + "type": "object", + "properties": { + "systemVolume": { + "$ref": "#/definitions/v1alpha1vmtemplateDiskVolume" + }, + "dataVolumes": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmtemplateDiskVolume" + } + } + } + }, + "vmAddDiskVolumeToVMResponse": { + "type": "object", + "properties": { + "needRestart": { + "type": "boolean" + } + } + }, + "vmAllowedOperation": { + "type": "string", + "enum": [ + "allowed_operation_snapshot", + "allowed_operation_clone", + "allowed_operation_live_migration" + ], + "default": "allowed_operation_snapshot" + }, + "vmCloneVMResponse": { + "type": "object" + }, + "vmColdMigrationResponse": { + "type": "object" + }, + "vmCreateCustomResourceResponse": { + "type": "object" + }, + "vmCreateVMResponse": { + "type": "object" + }, + "vmCreateVMSnapshotResponse": { + "type": "object" + }, + "vmCreateVMWithVMTemplateResponse": { + "type": "object" + }, + "vmDeleteVMResponse": { + "type": "object" + }, + "vmDeleteVMRestoreResponse": { + "type": "object" + }, + "vmDeleteVMSnapshotResponse": { + "type": "object" + }, + "vmEventLevel": { + "type": "string", + "enum": [ + "UNSPECIFIED", + "Normal", + "Warning" + ], + "default": "UNSPECIFIED", + "description": " - UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return." + }, + "vmExpandVMDiskCapacityResponse": { + "type": "object", + "properties": { + "needRestart": { + "type": "boolean" + } + } + }, + "vmGetVMResponse": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "name": { + "type": "string" + }, + "aliasName": { + "type": "string" + }, + "describe": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "ips": { + "type": "array", + "items": { + "type": "string" + } + }, + "status": { + "$ref": "#/definitions/vmVMStatus" + }, + "createdAt": { + "type": "string" + }, + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "sshKey": { + "type": "string" + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "vmErrorMessage": { + "$ref": "#/definitions/vmVmErrorMessage" + }, + "imageSource": { + "$ref": "#/definitions/v1alpha1vmImageSource" + }, + "osFamily": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "imageUrl": { + "type": "string" + }, + "node": { + "type": "string" + }, + "allowedOperation": { + "type": "array", + "items": { + "$ref": "#/definitions/vmAllowedOperation" + } + }, + "secret": { + "type": "string" + }, + "network": { + "$ref": "#/definitions/v1alpha1vmMultusNetworkInfo" + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmGPU" + } + } + } + }, + "vmListClusterNodesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmNode" + } + } + } + }, + "vmListClusterStorageClassesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmStorageClass" + } + } + } + }, + "vmListClusterVmsInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/vmVMStatus" + }, + "namespace": { + "type": "string" + }, + "ips": { + "type": "array", + "items": { + "type": "string" + } + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "createdAt": { + "type": "string" + }, + "osFamily": { + "type": "string" + }, + "vmErrorMessage": { + "$ref": "#/definitions/vmVmErrorMessage" + }, + "allowedOperation": { + "type": "array", + "items": { + "$ref": "#/definitions/vmAllowedOperation" + } + }, + "node": { + "type": "string" + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmGPUType" + } + }, + "migNodeSelector": { + "type": "string" + } + } + }, + "vmListClusterVmsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmListClusterVmsInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1vmPagination" + } + } + }, + "vmListNetworkInterfacesResponse": { + "type": "object", + "properties": { + "ipPools": { + "type": "array", + "items": { + "type": "string" + } + }, + "interfaces": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmNetworkInterfaceInfo" + } + }, + "ipPoolsV6": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "vmListSystemImagesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmSystemImage" + } + } + } + }, + "vmListVMEventsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmVmEvents" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1vmPagination" + } + } + }, + "vmListVMNetworksResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmVMNetwork" + } + } + } + }, + "vmListVMRestoresResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmVMRestore" + } + } + } + }, + "vmListVMSnapshotsResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmVMSnapshot" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1vmPagination" + } + } + }, + "vmListVMStoragesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmVMStorage" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1vmPagination" + } + } + }, + "vmLiveMigrateVMResponse": { + "type": "object" + }, + "vmMultusNetwork": { + "type": "object", + "properties": { + "networkMode": { + "type": "string" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmMultusNetworkItem" + } + } + } + }, + "vmMultusNetworkItem": { + "type": "object", + "properties": { + "interface": { + "type": "string" + }, + "multusConfig": { + "$ref": "#/definitions/v1alpha1vmMultusConfigInfo" + }, + "ipPoolNames": { + "type": "array", + "items": { + "type": "string" + } + }, + "ipPoolNamesV6": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "vmNode": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "phase": { + "$ref": "#/definitions/vmNodePhase" + } + } + }, + "vmNodePhase": { + "type": "string", + "enum": [ + "PhaseUnspecified", + "PhaseReady", + "PhaseNotReady", + "PhaseUnknown" + ], + "default": "PhaseUnspecified" + }, + "vmObject": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "kind": { + "type": "string" + } + } + }, + "vmRemoveVMDiskVolumeResponse": { + "type": "object" + }, + "vmRestoreVMSnapshotResponse": { + "type": "object" + }, + "vmSSH": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + }, + "sshKey": { + "type": "string" + } + } + }, + "vmSnapshotStatus": { + "type": "string", + "enum": [ + "snapshot_succeeded", + "snapshot_failed", + "snapshot_deleting", + "snapshot_processing", + "snapshot_unknown" + ], + "default": "snapshot_succeeded" + }, + "vmStorageClass": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "supportAccessMode": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmPersistentVolumeAccessMode" + } + } + } + }, + "vmStorageStatus": { + "type": "string", + "enum": [ + "storage_processing", + "storage_ready", + "storage_failed" + ], + "default": "storage_processing" + }, + "vmStorageType": { + "type": "string", + "enum": [ + "system", + "data" + ], + "default": "system" + }, + "vmSystemImage": { + "type": "object", + "properties": { + "osFamily": { + "type": "string" + }, + "version": { + "type": "array", + "items": { + "$ref": "#/definitions/vmSystemImageVersion" + } + } + } + }, + "vmSystemImageVersion": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "vmUpdateVMResponse": { + "type": "object" + }, + "vmUpdateVMRunningStatusResponse": { + "type": "object" + }, + "vmUpdateVMSnapshotResponse": { + "type": "object" + }, + "vmVMNetwork": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "ip": { + "type": "string" + } + } + }, + "vmVMOperation": { + "type": "string", + "enum": [ + "start", + "stop", + "restart" + ], + "default": "start" + }, + "vmVMRestore": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "complete": { + "type": "boolean" + }, + "createdAt": { + "type": "string" + }, + "restoreTime": { + "type": "string" + }, + "lastRestore": { + "type": "boolean" + } + } + }, + "vmVMSnapshot": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/vmSnapshotStatus" + }, + "restoreTime": { + "type": "string" + } + } + }, + "vmVMStatus": { + "type": "string", + "enum": [ + "running", + "processing", + "error", + "poweroff" + ], + "default": "running" + }, + "vmVMStorage": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/vmStorageType" + }, + "capacity": { + "type": "string", + "format": "int64" + }, + "status": { + "$ref": "#/definitions/vmStorageStatus" + }, + "storageClass": { + "type": "string" + }, + "allowExpand": { + "type": "boolean" + }, + "pvAccessMode": { + "$ref": "#/definitions/v1alpha1vmPersistentVolumeAccessMode" + }, + "hotpluggable": { + "type": "boolean" + } + } + }, + "vmVmErrorMessage": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "reason": { + "type": "string" + } + } + }, + "vmVmEvents": { + "type": "object", + "properties": { + "level": { + "$ref": "#/definitions/vmEventLevel" + }, + "component": { + "type": "string" + }, + "object": { + "$ref": "#/definitions/vmObject" + }, + "name": { + "type": "string" + }, + "detail": { + "type": "string" + }, + "time": { + "type": "string" + } + } + }, + "vmtemplateCreateVMTemplateByVMRequest": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "vmName": { + "type": "string" + }, + "vmtemplateName": { + "type": "string" + }, + "description": { + "type": "string" + } + } + }, + "vmtemplateCreateVMTemplateByVMResponse": { + "type": "object" + }, + "vmtemplateDeleteVMTemplateResponse": { + "type": "object" + }, + "vmtemplateGetVMTemplateResponse": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "createdAt": { + "type": "string" + }, + "osFamily": { + "type": "string" + }, + "imageUrl": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/vmtemplateTemplateType" + }, + "systemDiskCapacity": { + "type": "string", + "format": "int64" + }, + "imageSource": { + "$ref": "#/definitions/v1alpha1vmtemplateImageSource" + }, + "osVersion": { + "type": "string" + }, + "network": { + "type": "string" + }, + "disks": { + "$ref": "#/definitions/v1alpha1vmtemplateVMDisks" + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmtemplateGPU" + } + }, + "networks": { + "$ref": "#/definitions/v1alpha1vmtemplateMultusNetworkInfo" + } + } + }, + "vmtemplateIPPool": { + "type": "object", + "properties": { + "ipv4": { + "type": "array", + "items": { + "type": "string" + } + }, + "ipv6": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "vmtemplateListVMTemplatesResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/vmtemplateVMTemplateInfo" + } + }, + "pagination": { + "$ref": "#/definitions/v1alpha1vmtemplatePagination" + } + } + }, + "vmtemplateTemplateType": { + "type": "string", + "enum": [ + "custom", + "internal" + ], + "default": "custom" + }, + "vmtemplateVMTemplateInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/vmtemplateTemplateType" + }, + "cpu": { + "type": "integer", + "format": "int64" + }, + "memory": { + "type": "string", + "format": "int64", + "title": "单位:字节" + }, + "createdAt": { + "type": "string" + }, + "osFamily": { + "type": "string" + }, + "gpus": { + "type": "array", + "items": { + "$ref": "#/definitions/v1alpha1vmtemplateGPUType" + } + } + } + } + } +} diff --git a/docs/zh/docs/stylesheets/custom.css b/docs/zh/docs/stylesheets/custom.css new file mode 100644 index 0000000..e747cc6 --- /dev/null +++ b/docs/zh/docs/stylesheets/custom.css @@ -0,0 +1,58 @@ +#imgBaseDiv > img { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + max-width: 99%; + max-height: 99%; +} + +#imgBaseDiv { + width: 100%; + height: 100%; + position: fixed; + background: rgba(0, 0, 0, 0.9); + top: 0; + left: 0; + z-index: 1050; +} + +.responsive-video-container { + position: relative; + margin-bottom: 1em; + padding-bottom: 62.50%; + height: 0; + overflow: hidden; + max-width: 100%; +} + +iframe:not(.giscus-frame):not(.swagger-ui-iframe), +object, +embed { + position: absolute; + top: 0; + left: 0; + width: 100% !important; + height: 100%; +} + +.md-footer__inner { + display: none +} + +/* Maximum space for text block */ +.md-grid { + max-width: 94%; /* or 100%, if you want to stretch to full-width */ +} + + +/* +img { + height: auto; + width: auto; + border: 1px solid #ddd; + border-radius: 6px; + padding: 4px; + background-color: #fff; +} +*/ \ No newline at end of file diff --git a/docs/zh/docs/stylesheets/landing.css b/docs/zh/docs/stylesheets/landing.css new file mode 100644 index 0000000..ceefdc1 --- /dev/null +++ b/docs/zh/docs/stylesheets/landing.css @@ -0,0 +1,158 @@ +.tx-container { + background: + linear-gradient(to bottom, var(--md-primary-fg-color), #2196f3 100%, var(--md-default-bg-color) 100%) +} + +[data-md-color-scheme=slate] .tx-container { + background: + linear-gradient(to bottom, var(--md-primary-fg-color), #2196f3 100%, var(--md-default-bg-color) 100%) +} + +@media screen and (min-width: 60em) { + .tx-container { + background: + url("/assets/images/wave-regular.svg") no-repeat bottom, + linear-gradient(to bottom, var(--md-primary-fg-color), #2196f3 99%, var(--md-default-bg-color) 99%) + } + + [data-md-color-scheme=slate] .tx-container { + background: + url("/assets/images/wave-slate.svg") no-repeat bottom, + linear-gradient(to bottom, var(--md-primary-fg-color), #2196f3 99%, var(--md-default-bg-color) 99%) + } +} + +.tx-landing { + margin: 0 .8rem; + color: var(--md-primary-bg-color) +} + +.tx-landing h1 { + margin-bottom: 1rem; + color: currentColor; + font-weight: 700 +} + +@media screen and (max-width: 30em) { + .tx-landing h1 { + font-size: 1.4rem + } +} + +.tx-landing__content p a { + color: inherit; + text-decoration: underline; +} + +.tx-landing__testimonials { + width: 100%; + text-align: center; +} + +.tx-landing__content p a:hover { + color: darkblue; + text-decoration: underline; +} + +.tx-landing__logos { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; +} + +.tx-landing__logos img { + height: 8vh; + max-height: 81px; /* max height of images */ + width: auto; + margin: 2vh; + vertical-align: middle; +} + +.tx-landing__quotes { + padding-bottom: 5em; + text-align: center; +} + +@media screen and (min-width: 60em) { + .tx-landing__quotes { + margin: 1em 5em; + } +} + +.tx-landing__quotes figure { + margin: 2em auto 2em auto; +} + +.tx-landing__quote { + display: flex; + border-radius: 1em; + padding: 1em 1em 0 1em; + background: var(--md-primary-fg-color); +} + +.tx-landing__quote blockquote { + border: 0; + color: #fff; +} + +.tx-landing__quote a img { + height: 6vh; + max-height: 81px; /* max height of images */ + display: block; + margin-left: auto; + margin-right: auto; +} + +@media screen and (min-width: 60em) { + .tx-container { + padding-bottom: 14vw + } + + .tx-landing { + display: flex; + align-items: stretch + } + + .tx-landing__content { + max-width: 19rem; + margin-top: 3.5rem; + } + + .tx-landing__image { + order: 1; + width: 38rem; + transform: translateX(4rem) + } +} + +@media screen and (min-width: 77em) { + .tx-landing__image { + transform: translateX(8rem) + } +} + +.tx-landing .md-button { + margin-top: .5rem; + margin-right: .5rem; + color: var(--md-primary-bg-color) +} + +.tx-landing .md-button:hover, .tx-landing .md-button:focus { + color: var(--md-default-bg-color); + background-color: #8bc34a; + border-color: #8bc34a +} + +.md-typeset lottie-player { + max-width: 100%; + height: auto; +} + +.md-announce a { + color: var(--md-primary-bg-color); +} + +.md-banner a { + color: var(--md-primary-bg-color); +} diff --git a/docs/zh/docs/stylesheets/tags.md b/docs/zh/docs/stylesheets/tags.md new file mode 100644 index 0000000..422b139 --- /dev/null +++ b/docs/zh/docs/stylesheets/tags.md @@ -0,0 +1,5 @@ +# Tags + +Following is a list of relevant tags: + +[TAGS] \ No newline at end of file diff --git a/docs/zh/docs/stylesheets/zoom_image.js b/docs/zh/docs/stylesheets/zoom_image.js new file mode 100644 index 0000000..8114a8b --- /dev/null +++ b/docs/zh/docs/stylesheets/zoom_image.js @@ -0,0 +1,21 @@ +window.onload = function () { + for (let item of document.getElementsByTagName("img")) { + if (item.classList.contains("pass") === false) { + item.setAttribute("onclick", "clickAction(this)"); + } + } +}; + +function clickAction(img) { + let medusa = document.createElement("div"); + medusa.setAttribute("id", "imgBaseDiv"); + medusa.setAttribute("onclick", "closeImg()"); + let image = document.createElement("img"); + image.setAttribute("src", img.src); + medusa.appendChild(image); + document.body.appendChild(medusa); +} + +function closeImg() { + document.getElementById("imgBaseDiv").remove(); +} diff --git a/docs/zh/mkdocs.path.yaml b/docs/zh/mkdocs.path.yaml new file mode 100644 index 0000000..6f7b998 --- /dev/null +++ b/docs/zh/mkdocs.path.yaml @@ -0,0 +1,230 @@ +--- +# This file is used to split config and docs navigation +INHERIT: navigation.yml + +# Project information +site_name: AI 算力中心 +site_url: https://docs.daocloud.io/ +site_author: 算丰 +site_description: >- + AI 算力中心 下一代容器化平台集大成者,引领云原生浪潮,推动数字化转型。 + +# copyright +copyright: Copyright © 2016 - 2024 算丰 + +# Repository +repo_name: DaoCloud/DaoCloud-docs + +repo_url: https://github.com/DaoCloud/DaoCloud-docs +edit_uri: edit/main/docs/zh/docs/ + +use_directory_urls: true # disbale https://www.mkdocs.org/user-guide/configuration/#use_directory_urls +strict: false # enable strict mode, https://www.mkdocs.org/user-guide/configuration/#strict + +# Configuration +theme: + name: material + custom_dir: "theme" + # custom_dir: !ENV [THEME_DIR, "material"] + + # Don't include MkDocs' JavaScript + include_search_page: false + search_index_only: true + include_homepage_in_sidebar: false + + + # Static files + static_templates: + - 404.html + + language: "zh" + features: + - content.code.annotate + - content.code.copy + - content.tooltips + # - navigation.indexes + - navigation.tabs + # - navigation.instant + - navigation.prune + - navigation.sections + - navigation.tabs.sticky + - navigation.tracking + - navigation.top + - search.highlight + - search.suggest + - search.share + - toc.follow + - navigation.path + # - toc.integrate + + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + font: + text: Roboto + code: Roboto Mono + favicon: images/favicon.ico + logo: images/DaoCloud.png + icon: + logo: logo + repo: fontawesome/brands/github + +# Plugins +plugins: + - search: + separator: '[\\s\\u200b\\-]' + - swagger-ui-tag + # - mermaid2 + + # - with-pdf: + # cover: true + # # back_cover: true + # # cover_title: DaoCloud + # # enabled_if_env: ENABLE_PDF_EXPORT + # verbose: false + + + + - minify: + minify_html: true + minify_js: true + minify_css: true + htmlmin_opts: + remove_comments: true + + - redirects: + redirect_maps: + "api.md": "dce/index.md" + "dce/what-is-dce.md": "dce/index.md" + "zh/dce/index.md": "dce/index.md" + "zh/install/install-dce.md": "install/community/k8s/online.md" + + # module quick links + "insight.md": "insight/intro/index.md" + "kpanda.md": "kpanda/intro/index.md" + "ghippo.md": "ghippo/intro/index.md" + + + # - git-revision-date: #每页底部显示文档最后更新日期,安装 pip install mkdocs-git-revision-date-plugin + # enabled_if_env: "CI" + # - git-revision-date-localized: #每个页面底部添加本地化更新和创建日期,安装 pip install mkdocs-git-revision-date-localized-plugin + # timezone: Asia/Shanghai + # type: timeago #日期格式,有效值为 date、datetime、iso_date、iso_datetimetimeago + # fallback_to_build_date: true #默认 false,启用则回退到 mkdocs build 执行的时间 + # enable_creation_date: true #最后更新日期旁边显示与页面关联的文件的创建日期 + # exclude: + # - index.md + # enabled: !ENV [ENABLED_GIT_REVISION_DATE, true] + + # auto desgin nav in dirs + # - awesome-pages: + # filename: .pages.yml + # collapse_single_pages: true + # strict: false + # - tags: + # tags_file: stylesheets/tags.md + + # with mkdocs-git-authors-plugin + # - git-authors + + # - print-site + +# Customization +extra: + homepage: / + + # comments + comments: + enabled: true + mode: giscus + type: Discussions + + # switch language + alternate: + - link: / + name: 简体中文 + lang: zh + - link: /en/ + name: English + lang: en + generator: false + + status: + new: 最近添加 + beta: beta + +# Customization Javascript +extra_javascript: + - stylesheets/zoom_image.js + # - https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js # disable fix mermaid not working + +# Customization css +extra_css: + - stylesheets/custom.css + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - meta + - md_in_html + - tables + - toc: + permalink: true + title: 导航 + toc_depth: 5 + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + # emoji_index: !!python/name:materialx.emoji.twemoji + # emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + repo_url_shorthand: true + user: daocloud + repo: daocloud-docs + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + - pymdownx.critic + - pymdownx.snippets + # auto_append: + # - includes/glossary.md diff --git a/docs/zh/mkdocs.tiny.yml b/docs/zh/mkdocs.tiny.yml new file mode 100644 index 0000000..13365a7 --- /dev/null +++ b/docs/zh/mkdocs.tiny.yml @@ -0,0 +1,14 @@ +# This file is used to split config and docs navigation +# Project information +site_name: 算丰二号档案站 + +# custom module path +docs_dir: docs/middleware/ + +# Configuration +theme: + name: material + + # navigation config + features: + - navigation.tabs diff --git a/docs/zh/mkdocs.yml b/docs/zh/mkdocs.yml new file mode 100644 index 0000000..c19b7d3 --- /dev/null +++ b/docs/zh/mkdocs.yml @@ -0,0 +1,162 @@ +--- +# This file is used to split config and docs navigation +INHERIT: navigation.yml + +# Project information +site_name: 豐收二號檔案站 +site_url: https://sophdoc.github.io/ +site_author: Suanova +site_description: >- + Suanova documentation website. + +# copyright +copyright: Copyright © 2016 - 2024 Suanova + +# Repository +repo_name: sophongo/sophongo-docs + +repo_url: https://github.com/sophongo/sophdoc +edit_uri: edit/main/docs/zh/docs/ + +use_directory_urls: false # disable https://www.mkdocs.org/user-guide/configuration/#use_directory_urls +strict: false # enable strict mode, https://www.mkdocs.org/user-guide/configuration/#strict + +# Configuration +theme: + name: material + + features: + - content.code.annotate + - content.code.copy + - content.tooltips + - navigation.indexes + - navigation.tabs + - navigation.instant + - navigation.prune + - navigation.sections + - navigation.tabs.sticky + - navigation.tracking + - navigation.top + - search.highlight + - search.suggest + - search.share + - toc.follow + - navigation.path + # - toc.integrate + + palette: + # Palette toggle for automatic mode + - media: "(prefers-color-scheme)" + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + font: + text: Roboto + code: Roboto Mono + favicon: images/favicon.ico + logo: images/suanova.png + icon: + logo: logo + repo: fontawesome/brands/github + +# Plugins +plugins: + - search: + jieba_dict: dict.txt.small + jieba_dict_user: dict.txt.daocloud + lang: + - zh + - en + + - swagger-ui-tag # enable swagger-ui-tag plugin + +# Customization +extra: +# homepage: / + + # switch language + alternate: + - link: / + name: 简体中文 + lang: zh + - link: /en/ + name: English + lang: en + generator: false + + status: + new: 最近添加 + beta: beta + +# Customization Javascript +extra_javascript: + - stylesheets/zoom_image.js + # - https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js # disable fix mermaid not working + +# Customization css +extra_css: + - stylesheets/custom.css + +# Extensions +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - meta + - md_in_html + - tables + - toc: + permalink: true + title: 导航 + toc_depth: 3 + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + # emoji_index: !!python/name:materialx.emoji.twemoji + # emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + repo_url_shorthand: true + user: Sophongo + repo: Sophongo-docs + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde + - pymdownx.critic + - pymdownx.snippets + # auto_append: + # - includes/glossary.md diff --git a/docs/zh/navigation.yml b/docs/zh/navigation.yml new file mode 100644 index 0000000..aaa427e --- /dev/null +++ b/docs/zh/navigation.yml @@ -0,0 +1,546 @@ +# Page tree +nav: + - 首页: index.md + - 终端用户手册: + - 什么是 AI 算力平台: end-user/index.md + - 用户注册: end-user/register/index.md + - 算力服务: + - 云主机: + - 创建云主机: end-user/host/createhost.md + - 使用云主机: end-user/host/usehost.md + - 容器管理: + - 云上 K8s 集群: + - 接入集群: end-user/kpanda/clusters/integrate-cluster.md + - 访问集群: end-user/kpanda/clusters/access-cluster.md + - 集群角色: end-user/kpanda/clusters/cluster-role.md + - 集群状态: end-user/kpanda/clusters/cluster-status.md + - 卸载/解除接入集群: end-user/kpanda/clusters/delete-cluster.md + - 节点管理: + - 节点调度: end-user/kpanda/nodes/schedule.md + - 标签与注解: end-user/kpanda/nodes/labels-annotations.md + - 污点管理: end-user/kpanda/nodes/taints.md + - 节点详情: end-user/kpanda/nodes/node-details.md + - 工作负载: + - 创建 Deployment: end-user/kpanda/workloads/create-deployment.md + - 创建 StatefulSet: end-user/kpanda/workloads/create-statefulset.md + - 创建 DaemonSet: end-user/kpanda/workloads/create-daemonset.md + - 创建 CronJob: end-user/kpanda/workloads/create-cronjob.md + - 创建 Job: end-user/kpanda/workloads/create-job.md + - 工作负载参数配置: + - 工作负载状态: end-user/kpanda/workloads/pod-config/workload-status.md + - Job 参数: end-user/kpanda/workloads/pod-config/job-parameters.md + - 生命周期: end-user/kpanda/workloads/pod-config/lifecycle.md + - 环境变量: end-user/kpanda/workloads/pod-config/env-variables.md + - 健康检查: end-user/kpanda/workloads/pod-config/health-check.md + - 集群调度: end-user/kpanda/workloads/pod-config/scheduling-policy.md + - Helm 应用: + - Helm 模板: end-user/kpanda/helm/README.md + - 上传 Helm 模板: end-user/kpanda/helm/upload-helm.md + - 管理 Helm 应用: end-user/kpanda/helm/helm-app.md + - 管理 Helm 仓库: end-user/kpanda/helm/helm-repo.md + - Operator 应用: end-user/kpanda/olm/import-miniooperator.md + - 容器网络: + - 创建服务: end-user/kpanda/network/create-services.md + - 创建路由: end-user/kpanda/network/create-ingress.md + - 网络策略: end-user/kpanda/network/network-policy.md + - 自定义资源: end-user/kpanda/custom-resources/create.md + - 容器存储: + - 数据卷声明 PVC: end-user/kpanda/storage/pvc.md + - 数据卷 PV: end-user/kpanda/storage/pv.md + - 存储池 SC: end-user/kpanda/storage/sc.md + - 共享存储池: end-user/kpanda/storage/sc-share.md + - 配置与密钥: + - 创建配置项: end-user/kpanda/configmaps-secrets/create-configmap.md + - 使用配置项: end-user/kpanda/configmaps-secrets/use-configmap.md + - 创建密钥: end-user/kpanda/configmaps-secrets/create-secret.md + - 使用密钥: end-user/kpanda/configmaps-secrets/use-secret.md + - Configmap/Secret热加载: end-user/kpanda/configmaps-secrets/configmap-hot-loading.md + - 命名空间: + - 创建命名空间: end-user/kpanda/namespaces/createns.md + - 命名空间独享节点: end-user/kpanda/namespaces/exclusive.md + - 容器组安全策略: end-user/kpanda/namespaces/podsecurity.md + - 集群运维: + - 最近操作: end-user/kpanda/clusterops/latest-operations.md + - 集群设置: end-user/kpanda/clusterops/cluster-settings.md + - 集群巡检: + - 介绍: end-user/kpanda/inspect/index.md + - 创建巡检配置: end-user/kpanda/inspect/config.md + - 执行巡检: end-user/kpanda/inspect/inspect.md + - 查看巡检报告: end-user/kpanda/inspect/report.md + - 备份恢复: + - 介绍: end-user/kpanda/backup/index.md + - 安装 Velero 插件: end-user/kpanda/backup/install-velero.md + - 应用备份: end-user/kpanda/backup/deployment.md + - ETCD 备份: end-user/kpanda/backup/etcd-backup.md + - 安全管理: + - 安全扫描类型: end-user/kpanda/security/index.md + - 合规性扫描: + - 扫描配置: end-user/kpanda/security/cis/config.md + - 扫描策略: end-user/kpanda/security/cis/policy.md + - 扫描报告: end-user/kpanda/security/cis/report.md + - 权限扫描: end-user/kpanda/security/audit.md + - 漏洞扫描: end-user/kpanda/security/hunter.md + - 权限管理: + - 权限体系介绍: end-user/kpanda/permissions/permission-brief.md + - 集群和命名空间授权: end-user/kpanda/permissions/cluster-ns-auth.md + - 增加容器管理内置权限点: end-user/kpanda/permissions/custom-kpanda-role.md + - 算法开发: + - 创建 AI 工作负载: end-user/share/workload.md + - 使用 Notebook: end-user/share/notebook.md + - 创建训练任务: + - 创建训练任务: end-user/baize/jobs/create.md + - 创建 Pytorch 任务: end-user/baize/jobs/pytorch.md + - 创建 Tensorflow 任务: end-user/baize/jobs/tensorflow.md + - 创建 MPI 任务: end-user/baize/jobs/mpi.md + - 创建 MXNet 任务: end-user/baize/jobs/mxnet.md + - 创建 PaddlePaddle 任务: end-user/baize/jobs/paddle.md + - 删除任务: end-user/baize/jobs/delete.md + - 查看任务负载: end-user/baize/jobs/view.md + - 任务分析: end-user/baize/jobs/tensorboard.md + - 数据管理: + - 数据集列表: end-user/baize/dataset/create-use-delete.md + - 环境管理: end-user/baize/dataset/environments.md + - 模型服务: + - 模型支持情况: end-user/baize/inference/models.md + - 创建 Triton 推理服务: end-user/baize/inference/triton-inference.md + - 创建 vLLM 推理服务: end-user/baize/inference/vllm-inference.md + - 管理: + - 可观测性: + - 仪表盘: + - 概览: end-user/insight/dashboard/overview.md + - 仪表盘: end-user/insight/dashboard/dashboard.md + - 以管理员登录 Grafana: end-user/insight/dashboard/login-grafana.md + - 导入自定义仪表盘: end-user/insight/dashboard/import-dashboard.md + - 基础设施: + - 集群: end-user/insight/infra/cluster.md + - 节点: end-user/insight/infra/node.md + - 命名空间: end-user/insight/infra/namespace.md + - 工作负载: end-user/insight/infra/container.md + - 事件查询: end-user/insight/infra/event.md + - 拨测: end-user/insight/infra/probe.md + - 指标: end-user/insight/data-query/metric.md + - 日志: end-user/insight/data-query/log.md + - 链路追踪: + - 服务拓扑: end-user/insight/trace/topology.md + - 服务: end-user/insight/trace/service.md + - 链路查询: end-user/insight/trace/trace.md + - 告警: + - end-user/insight/alert-center/index.md + - 告警策略: end-user/insight/alert-center/alert-policy.md + - 告警模板: end-user/insight/alert-center/alert-template.md + - 通知配置: end-user/insight/alert-center/message.md + - 配置通知服务器: end-user/insight/alert-center/sms-provider.md + - 消息模板: end-user/insight/alert-center/msg-template.md + - 告警静默: end-user/insight/alert-center/silent.md + - 告警抑制: end-user/insight/alert-center/inhibition.md + - 采集管理: + - 采集管理: end-user/insight/collection-manag/collection-manag.md + - 服务监控: end-user/insight/collection-manag/service-monitor.md + - 采集组件insight-agent状态: end-user/insight/collection-manag/agent-status.md + - 全局管理: + - 工作空间与层级: + - end-user/ghippo/workspace/ws-folder.md + - 资源配额: end-user/ghippo/workspace/quota.md + - 资源组与共享资源的区别: end-user/ghippo/workspace/res-gp-and-shared-res.md + - 资源绑定权限说明: end-user/ghippo/workspace/wsbind-permission.md + - 个人中心: + - 安全设置: end-user/ghippo/personal-center/security-setting.md + - 访问密钥: end-user/ghippo/personal-center/accesstoken.md + - SSH 公钥: end-user/ghippo/personal-center/ssh-key.md + - 语言设置: end-user/ghippo/personal-center/language.md + - 管理员手册: + - 什么是 AI 算力平台: admin/index.md + - 算力服务: + - 云主机: + - 安装: + - 安装云主机: admin/virtnest/install/index.md + - 安装依赖及前提条件: admin/virtnest/install/install-dependency.md + - 离线升级: admin/virtnest/install/offline-install.md + - 安装 virtnest-agent: admin/virtnest/install/virtnest-agent.md + - 快速入门: + - 创建云主机: admin/virtnest/quickstart/index.md + - 更新云主机: admin/virtnest/quickstart/update.md + - 连接云主机: admin/virtnest/quickstart/access.md + - 通过 NodePort 访问云主机: admin/virtnest/quickstart/nodeport.md + - 云主机详情: admin/virtnest/quickstart/detail.md + - 云主机管理: + - 创建密钥: admin/virtnest/vm/create-secret.md + - 克隆云主机: admin/virtnest/vm/clone.md + - 快照管理: admin/virtnest/vm/snapshot.md + - 定时快照: admin/virtnest/vm/scheduled-snapshot.md + - 实时迁移: admin/virtnest/vm/live-migration.md + - 集群内冷迁移: admin/virtnest/vm/migratiom.md + - 云主机跨集群迁移: admin/virtnest/vm/cross-cluster-migrate.md + - 云主机监控: admin/virtnest/vm/monitor.md + - 云主机网络: admin/virtnest/vm/vm-network.md + - 云主机存储: admin/virtnest/vm/vm-sc.md + - 云主机漂移: admin/virtnest/vm/auto-migrate.md + - 云主机健康检查: admin/virtnest/vm/health-check.md + - 云主机 GPU: + - 云主机 GPU: admin/virtnest/gpu/vm-gpu.md + - 云主机 vGPU: admin/virtnest/gpu/vm-vgpu.md + - 云主机模板: + - 通过模板创建云主机: admin/virtnest/template/index.md + - 云主机模板: admin/virtnest/template/tep.md + - 云主机镜像: admin/virtnest/vm-image/index.md + - 最佳实践: + - 从 VMware 导入传统 Linux 云主机: admin/virtnest/best-practice/import-ubuntu.md + - 从 VMware 导入传统 Windows 云主机: admin/virtnest/best-practice/import-windows.md + - 创建 Windows 云主机: admin/virtnest/best-practice/vm-windows.md + - 容器管理: + - 集群管理: + - 创建集群: admin/kpanda/clusters/create-cluster.md + - 接入集群: admin/kpanda/clusters/integrate-cluster.md + - 访问集群: admin/kpanda/clusters/access-cluster.md + - 升级集群: admin/kpanda/clusters/upgrade-cluster.md + - 卸载/解除接入集群: admin/kpanda/clusters/delete-cluster.md + - 集群角色: admin/kpanda/clusters/cluster-role.md + - 集群状态: admin/kpanda/clusters/cluster-status.md + - 如何选择运行时: admin/kpanda/clusters/runtime.md + - 集群版本支持范围: admin/kpanda/clusters/cluster-version.md + - 接入 Rancher 集群: admin/kpanda/clusters/integrate-rancher-cluster.md + - 集群中部署第二调度器: admin/kpanda/clusters/cluster-scheduler-plugin.md + - 集群证书更新: admin/kpanda/clusters/k8s-cert.md + - 节点管理: + - 节点可用性检查: admin/kpanda/nodes/node-check.md + - 节点认证: admin/kpanda/nodes/node-authentication.md + - 节点扩容: admin/kpanda/nodes/add-node.md + - 节点缩容: admin/kpanda/nodes/delete-node.md + - 污点管理: admin/kpanda/nodes/taints.md + - 节点调度: admin/kpanda/nodes/schedule.md + - 节点详情: admin/kpanda/nodes/node-details.md + - 标签与注解: admin/kpanda/nodes/labels-annotations.md + - 添加工作节点: admin/k8s/add-node.md + - 移除 GPU 工作节点: admin/k8s/remove-node.md + - 命名空间: + - 创建命名空间: admin/kpanda/namespaces/createns.md + - 命名空间独享节点: admin/kpanda/namespaces/exclusive.md + - 容器组安全策略: admin/kpanda/namespaces/podsecurity.md + - 弹性伸缩: + - 安装 metrics-server 插件: admin/kpanda/scale/install-metrics-server.md + - 安装 kubernetes-cronhpa-controller: admin/kpanda/scale/install-cronhpa.md + - 安装 VPA 插件: admin/kpanda/scale/install-vpa.md + - 基于内置指标创建 HPA: admin/kpanda/scale/create-hpa.md + - 基于自定义指标创建 HPA: admin/kpanda/scale/custom-hpa.md + - 创建 VPA 策略: admin/kpanda/scale/create-vpa.md + - HPA和CronHPA兼容规则: admin/kpanda/scale/hpa-cronhpa-compatibility-rules.md + - 其他方案: + - Knative 介绍: admin/kpanda/scale/knative/knative.md + - 安装 Knative: admin/kpanda/scale/knative/install.md + - Kantive 场景: admin/kpanda/scale/knative/scene.md + - Knative 实践: admin/kpanda/scale/knative/playground.md + - Helm 应用: + - Helm 模板: admin/kpanda/helm/README.md + - 上传 Helm 模板: admin/kpanda/helm/upload-helm.md + - 管理 Helm 应用: admin/kpanda/helm/helm-app.md + - 管理 Helm 仓库: admin/kpanda/helm/helm-repo.md + - 多架构 Helm 应用: admin/kpanda/helm/multi-archi-helm.md + - 自定义Helm应用导入Addon: admin/kpanda/helm/Import-addon.md + - Operator 应用: admin/kpanda/olm/import-miniooperator.md + - 容器网络: + - 创建服务: admin/kpanda/network/create-services.md + - 创建路由: admin/kpanda/network/create-ingress.md + - 网络策略: admin/kpanda/network/network-policy.md + - 容器存储: + - 数据卷声明: admin/kpanda/storage/pvc.md + - 数据卷: admin/kpanda/storage/pv.md + - 存储池: admin/kpanda/storage/sc.md + - 共享存储池: admin/kpanda/storage/sc-share.md + - 自定义资源: admin/kpanda/custom-resources/create.md + - 配置与密钥: + - 创建配置项: admin/kpanda/configmaps-secrets/create-configmap.md + - 使用配置项: admin/kpanda/configmaps-secrets/use-configmap.md + - 创建密钥: admin/kpanda/configmaps-secrets/create-secret.md + - 使用密钥: admin/kpanda/configmaps-secrets/use-secret.md + - Configmap/Secret热加载: admin/kpanda/configmaps-secrets/configmap-hot-loading.md + - 集群运维: + - 最近操作: admin/kpanda/clusterops/latest-operations.md + - 集群升级: admin/kpanda/clusters/upgrade-cluster.md + - 集群设置: admin/kpanda/clusterops/cluster-settings.md + - 集群动态资源超卖: admin/kpanda/clusterops/cluster-oversold.md + - 集群巡检: + - 介绍: admin/kpanda/inspect/index.md + - 创建巡检配置: admin/kpanda/inspect/config.md + - 执行巡检: admin/kpanda/inspect/inspect.md + - 查看巡检报告: admin/kpanda/inspect/report.md + - 备份恢复: + - 介绍: admin/kpanda/backup/index.md + - 安装 Velero 插件: admin/kpanda/backup/install-velero.md + - 应用备份: admin/kpanda/backup/deployment.md + - etcd 备份: admin/kpanda/backup/etcd-backup.md + - 安全管理: + - 安全扫描类型: admin/kpanda/security/index.md + - 合规性扫描: + - 扫描配置: admin/kpanda/security/cis/config.md + - 扫描策略: admin/kpanda/security/cis/policy.md + - 扫描报告: admin/kpanda/security/cis/report.md + - 权限扫描: admin/kpanda/security/audit.md + - 漏洞扫描: admin/kpanda/security/hunter.md + - 集成 Falco 安全工具: + - 介绍: admin/security/falco.md + - 安装: admin/security/falco-install.md + - Falco-exporter: admin/security/falco-exporter.md + - 权限管理: + - 权限体系介绍: admin/kpanda/permissions/permission-brief.md + - 集群和命名空间授权: admin/kpanda/permissions/cluster-ns-auth.md + - 增加容器管理内置权限点: admin/kpanda/permissions/custom-kpanda-role.md + - GPU 管理: + - GPU 管理概述: admin/kpanda/gpu/index.md + - GPU 支持矩阵: admin/kpanda/gpu/gpu_matrix.md + - NVIDIA GPU 管理: + - NVIDIA GPU模式说明: admin/kpanda/gpu/nvidia/index.md + - GPU Operator: + - 离线安装GPU Operator: admin/kpanda/gpu/nvidia/install_nvidia_driver_of_operator.md + - 上传Red Hat GPU Operator离线镜像: admin/kpanda/gpu/nvidia/push_image_to_repo.md + - 构建Red Hat 8.4离线yum源: admin/kpanda/gpu/nvidia/upgrade_yum_source_redhat8_4.md + - 构建Red Hat 7.9离线yum源: admin/kpanda/gpu/nvidia/yum_source_redhat7_9.md + - 构建Red Hat 9.2离线yum源: admin/kpanda/gpu/nvidia/rhel9.2_offline_install_driver.md + - Ubuntu22.04 离线安装GPU驱动: admin/kpanda/gpu/nvidia/ubuntu22.04_offline_install_driver.md + - NVIDIA GPU整卡模式: admin/kpanda/gpu/nvidia/full_gpu_userguide.md + - NVIDIA vGPU模式: + - 安装 vGPU Addon: admin/kpanda/gpu/nvidia/vgpu/vgpu_addon.md + - 使用 NVIDIA vGPU: admin/kpanda/gpu/nvidia/vgpu/vgpu_user.md + - 构建 vGPU 显存超配镜像: admin/kpanda/gpu/nvidia/vgpu/hami.md + - NVIDIA MIG 模式: + - NVIDIA MIG 概述: admin/kpanda/gpu/nvidia/mig/index.md + - 开启 MIG 功能: admin/kpanda/gpu/nvidia/mig/create_mig.md + - 使用 NVIDIA MIG: admin/kpanda/gpu/nvidia/mig/mig_usage.md + - MIG 相关命令: admin/kpanda/gpu/nvidia/mig/mig_command.md + - GPU 配额管理: admin/kpanda/gpu/vgpu_quota.md + - GPU 动态调节: admin/kpanda/gpu/dynamic-regulation.md + - GPU 监控告警: + - GPU 监控指标: admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-metrics.md + - GPU 告警规则: admin/kpanda/gpu/nvidia/gpu-monitoring-alarm/gpu-alarm.md + - 使用 Volcano: + - 安装 Volcano: admin/kpanda/gpu/volcano/volcano_user_guide.md + - 使用Volcano Gang Scheduler: admin/kpanda/gpu/volcano/volcano-gang-scheduler.md + - 使用 Volcano 优先级抢占策略: admin/kpanda/gpu/volcano/volcano_priority.md + - 使用 Volcano Binpack 策略: admin/kpanda/gpu/volcano/volcano_binpack.md + - 使用 Volcano DRF 策略: admin/kpanda/gpu/volcano/drf.md + - 使用 Volcano NUMA 亲和性调度: admin/kpanda/gpu/volcano/numa.md + - GPU 调度配置: admin/kpanda/gpu/gpu_scheduler_config.md + - 昇腾 NPU 管理: + - 昇腾 NPU 组件安装: admin/kpanda/gpu/ascend/ascend_driver_install.md + - 使用昇腾 NPU: admin/kpanda/gpu/ascend/ascend_usage.md + - 启用昇腾 VNPU: admin/kpanda/gpu/ascend/vnpu.md + - 天数 GPU 管理: admin/kpanda/gpu/Iluvatar_usage.md + - 沐曦 GPU 管理: admin/kpanda/gpu/metax/usemetax.md + - 寒武纪 GPU 管理: admin/kpanda/gpu/mlu/use-mlu.md + - GPU 相关FAQ: admin/kpanda/gpu/FAQ.md + - 最佳实践: + - 对 etcd 进行备份还原: admin/kpanda/best-practice/etcd-backup.md + - 跨集群备份恢复MySQL: admin/kpanda/best-practice/backup-mysql-on-nfs.md + - 工作集群相关实践: + - 加固自建工作集群: admin/kpanda/best-practice/hardening-cluster.md + - 离线部署/升级工作集群: admin/kpanda/best-practice/update-offline-cluster.md + - 工作集群添加异构节点: admin/kpanda/best-practice/multi-arch.md + - 工作集群的控制节点扩容: admin/kpanda/best-practice/add-master-node.md + - 替换工作集群首个控制节点: admin/kpanda/best-practice/replace-first-master-node.md + - 全局集群工作节点扩容: admin/kpanda/best-practice/add-worker-node-on-global.md + - CentOS上创建Ubuntu工作集群: admin/kpanda/best-practice/create-ubuntu-on-centos-platform.md + - CentOS上创建Red Hat工作集群: admin/kpanda/best-practice/create-redhat9.2-on-centos-platform.md + - 非主流操作系统上创建集群: admin/kpanda/best-practice/use-otherlinux-create-custer.md + - 部署/升级Kubean兼容版本: admin/kpanda/best-practice/kubean-low-version.md + - 限制Docker单容器磁盘空间: admin/kpanda/best-practice/limit-disk-usage-docker.md + - 边缘集群部署和管理实践: admin/kpanda/best-practice/k3s-lcm.md + - 在离线混部: + - 在离线混部概述: admin/kpanda/best-practice/co-located/index.md + - koordinator 安装: admin/kpanda/best-practice/co-located/install.md + - 算法开发: + - 运维管理: + - 介绍: admin/baize/oam/index.md + - 资源管理: admin/baize/oam/resource.md + - 队列管理: + - 创建队列: admin/baize/oam/queue/create.md + - 删除队列: admin/baize/oam/queue/delete.md + - 最佳实践: + - 部署 NFS 做数据集预热: admin/baize/best-practice/deploy-nfs-in-worker.md + - 更新 Notebook 内置镜像: admin/baize/best-practice/change-notebook-image.md + - Checkpoint 机制及使用介绍: admin/baize/best-practice/checkpoint.md + - 使用 Baize 微调 ChatGLM3: admin/baize/best-practice/finetunel-llm.md + - 提交 DeepSpeed 训练任务: admin/baize/best-practice/train-with-deepspeed.md + - 训练任务增加调度器选项: admin/baize/best-practice/add-scheduler.md + - 部署 Label Studio: admin/baize/best-practice/label-studio.md + - 故障排查: + - 故障排查索引: admin/baize/troubleshoot/index.md + - 集群下拉列表中找不到集群: admin/baize/troubleshoot/cluster-not-found.md + - Notebook 不受队列配额控制: admin/baize/troubleshoot/notebook-not-controlled-by-quotas.md + - 队列初始化失败: admin/baize/troubleshoot/local-queue-initialization-failed.md + - 管理: + - 可观测性: + - 快速入门: + - 部署资源规划: + - admin/insight/quickstart/res-plan/index.md + - Prometheus 资源规划: admin/insight/quickstart/res-plan/prometheus-res.md + - vmstorage 磁盘规划: admin/insight/quickstart/res-plan/vms-res-plan.md + - 调整 vmstorage 磁盘: admin/insight/quickstart/res-plan/modify-vms-disk.md + - 安装与升级: + - admin/insight/quickstart/install/index.md + - 在线安装 insight-agent: admin/insight/quickstart/install/install-agent.md + - 获取全局服务集群的数据存储地址: admin/insight/quickstart/install/gethosturl.md + - 升级注意事项: admin/insight/quickstart/install/upgrade-note.md + - 已知问题: admin/insight/quickstart/install/knownissues.md + - 大规模日志部署调整: admin/insight/best-practice/insight-kafka.md + - 定制Insight组件调度策略: admin/insight/quickstart/install/component-scheduling.md + - 开启大日志和大链路模式: admin/insight/quickstart/install/big-log-and-trace.md + - 其他发行版安装insight-agent: + - OpenShift 4.x: admin/insight/quickstart/other/install-agent-on-ocp.md + - 开始观测: + - OpenTelemetry 观测: + - 使用OTel赋予应用可观测: admin/insight/quickstart/otel/otel.md + - Operator无侵入增强应用: admin/insight/quickstart/otel/operator.md + - 向Insight发送链路数据: admin/insight/quickstart/otel/send_tracing_to_insight.md + - 链路数据尾部采样方案: admin/insight/best-practice/tail-based-sampling.md + - Java 应用观测: + - admin/insight/quickstart/otel/java/index.md + - 使用JMX Exporter暴露JVM监控指标: admin/insight/quickstart/otel/java/jvm-monitor/jmx-exporter.md + - 使用OTel Java Agent暴露JVM监控指标: admin/insight/quickstart/otel/java/jvm-monitor/otel-java-agent.md + - 已有JVM指标的Java应用对接可观测性: admin/insight/quickstart/otel/java/jvm-monitor/legacy-jvm.md + - 通过 OTel SDK 增强 Go 应用: admin/insight/quickstart/otel/golang/golang.md + - 使用OTel接收SkyWalking链路数据: admin/insight/best-practice/sw-to-otel.md + - 仪表盘: + - 概览: admin/insight/dashboard/overview.md + - 仪表盘: admin/insight/dashboard/dashboard.md + - 以管理员登录 Grafana: admin/insight/dashboard/login-grafana.md + - 导入自定义仪表盘: admin/insight/dashboard/import-dashboard.md + - 基础设施: + - 集群: admin/insight/infra/cluster.md + - 节点: admin/insight/infra/node.md + - 命名空间: admin/insight/infra/namespace.md + - 工作负载: admin/insight/infra/container.md + - 事件查询: admin/insight/infra/event.md + - 拨测: admin/insight/infra/probe.md + - 指标: admin/insight/data-query/metric.md + - 日志: admin/insight/data-query/log.md + - 链路追踪: + - 服务拓扑: admin/insight/trace/topology.md + - 服务: admin/insight/trace/service.md + - 调用链: admin/insight/trace/trace.md + - 告警: + - admin/insight/alert-center/index.md + - 告警策略: admin/insight/alert-center/alert-policy.md + - 告警模板: admin/insight/alert-center/alert-template.md + - 通知配置: admin/insight/alert-center/message.md + - 配置通知服务器: admin/insight/alert-center/sms-provider.md + - 消息模板: admin/insight/alert-center/msg-template.md + - 告警静默: admin/insight/alert-center/silent.md + - 告警抑制: admin/insight/alert-center/inhibition.md + - 数据采集: + - 采集管理: admin/insight/collection-manag/collection-manag.md + - 服务监控: admin/insight/collection-manag/service-monitor.md + - 采集组件insight-agent状态: admin/insight/collection-manag/agent-status.md + - 系统配置: + - 系统组件: admin/insight/system-config/system-component.md + - 系统配置: admin/insight/system-config/system-config.md + - 修改配置: admin/insight/system-config/modify-config.md + - 网络监控之集成 DeepFlow: admin/insight/best-practice/integration_deepflow.md + - 参考文档: + - 可观性参考指标说明: admin/insight/reference/used-metric-in-insight.md + - Insight Grafana 持久化到数据库: admin/insight/best-practice/grafana-use-db.md + - 自定义探测方式: admin/insight/collection-manag/probe-module.md + - 指标抓取说明: admin/insight/collection-manag/metric-collect.md + - 告警通知流程说明: admin/insight/reference/alertnotification.md + - 通知模板使用说明: admin/insight/reference/notify-helper.md + - Lucene 语法使用方法: admin/insight/reference/lucene.md + - 通过 Sidecar 采集容器日志: admin/insight/reference/tailing-sidecar.md + - 兼容性测试: + - Kubernetes 兼容性测试: admin/insight/compati-test/k8s-compatibility.md + - Rancher 兼容性测试: admin/insight/compati-test/rancher-compatibility.md + - Openshift 兼容性测试: admin/insight/compati-test/ocp-compatibility.md + - 常见问题: + - 链路数据的时钟偏移: admin/insight/faq/traceclockskew.md + - 日志采集排障指南: admin/insight/best-practice/debug-log.md + - 链路采集排障指南: admin/insight/best-practice/debug-trace.md + - 使用Insight定位异常: admin/insight/best-practice/find_root_cause.md + - ES 数据塞满时如何操作: admin/insight/faq/expand-once-es-full.md + - 容器日志黑名单: admin/insight/faq/ignore-pod-log-collect.md + - 全局管理: + - 安装、登录和升级: + - 离线升级全局管理: admin/ghippo/install/offline-install.md + - 自定义反向代理服务器地址: admin/ghippo/install/reverse-proxy.md + - 开启Folder/WS的隔离模式: admin/ghippo/install/user-isolation.md + - 国密网关: admin/ghippo/install/gm-gateway.md + - 登录: admin/ghippo/install/login.md + - 用户与访问控制: + - 什么是用户与访问控制: admin/ghippo/access-control/iam.md + - 用户: admin/ghippo/access-control/user.md + - 用户组: admin/ghippo/access-control/group.md + - 角色: + - admin/ghippo/access-control/role.md + - 系统角色: admin/ghippo/access-control/global.md + - 自定义角色: admin/ghippo/access-control/custom-role.md + - 身份提供商: + - admin/ghippo/access-control/idprovider.md + - LDAP: admin/ghippo/access-control/ldap.md + - OIDC: admin/ghippo/access-control/oidc.md + - OAuth 2.0 之企业微信: admin/ghippo/access-control/oauth2.0.md + - 接入管理: + - admin/ghippo/access-control/docking.md + - Webhook: admin/ghippo/access-control/webhook.md + - 工作空间与层级: + - admin/ghippo/workspace/ws-folder.md + - 绑定工作空间: admin/register/bindws.md + - 为工作空间分配资源: admin/register/wsres.md + - 创建和删除工作空间: admin/ghippo/workspace/workspace.md + - 工作空间权限: admin/ghippo/workspace/ws-permission.md + - 创建和删除文件夹: admin/ghippo/workspace/folders.md + - 文件夹权限: admin/ghippo/workspace/folder-permission.md + - 资源配额: admin/ghippo/workspace/quota.md + - 资源组与共享资源的区别: admin/ghippo/workspace/res-gp-and-shared-res.md + - 资源绑定权限说明: admin/ghippo/workspace/wsbind-permission.md + - 审计日志: + - 采集 K8s 审计日志: admin/ghippo/audit/open-audit.md + - 生成 K8s 审计日志: admin/ghippo/audit/open-k8s-audit.md + - 下载和导出审计日志: admin/ghippo/audit/audit-log.md + - 获取审计日志源IP: admin/ghippo/audit/source-ip.md + - 审计项汇总: + - 容器管理审计项: admin/ghippo/audit/gproduct-audit/kpanda.md + - 云主机审计项: admin/ghippo/audit/gproduct-audit/virtnest.md + - 可观测性审计项: admin/ghippo/audit/gproduct-audit/insight.md + - 全局管理审计项: admin/ghippo/audit/gproduct-audit/ghippo.md + - 运营管理: + - admin/ghippo/report-billing/index.md + - 报表管理: admin/ghippo/report-billing/report.md + - 计费计量: admin/ghippo/report-billing/billing.md + - 平台设置: + - 安全策略: admin/ghippo/platform-setting/security.md + - 邮箱服务器设置: admin/ghippo/platform-setting/mail-server.md + - 外观定制: admin/ghippo/platform-setting/appearance.md + - 关于平台: admin/ghippo/platform-setting/about.md + - 密码重置: admin/ghippo/password.md + - 个人中心: + - 安全设置: admin/ghippo/personal-center/security-setting.md + - 访问密钥: admin/ghippo/personal-center/accesstoken.md + - SSH 公钥: admin/ghippo/personal-center/ssh-key.md + - 语言设置: admin/ghippo/personal-center/language.md + - 最佳实践: + - 工作空间最佳实践: admin/ghippo/best-practice/ws-best-practice.md + - 工作空间绑定命名空间: admin/ghippo/best-practice/ws-to-ns.md + - 单集群分配给多个工作空间: admin/ghippo/best-practice/cluster-for-multiws.md + - 文件夹最佳实践: admin/ghippo/best-practice/folder-practice.md + - 普通用户授权规划: admin/ghippo/best-practice/authz-plan.md + - 超大型企业的架构管理: admin/ghippo/best-practice/super-group.md + - GProduct 对接全局管理: + - admin/ghippo/best-practice/gproduct/intro.md + - 接入导航栏: admin/ghippo/best-practice/gproduct/nav.md + - 接入路由和登录认证: admin/ghippo/best-practice/gproduct/route-auth.md + - 集成与被集成(OEM IN/OUT): + - OEM IN: admin/ghippo/best-practice/oem/oem-in.md + - OEM OUT: admin/ghippo/best-practice/oem/oem-out.md + - 定制对接 IdP: admin/ghippo/best-practice/oem/custom-idp.md + - Keycloak 自定义 IdP: admin/ghippo/best-practice/oem/keycloak-idp.md + - 定制导航栏: + - 定制导航栏: admin/ghippo/best-practice/menu/navigator.md + - 基于权限显示/隐藏导航栏菜单: admin/ghippo/best-practice/menu/menu-display-or-hiding.md + - 故障排查: + - ingressgateway 无法启动: admin/ghippo/troubleshooting/ghippo01.md + - 登录报错 401 或 403: admin/ghippo/troubleshooting/ghippo02.md + - keycloak 无法启动: admin/ghippo/troubleshooting/ghippo03.md + - 单独升级全局管理时失败: admin/ghippo/troubleshooting/ghippo04.md + - 开发者手册: + - OpenAPI 访问密钥: openapi/index.md + - 云主机 OpenAPI 文档: openapi/virtnest/index.md + - AI Lab OpenAPI 文档: openapi/baize/index.md + - 容器管理 OpenAPI 文档: openapi/kpanda/index.md + - 可观测性 OpenAPI 文档: openapi/insight/index.md + - 全局管理 OpenAPI 文档: openapi/ghippo/index.md diff --git a/docs/zh/scripts/download_image.py b/docs/zh/scripts/download_image.py new file mode 100644 index 0000000..3794474 --- /dev/null +++ b/docs/zh/scripts/download_image.py @@ -0,0 +1,79 @@ +import os +import re +import requests +from urllib.parse import urlparse +from pathlib import Path + + +def download_image(url, save_directory): + """下载图片并保存到指定目录,返回保存的文件名""" + try: + response = requests.get(url, timeout=10) + response.raise_for_status() + # 从URL解析出文件名 + parsed_url = urlparse(url) + image_name = os.path.basename(parsed_url.path) + # 如果文件名为空,使用默认名称 + if not image_name: + image_name = "image.jpg" + # 解决重名文件问题 + original_image_name = image_name + counter = 1 + while os.path.exists(os.path.join(save_directory, image_name)): + name, ext = os.path.splitext(original_image_name) + image_name = f"{name}_{counter}{ext}" + counter += 1 + # 保存图片 + with open(os.path.join(save_directory, image_name), "wb") as f: + f.write(response.content) + return image_name + except Exception as e: + print(f"下载图片失败:{url},错误:{e}") + return None + + +def replace_image_links(markdown_content, markdown_path, images_directory): + """替换markdown内容中的图片链接,下载图片并更新链接""" + # 匹配markdown图片链接的正则表达式 + image_pattern = r"!\[.*?\]\((http.*?)\)" + matches = re.findall(image_pattern, markdown_content) + updated_content = markdown_content + for url in matches: + print(f"处理图片:{url}") + image_name = download_image(url, images_directory) + if image_name: + # 计算相对路径 + relative_path = os.path.relpath( + os.path.join(images_directory, image_name), + start=os.path.dirname(markdown_path), + ) + # 更新markdown内容 + updated_content = updated_content.replace(url, relative_path) + return updated_content + + +def process_markdown_files(root_directory, images_directory): + """递归处理目录下的所有markdown文件""" + for root, dirs, files in os.walk(root_directory): + for file in files: + if file.lower().endswith(".md"): + markdown_path = os.path.join(root, file) + print(f"处理文件:{markdown_path}") + with open(markdown_path, "r", encoding="utf-8") as f: + content = f.read() + updated_content = replace_image_links( + content, markdown_path, images_directory + ) + if updated_content != content: + # 如果内容有更新,写回文件 + with open(markdown_path, "w", encoding="utf-8") as f: + f.write(updated_content) + + +if __name__ == "__main__": + docs_directory = "docs" + images_directory = os.path.join(docs_directory, "images") + # 创建images目录 + os.makedirs(images_directory, exist_ok=True) + process_markdown_files(docs_directory, images_directory) + print("所有文件处理完成。") diff --git a/docs/zh/scripts/remove_navbar.py b/docs/zh/scripts/remove_navbar.py new file mode 100644 index 0000000..a90b625 --- /dev/null +++ b/docs/zh/scripts/remove_navbar.py @@ -0,0 +1,107 @@ +from PIL import Image +import numpy as np +import os +from multiprocessing import Pool, cpu_count + + +def detect_navbar_height(image): + """Detects the height of the navbar based on average row intensity.""" + gray_image = image.convert("L") + image_np = np.array(gray_image) + row_intensity = np.mean(image_np, axis=1) + + split_index = None + for i in range(1, len(row_intensity)): + if row_intensity[i] > 200: # 阈值可根据实际情况调整 + split_index = i + break + return split_index + + +def add_border(image, border_color=(200, 200, 200)): + """Adds a 1-pixel light gray border to the image.""" + border_size = 1 + new_width = image.width + 2 * border_size + new_height = image.height + 2 * border_size + + # 创建一个新图像,填充为边框颜色 + bordered_image = Image.new("RGB", (new_width, new_height), border_color) + # 将原始图像粘贴到新的图像中,居中 + bordered_image.paste(image, (border_size, border_size)) + return bordered_image + + +def process_image(args): + """Processes a single image: removes navbar and adds border.""" + image_path, output_path = args + try: + image = Image.open(image_path) + if image.mode != "RGB": + image = image.convert("RGB") + split_index = detect_navbar_height(image) + + if split_index is not None: + cropped_image = image.crop((0, split_index, image.width, image.height)) + # 添加1像素淡灰色边框 + bordered_image = add_border(cropped_image) + bordered_image.save(output_path) + print(f"已成功处理并添加边框: {image_path}, 保存到: {output_path}") + else: + print(f"未检测到导航栏: {image_path}") + # 即使未检测到导航栏,也添加边框 + bordered_image = add_border(image) + bordered_image.save(output_path) + print(f"已为未修改的图片添加边框: {image_path}, 保存到: {output_path}") + + except Exception as e: + print(f"处理图片 {image_path} 时出错: {e}") + + +def batch_process(input_dir, output_dir): + """Batch processes images in a folder to remove navbars and add borders using multiprocessing.""" + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + # 获取所有需要处理的图片路径 + image_files = [ + filename + for filename in os.listdir(input_dir) + if filename.lower().endswith((".png", ".jpg", ".jpeg")) + ] + + # 构建要处理的图片路径列表 + tasks = [ + (os.path.join(input_dir, filename), os.path.join(output_dir, filename)) + for filename in image_files + ] + + if tasks: + # 使用多进程池进行并行处理 + pool_size = min(cpu_count(), len(tasks)) # 不要创建多于需要的进程数 + with Pool(processes=pool_size) as pool: + pool.map(process_image, tasks) + else: + print(f"文件夹 {input_dir} 中没有找到符合条件的图片。") + + +def find_images_dirs(root_dir): + """Finds and returns a list of paths of 'images' directories within the given root directory.""" + images_dirs = [] + for dirpath, dirnames, _ in os.walk(root_dir): + if "images" in dirnames: + images_dir_path = os.path.join(dirpath, "images") + images_dirs.append(os.path.relpath(images_dir_path, root_dir)) + return images_dirs + + +if __name__ == "__main__": + root_directory = "docs" + images_dirs = find_images_dirs(root_directory) + if not images_dirs: + print("未找到任何包含 'images' 文件夹的目录。") + else: + for folder in images_dirs: + images_folder = os.path.join(root_directory, folder) + print(f"正在处理文件夹: {images_folder}") + batch_process(input_dir=images_folder, output_dir=images_folder) + print("所有图片处理完成。") diff --git a/docs/zh/theme/404.html b/docs/zh/theme/404.html new file mode 100644 index 0000000..7bbc338 --- /dev/null +++ b/docs/zh/theme/404.html @@ -0,0 +1,91 @@ + + + + + AI 算力中心 + + + + + + +
+
+
+
+
+
+

你似乎来到了未知的空间!

+

You may come in an unknown space!

+
+
+

想要探索一下吗?试试回到起点,找到迷失的自我。

+

Want to explore? Try to go back to the beginning and find where you are lost.

+ 返回首页 + Go to Home +
+
+
+
+
+
+ + + + diff --git a/docs/zh/theme/main.html b/docs/zh/theme/main.html new file mode 100644 index 0000000..f657b51 --- /dev/null +++ b/docs/zh/theme/main.html @@ -0,0 +1,33 @@ +{#- + This file was automatically generated - do not edit +-#} +{% extends "base.html" %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block announce %} + + 算丰二号全新上线咯!点击链接,免费体验! + + +{% endblock %} +{% block content %} + {% include "overrides/partials/content.html" %} +{% endblock %} +{% block scripts %} + {{ super() }} + + + +{% endblock %} diff --git a/docs/zh/theme/overrides/.icons/octoface.svg b/docs/zh/theme/overrides/.icons/octoface.svg new file mode 100644 index 0000000..df0186e --- /dev/null +++ b/docs/zh/theme/overrides/.icons/octoface.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape.avif b/docs/zh/theme/overrides/assets/images/layers/1-landscape.avif new file mode 100644 index 0000000..227ad22 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape.png b/docs/zh/theme/overrides/assets/images/layers/1-landscape.png new file mode 100644 index 0000000..4947122 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape.webp b/docs/zh/theme/overrides/assets/images/layers/1-landscape.webp new file mode 100644 index 0000000..12a97b5 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.avif b/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.avif new file mode 100644 index 0000000..4cc450b Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.png b/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.png new file mode 100644 index 0000000..5ba3731 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.webp b/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.webp new file mode 100644 index 0000000..60c13e4 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@2x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.avif b/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.avif new file mode 100644 index 0000000..f5849e0 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.png b/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.png new file mode 100644 index 0000000..8308e69 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.webp b/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.webp new file mode 100644 index 0000000..b5f423e Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@3x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.avif b/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.avif new file mode 100644 index 0000000..055e9e8 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.png b/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.png new file mode 100644 index 0000000..b6513aa Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.webp b/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.webp new file mode 100644 index 0000000..a6f8ae4 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/1-landscape@4x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau.avif b/docs/zh/theme/overrides/assets/images/layers/2-plateau.avif new file mode 100644 index 0000000..a840190 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau.png b/docs/zh/theme/overrides/assets/images/layers/2-plateau.png new file mode 100644 index 0000000..a5311db Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau.webp b/docs/zh/theme/overrides/assets/images/layers/2-plateau.webp new file mode 100644 index 0000000..299b41c Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.avif b/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.avif new file mode 100644 index 0000000..8f76503 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.png b/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.png new file mode 100644 index 0000000..e615102 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.webp b/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.webp new file mode 100644 index 0000000..9367d9c Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@2x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.avif b/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.avif new file mode 100644 index 0000000..9cb7281 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.png b/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.png new file mode 100644 index 0000000..6b2975f Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.webp b/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.webp new file mode 100644 index 0000000..1e6a788 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@3x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.avif b/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.avif new file mode 100644 index 0000000..4a4ffa6 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.png b/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.png new file mode 100644 index 0000000..66de822 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.webp b/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.webp new file mode 100644 index 0000000..af7c06d Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/2-plateau@4x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.avif b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.avif new file mode 100644 index 0000000..3a64dec Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.png b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.png new file mode 100644 index 0000000..024aff8 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.webp b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.webp new file mode 100644 index 0000000..4221d6f Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.avif b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.avif new file mode 100644 index 0000000..4cb8854 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.png b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.png new file mode 100644 index 0000000..d5feae1 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.webp b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.webp new file mode 100644 index 0000000..e1663eb Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@2x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.avif b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.avif new file mode 100644 index 0000000..ab7df5a Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.png b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.png new file mode 100644 index 0000000..37b39e9 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.webp b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.webp new file mode 100644 index 0000000..2b4f5ed Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@3x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.avif b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.avif new file mode 100644 index 0000000..c3323c4 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.png b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.png new file mode 100644 index 0000000..ffaa573 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.webp b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.webp new file mode 100644 index 0000000..e6d7b13 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/3-astronaut-1@4x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.avif b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.avif new file mode 100644 index 0000000..4c6d3f3 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.png b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.png new file mode 100644 index 0000000..905a0ae Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.webp b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.webp new file mode 100644 index 0000000..978fca9 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.avif b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.avif new file mode 100644 index 0000000..aae7473 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.png b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.png new file mode 100644 index 0000000..2026ee3 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.webp b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.webp new file mode 100644 index 0000000..1b77760 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@2x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.avif b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.avif new file mode 100644 index 0000000..ba33d05 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.png b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.png new file mode 100644 index 0000000..1bd811a Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.webp b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.webp new file mode 100644 index 0000000..b094e8a Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@3x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.avif b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.avif new file mode 100644 index 0000000..60c1787 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.png b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.png new file mode 100644 index 0000000..9520320 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.webp b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.webp new file mode 100644 index 0000000..c1ce5f9 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/4-astronaut-2@4x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1.avif b/docs/zh/theme/overrides/assets/images/layers/5-plants-1.avif new file mode 100644 index 0000000..c2668e2 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1.png b/docs/zh/theme/overrides/assets/images/layers/5-plants-1.png new file mode 100644 index 0000000..a4001be Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1.webp b/docs/zh/theme/overrides/assets/images/layers/5-plants-1.webp new file mode 100644 index 0000000..771f236 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.avif b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.avif new file mode 100644 index 0000000..7e39ea6 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.png b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.png new file mode 100644 index 0000000..5e537b7 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.webp b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.webp new file mode 100644 index 0000000..980ea24 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@2x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.avif b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.avif new file mode 100644 index 0000000..9d7d1ab Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.png b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.png new file mode 100644 index 0000000..1b3efb6 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.webp b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.webp new file mode 100644 index 0000000..49688c6 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@3x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.avif b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.avif new file mode 100644 index 0000000..ec34061 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.png b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.png new file mode 100644 index 0000000..8af3b36 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.webp b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.webp new file mode 100644 index 0000000..2d0da21 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/5-plants-1@4x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2.avif b/docs/zh/theme/overrides/assets/images/layers/6-plants-2.avif new file mode 100644 index 0000000..ec17d51 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2.png b/docs/zh/theme/overrides/assets/images/layers/6-plants-2.png new file mode 100644 index 0000000..eb2c9be Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2.webp b/docs/zh/theme/overrides/assets/images/layers/6-plants-2.webp new file mode 100644 index 0000000..40dde22 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.avif b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.avif new file mode 100644 index 0000000..c45980b Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.png b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.png new file mode 100644 index 0000000..a6ecade Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.webp b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.webp new file mode 100644 index 0000000..9b975bc Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@2x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.avif b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.avif new file mode 100644 index 0000000..bd973f6 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.png b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.png new file mode 100644 index 0000000..2416f96 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.webp b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.webp new file mode 100644 index 0000000..5c37f8c Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@3x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.avif b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.avif new file mode 100644 index 0000000..6e22986 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.avif differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.png b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.png new file mode 100644 index 0000000..ff40efc Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.png differ diff --git a/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.webp b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.webp new file mode 100644 index 0000000..fde5dcf Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/layers/6-plants-2@4x.webp differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/built-in-search.png b/docs/zh/theme/overrides/assets/images/spotlight/built-in-search.png new file mode 100644 index 0000000..d28587d Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/built-in-search.png differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/ci-cd.png b/docs/zh/theme/overrides/assets/images/spotlight/ci-cd.png new file mode 100644 index 0000000..2a44a3e Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/ci-cd.png differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/code-annotations.png b/docs/zh/theme/overrides/assets/images/spotlight/code-annotations.png new file mode 100644 index 0000000..15047b7 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/code-annotations.png differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/easy-to-use.jpg b/docs/zh/theme/overrides/assets/images/spotlight/easy-to-use.jpg new file mode 100644 index 0000000..3987105 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/easy-to-use.jpg differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/icons-emojis.png b/docs/zh/theme/overrides/assets/images/spotlight/icons-emojis.png new file mode 100644 index 0000000..17cf992 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/icons-emojis.png differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/ready.jpg b/docs/zh/theme/overrides/assets/images/spotlight/ready.jpg new file mode 100644 index 0000000..411aaab Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/ready.jpg differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/security.png b/docs/zh/theme/overrides/assets/images/spotlight/security.png new file mode 100644 index 0000000..cc0d4ae Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/security.png differ diff --git a/docs/zh/theme/overrides/assets/images/spotlight/social-cards.png b/docs/zh/theme/overrides/assets/images/spotlight/social-cards.png new file mode 100644 index 0000000..25fb35a Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/spotlight/social-cards.png differ diff --git a/docs/zh/theme/overrides/assets/images/users/john-maeda.jpg b/docs/zh/theme/overrides/assets/images/users/john-maeda.jpg new file mode 100644 index 0000000..60f416e Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/users/john-maeda.jpg differ diff --git a/docs/zh/theme/overrides/assets/images/users/michael-feng.jpg b/docs/zh/theme/overrides/assets/images/users/michael-feng.jpg new file mode 100644 index 0000000..774a467 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/users/michael-feng.jpg differ diff --git a/docs/zh/theme/overrides/assets/images/users/sebastian-ramirez.jpg b/docs/zh/theme/overrides/assets/images/users/sebastian-ramirez.jpg new file mode 100644 index 0000000..e77e8e5 Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/users/sebastian-ramirez.jpg differ diff --git a/docs/zh/theme/overrides/assets/images/wall.png b/docs/zh/theme/overrides/assets/images/wall.png new file mode 100644 index 0000000..d3c21fb Binary files /dev/null and b/docs/zh/theme/overrides/assets/images/wall.png differ diff --git a/docs/zh/theme/overrides/assets/javascripts/bundle.b97a6647.min.js b/docs/zh/theme/overrides/assets/javascripts/bundle.b97a6647.min.js new file mode 100644 index 0000000..e67e6bb --- /dev/null +++ b/docs/zh/theme/overrides/assets/javascripts/bundle.b97a6647.min.js @@ -0,0 +1,3 @@ +"use strict";(()=>{var To=Object.create;var nr=Object.defineProperty;var Oo=Object.getOwnPropertyDescriptor;var _o=Object.getOwnPropertyNames,Hr=Object.getOwnPropertySymbols,Mo=Object.getPrototypeOf,Rr=Object.prototype.hasOwnProperty,Lo=Object.prototype.propertyIsEnumerable;var Ir=(e,t,n)=>t in e?nr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Q=(e,t)=>{for(var n in t||(t={}))Rr.call(t,n)&&Ir(e,n,t[n]);if(Hr)for(var n of Hr(t))Lo.call(t,n)&&Ir(e,n,t[n]);return e};var Oe=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Co=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of _o(t))!Rr.call(e,o)&&o!==n&&nr(e,o,{get:()=>t[o],enumerable:!(r=Oo(t,o))||r.enumerable});return e};var qe=(e,t,n)=>(n=e!=null?To(Mo(e)):{},Co(t||!e||!e.__esModule?nr(n,"default",{value:e,enumerable:!0}):n,e));var en=Oe((Yi,yt)=>{var kr,Pr,$r,Fr,Wr,Ur,jr,zr,Dr,gt,or,Vr,Nr,Qr,Ke,qr,Kr,Yr,Br,Gr,Jr,Xr,Zr,xt;(function(e){var t=typeof global=="object"?global:typeof self=="object"?self:typeof this=="object"?this:{};typeof define=="function"&&define.amd?define("tslib",["exports"],function(r){e(n(t,n(r)))}):typeof yt=="object"&&typeof yt.exports=="object"?e(n(t,n(yt.exports))):e(n(t));function n(r,o){return r!==t&&(typeof Object.create=="function"?Object.defineProperty(r,"__esModule",{value:!0}):r.__esModule=!0),function(i,a){return r[i]=o?o(i,a):a}}})(function(e){var t=Object.setPrototypeOf||{__proto__ :[]}instanceof Array&&function(r,o){r.__proto__=o}||function(r,o){for(var i in o)Object.prototype.hasOwnProperty.call(o,i)&&(r[i]=o[i])};kr=function(r,o){if(typeof o!="function"&&o!==null)throw new TypeError("Class extends value "+String(o)+" is not a constructor or null");t(r,o);function i(){this.constructor=r}r.prototype=o===null?Object.create(o):(i.prototype=o.prototype,new i)},Pr=Object.assign||function(r){for(var o,i=1,a=arguments.length;i=0;u--)(p=r[u])&&(s=(c<3?p(s):c>3?p(o,i,s):p(o,i))||s);return c>3&&s&&Object.defineProperty(o,i,s),s},Wr=function(r,o){return function(i,a){o(i,a,r)}},Ur=function(r,o){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(r,o)},jr=function(r,o,i,a){function c(s){return s instanceof i?s:new i(function(p){p(s)})}return new(i||(i=Promise))(function(s,p){function u(d){try{f(a.next(d))}catch(l){p(l)}}function m(d){try{f(a.throw(d))}catch(l){p(l)}}function f(d){d.done?s(d.value):c(d.value).then(u,m)}f((a=a.apply(r,o||[])).next())})},zr=function(r,o){var i={label:0,sent:function(){if(s[0]&1)throw s[1];return s[1]},trys:[],ops:[]},a,c,s,p;return p={next:u(0),throw:u(1),return:u(2)},typeof Symbol=="function"&&(p[Symbol.iterator]=function(){return this}),p;function u(f){return function(d){return m([f,d])}}function m(f){if(a)throw new TypeError("Generator is already executing.");for(;i;)try{if(a=1,c&&(s=f[0]&2?c.return:f[0]?c.throw||((s=c.return)&&s.call(c),0):c.next)&&!(s=s.call(c,f[1])).done)return s;switch(c=0,s&&(f=[f[0]&2,s.value]),f[0]){case 0:case 1:s=f;break;case 4:return i.label++,{value:f[1],done:!1};case 5:i.label++,c=f[1],f=[0];continue;case 7:f=i.ops.pop(),i.trys.pop();continue;default:if(s=i.trys,!(s=s.length>0&&s[s.length-1])&&(f[0]===6||f[0]===2)){i=0;continue}if(f[0]===3&&(!s||f[1]>s[0]&&f[1]=r.length&&(r=void 0),{value:r&&r[a++],done:!r}}};throw new TypeError(o?"Object is not iterable.":"Symbol.iterator is not defined.")},or=function(r,o){var i=typeof Symbol=="function"&&r[Symbol.iterator];if(!i)return r;var a=i.call(r),c,s=[],p;try{for(;(o===void 0||o-- >0)&&!(c=a.next()).done;)s.push(c.value)}catch(u){p={error:u}}finally{try{c&&!c.done&&(i=a.return)&&i.call(a)}finally{if(p)throw p.error}}return s},Vr=function(){for(var r=[],o=0;o1||u(h,v)})})}function u(h,v){try{m(a[h](v))}catch(E){l(s[0][3],E)}}function m(h){h.value instanceof Ke?Promise.resolve(h.value.v).then(f,d):l(s[0][2],h)}function f(h){u("next",h)}function d(h){u("throw",h)}function l(h,v){h(v),s.shift(),s.length&&u(s[0][0],s[0][1])}},Kr=function(r){var o,i;return o={},a("next"),a("throw",function(c){throw c}),a("return"),o[Symbol.iterator]=function(){return this},o;function a(c,s){o[c]=r[c]?function(p){return(i=!i)?{value:Ke(r[c](p)),done:c==="return"}:s?s(p):p}:s}},Yr=function(r){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o=r[Symbol.asyncIterator],i;return o?o.call(r):(r=typeof gt=="function"?gt(r):r[Symbol.iterator](),i={},a("next"),a("throw"),a("return"),i[Symbol.asyncIterator]=function(){return this},i);function a(s){i[s]=r[s]&&function(p){return new Promise(function(u,m){p=r[s](p),c(u,m,p.done,p.value)})}}function c(s,p,u,m){Promise.resolve(m).then(function(f){s({value:f,done:u})},p)}},Br=function(r,o){return Object.defineProperty?Object.defineProperty(r,"raw",{value:o}):r.raw=o,r};var n=Object.create?function(r,o){Object.defineProperty(r,"default",{enumerable:!0,value:o})}:function(r,o){r.default=o};Gr=function(r){if(r&&r.__esModule)return r;var o={};if(r!=null)for(var i in r)i!=="default"&&Object.prototype.hasOwnProperty.call(r,i)&&xt(o,r,i);return n(o,r),o},Jr=function(r){return r&&r.__esModule?r:{default:r}},Xr=function(r,o,i,a){if(i==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof o=="function"?r!==o||!a:!o.has(r))throw new TypeError("Cannot read private member from an object whose class did not declare it");return i==="m"?a:i==="a"?a.call(r):a?a.value:o.get(r)},Zr=function(r,o,i,a,c){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!c)throw new TypeError("Private accessor was defined without a setter");if(typeof o=="function"?r!==o||!c:!o.has(r))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?c.call(r,i):c?c.value=i:o.set(r,i),i},e("__extends",kr),e("__assign",Pr),e("__rest",$r),e("__decorate",Fr),e("__param",Wr),e("__metadata",Ur),e("__awaiter",jr),e("__generator",zr),e("__exportStar",Dr),e("__createBinding",xt),e("__values",gt),e("__read",or),e("__spread",Vr),e("__spreadArrays",Nr),e("__spreadArray",Qr),e("__await",Ke),e("__asyncGenerator",qr),e("__asyncDelegator",Kr),e("__asyncValues",Yr),e("__makeTemplateObject",Br),e("__importStar",Gr),e("__importDefault",Jr),e("__classPrivateFieldGet",Xr),e("__classPrivateFieldSet",Zr)})});var lt=Oe(pe=>{(function(){var e,t,n,r,o,i,a,c,s,p,u,m,f,d,l,h,v,E,O,F;F=150,p=20,O=150,s=.75,pe.score=function(b,x,T){var C,g,y,H;return g=T.preparedQuery,C=T.allowErrors,C||o(b,g.core_lw,g.core_up)?(H=b.toLowerCase(),y=t(b,H,g),Math.ceil(y)):0},pe.isMatch=o=function(b,x,T){var C,g,y,H,U,N,W;if(y=b.length,H=x.length,!y||H>y)return!1;for(C=-1,g=-1;++g-1)return l(b,x,w,S,L,X,J);for(te=new Array(X),U=new Array(X),rr=E(X,J),B=Math.ceil(s*X)+5,ue=B,W=!0,P=-1;++PM&&(M=Te),N=0,S[P]===vt)if(tr=c(V,b,x),N=H>0?H:f(b,x,w,S,V,P,tr),y=$+m(V,P,tr,g,N),y>M)M=y,ue=B;else{if(_&&--ue<=0)return Math.max(M,te[X-1])*rr;_=!1}$=Te,H=U[P],U[P]=N,te[P]=M}}return M=te[X-1],M*rr},pe.isWordStart=c=function(b,x,T){var C,g;return b===0?!0:(C=x[b],g=x[b-1],i(g)||C!==T[b]&&g===T[b-1])},pe.isWordEnd=a=function(b,x,T,C){var g,y;return b===C-1?!0:(g=x[b],y=x[b+1],i(y)||g===T[b]&&y!==T[b+1])},i=function(b){return b===" "||b==="."||b==="-"||b==="_"||b==="/"||b==="\\"},v=function(b){var x;return bg?C:g)+10):y+F*g},pe.scoreConsecutives=f=function(b,x,T,C,g,y,H){var U,N,W,V,P,J,B;for(N=b.length,V=T.length,W=N-g,P=V-y,U=W-1&&(P=c(W,b,x),P&&(g=W))),N=-1,V=0;++N1&&W>1))return n;for(g=0,B=0,ue=0,P=0,H=-1,U=-1;++U-1){B++;continue}else break;for(;++H12*U)return!1;for(y=-1;++yC)return!1;return!0}}).call(pe)});var Zt=Oe(mt=>{(function(){var e,t,n,r,o,i,a,c,s,p;p=lt(),i=p.isMatch,e=p.computeScore,c=p.scoreSize,s=20,n=2.5,mt.score=function(u,m,f){var d,l,h,v;return l=f.preparedQuery,d=f.allowErrors,d||i(u,l.core_lw,l.core_up)?(v=u.toLowerCase(),h=e(u,v,l),h=a(u,v,h,f),Math.ceil(h)):0},a=function(u,m,f,d){var l,h,v,E,O,F,b,x,T,C;if(f===0)return 0;for(T=d.preparedQuery,C=d.useExtensionBonus,x=d.pathSeparator,O=u.length-1;u[O]===x;)O--;if(v=u.lastIndexOf(x,O),b=O-v,F=1,C&&(F+=o(m,T.ext,v,O,2),f*=F),v===-1)return f;for(E=T.depth;v>-1&&E-- >0;)v=u.lastIndexOf(x,v-1);return h=v===-1?f:F*e(u.slice(v+1,O+1),m.slice(v+1,O+1),T),l=.5*s/(s+t(u,O+1,x)),l*h+(1-l)*f*c(0,n*b)},mt.countDir=t=function(u,m,f){var d,l;if(m<1)return 0;for(d=0,l=-1;++lf)))return 0;for(E=m.length,h=d-O,h0?.9*o(u,m,f,O-2,l-1):v/h}}).call(mt)});var Tr=Oe((eo,to)=>{(function(){var e,t,n,r,o,i,a,c;c=Zt(),n=c.countDir,o=c.getExtension,to.exports=e=function(){function s(p,u){var m,f,d;if(d=u!=null?u:{},m=d.optCharRegEx,f=d.pathSeparator,!(p&&p.length))return null;this.query=p,this.query_lw=p.toLowerCase(),this.core=t(p,m),this.core_lw=this.core.toLowerCase(),this.core_up=a(this.core),this.depth=n(p,p.length,f),this.ext=o(this.query_lw),this.charCodes=r(this.query_lw)}return s}(),i=/[ _\-:\/\\]/g,t=function(s,p){return p==null&&(p=i),s.replace(p,"")},a=function(s){var p,u,m,f;for(u="",m=0,f=s.length;m{(function(){var e,t,n,r,o;r=lt(),t=Zt(),e=Tr(),n=function(i){return i.candidate},o=function(i,a){return a.score-i.score},no.exports=function(i,a,c){var s,p,u,m,f,d,l,h,v,E,O,F,b;for(h=[],u=c.key,f=c.maxResults,m=c.maxInners,O=c.usePathScoring,v=m!=null&&m>0?m:i.length+1,s=u!=null,l=O?t:r,F=0,b=i.length;F0&&(h.push({candidate:p,score:d}),!--v))));F++);return h.sort(o),i=h.map(n),f!=null&&(i=i.slice(0,f)),i}}).call(ro)});var io=Oe(er=>{(function(){var e,t,n,r,o,i,a,c,s,p;p=lt(),n=p.isMatch,r=p.isWordStart,s=p.scoreConsecutives,c=p.scoreCharacter,a=p.scoreAcronyms,er.match=o=function(u,m,f){var d,l,h,v,E,O;return d=f.allowErrors,E=f.preparedQuery,v=f.pathSeparator,d||n(u,E.core_lw,E.core_up)?(O=u.toLowerCase(),h=t(u,O,E),h.length===0||u.indexOf(v)>-1&&(l=e(u,O,E,v),h=i(h,l)),h):[]},er.wrap=function(u,m,f){var d,l,h,v,E,O,F,b,x;if(f.wrap!=null&&(x=f.wrap,O=x.tagClass,b=x.tagOpen,F=x.tagClose),O==null&&(O="highlight"),b==null&&(b=''),F==null&&(F=""),u===m)return b+u+F;if(h=o(u,m,f),h.length===0)return u;for(v="",d=-1,E=0;++dE&&(v+=u.substring(E,l),E=l);++dE&&(v+=b,v+=u.substring(E,l),v+=F,E=l)}return E<=u.length-1&&(v+=u.substring(E)),v},e=function(u,m,f,d){var l,h,v;for(v=u.length-1;u[v]===d;)v--;if(l=u.lastIndexOf(d,v),l===-1)return[];for(h=f.depth;h-- >0;)if(l=u.lastIndexOf(d,l-1),l===-1)return[];return l++,v++,t(u.slice(l,v),m.slice(l,v),f,l)},i=function(u,m){var f,d,l,h,v,E,O;if(v=u.length,E=m.length,E===0)return u.slice();if(v===0)return m.slice();for(l=-1,h=0,d=m[h],O=[];++l0?x:s(u,m,P,J,g,y,S),F=ue+c(g,y,S,O,C)),L=X[y],x=T[y],B>L?N=h:(B=L,N=E),F>B?(B=F,N=l):C=0,X[y]=B,T[y]=C,_[++V]=B>0?N:v;for(g=H-1,y=W-1,V=g*W+y,b=!0,U=[];b&&g>=0&&y>=0;)switch(_[V]){case E:g--,V-=W;break;case h:y--,V--;break;case l:U.push(g+d),y--,g--,V-=W+1;break;default:b=!1}return U.reverse(),U}}).call(er)});var Or=Oe((ao,so)=>{(function(){var e,t,n,r,o,i,a,c;n=oo(),r=io(),c=lt(),i=Zt(),e=Tr(),a=null,t=(typeof process!="undefined"&&process!==null?process.platform:void 0)==="win32"?"\\":"/",so.exports={filter:function(s,p,u){return u==null&&(u={}),(p!=null?p.length:void 0)&&(s!=null?s.length:void 0)?(u=o(u,p),n(s,p,u)):[]},score:function(s,p,u){return u==null&&(u={}),(s!=null?s.length:void 0)&&(p!=null?p.length:void 0)?(u=o(u,p),u.usePathScoring?i.score(s,p,u):c.score(s,p,u)):0},match:function(s,p,u){var m,f,d;return u==null&&(u={}),s?p?s===p?function(){d=[];for(var l=0,h=s.length;0<=h?lh;0<=h?l++:l--)d.push(l);return d}.apply(this):(u=o(u,p),r.match(s,p,u)):[]:[]},wrap:function(s,p,u){return u==null&&(u={}),s?p?(u=o(u,p),r.wrap(s,p,u)):[]:[]},prepareQuery:function(s,p){return p==null&&(p={}),p=o(p,s),p.preparedQuery}},o=function(s,p){return s.allowErrors==null&&(s.allowErrors=!1),s.usePathScoring==null&&(s.usePathScoring=!0),s.useExtensionBonus==null&&(s.useExtensionBonus=!1),s.pathSeparator==null&&(s.pathSeparator=t),s.optCharRegEx==null&&(s.optCharRegEx=null),s.wrap==null&&(s.wrap=null),s.preparedQuery==null&&(s.preparedQuery=a&&a.query===p?a:a=new e(p,s)),s}}).call(ao)});var Cr=Oe((ht,Lr)=>{(function(t,n){typeof ht=="object"&&typeof Lr=="object"?Lr.exports=n():typeof define=="function"&&define.amd?define([],n):typeof ht=="object"?ht.ClipboardJS=n():t.ClipboardJS=n()})(ht,function(){return function(){var e={686:function(r,o,i){"use strict";i.d(o,{default:function(){return X}});var a=i(279),c=i.n(a),s=i(370),p=i.n(s),u=i(817),m=i.n(u);function f(L){try{return document.execCommand(L)}catch(w){return!1}}var d=function(w){var S=m()(w);return f("cut"),S},l=d;function h(L){var w=document.documentElement.getAttribute("dir")==="rtl",S=document.createElement("textarea");S.style.fontSize="12pt",S.style.border="0",S.style.padding="0",S.style.margin="0",S.style.position="absolute",S.style[w?"right":"left"]="-9999px";var _=window.pageYOffset||document.documentElement.scrollTop;return S.style.top="".concat(_,"px"),S.setAttribute("readonly",""),S.value=L,S}var v=function(w,S){var _=h(w);S.container.appendChild(_);var M=m()(_);return f("copy"),_.remove(),M},E=function(w){var S=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},_="";return typeof w=="string"?_=v(w,S):w instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(w==null?void 0:w.type)?_=v(w.value,S):(_=m()(w),f("copy")),_},O=E;function F(L){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?F=function(S){return typeof S}:F=function(S){return S&&typeof Symbol=="function"&&S.constructor===Symbol&&S!==Symbol.prototype?"symbol":typeof S},F(L)}var b=function(){var w=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},S=w.action,_=S===void 0?"copy":S,M=w.container,$=w.target,te=w.text;if(_!=="copy"&&_!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if($!==void 0)if($&&F($)==="object"&&$.nodeType===1){if(_==="copy"&&$.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(_==="cut"&&($.hasAttribute("readonly")||$.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(te)return O(te,{container:M});if($)return _==="cut"?l($):O($,{container:M})},x=b;function T(L){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?T=function(S){return typeof S}:T=function(S){return S&&typeof Symbol=="function"&&S.constructor===Symbol&&S!==Symbol.prototype?"symbol":typeof S},T(L)}function C(L,w){if(!(L instanceof w))throw new TypeError("Cannot call a class as a function")}function g(L,w){for(var S=0;S0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof M.action=="function"?M.action:this.defaultAction,this.target=typeof M.target=="function"?M.target:this.defaultTarget,this.text=typeof M.text=="function"?M.text:this.defaultText,this.container=T(M.container)==="object"?M.container:document.body}},{key:"listenClick",value:function(M){var $=this;this.listener=p()(M,"click",function(te){return $.onClick(te)})}},{key:"onClick",value:function(M){var $=M.delegateTarget||M.currentTarget,te=this.action($)||"copy",Te=x({action:te,container:this.container,target:this.target($),text:this.text($)});this.emit(Te?"success":"error",{action:te,text:Te,trigger:$,clearSelection:function(){$&&$.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(M){return B("action",M)}},{key:"defaultTarget",value:function(M){var $=B("target",M);if($)return document.querySelector($)}},{key:"defaultText",value:function(M){return B("text",M)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(M){var $=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return O(M,$)}},{key:"cut",value:function(M){return l(M)}},{key:"isSupported",value:function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],$=typeof M=="string"?[M]:M,te=!!document.queryCommandSupported;return $.forEach(function(Te){te=te&&!!document.queryCommandSupported(Te)}),te}}]),S}(c()),X=ue},828:function(r){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(c,s){for(;c&&c.nodeType!==o;){if(typeof c.matches=="function"&&c.matches(s))return c;c=c.parentNode}}r.exports=a},438:function(r,o,i){var a=i(828);function c(u,m,f,d,l){var h=p.apply(this,arguments);return u.addEventListener(f,h,l),{destroy:function(){u.removeEventListener(f,h,l)}}}function s(u,m,f,d,l){return typeof u.addEventListener=="function"?c.apply(null,arguments):typeof f=="function"?c.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(h){return c(h,m,f,d,l)}))}function p(u,m,f,d){return function(l){l.delegateTarget=a(l.target,m),l.delegateTarget&&d.call(u,l)}}r.exports=s},879:function(r,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(r,o,i){var a=i(879),c=i(438);function s(f,d,l){if(!f&&!d&&!l)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(l))throw new TypeError("Third argument must be a Function");if(a.node(f))return p(f,d,l);if(a.nodeList(f))return u(f,d,l);if(a.string(f))return m(f,d,l);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(f,d,l){return f.addEventListener(d,l),{destroy:function(){f.removeEventListener(d,l)}}}function u(f,d,l){return Array.prototype.forEach.call(f,function(h){h.addEventListener(d,l)}),{destroy:function(){Array.prototype.forEach.call(f,function(h){h.removeEventListener(d,l)})}}}function m(f,d,l){return c(document.body,f,d,l)}r.exports=s},817:function(r){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var c=i.hasAttribute("readonly");c||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),c||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var s=window.getSelection(),p=document.createRange();p.selectNodeContents(i),s.removeAllRanges(),s.addRange(p),a=s.toString()}return a}r.exports=o},279:function(r){function o(){}o.prototype={on:function(i,a,c){var s=this.e||(this.e={});return(s[i]||(s[i]=[])).push({fn:a,ctx:c}),this},once:function(i,a,c){var s=this;function p(){s.off(i,p),a.apply(c,arguments)}return p._=a,this.on(i,p,c)},emit:function(i){var a=[].slice.call(arguments,1),c=((this.e||(this.e={}))[i]||[]).slice(),s=0,p=c.length;for(s;s{"use strict";var ji=/["'&<>]/;go.exports=zi;function zi(e){var t=""+e,n=ji.exec(t);if(!n)return t;var r,o="",i=0,a=0;for(i=n.index;i0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(n){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,n)},t.prototype._subscribe=function(n){return this._throwIfClosed(),this._checkFinalizedStatuses(n),this._innerSubscribe(n)},t.prototype._innerSubscribe=function(n){var r=this,o=this,i=o.hasError,a=o.isStopped,c=o.observers;return i||a?ir:(this.currentObservers=null,c.push(n),new ye(function(){r.currentObservers=null,_e(c,n)}))},t.prototype._checkFinalizedStatuses=function(n){var r=this,o=r.hasError,i=r.thrownError,a=r.isStopped;o?n.error(i):a&&n.complete()},t.prototype.asObservable=function(){var n=new j;return n.source=this,n},t.create=function(n,r){return new dn(n,r)},t}(j);var dn=function(e){Z(t,e);function t(n,r){var o=e.call(this)||this;return o.destination=n,o.source=r,o}return t.prototype.next=function(n){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.next)===null||o===void 0||o.call(r,n)},t.prototype.error=function(n){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.error)===null||o===void 0||o.call(r,n)},t.prototype.complete=function(){var n,r;(r=(n=this.destination)===null||n===void 0?void 0:n.complete)===null||r===void 0||r.call(n)},t.prototype._subscribe=function(n){var r,o;return(o=(r=this.source)===null||r===void 0?void 0:r.subscribe(n))!==null&&o!==void 0?o:ir},t}(ne);var at={now:function(){return(at.delegate||Date).now()},delegate:void 0};var hn=function(e){Z(t,e);function t(n,r,o){n===void 0&&(n=1/0),r===void 0&&(r=1/0),o===void 0&&(o=at);var i=e.call(this)||this;return i._bufferSize=n,i._windowTime=r,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=r===1/0,i._bufferSize=Math.max(1,n),i._windowTime=Math.max(1,r),i}return t.prototype.next=function(n){var r=this,o=r.isStopped,i=r._buffer,a=r._infiniteTimeWindow,c=r._timestampProvider,s=r._windowTime;o||(i.push(n),!a&&i.push(c.now()+s)),this._trimBuffer(),e.prototype.next.call(this,n)},t.prototype._subscribe=function(n){this._throwIfClosed(),this._trimBuffer();for(var r=this._innerSubscribe(n),o=this,i=o._infiniteTimeWindow,a=o._buffer,c=a.slice(),s=0;s0?e.prototype.requestAsyncId.call(this,n,r,o):(n.actions.push(this),n._scheduled||(n._scheduled=Je.requestAnimationFrame(function(){return n.flush(void 0)})))},t.prototype.recycleAsyncId=function(n,r,o){if(o===void 0&&(o=0),o!=null&&o>0||o==null&&this.delay>0)return e.prototype.recycleAsyncId.call(this,n,r,o);n.actions.some(function(i){return i.id===r})||(Je.cancelAnimationFrame(r),n._scheduled=void 0)},t}(Lt);var gn=function(e){Z(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(n){this._active=!0;var r=this._scheduled;this._scheduled=void 0;var o=this.actions,i;n=n||o.shift();do if(i=n.execute(n.state,n.delay))break;while((n=o[0])&&n.id===r&&o.shift());if(this._active=!1,i){for(;(n=o[0])&&n.id===r&&o.shift();)n.unsubscribe();throw i}},t}(Ct);var ke=new gn(vn);var ve=new j(function(e){return e.complete()});function At(e){return e&&A(e.schedule)}function fr(e){return e[e.length-1]}function Xe(e){return A(fr(e))?e.pop():void 0}function Se(e){return At(fr(e))?e.pop():void 0}function xn(e,t){return typeof fr(e)=="number"?e.pop():t}var Ze=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Ht(e){return A(e==null?void 0:e.then)}function It(e){return A(e[Ge])}function Rt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Wo(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Pt=Wo();function $t(e){return A(e==null?void 0:e[Pt])}function Ft(e){return nn(this,arguments,function(){var n,r,o,i;return St(this,function(a){switch(a.label){case 0:n=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,wt(n.read())];case 3:return r=a.sent(),o=r.value,i=r.done,i?[4,wt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,wt(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return n.releaseLock(),[7];case 10:return[2]}})})}function Wt(e){return A(e==null?void 0:e.getReader)}function z(e){if(e instanceof j)return e;if(e!=null){if(It(e))return Uo(e);if(Ze(e))return jo(e);if(Ht(e))return zo(e);if(Rt(e))return yn(e);if($t(e))return Do(e);if(Wt(e))return Vo(e)}throw kt(e)}function Uo(e){return new j(function(t){var n=e[Ge]();if(A(n.subscribe))return n.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function jo(e){return new j(function(t){for(var n=0;n0&&(u=new Fe({next:function(T){return x.next(T)},error:function(T){h=!0,v(),m=br(E,o,T),x.error(T)},complete:function(){l=!0,v(),m=br(E,a),x.complete()}}),z(F).subscribe(u))})(p)}}function br(e,t){for(var n=[],r=2;rut()||document.body),Ce(1));function nt(e){return si.pipe(I(t=>e.contains(t)),ge())}function Dn(e,t){return Y(ee(e,"mouseenter").pipe(I(()=>!0)),ee(e,"mouseleave").pipe(I(()=>!1))).pipe(t?ze(t):re,de(!1))}function Ve(e){return{x:e.offsetLeft,y:e.offsetTop}}function yr(e){return Y(ee(window,"load"),ee(window,"resize")).pipe(je(0,ke),I(()=>Ve(e)),de(Ve(e)))}function Sr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ae(e){return Y(ee(e,"scroll"),ee(window,"resize")).pipe(je(0,ke),I(()=>Sr(e)),de(Sr(e)))}var Nn=function(){if(typeof Map!="undefined")return Map;function e(t,n){var r=-1;return t.some(function(o,i){return o[0]===n?(r=i,!0):!1}),r}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__ .length},enumerable:!0,configurable:!0}),t.prototype.get=function(n){var r=e(this.__entries__ ,n),o=this.__entries__[r];return o&&o[1]},t.prototype.set=function(n,r){var o=e(this.__entries__ ,n);~o?this.__entries__[o][1]=r:this.__entries__ .push([n,r])},t.prototype.delete=function(n){var r=this.__entries__ ,o=e(r,n);~o&&r.splice(o,1)},t.prototype.has=function(n){return!!~e(this.__entries__ ,n)},t.prototype.clear=function(){this.__entries__ .splice(0)},t.prototype.forEach=function(n,r){r===void 0&&(r=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!wr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),mi?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!wr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var n=t.propertyName,r=n===void 0?"":n,o=li.some(function(i){return!!~r.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Qn=function(e,t){for(var n=0,r=Object.keys(t);n0},e}(),Kn=typeof WeakMap!="undefined"?new WeakMap:new Nn,Yn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var n=di.getInstance(),r=new Ti(t,n,this);Kn.set(this,r)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Yn.prototype[e]=function(){var t;return(t=Kn.get(this))[e].apply(t,arguments)}});var Oi=function(){return typeof Qt.ResizeObserver!="undefined"?Qt.ResizeObserver:Yn}(),Bn=Oi;var _i=new ne,jm=Le(()=>se(new Bn(e=>{for(let t of e)_i.next(t)}))).pipe(oe(e=>Y(pt,se(e)).pipe(me(()=>e.disconnect()))),Ce(1));function Ee(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Yt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function Bt(e){let t=e.parentElement;for(;t&&e.scrollHeight<=t.scrollHeight;)t=(e=t).parentElement;return t?e:void 0}var Gn=new ne,Mi=Le(()=>se(new IntersectionObserver(e=>{for(let t of e)Gn.next(t)},{threshold:0}))).pipe(oe(e=>Y(pt,se(e)).pipe(me(()=>e.disconnect()))),Ce(1));function Gt(e){return Mi.pipe(xe(t=>t.observe(e)),oe(t=>Gn.pipe(ce(({target:n})=>n===e),me(()=>t.unobserve(e)),I(({isIntersecting:n})=>n))))}function Er(e,t=16){return Ae(e).pipe(I(({y:n})=>{let r=Ee(e),o=Yt(e);return n>=o.height-r.height-t}),ge())}var od={drawer:q("[data-md-toggle=drawer]"),search:q("[data-md-toggle=search]")};function Ne(){return new URL(location.href)}function Jn(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let n of t)Jn(e,n)}function D(e,t,...n){let r=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?r.setAttribute(o,t[o]):r.setAttribute(o,""));for(let o of n)Jn(r,o);return r}function Jt(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function Xn(e,t={credentials:"same-origin"}){return le(fetch(`${e}`,t)).pipe(Vt(()=>ve),oe(n=>n.status!==200?lr(()=>new Error(n.statusText)):se(n)))}function Qe(e,t){return Xn(e,t).pipe(oe(n=>n.json()),Ce(1))}function Pe(e,t=document){return q(`[data-mdx-component=${e}]`,t)}function Xt(e,t=document){return ie(`[data-mdx-component=${e}]`,t)}var Li=q("#__config"),ft=JSON.parse(Li.textContent);ft.base=`${new URL(ft.base,Ne())}`;function He(){return ft}function Ie(e,t){return typeof t!="undefined"?ft.translations[e].replace("#",t.toString()):ft.translations[e]}function Zn(e){let t=nt(e),n=Y(ee(e,"keyup"),ee(e,"focus").pipe(hr(1))).pipe(I(()=>e.value),de(e.value),ge());return t.pipe(ce(r=>!r),rt(n)).subscribe(([,r])=>{let o=document.location.pathname;typeof ga=="function"&&r.length&&ga("send","pageview",`${o}?q=[icon]+${r}`)}),we([n,t]).pipe(I(([r,o])=>({ref:e,value:r,focus:o})))}var _r=qe(Or());var po=qe(Or());function co(e,t){return(0,po.wrap)(e.shortcode,t,{wrap:{tagOpen:"",tagClose:""}})}function uo(e,t,n){return D("li",{class:"mdx-iconsearch-result__item"},D("span",{class:"twemoji"},D("img",{src:e.url})),D("button",{class:"md-clipboard--inline",title:Ie("clipboard.copy"),"data-clipboard-text":n?e.shortcode:`:${e.shortcode}:`},D("code",null,n?co(e,t):`:${co(e,t)}:`)))}function fo(e){let t=`@${e.name}`;return D("a",{href:e.url,title:t,class:"mdx-sponsorship__item"},D("img",{src:e.image}))}function lo(e){return D("a",{href:"https://github.com/sponsors/squidfunk",class:"mdx-sponsorship__item mdx-sponsorship__item--private"},"+",e)}function Ci(e,{index$:t,query$:n}){switch(e.getAttribute("data-mdx-mode")){case"file":return we([n.pipe(Nt("value")),t.pipe(I(({icons:r})=>Object.values(r.data).map(o=>o.replace(/\.svg$/,""))))]).pipe(I(([{value:r},o])=>(0,_r.filter)(o,r)),oe(r=>t.pipe(I(({icons:o})=>({data:r.map(i=>({shortcode:i,url:[o.base,i,".svg"].join("")}))})))));default:return we([n.pipe(Nt("value")),t.pipe(I(({icons:r,emojis:o})=>[...Object.keys(r.data),...Object.keys(o.data)]))]).pipe(I(([{value:r},o])=>(0,_r.filter)(o,r)),oe(r=>t.pipe(I(({icons:o,emojis:i})=>({data:r.map(a=>{let c=a in o.data?o:i;return{shortcode:a,url:[c.base,c.data[a]].join("")}})})))))}}function mo(e,{index$:t,query$:n}){let r=new ne,o=Er(e).pipe(ce(Boolean)),i=q(":scope > :first-child",e);r.pipe(rt(n)).subscribe(([{data:s},{value:p}])=>{if(p)switch(s.length){case 0:i.textContent="No matches";break;case 1:i.textContent="1 match";break;default:i.textContent=`${Jt(s.length)} matches`}else i.textContent="Type to start searching"});let a=e.getAttribute("data-mdx-mode")==="file",c=q(":scope > :last-child",e);return r.pipe(xe(()=>c.innerHTML=""),oe(({data:s})=>Y(se(...s.slice(0,10)),se(...s.slice(10)).pipe(mr(10),xr(o),oe(([p])=>p)))),rt(n)).subscribe(([s,{value:p}])=>c.appendChild(uo(s,p,a))),Ci(e,{query$:n,index$:t}).pipe(xe(s=>r.next(s)),me(()=>r.complete()),I(s=>Q({ref:e},s)))}function ho(e){let t=He(),n=Qe(new URL("overrides/assets/javascripts/iconsearch_index.json",t.base)),r=Pe("iconsearch-query",e),o=Pe("iconsearch-result",e),i=Zn(r),a=mo(o,{index$:n,query$:i});return Y(i,a)}function Ai(e){return Y(...ie(":scope [hidden]",e).map(t=>Gt(t).pipe(ce(n=>n),tt(1),I(()=>({active:t})))))}function bo(e){return Le(()=>{let t=new ne;t.subscribe(({active:r})=>{r.hidden=!1}),navigator.userAgent.includes("Gecko/")&&Ae(e).pipe(I(({y:r})=>r>1),ge()).subscribe(r=>{let o=Pe("hero");o.hidden=r});let n=q(":scope > :nth-child(2)",e);return we([Ae(e),yr(n)]).subscribe(([{y:r},o])=>{q("header").classList.toggle("md-header--shadow",r>o.y)}),Ai(e).pipe(xe(r=>t.next(r)),me(()=>t.complete()),I(r=>Q({ref:e},r)))})}function Mr(e,t){return t==="inline"?D("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},D("div",{class:"md-tooltip__inner md-typeset"})):D("div",{class:"md-tooltip",id:e,role:"tooltip"},D("div",{class:"md-tooltip__inner md-typeset"}))}var Hi=0;function Ii(e,t){document.body.append(e);let{width:n}=Ee(e);e.style.setProperty("--md-tooltip-width",`${n}px`),e.remove();let r=Bt(t),o=typeof r!="undefined"?Ae(r):se({x:0,y:0}),i=Y(nt(t),Dn(t));return we([i,o]).pipe(I(([a,c])=>{let{x:s,y:p}=Ve(t),u=Ee(t);return{active:a,offset:{x:s-c.x+u.width/2-n/2,y:p-c.y+u.height+8}}}))}function dt(e){let t=e.title;if(!t.length||e.closest("table"))return ve;let n=`__tooltip_${Hi++}`,r=Mr(n,"inline"),o=q(".md-typeset",r);return o.innerHTML=t,Le(()=>{let i=new ne;return i.subscribe({next({offset:a}){r.style.setProperty("--md-tooltip-x",`${a.x}px`),r.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){r.style.removeProperty("--md-tooltip-x"),r.style.removeProperty("--md-tooltip-y")}}),Y(i.pipe(ce(({active:a})=>a)),i.pipe(ze(250),ce(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",r),e.setAttribute("aria-describedby",n),e.removeAttribute("title")):(r.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){r.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(je(16,ke)).subscribe(({active:a})=>{r.classList.toggle("md-tooltip--active",a)}),i.pipe(gr(125,ke),ce(()=>!!e.offsetParent),I(()=>e.offsetParent.getBoundingClientRect()),I(({x:a})=>a)).subscribe({next(a){a?r.style.setProperty("--md-tooltip-0",`${-a}px`):r.style.removeProperty("--md-tooltip-0")},complete(){r.style.removeProperty("--md-tooltip-0")}}),Ii(r,e).pipe(xe(a=>i.next(a)),me(()=>i.complete()),I(a=>Q({ref:e},a)))}).pipe(We(fe))}var ki=qe(Cr());var yv=D("table");var $i=qe(Cr());var Di=qe(xo());function wo(e){let t=Qe("https://3if8u9o552.execute-api.us-east-1.amazonaws.com/_/"),n=Pe("sponsorship-count"),r=Pe("sponsorship-total");return t.subscribe(o=>{e.removeAttribute("hidden");let i=q(":scope > :first-child",e);for(let a of o.sponsors)if(a.type==="public"){let c=fo(a.user);i.appendChild(c),dt(c).subscribe()}i.appendChild(lo(o.sponsors.filter(({type:a})=>a==="private").length)),n.innerText=`${o.sponsors.length}`,r.innerText=`$ ${o.total.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",")} a month`}),t.pipe(I(o=>Q({ref:e},o)))}function Eo(){let{origin:e}=new URL(location.href);typeof ga!="undefined"&&ee(document.body,"click").subscribe(t=>{if(t.target instanceof HTMLElement){let n=t.target.closest("a");n&&n.origin!==e&&ga("send","event","outbound","click",n.href)}})}Eo();var qi=document$.pipe(oe(()=>Y(...Xt("iconsearch").map(e=>ho(e)),...Xt("parallax").map(e=>bo(e)),...Xt("sponsorship").map(e=>wo(e)))));qi.subscribe();})(); diff --git a/docs/zh/theme/overrides/assets/javascripts/iconsearch_index.json b/docs/zh/theme/overrides/assets/javascripts/iconsearch_index.json new file mode 100644 index 0000000..e8a6e3d --- /dev/null +++ b/docs/zh/theme/overrides/assets/javascripts/iconsearch_index.json @@ -0,0 +1 @@ +{"icons":{"base":"https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/material/.icons/","data":{"fontawesome-brands-42-group":"fontawesome/brands/42-group.svg","fontawesome-brands-500px":"fontawesome/brands/500px.svg","fontawesome-brands-accessible-icon":"fontawesome/brands/accessible-icon.svg","fontawesome-brands-accusoft":"fontawesome/brands/accusoft.svg","fontawesome-brands-adn":"fontawesome/brands/adn.svg","fontawesome-brands-adversal":"fontawesome/brands/adversal.svg","fontawesome-brands-affiliatetheme":"fontawesome/brands/affiliatetheme.svg","fontawesome-brands-airbnb":"fontawesome/brands/airbnb.svg","fontawesome-brands-algolia":"fontawesome/brands/algolia.svg","fontawesome-brands-alipay":"fontawesome/brands/alipay.svg","fontawesome-brands-amazon-pay":"fontawesome/brands/amazon-pay.svg","fontawesome-brands-amazon":"fontawesome/brands/amazon.svg","fontawesome-brands-amilia":"fontawesome/brands/amilia.svg","fontawesome-brands-android":"fontawesome/brands/android.svg","fontawesome-brands-angellist":"fontawesome/brands/angellist.svg","fontawesome-brands-angrycreative":"fontawesome/brands/angrycreative.svg","fontawesome-brands-angular":"fontawesome/brands/angular.svg","fontawesome-brands-app-store-ios":"fontawesome/brands/app-store-ios.svg","fontawesome-brands-app-store":"fontawesome/brands/app-store.svg","fontawesome-brands-apper":"fontawesome/brands/apper.svg","fontawesome-brands-apple-pay":"fontawesome/brands/apple-pay.svg","fontawesome-brands-apple":"fontawesome/brands/apple.svg","fontawesome-brands-artstation":"fontawesome/brands/artstation.svg","fontawesome-brands-asymmetrik":"fontawesome/brands/asymmetrik.svg","fontawesome-brands-atlassian":"fontawesome/brands/atlassian.svg","fontawesome-brands-audible":"fontawesome/brands/audible.svg","fontawesome-brands-autoprefixer":"fontawesome/brands/autoprefixer.svg","fontawesome-brands-avianex":"fontawesome/brands/avianex.svg","fontawesome-brands-aviato":"fontawesome/brands/aviato.svg","fontawesome-brands-aws":"fontawesome/brands/aws.svg","fontawesome-brands-bandcamp":"fontawesome/brands/bandcamp.svg","fontawesome-brands-battle-net":"fontawesome/brands/battle-net.svg","fontawesome-brands-behance":"fontawesome/brands/behance.svg","fontawesome-brands-bilibili":"fontawesome/brands/bilibili.svg","fontawesome-brands-bimobject":"fontawesome/brands/bimobject.svg","fontawesome-brands-bitbucket":"fontawesome/brands/bitbucket.svg","fontawesome-brands-bitcoin":"fontawesome/brands/bitcoin.svg","fontawesome-brands-bity":"fontawesome/brands/bity.svg","fontawesome-brands-black-tie":"fontawesome/brands/black-tie.svg","fontawesome-brands-blackberry":"fontawesome/brands/blackberry.svg","fontawesome-brands-blogger-b":"fontawesome/brands/blogger-b.svg","fontawesome-brands-blogger":"fontawesome/brands/blogger.svg","fontawesome-brands-bluetooth-b":"fontawesome/brands/bluetooth-b.svg","fontawesome-brands-bluetooth":"fontawesome/brands/bluetooth.svg","fontawesome-brands-bootstrap":"fontawesome/brands/bootstrap.svg","fontawesome-brands-bots":"fontawesome/brands/bots.svg","fontawesome-brands-btc":"fontawesome/brands/btc.svg","fontawesome-brands-buffer":"fontawesome/brands/buffer.svg","fontawesome-brands-buromobelexperte":"fontawesome/brands/buromobelexperte.svg","fontawesome-brands-buy-n-large":"fontawesome/brands/buy-n-large.svg","fontawesome-brands-buysellads":"fontawesome/brands/buysellads.svg","fontawesome-brands-canadian-maple-leaf":"fontawesome/brands/canadian-maple-leaf.svg","fontawesome-brands-cc-amazon-pay":"fontawesome/brands/cc-amazon-pay.svg","fontawesome-brands-cc-amex":"fontawesome/brands/cc-amex.svg","fontawesome-brands-cc-apple-pay":"fontawesome/brands/cc-apple-pay.svg","fontawesome-brands-cc-diners-club":"fontawesome/brands/cc-diners-club.svg","fontawesome-brands-cc-discover":"fontawesome/brands/cc-discover.svg","fontawesome-brands-cc-jcb":"fontawesome/brands/cc-jcb.svg","fontawesome-brands-cc-mastercard":"fontawesome/brands/cc-mastercard.svg","fontawesome-brands-cc-paypal":"fontawesome/brands/cc-paypal.svg","fontawesome-brands-cc-stripe":"fontawesome/brands/cc-stripe.svg","fontawesome-brands-cc-visa":"fontawesome/brands/cc-visa.svg","fontawesome-brands-centercode":"fontawesome/brands/centercode.svg","fontawesome-brands-centos":"fontawesome/brands/centos.svg","fontawesome-brands-chrome":"fontawesome/brands/chrome.svg","fontawesome-brands-chromecast":"fontawesome/brands/chromecast.svg","fontawesome-brands-cloudflare":"fontawesome/brands/cloudflare.svg","fontawesome-brands-cloudscale":"fontawesome/brands/cloudscale.svg","fontawesome-brands-cloudsmith":"fontawesome/brands/cloudsmith.svg","fontawesome-brands-cloudversify":"fontawesome/brands/cloudversify.svg","fontawesome-brands-cmplid":"fontawesome/brands/cmplid.svg","fontawesome-brands-codepen":"fontawesome/brands/codepen.svg","fontawesome-brands-codiepie":"fontawesome/brands/codiepie.svg","fontawesome-brands-confluence":"fontawesome/brands/confluence.svg","fontawesome-brands-connectdevelop":"fontawesome/brands/connectdevelop.svg","fontawesome-brands-contao":"fontawesome/brands/contao.svg","fontawesome-brands-cotton-bureau":"fontawesome/brands/cotton-bureau.svg","fontawesome-brands-cpanel":"fontawesome/brands/cpanel.svg","fontawesome-brands-creative-commons-by":"fontawesome/brands/creative-commons-by.svg","fontawesome-brands-creative-commons-nc-eu":"fontawesome/brands/creative-commons-nc-eu.svg","fontawesome-brands-creative-commons-nc-jp":"fontawesome/brands/creative-commons-nc-jp.svg","fontawesome-brands-creative-commons-nc":"fontawesome/brands/creative-commons-nc.svg","fontawesome-brands-creative-commons-nd":"fontawesome/brands/creative-commons-nd.svg","fontawesome-brands-creative-commons-pd-alt":"fontawesome/brands/creative-commons-pd-alt.svg","fontawesome-brands-creative-commons-pd":"fontawesome/brands/creative-commons-pd.svg","fontawesome-brands-creative-commons-remix":"fontawesome/brands/creative-commons-remix.svg","fontawesome-brands-creative-commons-sa":"fontawesome/brands/creative-commons-sa.svg","fontawesome-brands-creative-commons-sampling-plus":"fontawesome/brands/creative-commons-sampling-plus.svg","fontawesome-brands-creative-commons-sampling":"fontawesome/brands/creative-commons-sampling.svg","fontawesome-brands-creative-commons-share":"fontawesome/brands/creative-commons-share.svg","fontawesome-brands-creative-commons-zero":"fontawesome/brands/creative-commons-zero.svg","fontawesome-brands-creative-commons":"fontawesome/brands/creative-commons.svg","fontawesome-brands-critical-role":"fontawesome/brands/critical-role.svg","fontawesome-brands-css3-alt":"fontawesome/brands/css3-alt.svg","fontawesome-brands-css3":"fontawesome/brands/css3.svg","fontawesome-brands-cuttlefish":"fontawesome/brands/cuttlefish.svg","fontawesome-brands-d-and-d-beyond":"fontawesome/brands/d-and-d-beyond.svg","fontawesome-brands-d-and-d":"fontawesome/brands/d-and-d.svg","fontawesome-brands-dailymotion":"fontawesome/brands/dailymotion.svg","fontawesome-brands-dashcube":"fontawesome/brands/dashcube.svg","fontawesome-brands-deezer":"fontawesome/brands/deezer.svg","fontawesome-brands-delicious":"fontawesome/brands/delicious.svg","fontawesome-brands-deploydog":"fontawesome/brands/deploydog.svg","fontawesome-brands-deskpro":"fontawesome/brands/deskpro.svg","fontawesome-brands-dev":"fontawesome/brands/dev.svg","fontawesome-brands-deviantart":"fontawesome/brands/deviantart.svg","fontawesome-brands-dhl":"fontawesome/brands/dhl.svg","fontawesome-brands-diaspora":"fontawesome/brands/diaspora.svg","fontawesome-brands-digg":"fontawesome/brands/digg.svg","fontawesome-brands-digital-ocean":"fontawesome/brands/digital-ocean.svg","fontawesome-brands-discord":"fontawesome/brands/discord.svg","fontawesome-brands-discourse":"fontawesome/brands/discourse.svg","fontawesome-brands-dochub":"fontawesome/brands/dochub.svg","fontawesome-brands-docker":"fontawesome/brands/docker.svg","fontawesome-brands-draft2digital":"fontawesome/brands/draft2digital.svg","fontawesome-brands-dribbble":"fontawesome/brands/dribbble.svg","fontawesome-brands-dropbox":"fontawesome/brands/dropbox.svg","fontawesome-brands-drupal":"fontawesome/brands/drupal.svg","fontawesome-brands-dyalog":"fontawesome/brands/dyalog.svg","fontawesome-brands-earlybirds":"fontawesome/brands/earlybirds.svg","fontawesome-brands-ebay":"fontawesome/brands/ebay.svg","fontawesome-brands-edge-legacy":"fontawesome/brands/edge-legacy.svg","fontawesome-brands-edge":"fontawesome/brands/edge.svg","fontawesome-brands-elementor":"fontawesome/brands/elementor.svg","fontawesome-brands-ello":"fontawesome/brands/ello.svg","fontawesome-brands-ember":"fontawesome/brands/ember.svg","fontawesome-brands-empire":"fontawesome/brands/empire.svg","fontawesome-brands-envira":"fontawesome/brands/envira.svg","fontawesome-brands-erlang":"fontawesome/brands/erlang.svg","fontawesome-brands-ethereum":"fontawesome/brands/ethereum.svg","fontawesome-brands-etsy":"fontawesome/brands/etsy.svg","fontawesome-brands-evernote":"fontawesome/brands/evernote.svg","fontawesome-brands-expeditedssl":"fontawesome/brands/expeditedssl.svg","fontawesome-brands-facebook-f":"fontawesome/brands/facebook-f.svg","fontawesome-brands-facebook-messenger":"fontawesome/brands/facebook-messenger.svg","fontawesome-brands-facebook":"fontawesome/brands/facebook.svg","fontawesome-brands-fantasy-flight-games":"fontawesome/brands/fantasy-flight-games.svg","fontawesome-brands-fedex":"fontawesome/brands/fedex.svg","fontawesome-brands-fedora":"fontawesome/brands/fedora.svg","fontawesome-brands-figma":"fontawesome/brands/figma.svg","fontawesome-brands-firefox-browser":"fontawesome/brands/firefox-browser.svg","fontawesome-brands-firefox":"fontawesome/brands/firefox.svg","fontawesome-brands-first-order-alt":"fontawesome/brands/first-order-alt.svg","fontawesome-brands-first-order":"fontawesome/brands/first-order.svg","fontawesome-brands-firstdraft":"fontawesome/brands/firstdraft.svg","fontawesome-brands-flickr":"fontawesome/brands/flickr.svg","fontawesome-brands-flipboard":"fontawesome/brands/flipboard.svg","fontawesome-brands-fly":"fontawesome/brands/fly.svg","fontawesome-brands-font-awesome":"fontawesome/brands/font-awesome.svg","fontawesome-brands-fonticons-fi":"fontawesome/brands/fonticons-fi.svg","fontawesome-brands-fonticons":"fontawesome/brands/fonticons.svg","fontawesome-brands-fort-awesome-alt":"fontawesome/brands/fort-awesome-alt.svg","fontawesome-brands-fort-awesome":"fontawesome/brands/fort-awesome.svg","fontawesome-brands-forumbee":"fontawesome/brands/forumbee.svg","fontawesome-brands-foursquare":"fontawesome/brands/foursquare.svg","fontawesome-brands-free-code-camp":"fontawesome/brands/free-code-camp.svg","fontawesome-brands-freebsd":"fontawesome/brands/freebsd.svg","fontawesome-brands-fulcrum":"fontawesome/brands/fulcrum.svg","fontawesome-brands-galactic-republic":"fontawesome/brands/galactic-republic.svg","fontawesome-brands-galactic-senate":"fontawesome/brands/galactic-senate.svg","fontawesome-brands-get-pocket":"fontawesome/brands/get-pocket.svg","fontawesome-brands-gg-circle":"fontawesome/brands/gg-circle.svg","fontawesome-brands-gg":"fontawesome/brands/gg.svg","fontawesome-brands-git-alt":"fontawesome/brands/git-alt.svg","fontawesome-brands-git":"fontawesome/brands/git.svg","fontawesome-brands-github-alt":"fontawesome/brands/github-alt.svg","fontawesome-brands-github":"fontawesome/brands/github.svg","fontawesome-brands-gitkraken":"fontawesome/brands/gitkraken.svg","fontawesome-brands-gitlab":"fontawesome/brands/gitlab.svg","fontawesome-brands-gitter":"fontawesome/brands/gitter.svg","fontawesome-brands-glide-g":"fontawesome/brands/glide-g.svg","fontawesome-brands-glide":"fontawesome/brands/glide.svg","fontawesome-brands-gofore":"fontawesome/brands/gofore.svg","fontawesome-brands-golang":"fontawesome/brands/golang.svg","fontawesome-brands-goodreads-g":"fontawesome/brands/goodreads-g.svg","fontawesome-brands-goodreads":"fontawesome/brands/goodreads.svg","fontawesome-brands-google-drive":"fontawesome/brands/google-drive.svg","fontawesome-brands-google-pay":"fontawesome/brands/google-pay.svg","fontawesome-brands-google-play":"fontawesome/brands/google-play.svg","fontawesome-brands-google-plus-g":"fontawesome/brands/google-plus-g.svg","fontawesome-brands-google-plus":"fontawesome/brands/google-plus.svg","fontawesome-brands-google-wallet":"fontawesome/brands/google-wallet.svg","fontawesome-brands-google":"fontawesome/brands/google.svg","fontawesome-brands-gratipay":"fontawesome/brands/gratipay.svg","fontawesome-brands-grav":"fontawesome/brands/grav.svg","fontawesome-brands-gripfire":"fontawesome/brands/gripfire.svg","fontawesome-brands-grunt":"fontawesome/brands/grunt.svg","fontawesome-brands-guilded":"fontawesome/brands/guilded.svg","fontawesome-brands-gulp":"fontawesome/brands/gulp.svg","fontawesome-brands-hacker-news":"fontawesome/brands/hacker-news.svg","fontawesome-brands-hackerrank":"fontawesome/brands/hackerrank.svg","fontawesome-brands-hashnode":"fontawesome/brands/hashnode.svg","fontawesome-brands-hips":"fontawesome/brands/hips.svg","fontawesome-brands-hire-a-helper":"fontawesome/brands/hire-a-helper.svg","fontawesome-brands-hive":"fontawesome/brands/hive.svg","fontawesome-brands-hooli":"fontawesome/brands/hooli.svg","fontawesome-brands-hornbill":"fontawesome/brands/hornbill.svg","fontawesome-brands-hotjar":"fontawesome/brands/hotjar.svg","fontawesome-brands-houzz":"fontawesome/brands/houzz.svg","fontawesome-brands-html5":"fontawesome/brands/html5.svg","fontawesome-brands-hubspot":"fontawesome/brands/hubspot.svg","fontawesome-brands-ideal":"fontawesome/brands/ideal.svg","fontawesome-brands-imdb":"fontawesome/brands/imdb.svg","fontawesome-brands-instagram":"fontawesome/brands/instagram.svg","fontawesome-brands-instalod":"fontawesome/brands/instalod.svg","fontawesome-brands-intercom":"fontawesome/brands/intercom.svg","fontawesome-brands-internet-explorer":"fontawesome/brands/internet-explorer.svg","fontawesome-brands-invision":"fontawesome/brands/invision.svg","fontawesome-brands-ioxhost":"fontawesome/brands/ioxhost.svg","fontawesome-brands-itch-io":"fontawesome/brands/itch-io.svg","fontawesome-brands-itunes-note":"fontawesome/brands/itunes-note.svg","fontawesome-brands-itunes":"fontawesome/brands/itunes.svg","fontawesome-brands-java":"fontawesome/brands/java.svg","fontawesome-brands-jedi-order":"fontawesome/brands/jedi-order.svg","fontawesome-brands-jenkins":"fontawesome/brands/jenkins.svg","fontawesome-brands-jira":"fontawesome/brands/jira.svg","fontawesome-brands-joget":"fontawesome/brands/joget.svg","fontawesome-brands-joomla":"fontawesome/brands/joomla.svg","fontawesome-brands-js":"fontawesome/brands/js.svg","fontawesome-brands-jsfiddle":"fontawesome/brands/jsfiddle.svg","fontawesome-brands-kaggle":"fontawesome/brands/kaggle.svg","fontawesome-brands-keybase":"fontawesome/brands/keybase.svg","fontawesome-brands-keycdn":"fontawesome/brands/keycdn.svg","fontawesome-brands-kickstarter-k":"fontawesome/brands/kickstarter-k.svg","fontawesome-brands-kickstarter":"fontawesome/brands/kickstarter.svg","fontawesome-brands-korvue":"fontawesome/brands/korvue.svg","fontawesome-brands-laravel":"fontawesome/brands/laravel.svg","fontawesome-brands-lastfm":"fontawesome/brands/lastfm.svg","fontawesome-brands-leanpub":"fontawesome/brands/leanpub.svg","fontawesome-brands-less":"fontawesome/brands/less.svg","fontawesome-brands-line":"fontawesome/brands/line.svg","fontawesome-brands-linkedin-in":"fontawesome/brands/linkedin-in.svg","fontawesome-brands-linkedin":"fontawesome/brands/linkedin.svg","fontawesome-brands-linode":"fontawesome/brands/linode.svg","fontawesome-brands-linux":"fontawesome/brands/linux.svg","fontawesome-brands-lyft":"fontawesome/brands/lyft.svg","fontawesome-brands-magento":"fontawesome/brands/magento.svg","fontawesome-brands-mailchimp":"fontawesome/brands/mailchimp.svg","fontawesome-brands-mandalorian":"fontawesome/brands/mandalorian.svg","fontawesome-brands-markdown":"fontawesome/brands/markdown.svg","fontawesome-brands-mastodon":"fontawesome/brands/mastodon.svg","fontawesome-brands-maxcdn":"fontawesome/brands/maxcdn.svg","fontawesome-brands-mdb":"fontawesome/brands/mdb.svg","fontawesome-brands-medapps":"fontawesome/brands/medapps.svg","fontawesome-brands-medium":"fontawesome/brands/medium.svg","fontawesome-brands-medrt":"fontawesome/brands/medrt.svg","fontawesome-brands-meetup":"fontawesome/brands/meetup.svg","fontawesome-brands-megaport":"fontawesome/brands/megaport.svg","fontawesome-brands-mendeley":"fontawesome/brands/mendeley.svg","fontawesome-brands-meta":"fontawesome/brands/meta.svg","fontawesome-brands-microblog":"fontawesome/brands/microblog.svg","fontawesome-brands-microsoft":"fontawesome/brands/microsoft.svg","fontawesome-brands-mix":"fontawesome/brands/mix.svg","fontawesome-brands-mixcloud":"fontawesome/brands/mixcloud.svg","fontawesome-brands-mixer":"fontawesome/brands/mixer.svg","fontawesome-brands-mizuni":"fontawesome/brands/mizuni.svg","fontawesome-brands-modx":"fontawesome/brands/modx.svg","fontawesome-brands-monero":"fontawesome/brands/monero.svg","fontawesome-brands-napster":"fontawesome/brands/napster.svg","fontawesome-brands-neos":"fontawesome/brands/neos.svg","fontawesome-brands-nfc-directional":"fontawesome/brands/nfc-directional.svg","fontawesome-brands-nfc-symbol":"fontawesome/brands/nfc-symbol.svg","fontawesome-brands-nimblr":"fontawesome/brands/nimblr.svg","fontawesome-brands-node-js":"fontawesome/brands/node-js.svg","fontawesome-brands-node":"fontawesome/brands/node.svg","fontawesome-brands-npm":"fontawesome/brands/npm.svg","fontawesome-brands-ns8":"fontawesome/brands/ns8.svg","fontawesome-brands-nutritionix":"fontawesome/brands/nutritionix.svg","fontawesome-brands-octopus-deploy":"fontawesome/brands/octopus-deploy.svg","fontawesome-brands-odnoklassniki":"fontawesome/brands/odnoklassniki.svg","fontawesome-brands-old-republic":"fontawesome/brands/old-republic.svg","fontawesome-brands-opencart":"fontawesome/brands/opencart.svg","fontawesome-brands-openid":"fontawesome/brands/openid.svg","fontawesome-brands-opera":"fontawesome/brands/opera.svg","fontawesome-brands-optin-monster":"fontawesome/brands/optin-monster.svg","fontawesome-brands-orcid":"fontawesome/brands/orcid.svg","fontawesome-brands-osi":"fontawesome/brands/osi.svg","fontawesome-brands-padlet":"fontawesome/brands/padlet.svg","fontawesome-brands-page4":"fontawesome/brands/page4.svg","fontawesome-brands-pagelines":"fontawesome/brands/pagelines.svg","fontawesome-brands-palfed":"fontawesome/brands/palfed.svg","fontawesome-brands-patreon":"fontawesome/brands/patreon.svg","fontawesome-brands-paypal":"fontawesome/brands/paypal.svg","fontawesome-brands-perbyte":"fontawesome/brands/perbyte.svg","fontawesome-brands-periscope":"fontawesome/brands/periscope.svg","fontawesome-brands-phabricator":"fontawesome/brands/phabricator.svg","fontawesome-brands-phoenix-framework":"fontawesome/brands/phoenix-framework.svg","fontawesome-brands-phoenix-squadron":"fontawesome/brands/phoenix-squadron.svg","fontawesome-brands-php":"fontawesome/brands/php.svg","fontawesome-brands-pied-piper-alt":"fontawesome/brands/pied-piper-alt.svg","fontawesome-brands-pied-piper-hat":"fontawesome/brands/pied-piper-hat.svg","fontawesome-brands-pied-piper-pp":"fontawesome/brands/pied-piper-pp.svg","fontawesome-brands-pied-piper":"fontawesome/brands/pied-piper.svg","fontawesome-brands-pinterest-p":"fontawesome/brands/pinterest-p.svg","fontawesome-brands-pinterest":"fontawesome/brands/pinterest.svg","fontawesome-brands-pix":"fontawesome/brands/pix.svg","fontawesome-brands-playstation":"fontawesome/brands/playstation.svg","fontawesome-brands-product-hunt":"fontawesome/brands/product-hunt.svg","fontawesome-brands-pushed":"fontawesome/brands/pushed.svg","fontawesome-brands-python":"fontawesome/brands/python.svg","fontawesome-brands-qq":"fontawesome/brands/qq.svg","fontawesome-brands-quinscape":"fontawesome/brands/quinscape.svg","fontawesome-brands-quora":"fontawesome/brands/quora.svg","fontawesome-brands-r-project":"fontawesome/brands/r-project.svg","fontawesome-brands-raspberry-pi":"fontawesome/brands/raspberry-pi.svg","fontawesome-brands-ravelry":"fontawesome/brands/ravelry.svg","fontawesome-brands-react":"fontawesome/brands/react.svg","fontawesome-brands-reacteurope":"fontawesome/brands/reacteurope.svg","fontawesome-brands-readme":"fontawesome/brands/readme.svg","fontawesome-brands-rebel":"fontawesome/brands/rebel.svg","fontawesome-brands-red-river":"fontawesome/brands/red-river.svg","fontawesome-brands-reddit-alien":"fontawesome/brands/reddit-alien.svg","fontawesome-brands-reddit":"fontawesome/brands/reddit.svg","fontawesome-brands-redhat":"fontawesome/brands/redhat.svg","fontawesome-brands-renren":"fontawesome/brands/renren.svg","fontawesome-brands-replyd":"fontawesome/brands/replyd.svg","fontawesome-brands-researchgate":"fontawesome/brands/researchgate.svg","fontawesome-brands-resolving":"fontawesome/brands/resolving.svg","fontawesome-brands-rev":"fontawesome/brands/rev.svg","fontawesome-brands-rocketchat":"fontawesome/brands/rocketchat.svg","fontawesome-brands-rockrms":"fontawesome/brands/rockrms.svg","fontawesome-brands-rust":"fontawesome/brands/rust.svg","fontawesome-brands-safari":"fontawesome/brands/safari.svg","fontawesome-brands-salesforce":"fontawesome/brands/salesforce.svg","fontawesome-brands-sass":"fontawesome/brands/sass.svg","fontawesome-brands-schlix":"fontawesome/brands/schlix.svg","fontawesome-brands-screenpal":"fontawesome/brands/screenpal.svg","fontawesome-brands-scribd":"fontawesome/brands/scribd.svg","fontawesome-brands-searchengin":"fontawesome/brands/searchengin.svg","fontawesome-brands-sellcast":"fontawesome/brands/sellcast.svg","fontawesome-brands-sellsy":"fontawesome/brands/sellsy.svg","fontawesome-brands-servicestack":"fontawesome/brands/servicestack.svg","fontawesome-brands-shirtsinbulk":"fontawesome/brands/shirtsinbulk.svg","fontawesome-brands-shopify":"fontawesome/brands/shopify.svg","fontawesome-brands-shopware":"fontawesome/brands/shopware.svg","fontawesome-brands-simplybuilt":"fontawesome/brands/simplybuilt.svg","fontawesome-brands-sistrix":"fontawesome/brands/sistrix.svg","fontawesome-brands-sith":"fontawesome/brands/sith.svg","fontawesome-brands-sitrox":"fontawesome/brands/sitrox.svg","fontawesome-brands-sketch":"fontawesome/brands/sketch.svg","fontawesome-brands-skyatlas":"fontawesome/brands/skyatlas.svg","fontawesome-brands-skype":"fontawesome/brands/skype.svg","fontawesome-brands-slack":"fontawesome/brands/slack.svg","fontawesome-brands-slideshare":"fontawesome/brands/slideshare.svg","fontawesome-brands-snapchat":"fontawesome/brands/snapchat.svg","fontawesome-brands-soundcloud":"fontawesome/brands/soundcloud.svg","fontawesome-brands-sourcetree":"fontawesome/brands/sourcetree.svg","fontawesome-brands-space-awesome":"fontawesome/brands/space-awesome.svg","fontawesome-brands-speakap":"fontawesome/brands/speakap.svg","fontawesome-brands-speaker-deck":"fontawesome/brands/speaker-deck.svg","fontawesome-brands-spotify":"fontawesome/brands/spotify.svg","fontawesome-brands-square-behance":"fontawesome/brands/square-behance.svg","fontawesome-brands-square-dribbble":"fontawesome/brands/square-dribbble.svg","fontawesome-brands-square-facebook":"fontawesome/brands/square-facebook.svg","fontawesome-brands-square-font-awesome-stroke":"fontawesome/brands/square-font-awesome-stroke.svg","fontawesome-brands-square-font-awesome":"fontawesome/brands/square-font-awesome.svg","fontawesome-brands-square-git":"fontawesome/brands/square-git.svg","fontawesome-brands-square-github":"fontawesome/brands/square-github.svg","fontawesome-brands-square-gitlab":"fontawesome/brands/square-gitlab.svg","fontawesome-brands-square-google-plus":"fontawesome/brands/square-google-plus.svg","fontawesome-brands-square-hacker-news":"fontawesome/brands/square-hacker-news.svg","fontawesome-brands-square-instagram":"fontawesome/brands/square-instagram.svg","fontawesome-brands-square-js":"fontawesome/brands/square-js.svg","fontawesome-brands-square-lastfm":"fontawesome/brands/square-lastfm.svg","fontawesome-brands-square-odnoklassniki":"fontawesome/brands/square-odnoklassniki.svg","fontawesome-brands-square-pied-piper":"fontawesome/brands/square-pied-piper.svg","fontawesome-brands-square-pinterest":"fontawesome/brands/square-pinterest.svg","fontawesome-brands-square-reddit":"fontawesome/brands/square-reddit.svg","fontawesome-brands-square-snapchat":"fontawesome/brands/square-snapchat.svg","fontawesome-brands-square-steam":"fontawesome/brands/square-steam.svg","fontawesome-brands-square-tumblr":"fontawesome/brands/square-tumblr.svg","fontawesome-brands-square-twitter":"fontawesome/brands/square-twitter.svg","fontawesome-brands-square-viadeo":"fontawesome/brands/square-viadeo.svg","fontawesome-brands-square-vimeo":"fontawesome/brands/square-vimeo.svg","fontawesome-brands-square-whatsapp":"fontawesome/brands/square-whatsapp.svg","fontawesome-brands-square-xing":"fontawesome/brands/square-xing.svg","fontawesome-brands-square-youtube":"fontawesome/brands/square-youtube.svg","fontawesome-brands-squarespace":"fontawesome/brands/squarespace.svg","fontawesome-brands-stack-exchange":"fontawesome/brands/stack-exchange.svg","fontawesome-brands-stack-overflow":"fontawesome/brands/stack-overflow.svg","fontawesome-brands-stackpath":"fontawesome/brands/stackpath.svg","fontawesome-brands-staylinked":"fontawesome/brands/staylinked.svg","fontawesome-brands-steam-symbol":"fontawesome/brands/steam-symbol.svg","fontawesome-brands-steam":"fontawesome/brands/steam.svg","fontawesome-brands-sticker-mule":"fontawesome/brands/sticker-mule.svg","fontawesome-brands-strava":"fontawesome/brands/strava.svg","fontawesome-brands-stripe-s":"fontawesome/brands/stripe-s.svg","fontawesome-brands-stripe":"fontawesome/brands/stripe.svg","fontawesome-brands-studiovinari":"fontawesome/brands/studiovinari.svg","fontawesome-brands-stumbleupon-circle":"fontawesome/brands/stumbleupon-circle.svg","fontawesome-brands-stumbleupon":"fontawesome/brands/stumbleupon.svg","fontawesome-brands-superpowers":"fontawesome/brands/superpowers.svg","fontawesome-brands-supple":"fontawesome/brands/supple.svg","fontawesome-brands-suse":"fontawesome/brands/suse.svg","fontawesome-brands-swift":"fontawesome/brands/swift.svg","fontawesome-brands-symfony":"fontawesome/brands/symfony.svg","fontawesome-brands-teamspeak":"fontawesome/brands/teamspeak.svg","fontawesome-brands-telegram":"fontawesome/brands/telegram.svg","fontawesome-brands-tencent-weibo":"fontawesome/brands/tencent-weibo.svg","fontawesome-brands-the-red-yeti":"fontawesome/brands/the-red-yeti.svg","fontawesome-brands-themeco":"fontawesome/brands/themeco.svg","fontawesome-brands-themeisle":"fontawesome/brands/themeisle.svg","fontawesome-brands-think-peaks":"fontawesome/brands/think-peaks.svg","fontawesome-brands-tiktok":"fontawesome/brands/tiktok.svg","fontawesome-brands-trade-federation":"fontawesome/brands/trade-federation.svg","fontawesome-brands-trello":"fontawesome/brands/trello.svg","fontawesome-brands-tumblr":"fontawesome/brands/tumblr.svg","fontawesome-brands-twitch":"fontawesome/brands/twitch.svg","fontawesome-brands-twitter":"fontawesome/brands/twitter.svg","fontawesome-brands-typo3":"fontawesome/brands/typo3.svg","fontawesome-brands-uber":"fontawesome/brands/uber.svg","fontawesome-brands-ubuntu":"fontawesome/brands/ubuntu.svg","fontawesome-brands-uikit":"fontawesome/brands/uikit.svg","fontawesome-brands-umbraco":"fontawesome/brands/umbraco.svg","fontawesome-brands-uncharted":"fontawesome/brands/uncharted.svg","fontawesome-brands-uniregistry":"fontawesome/brands/uniregistry.svg","fontawesome-brands-unity":"fontawesome/brands/unity.svg","fontawesome-brands-unsplash":"fontawesome/brands/unsplash.svg","fontawesome-brands-untappd":"fontawesome/brands/untappd.svg","fontawesome-brands-ups":"fontawesome/brands/ups.svg","fontawesome-brands-usb":"fontawesome/brands/usb.svg","fontawesome-brands-usps":"fontawesome/brands/usps.svg","fontawesome-brands-ussunnah":"fontawesome/brands/ussunnah.svg","fontawesome-brands-vaadin":"fontawesome/brands/vaadin.svg","fontawesome-brands-viacoin":"fontawesome/brands/viacoin.svg","fontawesome-brands-viadeo":"fontawesome/brands/viadeo.svg","fontawesome-brands-viber":"fontawesome/brands/viber.svg","fontawesome-brands-vimeo-v":"fontawesome/brands/vimeo-v.svg","fontawesome-brands-vimeo":"fontawesome/brands/vimeo.svg","fontawesome-brands-vine":"fontawesome/brands/vine.svg","fontawesome-brands-vk":"fontawesome/brands/vk.svg","fontawesome-brands-vnv":"fontawesome/brands/vnv.svg","fontawesome-brands-vuejs":"fontawesome/brands/vuejs.svg","fontawesome-brands-watchman-monitoring":"fontawesome/brands/watchman-monitoring.svg","fontawesome-brands-waze":"fontawesome/brands/waze.svg","fontawesome-brands-weebly":"fontawesome/brands/weebly.svg","fontawesome-brands-weibo":"fontawesome/brands/weibo.svg","fontawesome-brands-weixin":"fontawesome/brands/weixin.svg","fontawesome-brands-whatsapp":"fontawesome/brands/whatsapp.svg","fontawesome-brands-whmcs":"fontawesome/brands/whmcs.svg","fontawesome-brands-wikipedia-w":"fontawesome/brands/wikipedia-w.svg","fontawesome-brands-windows":"fontawesome/brands/windows.svg","fontawesome-brands-wirsindhandwerk":"fontawesome/brands/wirsindhandwerk.svg","fontawesome-brands-wix":"fontawesome/brands/wix.svg","fontawesome-brands-wizards-of-the-coast":"fontawesome/brands/wizards-of-the-coast.svg","fontawesome-brands-wodu":"fontawesome/brands/wodu.svg","fontawesome-brands-wolf-pack-battalion":"fontawesome/brands/wolf-pack-battalion.svg","fontawesome-brands-wordpress-simple":"fontawesome/brands/wordpress-simple.svg","fontawesome-brands-wordpress":"fontawesome/brands/wordpress.svg","fontawesome-brands-wpbeginner":"fontawesome/brands/wpbeginner.svg","fontawesome-brands-wpexplorer":"fontawesome/brands/wpexplorer.svg","fontawesome-brands-wpforms":"fontawesome/brands/wpforms.svg","fontawesome-brands-wpressr":"fontawesome/brands/wpressr.svg","fontawesome-brands-xbox":"fontawesome/brands/xbox.svg","fontawesome-brands-xing":"fontawesome/brands/xing.svg","fontawesome-brands-y-combinator":"fontawesome/brands/y-combinator.svg","fontawesome-brands-yahoo":"fontawesome/brands/yahoo.svg","fontawesome-brands-yammer":"fontawesome/brands/yammer.svg","fontawesome-brands-yandex-international":"fontawesome/brands/yandex-international.svg","fontawesome-brands-yandex":"fontawesome/brands/yandex.svg","fontawesome-brands-yarn":"fontawesome/brands/yarn.svg","fontawesome-brands-yelp":"fontawesome/brands/yelp.svg","fontawesome-brands-yoast":"fontawesome/brands/yoast.svg","fontawesome-brands-youtube":"fontawesome/brands/youtube.svg","fontawesome-brands-zhihu":"fontawesome/brands/zhihu.svg","fontawesome-regular-address-book":"fontawesome/regular/address-book.svg","fontawesome-regular-address-card":"fontawesome/regular/address-card.svg","fontawesome-regular-bell-slash":"fontawesome/regular/bell-slash.svg","fontawesome-regular-bell":"fontawesome/regular/bell.svg","fontawesome-regular-bookmark":"fontawesome/regular/bookmark.svg","fontawesome-regular-building":"fontawesome/regular/building.svg","fontawesome-regular-calendar-check":"fontawesome/regular/calendar-check.svg","fontawesome-regular-calendar-days":"fontawesome/regular/calendar-days.svg","fontawesome-regular-calendar-minus":"fontawesome/regular/calendar-minus.svg","fontawesome-regular-calendar-plus":"fontawesome/regular/calendar-plus.svg","fontawesome-regular-calendar-xmark":"fontawesome/regular/calendar-xmark.svg","fontawesome-regular-calendar":"fontawesome/regular/calendar.svg","fontawesome-regular-chart-bar":"fontawesome/regular/chart-bar.svg","fontawesome-regular-chess-bishop":"fontawesome/regular/chess-bishop.svg","fontawesome-regular-chess-king":"fontawesome/regular/chess-king.svg","fontawesome-regular-chess-knight":"fontawesome/regular/chess-knight.svg","fontawesome-regular-chess-pawn":"fontawesome/regular/chess-pawn.svg","fontawesome-regular-chess-queen":"fontawesome/regular/chess-queen.svg","fontawesome-regular-chess-rook":"fontawesome/regular/chess-rook.svg","fontawesome-regular-circle-check":"fontawesome/regular/circle-check.svg","fontawesome-regular-circle-dot":"fontawesome/regular/circle-dot.svg","fontawesome-regular-circle-down":"fontawesome/regular/circle-down.svg","fontawesome-regular-circle-left":"fontawesome/regular/circle-left.svg","fontawesome-regular-circle-pause":"fontawesome/regular/circle-pause.svg","fontawesome-regular-circle-play":"fontawesome/regular/circle-play.svg","fontawesome-regular-circle-question":"fontawesome/regular/circle-question.svg","fontawesome-regular-circle-right":"fontawesome/regular/circle-right.svg","fontawesome-regular-circle-stop":"fontawesome/regular/circle-stop.svg","fontawesome-regular-circle-up":"fontawesome/regular/circle-up.svg","fontawesome-regular-circle-user":"fontawesome/regular/circle-user.svg","fontawesome-regular-circle-xmark":"fontawesome/regular/circle-xmark.svg","fontawesome-regular-circle":"fontawesome/regular/circle.svg","fontawesome-regular-clipboard":"fontawesome/regular/clipboard.svg","fontawesome-regular-clock":"fontawesome/regular/clock.svg","fontawesome-regular-clone":"fontawesome/regular/clone.svg","fontawesome-regular-closed-captioning":"fontawesome/regular/closed-captioning.svg","fontawesome-regular-comment-dots":"fontawesome/regular/comment-dots.svg","fontawesome-regular-comment":"fontawesome/regular/comment.svg","fontawesome-regular-comments":"fontawesome/regular/comments.svg","fontawesome-regular-compass":"fontawesome/regular/compass.svg","fontawesome-regular-copy":"fontawesome/regular/copy.svg","fontawesome-regular-copyright":"fontawesome/regular/copyright.svg","fontawesome-regular-credit-card":"fontawesome/regular/credit-card.svg","fontawesome-regular-envelope-open":"fontawesome/regular/envelope-open.svg","fontawesome-regular-envelope":"fontawesome/regular/envelope.svg","fontawesome-regular-eye-slash":"fontawesome/regular/eye-slash.svg","fontawesome-regular-eye":"fontawesome/regular/eye.svg","fontawesome-regular-face-angry":"fontawesome/regular/face-angry.svg","fontawesome-regular-face-dizzy":"fontawesome/regular/face-dizzy.svg","fontawesome-regular-face-flushed":"fontawesome/regular/face-flushed.svg","fontawesome-regular-face-frown-open":"fontawesome/regular/face-frown-open.svg","fontawesome-regular-face-frown":"fontawesome/regular/face-frown.svg","fontawesome-regular-face-grimace":"fontawesome/regular/face-grimace.svg","fontawesome-regular-face-grin-beam-sweat":"fontawesome/regular/face-grin-beam-sweat.svg","fontawesome-regular-face-grin-beam":"fontawesome/regular/face-grin-beam.svg","fontawesome-regular-face-grin-hearts":"fontawesome/regular/face-grin-hearts.svg","fontawesome-regular-face-grin-squint-tears":"fontawesome/regular/face-grin-squint-tears.svg","fontawesome-regular-face-grin-squint":"fontawesome/regular/face-grin-squint.svg","fontawesome-regular-face-grin-stars":"fontawesome/regular/face-grin-stars.svg","fontawesome-regular-face-grin-tears":"fontawesome/regular/face-grin-tears.svg","fontawesome-regular-face-grin-tongue-squint":"fontawesome/regular/face-grin-tongue-squint.svg","fontawesome-regular-face-grin-tongue-wink":"fontawesome/regular/face-grin-tongue-wink.svg","fontawesome-regular-face-grin-tongue":"fontawesome/regular/face-grin-tongue.svg","fontawesome-regular-face-grin-wide":"fontawesome/regular/face-grin-wide.svg","fontawesome-regular-face-grin-wink":"fontawesome/regular/face-grin-wink.svg","fontawesome-regular-face-grin":"fontawesome/regular/face-grin.svg","fontawesome-regular-face-kiss-beam":"fontawesome/regular/face-kiss-beam.svg","fontawesome-regular-face-kiss-wink-heart":"fontawesome/regular/face-kiss-wink-heart.svg","fontawesome-regular-face-kiss":"fontawesome/regular/face-kiss.svg","fontawesome-regular-face-laugh-beam":"fontawesome/regular/face-laugh-beam.svg","fontawesome-regular-face-laugh-squint":"fontawesome/regular/face-laugh-squint.svg","fontawesome-regular-face-laugh-wink":"fontawesome/regular/face-laugh-wink.svg","fontawesome-regular-face-laugh":"fontawesome/regular/face-laugh.svg","fontawesome-regular-face-meh-blank":"fontawesome/regular/face-meh-blank.svg","fontawesome-regular-face-meh":"fontawesome/regular/face-meh.svg","fontawesome-regular-face-rolling-eyes":"fontawesome/regular/face-rolling-eyes.svg","fontawesome-regular-face-sad-cry":"fontawesome/regular/face-sad-cry.svg","fontawesome-regular-face-sad-tear":"fontawesome/regular/face-sad-tear.svg","fontawesome-regular-face-smile-beam":"fontawesome/regular/face-smile-beam.svg","fontawesome-regular-face-smile-wink":"fontawesome/regular/face-smile-wink.svg","fontawesome-regular-face-smile":"fontawesome/regular/face-smile.svg","fontawesome-regular-face-surprise":"fontawesome/regular/face-surprise.svg","fontawesome-regular-face-tired":"fontawesome/regular/face-tired.svg","fontawesome-regular-file-audio":"fontawesome/regular/file-audio.svg","fontawesome-regular-file-code":"fontawesome/regular/file-code.svg","fontawesome-regular-file-excel":"fontawesome/regular/file-excel.svg","fontawesome-regular-file-image":"fontawesome/regular/file-image.svg","fontawesome-regular-file-lines":"fontawesome/regular/file-lines.svg","fontawesome-regular-file-pdf":"fontawesome/regular/file-pdf.svg","fontawesome-regular-file-powerpoint":"fontawesome/regular/file-powerpoint.svg","fontawesome-regular-file-video":"fontawesome/regular/file-video.svg","fontawesome-regular-file-word":"fontawesome/regular/file-word.svg","fontawesome-regular-file-zipper":"fontawesome/regular/file-zipper.svg","fontawesome-regular-file":"fontawesome/regular/file.svg","fontawesome-regular-flag":"fontawesome/regular/flag.svg","fontawesome-regular-floppy-disk":"fontawesome/regular/floppy-disk.svg","fontawesome-regular-folder-closed":"fontawesome/regular/folder-closed.svg","fontawesome-regular-folder-open":"fontawesome/regular/folder-open.svg","fontawesome-regular-folder":"fontawesome/regular/folder.svg","fontawesome-regular-font-awesome":"fontawesome/regular/font-awesome.svg","fontawesome-regular-futbol":"fontawesome/regular/futbol.svg","fontawesome-regular-gem":"fontawesome/regular/gem.svg","fontawesome-regular-hand-back-fist":"fontawesome/regular/hand-back-fist.svg","fontawesome-regular-hand-lizard":"fontawesome/regular/hand-lizard.svg","fontawesome-regular-hand-peace":"fontawesome/regular/hand-peace.svg","fontawesome-regular-hand-point-down":"fontawesome/regular/hand-point-down.svg","fontawesome-regular-hand-point-left":"fontawesome/regular/hand-point-left.svg","fontawesome-regular-hand-point-right":"fontawesome/regular/hand-point-right.svg","fontawesome-regular-hand-point-up":"fontawesome/regular/hand-point-up.svg","fontawesome-regular-hand-pointer":"fontawesome/regular/hand-pointer.svg","fontawesome-regular-hand-scissors":"fontawesome/regular/hand-scissors.svg","fontawesome-regular-hand-spock":"fontawesome/regular/hand-spock.svg","fontawesome-regular-hand":"fontawesome/regular/hand.svg","fontawesome-regular-handshake":"fontawesome/regular/handshake.svg","fontawesome-regular-hard-drive":"fontawesome/regular/hard-drive.svg","fontawesome-regular-heart":"fontawesome/regular/heart.svg","fontawesome-regular-hospital":"fontawesome/regular/hospital.svg","fontawesome-regular-hourglass-half":"fontawesome/regular/hourglass-half.svg","fontawesome-regular-hourglass":"fontawesome/regular/hourglass.svg","fontawesome-regular-id-badge":"fontawesome/regular/id-badge.svg","fontawesome-regular-id-card":"fontawesome/regular/id-card.svg","fontawesome-regular-image":"fontawesome/regular/image.svg","fontawesome-regular-images":"fontawesome/regular/images.svg","fontawesome-regular-keyboard":"fontawesome/regular/keyboard.svg","fontawesome-regular-lemon":"fontawesome/regular/lemon.svg","fontawesome-regular-life-ring":"fontawesome/regular/life-ring.svg","fontawesome-regular-lightbulb":"fontawesome/regular/lightbulb.svg","fontawesome-regular-map":"fontawesome/regular/map.svg","fontawesome-regular-message":"fontawesome/regular/message.svg","fontawesome-regular-money-bill-1":"fontawesome/regular/money-bill-1.svg","fontawesome-regular-moon":"fontawesome/regular/moon.svg","fontawesome-regular-newspaper":"fontawesome/regular/newspaper.svg","fontawesome-regular-notdef":"fontawesome/regular/notdef.svg","fontawesome-regular-note-sticky":"fontawesome/regular/note-sticky.svg","fontawesome-regular-object-group":"fontawesome/regular/object-group.svg","fontawesome-regular-object-ungroup":"fontawesome/regular/object-ungroup.svg","fontawesome-regular-paper-plane":"fontawesome/regular/paper-plane.svg","fontawesome-regular-paste":"fontawesome/regular/paste.svg","fontawesome-regular-pen-to-square":"fontawesome/regular/pen-to-square.svg","fontawesome-regular-rectangle-list":"fontawesome/regular/rectangle-list.svg","fontawesome-regular-rectangle-xmark":"fontawesome/regular/rectangle-xmark.svg","fontawesome-regular-registered":"fontawesome/regular/registered.svg","fontawesome-regular-share-from-square":"fontawesome/regular/share-from-square.svg","fontawesome-regular-snowflake":"fontawesome/regular/snowflake.svg","fontawesome-regular-square-caret-down":"fontawesome/regular/square-caret-down.svg","fontawesome-regular-square-caret-left":"fontawesome/regular/square-caret-left.svg","fontawesome-regular-square-caret-right":"fontawesome/regular/square-caret-right.svg","fontawesome-regular-square-caret-up":"fontawesome/regular/square-caret-up.svg","fontawesome-regular-square-check":"fontawesome/regular/square-check.svg","fontawesome-regular-square-full":"fontawesome/regular/square-full.svg","fontawesome-regular-square-minus":"fontawesome/regular/square-minus.svg","fontawesome-regular-square-plus":"fontawesome/regular/square-plus.svg","fontawesome-regular-square":"fontawesome/regular/square.svg","fontawesome-regular-star-half-stroke":"fontawesome/regular/star-half-stroke.svg","fontawesome-regular-star-half":"fontawesome/regular/star-half.svg","fontawesome-regular-star":"fontawesome/regular/star.svg","fontawesome-regular-sun":"fontawesome/regular/sun.svg","fontawesome-regular-thumbs-down":"fontawesome/regular/thumbs-down.svg","fontawesome-regular-thumbs-up":"fontawesome/regular/thumbs-up.svg","fontawesome-regular-trash-can":"fontawesome/regular/trash-can.svg","fontawesome-regular-user":"fontawesome/regular/user.svg","fontawesome-regular-window-maximize":"fontawesome/regular/window-maximize.svg","fontawesome-regular-window-minimize":"fontawesome/regular/window-minimize.svg","fontawesome-regular-window-restore":"fontawesome/regular/window-restore.svg","fontawesome-solid-0":"fontawesome/solid/0.svg","fontawesome-solid-1":"fontawesome/solid/1.svg","fontawesome-solid-2":"fontawesome/solid/2.svg","fontawesome-solid-3":"fontawesome/solid/3.svg","fontawesome-solid-4":"fontawesome/solid/4.svg","fontawesome-solid-5":"fontawesome/solid/5.svg","fontawesome-solid-6":"fontawesome/solid/6.svg","fontawesome-solid-7":"fontawesome/solid/7.svg","fontawesome-solid-8":"fontawesome/solid/8.svg","fontawesome-solid-9":"fontawesome/solid/9.svg","fontawesome-solid-a":"fontawesome/solid/a.svg","fontawesome-solid-address-book":"fontawesome/solid/address-book.svg","fontawesome-solid-address-card":"fontawesome/solid/address-card.svg","fontawesome-solid-align-center":"fontawesome/solid/align-center.svg","fontawesome-solid-align-justify":"fontawesome/solid/align-justify.svg","fontawesome-solid-align-left":"fontawesome/solid/align-left.svg","fontawesome-solid-align-right":"fontawesome/solid/align-right.svg","fontawesome-solid-anchor-circle-check":"fontawesome/solid/anchor-circle-check.svg","fontawesome-solid-anchor-circle-exclamation":"fontawesome/solid/anchor-circle-exclamation.svg","fontawesome-solid-anchor-circle-xmark":"fontawesome/solid/anchor-circle-xmark.svg","fontawesome-solid-anchor-lock":"fontawesome/solid/anchor-lock.svg","fontawesome-solid-anchor":"fontawesome/solid/anchor.svg","fontawesome-solid-angle-down":"fontawesome/solid/angle-down.svg","fontawesome-solid-angle-left":"fontawesome/solid/angle-left.svg","fontawesome-solid-angle-right":"fontawesome/solid/angle-right.svg","fontawesome-solid-angle-up":"fontawesome/solid/angle-up.svg","fontawesome-solid-angles-down":"fontawesome/solid/angles-down.svg","fontawesome-solid-angles-left":"fontawesome/solid/angles-left.svg","fontawesome-solid-angles-right":"fontawesome/solid/angles-right.svg","fontawesome-solid-angles-up":"fontawesome/solid/angles-up.svg","fontawesome-solid-ankh":"fontawesome/solid/ankh.svg","fontawesome-solid-apple-whole":"fontawesome/solid/apple-whole.svg","fontawesome-solid-archway":"fontawesome/solid/archway.svg","fontawesome-solid-arrow-down-1-9":"fontawesome/solid/arrow-down-1-9.svg","fontawesome-solid-arrow-down-9-1":"fontawesome/solid/arrow-down-9-1.svg","fontawesome-solid-arrow-down-a-z":"fontawesome/solid/arrow-down-a-z.svg","fontawesome-solid-arrow-down-long":"fontawesome/solid/arrow-down-long.svg","fontawesome-solid-arrow-down-short-wide":"fontawesome/solid/arrow-down-short-wide.svg","fontawesome-solid-arrow-down-up-across-line":"fontawesome/solid/arrow-down-up-across-line.svg","fontawesome-solid-arrow-down-up-lock":"fontawesome/solid/arrow-down-up-lock.svg","fontawesome-solid-arrow-down-wide-short":"fontawesome/solid/arrow-down-wide-short.svg","fontawesome-solid-arrow-down-z-a":"fontawesome/solid/arrow-down-z-a.svg","fontawesome-solid-arrow-down":"fontawesome/solid/arrow-down.svg","fontawesome-solid-arrow-left-long":"fontawesome/solid/arrow-left-long.svg","fontawesome-solid-arrow-left":"fontawesome/solid/arrow-left.svg","fontawesome-solid-arrow-pointer":"fontawesome/solid/arrow-pointer.svg","fontawesome-solid-arrow-right-arrow-left":"fontawesome/solid/arrow-right-arrow-left.svg","fontawesome-solid-arrow-right-from-bracket":"fontawesome/solid/arrow-right-from-bracket.svg","fontawesome-solid-arrow-right-long":"fontawesome/solid/arrow-right-long.svg","fontawesome-solid-arrow-right-to-bracket":"fontawesome/solid/arrow-right-to-bracket.svg","fontawesome-solid-arrow-right-to-city":"fontawesome/solid/arrow-right-to-city.svg","fontawesome-solid-arrow-right":"fontawesome/solid/arrow-right.svg","fontawesome-solid-arrow-rotate-left":"fontawesome/solid/arrow-rotate-left.svg","fontawesome-solid-arrow-rotate-right":"fontawesome/solid/arrow-rotate-right.svg","fontawesome-solid-arrow-trend-down":"fontawesome/solid/arrow-trend-down.svg","fontawesome-solid-arrow-trend-up":"fontawesome/solid/arrow-trend-up.svg","fontawesome-solid-arrow-turn-down":"fontawesome/solid/arrow-turn-down.svg","fontawesome-solid-arrow-turn-up":"fontawesome/solid/arrow-turn-up.svg","fontawesome-solid-arrow-up-1-9":"fontawesome/solid/arrow-up-1-9.svg","fontawesome-solid-arrow-up-9-1":"fontawesome/solid/arrow-up-9-1.svg","fontawesome-solid-arrow-up-a-z":"fontawesome/solid/arrow-up-a-z.svg","fontawesome-solid-arrow-up-from-bracket":"fontawesome/solid/arrow-up-from-bracket.svg","fontawesome-solid-arrow-up-from-ground-water":"fontawesome/solid/arrow-up-from-ground-water.svg","fontawesome-solid-arrow-up-from-water-pump":"fontawesome/solid/arrow-up-from-water-pump.svg","fontawesome-solid-arrow-up-long":"fontawesome/solid/arrow-up-long.svg","fontawesome-solid-arrow-up-right-dots":"fontawesome/solid/arrow-up-right-dots.svg","fontawesome-solid-arrow-up-right-from-square":"fontawesome/solid/arrow-up-right-from-square.svg","fontawesome-solid-arrow-up-short-wide":"fontawesome/solid/arrow-up-short-wide.svg","fontawesome-solid-arrow-up-wide-short":"fontawesome/solid/arrow-up-wide-short.svg","fontawesome-solid-arrow-up-z-a":"fontawesome/solid/arrow-up-z-a.svg","fontawesome-solid-arrow-up":"fontawesome/solid/arrow-up.svg","fontawesome-solid-arrows-down-to-line":"fontawesome/solid/arrows-down-to-line.svg","fontawesome-solid-arrows-down-to-people":"fontawesome/solid/arrows-down-to-people.svg","fontawesome-solid-arrows-left-right-to-line":"fontawesome/solid/arrows-left-right-to-line.svg","fontawesome-solid-arrows-left-right":"fontawesome/solid/arrows-left-right.svg","fontawesome-solid-arrows-rotate":"fontawesome/solid/arrows-rotate.svg","fontawesome-solid-arrows-spin":"fontawesome/solid/arrows-spin.svg","fontawesome-solid-arrows-split-up-and-left":"fontawesome/solid/arrows-split-up-and-left.svg","fontawesome-solid-arrows-to-circle":"fontawesome/solid/arrows-to-circle.svg","fontawesome-solid-arrows-to-dot":"fontawesome/solid/arrows-to-dot.svg","fontawesome-solid-arrows-to-eye":"fontawesome/solid/arrows-to-eye.svg","fontawesome-solid-arrows-turn-right":"fontawesome/solid/arrows-turn-right.svg","fontawesome-solid-arrows-turn-to-dots":"fontawesome/solid/arrows-turn-to-dots.svg","fontawesome-solid-arrows-up-down-left-right":"fontawesome/solid/arrows-up-down-left-right.svg","fontawesome-solid-arrows-up-down":"fontawesome/solid/arrows-up-down.svg","fontawesome-solid-arrows-up-to-line":"fontawesome/solid/arrows-up-to-line.svg","fontawesome-solid-asterisk":"fontawesome/solid/asterisk.svg","fontawesome-solid-at":"fontawesome/solid/at.svg","fontawesome-solid-atom":"fontawesome/solid/atom.svg","fontawesome-solid-audio-description":"fontawesome/solid/audio-description.svg","fontawesome-solid-austral-sign":"fontawesome/solid/austral-sign.svg","fontawesome-solid-award":"fontawesome/solid/award.svg","fontawesome-solid-b":"fontawesome/solid/b.svg","fontawesome-solid-baby-carriage":"fontawesome/solid/baby-carriage.svg","fontawesome-solid-baby":"fontawesome/solid/baby.svg","fontawesome-solid-backward-fast":"fontawesome/solid/backward-fast.svg","fontawesome-solid-backward-step":"fontawesome/solid/backward-step.svg","fontawesome-solid-backward":"fontawesome/solid/backward.svg","fontawesome-solid-bacon":"fontawesome/solid/bacon.svg","fontawesome-solid-bacteria":"fontawesome/solid/bacteria.svg","fontawesome-solid-bacterium":"fontawesome/solid/bacterium.svg","fontawesome-solid-bag-shopping":"fontawesome/solid/bag-shopping.svg","fontawesome-solid-bahai":"fontawesome/solid/bahai.svg","fontawesome-solid-baht-sign":"fontawesome/solid/baht-sign.svg","fontawesome-solid-ban-smoking":"fontawesome/solid/ban-smoking.svg","fontawesome-solid-ban":"fontawesome/solid/ban.svg","fontawesome-solid-bandage":"fontawesome/solid/bandage.svg","fontawesome-solid-barcode":"fontawesome/solid/barcode.svg","fontawesome-solid-bars-progress":"fontawesome/solid/bars-progress.svg","fontawesome-solid-bars-staggered":"fontawesome/solid/bars-staggered.svg","fontawesome-solid-bars":"fontawesome/solid/bars.svg","fontawesome-solid-baseball-bat-ball":"fontawesome/solid/baseball-bat-ball.svg","fontawesome-solid-baseball":"fontawesome/solid/baseball.svg","fontawesome-solid-basket-shopping":"fontawesome/solid/basket-shopping.svg","fontawesome-solid-basketball":"fontawesome/solid/basketball.svg","fontawesome-solid-bath":"fontawesome/solid/bath.svg","fontawesome-solid-battery-empty":"fontawesome/solid/battery-empty.svg","fontawesome-solid-battery-full":"fontawesome/solid/battery-full.svg","fontawesome-solid-battery-half":"fontawesome/solid/battery-half.svg","fontawesome-solid-battery-quarter":"fontawesome/solid/battery-quarter.svg","fontawesome-solid-battery-three-quarters":"fontawesome/solid/battery-three-quarters.svg","fontawesome-solid-bed-pulse":"fontawesome/solid/bed-pulse.svg","fontawesome-solid-bed":"fontawesome/solid/bed.svg","fontawesome-solid-beer-mug-empty":"fontawesome/solid/beer-mug-empty.svg","fontawesome-solid-bell-concierge":"fontawesome/solid/bell-concierge.svg","fontawesome-solid-bell-slash":"fontawesome/solid/bell-slash.svg","fontawesome-solid-bell":"fontawesome/solid/bell.svg","fontawesome-solid-bezier-curve":"fontawesome/solid/bezier-curve.svg","fontawesome-solid-bicycle":"fontawesome/solid/bicycle.svg","fontawesome-solid-binoculars":"fontawesome/solid/binoculars.svg","fontawesome-solid-biohazard":"fontawesome/solid/biohazard.svg","fontawesome-solid-bitcoin-sign":"fontawesome/solid/bitcoin-sign.svg","fontawesome-solid-blender-phone":"fontawesome/solid/blender-phone.svg","fontawesome-solid-blender":"fontawesome/solid/blender.svg","fontawesome-solid-blog":"fontawesome/solid/blog.svg","fontawesome-solid-bold":"fontawesome/solid/bold.svg","fontawesome-solid-bolt-lightning":"fontawesome/solid/bolt-lightning.svg","fontawesome-solid-bolt":"fontawesome/solid/bolt.svg","fontawesome-solid-bomb":"fontawesome/solid/bomb.svg","fontawesome-solid-bone":"fontawesome/solid/bone.svg","fontawesome-solid-bong":"fontawesome/solid/bong.svg","fontawesome-solid-book-atlas":"fontawesome/solid/book-atlas.svg","fontawesome-solid-book-bible":"fontawesome/solid/book-bible.svg","fontawesome-solid-book-bookmark":"fontawesome/solid/book-bookmark.svg","fontawesome-solid-book-journal-whills":"fontawesome/solid/book-journal-whills.svg","fontawesome-solid-book-medical":"fontawesome/solid/book-medical.svg","fontawesome-solid-book-open-reader":"fontawesome/solid/book-open-reader.svg","fontawesome-solid-book-open":"fontawesome/solid/book-open.svg","fontawesome-solid-book-quran":"fontawesome/solid/book-quran.svg","fontawesome-solid-book-skull":"fontawesome/solid/book-skull.svg","fontawesome-solid-book-tanakh":"fontawesome/solid/book-tanakh.svg","fontawesome-solid-book":"fontawesome/solid/book.svg","fontawesome-solid-bookmark":"fontawesome/solid/bookmark.svg","fontawesome-solid-border-all":"fontawesome/solid/border-all.svg","fontawesome-solid-border-none":"fontawesome/solid/border-none.svg","fontawesome-solid-border-top-left":"fontawesome/solid/border-top-left.svg","fontawesome-solid-bore-hole":"fontawesome/solid/bore-hole.svg","fontawesome-solid-bottle-droplet":"fontawesome/solid/bottle-droplet.svg","fontawesome-solid-bottle-water":"fontawesome/solid/bottle-water.svg","fontawesome-solid-bowl-food":"fontawesome/solid/bowl-food.svg","fontawesome-solid-bowl-rice":"fontawesome/solid/bowl-rice.svg","fontawesome-solid-bowling-ball":"fontawesome/solid/bowling-ball.svg","fontawesome-solid-box-archive":"fontawesome/solid/box-archive.svg","fontawesome-solid-box-open":"fontawesome/solid/box-open.svg","fontawesome-solid-box-tissue":"fontawesome/solid/box-tissue.svg","fontawesome-solid-box":"fontawesome/solid/box.svg","fontawesome-solid-boxes-packing":"fontawesome/solid/boxes-packing.svg","fontawesome-solid-boxes-stacked":"fontawesome/solid/boxes-stacked.svg","fontawesome-solid-braille":"fontawesome/solid/braille.svg","fontawesome-solid-brain":"fontawesome/solid/brain.svg","fontawesome-solid-brazilian-real-sign":"fontawesome/solid/brazilian-real-sign.svg","fontawesome-solid-bread-slice":"fontawesome/solid/bread-slice.svg","fontawesome-solid-bridge-circle-check":"fontawesome/solid/bridge-circle-check.svg","fontawesome-solid-bridge-circle-exclamation":"fontawesome/solid/bridge-circle-exclamation.svg","fontawesome-solid-bridge-circle-xmark":"fontawesome/solid/bridge-circle-xmark.svg","fontawesome-solid-bridge-lock":"fontawesome/solid/bridge-lock.svg","fontawesome-solid-bridge-water":"fontawesome/solid/bridge-water.svg","fontawesome-solid-bridge":"fontawesome/solid/bridge.svg","fontawesome-solid-briefcase-medical":"fontawesome/solid/briefcase-medical.svg","fontawesome-solid-briefcase":"fontawesome/solid/briefcase.svg","fontawesome-solid-broom-ball":"fontawesome/solid/broom-ball.svg","fontawesome-solid-broom":"fontawesome/solid/broom.svg","fontawesome-solid-brush":"fontawesome/solid/brush.svg","fontawesome-solid-bucket":"fontawesome/solid/bucket.svg","fontawesome-solid-bug-slash":"fontawesome/solid/bug-slash.svg","fontawesome-solid-bug":"fontawesome/solid/bug.svg","fontawesome-solid-bugs":"fontawesome/solid/bugs.svg","fontawesome-solid-building-circle-arrow-right":"fontawesome/solid/building-circle-arrow-right.svg","fontawesome-solid-building-circle-check":"fontawesome/solid/building-circle-check.svg","fontawesome-solid-building-circle-exclamation":"fontawesome/solid/building-circle-exclamation.svg","fontawesome-solid-building-circle-xmark":"fontawesome/solid/building-circle-xmark.svg","fontawesome-solid-building-columns":"fontawesome/solid/building-columns.svg","fontawesome-solid-building-flag":"fontawesome/solid/building-flag.svg","fontawesome-solid-building-lock":"fontawesome/solid/building-lock.svg","fontawesome-solid-building-ngo":"fontawesome/solid/building-ngo.svg","fontawesome-solid-building-shield":"fontawesome/solid/building-shield.svg","fontawesome-solid-building-un":"fontawesome/solid/building-un.svg","fontawesome-solid-building-user":"fontawesome/solid/building-user.svg","fontawesome-solid-building-wheat":"fontawesome/solid/building-wheat.svg","fontawesome-solid-building":"fontawesome/solid/building.svg","fontawesome-solid-bullhorn":"fontawesome/solid/bullhorn.svg","fontawesome-solid-bullseye":"fontawesome/solid/bullseye.svg","fontawesome-solid-burger":"fontawesome/solid/burger.svg","fontawesome-solid-burst":"fontawesome/solid/burst.svg","fontawesome-solid-bus-simple":"fontawesome/solid/bus-simple.svg","fontawesome-solid-bus":"fontawesome/solid/bus.svg","fontawesome-solid-business-time":"fontawesome/solid/business-time.svg","fontawesome-solid-c":"fontawesome/solid/c.svg","fontawesome-solid-cable-car":"fontawesome/solid/cable-car.svg","fontawesome-solid-cake-candles":"fontawesome/solid/cake-candles.svg","fontawesome-solid-calculator":"fontawesome/solid/calculator.svg","fontawesome-solid-calendar-check":"fontawesome/solid/calendar-check.svg","fontawesome-solid-calendar-day":"fontawesome/solid/calendar-day.svg","fontawesome-solid-calendar-days":"fontawesome/solid/calendar-days.svg","fontawesome-solid-calendar-minus":"fontawesome/solid/calendar-minus.svg","fontawesome-solid-calendar-plus":"fontawesome/solid/calendar-plus.svg","fontawesome-solid-calendar-week":"fontawesome/solid/calendar-week.svg","fontawesome-solid-calendar-xmark":"fontawesome/solid/calendar-xmark.svg","fontawesome-solid-calendar":"fontawesome/solid/calendar.svg","fontawesome-solid-camera-retro":"fontawesome/solid/camera-retro.svg","fontawesome-solid-camera-rotate":"fontawesome/solid/camera-rotate.svg","fontawesome-solid-camera":"fontawesome/solid/camera.svg","fontawesome-solid-campground":"fontawesome/solid/campground.svg","fontawesome-solid-candy-cane":"fontawesome/solid/candy-cane.svg","fontawesome-solid-cannabis":"fontawesome/solid/cannabis.svg","fontawesome-solid-capsules":"fontawesome/solid/capsules.svg","fontawesome-solid-car-battery":"fontawesome/solid/car-battery.svg","fontawesome-solid-car-burst":"fontawesome/solid/car-burst.svg","fontawesome-solid-car-on":"fontawesome/solid/car-on.svg","fontawesome-solid-car-rear":"fontawesome/solid/car-rear.svg","fontawesome-solid-car-side":"fontawesome/solid/car-side.svg","fontawesome-solid-car-tunnel":"fontawesome/solid/car-tunnel.svg","fontawesome-solid-car":"fontawesome/solid/car.svg","fontawesome-solid-caravan":"fontawesome/solid/caravan.svg","fontawesome-solid-caret-down":"fontawesome/solid/caret-down.svg","fontawesome-solid-caret-left":"fontawesome/solid/caret-left.svg","fontawesome-solid-caret-right":"fontawesome/solid/caret-right.svg","fontawesome-solid-caret-up":"fontawesome/solid/caret-up.svg","fontawesome-solid-carrot":"fontawesome/solid/carrot.svg","fontawesome-solid-cart-arrow-down":"fontawesome/solid/cart-arrow-down.svg","fontawesome-solid-cart-flatbed-suitcase":"fontawesome/solid/cart-flatbed-suitcase.svg","fontawesome-solid-cart-flatbed":"fontawesome/solid/cart-flatbed.svg","fontawesome-solid-cart-plus":"fontawesome/solid/cart-plus.svg","fontawesome-solid-cart-shopping":"fontawesome/solid/cart-shopping.svg","fontawesome-solid-cash-register":"fontawesome/solid/cash-register.svg","fontawesome-solid-cat":"fontawesome/solid/cat.svg","fontawesome-solid-cedi-sign":"fontawesome/solid/cedi-sign.svg","fontawesome-solid-cent-sign":"fontawesome/solid/cent-sign.svg","fontawesome-solid-certificate":"fontawesome/solid/certificate.svg","fontawesome-solid-chair":"fontawesome/solid/chair.svg","fontawesome-solid-chalkboard-user":"fontawesome/solid/chalkboard-user.svg","fontawesome-solid-chalkboard":"fontawesome/solid/chalkboard.svg","fontawesome-solid-champagne-glasses":"fontawesome/solid/champagne-glasses.svg","fontawesome-solid-charging-station":"fontawesome/solid/charging-station.svg","fontawesome-solid-chart-area":"fontawesome/solid/chart-area.svg","fontawesome-solid-chart-bar":"fontawesome/solid/chart-bar.svg","fontawesome-solid-chart-column":"fontawesome/solid/chart-column.svg","fontawesome-solid-chart-gantt":"fontawesome/solid/chart-gantt.svg","fontawesome-solid-chart-line":"fontawesome/solid/chart-line.svg","fontawesome-solid-chart-pie":"fontawesome/solid/chart-pie.svg","fontawesome-solid-chart-simple":"fontawesome/solid/chart-simple.svg","fontawesome-solid-check-double":"fontawesome/solid/check-double.svg","fontawesome-solid-check-to-slot":"fontawesome/solid/check-to-slot.svg","fontawesome-solid-check":"fontawesome/solid/check.svg","fontawesome-solid-cheese":"fontawesome/solid/cheese.svg","fontawesome-solid-chess-bishop":"fontawesome/solid/chess-bishop.svg","fontawesome-solid-chess-board":"fontawesome/solid/chess-board.svg","fontawesome-solid-chess-king":"fontawesome/solid/chess-king.svg","fontawesome-solid-chess-knight":"fontawesome/solid/chess-knight.svg","fontawesome-solid-chess-pawn":"fontawesome/solid/chess-pawn.svg","fontawesome-solid-chess-queen":"fontawesome/solid/chess-queen.svg","fontawesome-solid-chess-rook":"fontawesome/solid/chess-rook.svg","fontawesome-solid-chess":"fontawesome/solid/chess.svg","fontawesome-solid-chevron-down":"fontawesome/solid/chevron-down.svg","fontawesome-solid-chevron-left":"fontawesome/solid/chevron-left.svg","fontawesome-solid-chevron-right":"fontawesome/solid/chevron-right.svg","fontawesome-solid-chevron-up":"fontawesome/solid/chevron-up.svg","fontawesome-solid-child-dress":"fontawesome/solid/child-dress.svg","fontawesome-solid-child-reaching":"fontawesome/solid/child-reaching.svg","fontawesome-solid-child-rifle":"fontawesome/solid/child-rifle.svg","fontawesome-solid-child":"fontawesome/solid/child.svg","fontawesome-solid-children":"fontawesome/solid/children.svg","fontawesome-solid-church":"fontawesome/solid/church.svg","fontawesome-solid-circle-arrow-down":"fontawesome/solid/circle-arrow-down.svg","fontawesome-solid-circle-arrow-left":"fontawesome/solid/circle-arrow-left.svg","fontawesome-solid-circle-arrow-right":"fontawesome/solid/circle-arrow-right.svg","fontawesome-solid-circle-arrow-up":"fontawesome/solid/circle-arrow-up.svg","fontawesome-solid-circle-check":"fontawesome/solid/circle-check.svg","fontawesome-solid-circle-chevron-down":"fontawesome/solid/circle-chevron-down.svg","fontawesome-solid-circle-chevron-left":"fontawesome/solid/circle-chevron-left.svg","fontawesome-solid-circle-chevron-right":"fontawesome/solid/circle-chevron-right.svg","fontawesome-solid-circle-chevron-up":"fontawesome/solid/circle-chevron-up.svg","fontawesome-solid-circle-dollar-to-slot":"fontawesome/solid/circle-dollar-to-slot.svg","fontawesome-solid-circle-dot":"fontawesome/solid/circle-dot.svg","fontawesome-solid-circle-down":"fontawesome/solid/circle-down.svg","fontawesome-solid-circle-exclamation":"fontawesome/solid/circle-exclamation.svg","fontawesome-solid-circle-h":"fontawesome/solid/circle-h.svg","fontawesome-solid-circle-half-stroke":"fontawesome/solid/circle-half-stroke.svg","fontawesome-solid-circle-info":"fontawesome/solid/circle-info.svg","fontawesome-solid-circle-left":"fontawesome/solid/circle-left.svg","fontawesome-solid-circle-minus":"fontawesome/solid/circle-minus.svg","fontawesome-solid-circle-nodes":"fontawesome/solid/circle-nodes.svg","fontawesome-solid-circle-notch":"fontawesome/solid/circle-notch.svg","fontawesome-solid-circle-pause":"fontawesome/solid/circle-pause.svg","fontawesome-solid-circle-play":"fontawesome/solid/circle-play.svg","fontawesome-solid-circle-plus":"fontawesome/solid/circle-plus.svg","fontawesome-solid-circle-question":"fontawesome/solid/circle-question.svg","fontawesome-solid-circle-radiation":"fontawesome/solid/circle-radiation.svg","fontawesome-solid-circle-right":"fontawesome/solid/circle-right.svg","fontawesome-solid-circle-stop":"fontawesome/solid/circle-stop.svg","fontawesome-solid-circle-up":"fontawesome/solid/circle-up.svg","fontawesome-solid-circle-user":"fontawesome/solid/circle-user.svg","fontawesome-solid-circle-xmark":"fontawesome/solid/circle-xmark.svg","fontawesome-solid-circle":"fontawesome/solid/circle.svg","fontawesome-solid-city":"fontawesome/solid/city.svg","fontawesome-solid-clapperboard":"fontawesome/solid/clapperboard.svg","fontawesome-solid-clipboard-check":"fontawesome/solid/clipboard-check.svg","fontawesome-solid-clipboard-list":"fontawesome/solid/clipboard-list.svg","fontawesome-solid-clipboard-question":"fontawesome/solid/clipboard-question.svg","fontawesome-solid-clipboard-user":"fontawesome/solid/clipboard-user.svg","fontawesome-solid-clipboard":"fontawesome/solid/clipboard.svg","fontawesome-solid-clock-rotate-left":"fontawesome/solid/clock-rotate-left.svg","fontawesome-solid-clock":"fontawesome/solid/clock.svg","fontawesome-solid-clone":"fontawesome/solid/clone.svg","fontawesome-solid-closed-captioning":"fontawesome/solid/closed-captioning.svg","fontawesome-solid-cloud-arrow-down":"fontawesome/solid/cloud-arrow-down.svg","fontawesome-solid-cloud-arrow-up":"fontawesome/solid/cloud-arrow-up.svg","fontawesome-solid-cloud-bolt":"fontawesome/solid/cloud-bolt.svg","fontawesome-solid-cloud-meatball":"fontawesome/solid/cloud-meatball.svg","fontawesome-solid-cloud-moon-rain":"fontawesome/solid/cloud-moon-rain.svg","fontawesome-solid-cloud-moon":"fontawesome/solid/cloud-moon.svg","fontawesome-solid-cloud-rain":"fontawesome/solid/cloud-rain.svg","fontawesome-solid-cloud-showers-heavy":"fontawesome/solid/cloud-showers-heavy.svg","fontawesome-solid-cloud-showers-water":"fontawesome/solid/cloud-showers-water.svg","fontawesome-solid-cloud-sun-rain":"fontawesome/solid/cloud-sun-rain.svg","fontawesome-solid-cloud-sun":"fontawesome/solid/cloud-sun.svg","fontawesome-solid-cloud":"fontawesome/solid/cloud.svg","fontawesome-solid-clover":"fontawesome/solid/clover.svg","fontawesome-solid-code-branch":"fontawesome/solid/code-branch.svg","fontawesome-solid-code-commit":"fontawesome/solid/code-commit.svg","fontawesome-solid-code-compare":"fontawesome/solid/code-compare.svg","fontawesome-solid-code-fork":"fontawesome/solid/code-fork.svg","fontawesome-solid-code-merge":"fontawesome/solid/code-merge.svg","fontawesome-solid-code-pull-request":"fontawesome/solid/code-pull-request.svg","fontawesome-solid-code":"fontawesome/solid/code.svg","fontawesome-solid-coins":"fontawesome/solid/coins.svg","fontawesome-solid-colon-sign":"fontawesome/solid/colon-sign.svg","fontawesome-solid-comment-dollar":"fontawesome/solid/comment-dollar.svg","fontawesome-solid-comment-dots":"fontawesome/solid/comment-dots.svg","fontawesome-solid-comment-medical":"fontawesome/solid/comment-medical.svg","fontawesome-solid-comment-slash":"fontawesome/solid/comment-slash.svg","fontawesome-solid-comment-sms":"fontawesome/solid/comment-sms.svg","fontawesome-solid-comment":"fontawesome/solid/comment.svg","fontawesome-solid-comments-dollar":"fontawesome/solid/comments-dollar.svg","fontawesome-solid-comments":"fontawesome/solid/comments.svg","fontawesome-solid-compact-disc":"fontawesome/solid/compact-disc.svg","fontawesome-solid-compass-drafting":"fontawesome/solid/compass-drafting.svg","fontawesome-solid-compass":"fontawesome/solid/compass.svg","fontawesome-solid-compress":"fontawesome/solid/compress.svg","fontawesome-solid-computer-mouse":"fontawesome/solid/computer-mouse.svg","fontawesome-solid-computer":"fontawesome/solid/computer.svg","fontawesome-solid-cookie-bite":"fontawesome/solid/cookie-bite.svg","fontawesome-solid-cookie":"fontawesome/solid/cookie.svg","fontawesome-solid-copy":"fontawesome/solid/copy.svg","fontawesome-solid-copyright":"fontawesome/solid/copyright.svg","fontawesome-solid-couch":"fontawesome/solid/couch.svg","fontawesome-solid-cow":"fontawesome/solid/cow.svg","fontawesome-solid-credit-card":"fontawesome/solid/credit-card.svg","fontawesome-solid-crop-simple":"fontawesome/solid/crop-simple.svg","fontawesome-solid-crop":"fontawesome/solid/crop.svg","fontawesome-solid-cross":"fontawesome/solid/cross.svg","fontawesome-solid-crosshairs":"fontawesome/solid/crosshairs.svg","fontawesome-solid-crow":"fontawesome/solid/crow.svg","fontawesome-solid-crown":"fontawesome/solid/crown.svg","fontawesome-solid-crutch":"fontawesome/solid/crutch.svg","fontawesome-solid-cruzeiro-sign":"fontawesome/solid/cruzeiro-sign.svg","fontawesome-solid-cube":"fontawesome/solid/cube.svg","fontawesome-solid-cubes-stacked":"fontawesome/solid/cubes-stacked.svg","fontawesome-solid-cubes":"fontawesome/solid/cubes.svg","fontawesome-solid-d":"fontawesome/solid/d.svg","fontawesome-solid-database":"fontawesome/solid/database.svg","fontawesome-solid-delete-left":"fontawesome/solid/delete-left.svg","fontawesome-solid-democrat":"fontawesome/solid/democrat.svg","fontawesome-solid-desktop":"fontawesome/solid/desktop.svg","fontawesome-solid-dharmachakra":"fontawesome/solid/dharmachakra.svg","fontawesome-solid-diagram-next":"fontawesome/solid/diagram-next.svg","fontawesome-solid-diagram-predecessor":"fontawesome/solid/diagram-predecessor.svg","fontawesome-solid-diagram-project":"fontawesome/solid/diagram-project.svg","fontawesome-solid-diagram-successor":"fontawesome/solid/diagram-successor.svg","fontawesome-solid-diamond-turn-right":"fontawesome/solid/diamond-turn-right.svg","fontawesome-solid-diamond":"fontawesome/solid/diamond.svg","fontawesome-solid-dice-d20":"fontawesome/solid/dice-d20.svg","fontawesome-solid-dice-d6":"fontawesome/solid/dice-d6.svg","fontawesome-solid-dice-five":"fontawesome/solid/dice-five.svg","fontawesome-solid-dice-four":"fontawesome/solid/dice-four.svg","fontawesome-solid-dice-one":"fontawesome/solid/dice-one.svg","fontawesome-solid-dice-six":"fontawesome/solid/dice-six.svg","fontawesome-solid-dice-three":"fontawesome/solid/dice-three.svg","fontawesome-solid-dice-two":"fontawesome/solid/dice-two.svg","fontawesome-solid-dice":"fontawesome/solid/dice.svg","fontawesome-solid-disease":"fontawesome/solid/disease.svg","fontawesome-solid-display":"fontawesome/solid/display.svg","fontawesome-solid-divide":"fontawesome/solid/divide.svg","fontawesome-solid-dna":"fontawesome/solid/dna.svg","fontawesome-solid-dog":"fontawesome/solid/dog.svg","fontawesome-solid-dollar-sign":"fontawesome/solid/dollar-sign.svg","fontawesome-solid-dolly":"fontawesome/solid/dolly.svg","fontawesome-solid-dong-sign":"fontawesome/solid/dong-sign.svg","fontawesome-solid-door-closed":"fontawesome/solid/door-closed.svg","fontawesome-solid-door-open":"fontawesome/solid/door-open.svg","fontawesome-solid-dove":"fontawesome/solid/dove.svg","fontawesome-solid-down-left-and-up-right-to-center":"fontawesome/solid/down-left-and-up-right-to-center.svg","fontawesome-solid-down-long":"fontawesome/solid/down-long.svg","fontawesome-solid-download":"fontawesome/solid/download.svg","fontawesome-solid-dragon":"fontawesome/solid/dragon.svg","fontawesome-solid-draw-polygon":"fontawesome/solid/draw-polygon.svg","fontawesome-solid-droplet-slash":"fontawesome/solid/droplet-slash.svg","fontawesome-solid-droplet":"fontawesome/solid/droplet.svg","fontawesome-solid-drum-steelpan":"fontawesome/solid/drum-steelpan.svg","fontawesome-solid-drum":"fontawesome/solid/drum.svg","fontawesome-solid-drumstick-bite":"fontawesome/solid/drumstick-bite.svg","fontawesome-solid-dumbbell":"fontawesome/solid/dumbbell.svg","fontawesome-solid-dumpster-fire":"fontawesome/solid/dumpster-fire.svg","fontawesome-solid-dumpster":"fontawesome/solid/dumpster.svg","fontawesome-solid-dungeon":"fontawesome/solid/dungeon.svg","fontawesome-solid-e":"fontawesome/solid/e.svg","fontawesome-solid-ear-deaf":"fontawesome/solid/ear-deaf.svg","fontawesome-solid-ear-listen":"fontawesome/solid/ear-listen.svg","fontawesome-solid-earth-africa":"fontawesome/solid/earth-africa.svg","fontawesome-solid-earth-americas":"fontawesome/solid/earth-americas.svg","fontawesome-solid-earth-asia":"fontawesome/solid/earth-asia.svg","fontawesome-solid-earth-europe":"fontawesome/solid/earth-europe.svg","fontawesome-solid-earth-oceania":"fontawesome/solid/earth-oceania.svg","fontawesome-solid-egg":"fontawesome/solid/egg.svg","fontawesome-solid-eject":"fontawesome/solid/eject.svg","fontawesome-solid-elevator":"fontawesome/solid/elevator.svg","fontawesome-solid-ellipsis-vertical":"fontawesome/solid/ellipsis-vertical.svg","fontawesome-solid-ellipsis":"fontawesome/solid/ellipsis.svg","fontawesome-solid-envelope-circle-check":"fontawesome/solid/envelope-circle-check.svg","fontawesome-solid-envelope-open-text":"fontawesome/solid/envelope-open-text.svg","fontawesome-solid-envelope-open":"fontawesome/solid/envelope-open.svg","fontawesome-solid-envelope":"fontawesome/solid/envelope.svg","fontawesome-solid-envelopes-bulk":"fontawesome/solid/envelopes-bulk.svg","fontawesome-solid-equals":"fontawesome/solid/equals.svg","fontawesome-solid-eraser":"fontawesome/solid/eraser.svg","fontawesome-solid-ethernet":"fontawesome/solid/ethernet.svg","fontawesome-solid-euro-sign":"fontawesome/solid/euro-sign.svg","fontawesome-solid-exclamation":"fontawesome/solid/exclamation.svg","fontawesome-solid-expand":"fontawesome/solid/expand.svg","fontawesome-solid-explosion":"fontawesome/solid/explosion.svg","fontawesome-solid-eye-dropper":"fontawesome/solid/eye-dropper.svg","fontawesome-solid-eye-low-vision":"fontawesome/solid/eye-low-vision.svg","fontawesome-solid-eye-slash":"fontawesome/solid/eye-slash.svg","fontawesome-solid-eye":"fontawesome/solid/eye.svg","fontawesome-solid-f":"fontawesome/solid/f.svg","fontawesome-solid-face-angry":"fontawesome/solid/face-angry.svg","fontawesome-solid-face-dizzy":"fontawesome/solid/face-dizzy.svg","fontawesome-solid-face-flushed":"fontawesome/solid/face-flushed.svg","fontawesome-solid-face-frown-open":"fontawesome/solid/face-frown-open.svg","fontawesome-solid-face-frown":"fontawesome/solid/face-frown.svg","fontawesome-solid-face-grimace":"fontawesome/solid/face-grimace.svg","fontawesome-solid-face-grin-beam-sweat":"fontawesome/solid/face-grin-beam-sweat.svg","fontawesome-solid-face-grin-beam":"fontawesome/solid/face-grin-beam.svg","fontawesome-solid-face-grin-hearts":"fontawesome/solid/face-grin-hearts.svg","fontawesome-solid-face-grin-squint-tears":"fontawesome/solid/face-grin-squint-tears.svg","fontawesome-solid-face-grin-squint":"fontawesome/solid/face-grin-squint.svg","fontawesome-solid-face-grin-stars":"fontawesome/solid/face-grin-stars.svg","fontawesome-solid-face-grin-tears":"fontawesome/solid/face-grin-tears.svg","fontawesome-solid-face-grin-tongue-squint":"fontawesome/solid/face-grin-tongue-squint.svg","fontawesome-solid-face-grin-tongue-wink":"fontawesome/solid/face-grin-tongue-wink.svg","fontawesome-solid-face-grin-tongue":"fontawesome/solid/face-grin-tongue.svg","fontawesome-solid-face-grin-wide":"fontawesome/solid/face-grin-wide.svg","fontawesome-solid-face-grin-wink":"fontawesome/solid/face-grin-wink.svg","fontawesome-solid-face-grin":"fontawesome/solid/face-grin.svg","fontawesome-solid-face-kiss-beam":"fontawesome/solid/face-kiss-beam.svg","fontawesome-solid-face-kiss-wink-heart":"fontawesome/solid/face-kiss-wink-heart.svg","fontawesome-solid-face-kiss":"fontawesome/solid/face-kiss.svg","fontawesome-solid-face-laugh-beam":"fontawesome/solid/face-laugh-beam.svg","fontawesome-solid-face-laugh-squint":"fontawesome/solid/face-laugh-squint.svg","fontawesome-solid-face-laugh-wink":"fontawesome/solid/face-laugh-wink.svg","fontawesome-solid-face-laugh":"fontawesome/solid/face-laugh.svg","fontawesome-solid-face-meh-blank":"fontawesome/solid/face-meh-blank.svg","fontawesome-solid-face-meh":"fontawesome/solid/face-meh.svg","fontawesome-solid-face-rolling-eyes":"fontawesome/solid/face-rolling-eyes.svg","fontawesome-solid-face-sad-cry":"fontawesome/solid/face-sad-cry.svg","fontawesome-solid-face-sad-tear":"fontawesome/solid/face-sad-tear.svg","fontawesome-solid-face-smile-beam":"fontawesome/solid/face-smile-beam.svg","fontawesome-solid-face-smile-wink":"fontawesome/solid/face-smile-wink.svg","fontawesome-solid-face-smile":"fontawesome/solid/face-smile.svg","fontawesome-solid-face-surprise":"fontawesome/solid/face-surprise.svg","fontawesome-solid-face-tired":"fontawesome/solid/face-tired.svg","fontawesome-solid-fan":"fontawesome/solid/fan.svg","fontawesome-solid-faucet-drip":"fontawesome/solid/faucet-drip.svg","fontawesome-solid-faucet":"fontawesome/solid/faucet.svg","fontawesome-solid-fax":"fontawesome/solid/fax.svg","fontawesome-solid-feather-pointed":"fontawesome/solid/feather-pointed.svg","fontawesome-solid-feather":"fontawesome/solid/feather.svg","fontawesome-solid-ferry":"fontawesome/solid/ferry.svg","fontawesome-solid-file-arrow-down":"fontawesome/solid/file-arrow-down.svg","fontawesome-solid-file-arrow-up":"fontawesome/solid/file-arrow-up.svg","fontawesome-solid-file-audio":"fontawesome/solid/file-audio.svg","fontawesome-solid-file-circle-check":"fontawesome/solid/file-circle-check.svg","fontawesome-solid-file-circle-exclamation":"fontawesome/solid/file-circle-exclamation.svg","fontawesome-solid-file-circle-minus":"fontawesome/solid/file-circle-minus.svg","fontawesome-solid-file-circle-plus":"fontawesome/solid/file-circle-plus.svg","fontawesome-solid-file-circle-question":"fontawesome/solid/file-circle-question.svg","fontawesome-solid-file-circle-xmark":"fontawesome/solid/file-circle-xmark.svg","fontawesome-solid-file-code":"fontawesome/solid/file-code.svg","fontawesome-solid-file-contract":"fontawesome/solid/file-contract.svg","fontawesome-solid-file-csv":"fontawesome/solid/file-csv.svg","fontawesome-solid-file-excel":"fontawesome/solid/file-excel.svg","fontawesome-solid-file-export":"fontawesome/solid/file-export.svg","fontawesome-solid-file-image":"fontawesome/solid/file-image.svg","fontawesome-solid-file-import":"fontawesome/solid/file-import.svg","fontawesome-solid-file-invoice-dollar":"fontawesome/solid/file-invoice-dollar.svg","fontawesome-solid-file-invoice":"fontawesome/solid/file-invoice.svg","fontawesome-solid-file-lines":"fontawesome/solid/file-lines.svg","fontawesome-solid-file-medical":"fontawesome/solid/file-medical.svg","fontawesome-solid-file-pdf":"fontawesome/solid/file-pdf.svg","fontawesome-solid-file-pen":"fontawesome/solid/file-pen.svg","fontawesome-solid-file-powerpoint":"fontawesome/solid/file-powerpoint.svg","fontawesome-solid-file-prescription":"fontawesome/solid/file-prescription.svg","fontawesome-solid-file-shield":"fontawesome/solid/file-shield.svg","fontawesome-solid-file-signature":"fontawesome/solid/file-signature.svg","fontawesome-solid-file-video":"fontawesome/solid/file-video.svg","fontawesome-solid-file-waveform":"fontawesome/solid/file-waveform.svg","fontawesome-solid-file-word":"fontawesome/solid/file-word.svg","fontawesome-solid-file-zipper":"fontawesome/solid/file-zipper.svg","fontawesome-solid-file":"fontawesome/solid/file.svg","fontawesome-solid-fill-drip":"fontawesome/solid/fill-drip.svg","fontawesome-solid-fill":"fontawesome/solid/fill.svg","fontawesome-solid-film":"fontawesome/solid/film.svg","fontawesome-solid-filter-circle-dollar":"fontawesome/solid/filter-circle-dollar.svg","fontawesome-solid-filter-circle-xmark":"fontawesome/solid/filter-circle-xmark.svg","fontawesome-solid-filter":"fontawesome/solid/filter.svg","fontawesome-solid-fingerprint":"fontawesome/solid/fingerprint.svg","fontawesome-solid-fire-burner":"fontawesome/solid/fire-burner.svg","fontawesome-solid-fire-extinguisher":"fontawesome/solid/fire-extinguisher.svg","fontawesome-solid-fire-flame-curved":"fontawesome/solid/fire-flame-curved.svg","fontawesome-solid-fire-flame-simple":"fontawesome/solid/fire-flame-simple.svg","fontawesome-solid-fire":"fontawesome/solid/fire.svg","fontawesome-solid-fish-fins":"fontawesome/solid/fish-fins.svg","fontawesome-solid-fish":"fontawesome/solid/fish.svg","fontawesome-solid-flag-checkered":"fontawesome/solid/flag-checkered.svg","fontawesome-solid-flag-usa":"fontawesome/solid/flag-usa.svg","fontawesome-solid-flag":"fontawesome/solid/flag.svg","fontawesome-solid-flask-vial":"fontawesome/solid/flask-vial.svg","fontawesome-solid-flask":"fontawesome/solid/flask.svg","fontawesome-solid-floppy-disk":"fontawesome/solid/floppy-disk.svg","fontawesome-solid-florin-sign":"fontawesome/solid/florin-sign.svg","fontawesome-solid-folder-closed":"fontawesome/solid/folder-closed.svg","fontawesome-solid-folder-minus":"fontawesome/solid/folder-minus.svg","fontawesome-solid-folder-open":"fontawesome/solid/folder-open.svg","fontawesome-solid-folder-plus":"fontawesome/solid/folder-plus.svg","fontawesome-solid-folder-tree":"fontawesome/solid/folder-tree.svg","fontawesome-solid-folder":"fontawesome/solid/folder.svg","fontawesome-solid-font-awesome":"fontawesome/solid/font-awesome.svg","fontawesome-solid-font":"fontawesome/solid/font.svg","fontawesome-solid-football":"fontawesome/solid/football.svg","fontawesome-solid-forward-fast":"fontawesome/solid/forward-fast.svg","fontawesome-solid-forward-step":"fontawesome/solid/forward-step.svg","fontawesome-solid-forward":"fontawesome/solid/forward.svg","fontawesome-solid-franc-sign":"fontawesome/solid/franc-sign.svg","fontawesome-solid-frog":"fontawesome/solid/frog.svg","fontawesome-solid-futbol":"fontawesome/solid/futbol.svg","fontawesome-solid-g":"fontawesome/solid/g.svg","fontawesome-solid-gamepad":"fontawesome/solid/gamepad.svg","fontawesome-solid-gas-pump":"fontawesome/solid/gas-pump.svg","fontawesome-solid-gauge-high":"fontawesome/solid/gauge-high.svg","fontawesome-solid-gauge-simple-high":"fontawesome/solid/gauge-simple-high.svg","fontawesome-solid-gauge-simple":"fontawesome/solid/gauge-simple.svg","fontawesome-solid-gauge":"fontawesome/solid/gauge.svg","fontawesome-solid-gavel":"fontawesome/solid/gavel.svg","fontawesome-solid-gear":"fontawesome/solid/gear.svg","fontawesome-solid-gears":"fontawesome/solid/gears.svg","fontawesome-solid-gem":"fontawesome/solid/gem.svg","fontawesome-solid-genderless":"fontawesome/solid/genderless.svg","fontawesome-solid-ghost":"fontawesome/solid/ghost.svg","fontawesome-solid-gift":"fontawesome/solid/gift.svg","fontawesome-solid-gifts":"fontawesome/solid/gifts.svg","fontawesome-solid-glass-water-droplet":"fontawesome/solid/glass-water-droplet.svg","fontawesome-solid-glass-water":"fontawesome/solid/glass-water.svg","fontawesome-solid-glasses":"fontawesome/solid/glasses.svg","fontawesome-solid-globe":"fontawesome/solid/globe.svg","fontawesome-solid-golf-ball-tee":"fontawesome/solid/golf-ball-tee.svg","fontawesome-solid-gopuram":"fontawesome/solid/gopuram.svg","fontawesome-solid-graduation-cap":"fontawesome/solid/graduation-cap.svg","fontawesome-solid-greater-than-equal":"fontawesome/solid/greater-than-equal.svg","fontawesome-solid-greater-than":"fontawesome/solid/greater-than.svg","fontawesome-solid-grip-lines-vertical":"fontawesome/solid/grip-lines-vertical.svg","fontawesome-solid-grip-lines":"fontawesome/solid/grip-lines.svg","fontawesome-solid-grip-vertical":"fontawesome/solid/grip-vertical.svg","fontawesome-solid-grip":"fontawesome/solid/grip.svg","fontawesome-solid-group-arrows-rotate":"fontawesome/solid/group-arrows-rotate.svg","fontawesome-solid-guarani-sign":"fontawesome/solid/guarani-sign.svg","fontawesome-solid-guitar":"fontawesome/solid/guitar.svg","fontawesome-solid-gun":"fontawesome/solid/gun.svg","fontawesome-solid-h":"fontawesome/solid/h.svg","fontawesome-solid-hammer":"fontawesome/solid/hammer.svg","fontawesome-solid-hamsa":"fontawesome/solid/hamsa.svg","fontawesome-solid-hand-back-fist":"fontawesome/solid/hand-back-fist.svg","fontawesome-solid-hand-dots":"fontawesome/solid/hand-dots.svg","fontawesome-solid-hand-fist":"fontawesome/solid/hand-fist.svg","fontawesome-solid-hand-holding-dollar":"fontawesome/solid/hand-holding-dollar.svg","fontawesome-solid-hand-holding-droplet":"fontawesome/solid/hand-holding-droplet.svg","fontawesome-solid-hand-holding-hand":"fontawesome/solid/hand-holding-hand.svg","fontawesome-solid-hand-holding-heart":"fontawesome/solid/hand-holding-heart.svg","fontawesome-solid-hand-holding-medical":"fontawesome/solid/hand-holding-medical.svg","fontawesome-solid-hand-holding":"fontawesome/solid/hand-holding.svg","fontawesome-solid-hand-lizard":"fontawesome/solid/hand-lizard.svg","fontawesome-solid-hand-middle-finger":"fontawesome/solid/hand-middle-finger.svg","fontawesome-solid-hand-peace":"fontawesome/solid/hand-peace.svg","fontawesome-solid-hand-point-down":"fontawesome/solid/hand-point-down.svg","fontawesome-solid-hand-point-left":"fontawesome/solid/hand-point-left.svg","fontawesome-solid-hand-point-right":"fontawesome/solid/hand-point-right.svg","fontawesome-solid-hand-point-up":"fontawesome/solid/hand-point-up.svg","fontawesome-solid-hand-pointer":"fontawesome/solid/hand-pointer.svg","fontawesome-solid-hand-scissors":"fontawesome/solid/hand-scissors.svg","fontawesome-solid-hand-sparkles":"fontawesome/solid/hand-sparkles.svg","fontawesome-solid-hand-spock":"fontawesome/solid/hand-spock.svg","fontawesome-solid-hand":"fontawesome/solid/hand.svg","fontawesome-solid-handcuffs":"fontawesome/solid/handcuffs.svg","fontawesome-solid-hands-asl-interpreting":"fontawesome/solid/hands-asl-interpreting.svg","fontawesome-solid-hands-bound":"fontawesome/solid/hands-bound.svg","fontawesome-solid-hands-bubbles":"fontawesome/solid/hands-bubbles.svg","fontawesome-solid-hands-clapping":"fontawesome/solid/hands-clapping.svg","fontawesome-solid-hands-holding-child":"fontawesome/solid/hands-holding-child.svg","fontawesome-solid-hands-holding-circle":"fontawesome/solid/hands-holding-circle.svg","fontawesome-solid-hands-holding":"fontawesome/solid/hands-holding.svg","fontawesome-solid-hands-praying":"fontawesome/solid/hands-praying.svg","fontawesome-solid-hands":"fontawesome/solid/hands.svg","fontawesome-solid-handshake-angle":"fontawesome/solid/handshake-angle.svg","fontawesome-solid-handshake-simple-slash":"fontawesome/solid/handshake-simple-slash.svg","fontawesome-solid-handshake-simple":"fontawesome/solid/handshake-simple.svg","fontawesome-solid-handshake-slash":"fontawesome/solid/handshake-slash.svg","fontawesome-solid-handshake":"fontawesome/solid/handshake.svg","fontawesome-solid-hanukiah":"fontawesome/solid/hanukiah.svg","fontawesome-solid-hard-drive":"fontawesome/solid/hard-drive.svg","fontawesome-solid-hashtag":"fontawesome/solid/hashtag.svg","fontawesome-solid-hat-cowboy-side":"fontawesome/solid/hat-cowboy-side.svg","fontawesome-solid-hat-cowboy":"fontawesome/solid/hat-cowboy.svg","fontawesome-solid-hat-wizard":"fontawesome/solid/hat-wizard.svg","fontawesome-solid-head-side-cough-slash":"fontawesome/solid/head-side-cough-slash.svg","fontawesome-solid-head-side-cough":"fontawesome/solid/head-side-cough.svg","fontawesome-solid-head-side-mask":"fontawesome/solid/head-side-mask.svg","fontawesome-solid-head-side-virus":"fontawesome/solid/head-side-virus.svg","fontawesome-solid-heading":"fontawesome/solid/heading.svg","fontawesome-solid-headphones-simple":"fontawesome/solid/headphones-simple.svg","fontawesome-solid-headphones":"fontawesome/solid/headphones.svg","fontawesome-solid-headset":"fontawesome/solid/headset.svg","fontawesome-solid-heart-circle-bolt":"fontawesome/solid/heart-circle-bolt.svg","fontawesome-solid-heart-circle-check":"fontawesome/solid/heart-circle-check.svg","fontawesome-solid-heart-circle-exclamation":"fontawesome/solid/heart-circle-exclamation.svg","fontawesome-solid-heart-circle-minus":"fontawesome/solid/heart-circle-minus.svg","fontawesome-solid-heart-circle-plus":"fontawesome/solid/heart-circle-plus.svg","fontawesome-solid-heart-circle-xmark":"fontawesome/solid/heart-circle-xmark.svg","fontawesome-solid-heart-crack":"fontawesome/solid/heart-crack.svg","fontawesome-solid-heart-pulse":"fontawesome/solid/heart-pulse.svg","fontawesome-solid-heart":"fontawesome/solid/heart.svg","fontawesome-solid-helicopter-symbol":"fontawesome/solid/helicopter-symbol.svg","fontawesome-solid-helicopter":"fontawesome/solid/helicopter.svg","fontawesome-solid-helmet-safety":"fontawesome/solid/helmet-safety.svg","fontawesome-solid-helmet-un":"fontawesome/solid/helmet-un.svg","fontawesome-solid-highlighter":"fontawesome/solid/highlighter.svg","fontawesome-solid-hill-avalanche":"fontawesome/solid/hill-avalanche.svg","fontawesome-solid-hill-rockslide":"fontawesome/solid/hill-rockslide.svg","fontawesome-solid-hippo":"fontawesome/solid/hippo.svg","fontawesome-solid-hockey-puck":"fontawesome/solid/hockey-puck.svg","fontawesome-solid-holly-berry":"fontawesome/solid/holly-berry.svg","fontawesome-solid-horse-head":"fontawesome/solid/horse-head.svg","fontawesome-solid-horse":"fontawesome/solid/horse.svg","fontawesome-solid-hospital-user":"fontawesome/solid/hospital-user.svg","fontawesome-solid-hospital":"fontawesome/solid/hospital.svg","fontawesome-solid-hot-tub-person":"fontawesome/solid/hot-tub-person.svg","fontawesome-solid-hotdog":"fontawesome/solid/hotdog.svg","fontawesome-solid-hotel":"fontawesome/solid/hotel.svg","fontawesome-solid-hourglass-end":"fontawesome/solid/hourglass-end.svg","fontawesome-solid-hourglass-half":"fontawesome/solid/hourglass-half.svg","fontawesome-solid-hourglass-start":"fontawesome/solid/hourglass-start.svg","fontawesome-solid-hourglass":"fontawesome/solid/hourglass.svg","fontawesome-solid-house-chimney-crack":"fontawesome/solid/house-chimney-crack.svg","fontawesome-solid-house-chimney-medical":"fontawesome/solid/house-chimney-medical.svg","fontawesome-solid-house-chimney-user":"fontawesome/solid/house-chimney-user.svg","fontawesome-solid-house-chimney-window":"fontawesome/solid/house-chimney-window.svg","fontawesome-solid-house-chimney":"fontawesome/solid/house-chimney.svg","fontawesome-solid-house-circle-check":"fontawesome/solid/house-circle-check.svg","fontawesome-solid-house-circle-exclamation":"fontawesome/solid/house-circle-exclamation.svg","fontawesome-solid-house-circle-xmark":"fontawesome/solid/house-circle-xmark.svg","fontawesome-solid-house-crack":"fontawesome/solid/house-crack.svg","fontawesome-solid-house-fire":"fontawesome/solid/house-fire.svg","fontawesome-solid-house-flag":"fontawesome/solid/house-flag.svg","fontawesome-solid-house-flood-water-circle-arrow-right":"fontawesome/solid/house-flood-water-circle-arrow-right.svg","fontawesome-solid-house-flood-water":"fontawesome/solid/house-flood-water.svg","fontawesome-solid-house-laptop":"fontawesome/solid/house-laptop.svg","fontawesome-solid-house-lock":"fontawesome/solid/house-lock.svg","fontawesome-solid-house-medical-circle-check":"fontawesome/solid/house-medical-circle-check.svg","fontawesome-solid-house-medical-circle-exclamation":"fontawesome/solid/house-medical-circle-exclamation.svg","fontawesome-solid-house-medical-circle-xmark":"fontawesome/solid/house-medical-circle-xmark.svg","fontawesome-solid-house-medical-flag":"fontawesome/solid/house-medical-flag.svg","fontawesome-solid-house-medical":"fontawesome/solid/house-medical.svg","fontawesome-solid-house-signal":"fontawesome/solid/house-signal.svg","fontawesome-solid-house-tsunami":"fontawesome/solid/house-tsunami.svg","fontawesome-solid-house-user":"fontawesome/solid/house-user.svg","fontawesome-solid-house":"fontawesome/solid/house.svg","fontawesome-solid-hryvnia-sign":"fontawesome/solid/hryvnia-sign.svg","fontawesome-solid-hurricane":"fontawesome/solid/hurricane.svg","fontawesome-solid-i-cursor":"fontawesome/solid/i-cursor.svg","fontawesome-solid-i":"fontawesome/solid/i.svg","fontawesome-solid-ice-cream":"fontawesome/solid/ice-cream.svg","fontawesome-solid-icicles":"fontawesome/solid/icicles.svg","fontawesome-solid-icons":"fontawesome/solid/icons.svg","fontawesome-solid-id-badge":"fontawesome/solid/id-badge.svg","fontawesome-solid-id-card-clip":"fontawesome/solid/id-card-clip.svg","fontawesome-solid-id-card":"fontawesome/solid/id-card.svg","fontawesome-solid-igloo":"fontawesome/solid/igloo.svg","fontawesome-solid-image-portrait":"fontawesome/solid/image-portrait.svg","fontawesome-solid-image":"fontawesome/solid/image.svg","fontawesome-solid-images":"fontawesome/solid/images.svg","fontawesome-solid-inbox":"fontawesome/solid/inbox.svg","fontawesome-solid-indent":"fontawesome/solid/indent.svg","fontawesome-solid-indian-rupee-sign":"fontawesome/solid/indian-rupee-sign.svg","fontawesome-solid-industry":"fontawesome/solid/industry.svg","fontawesome-solid-infinity":"fontawesome/solid/infinity.svg","fontawesome-solid-info":"fontawesome/solid/info.svg","fontawesome-solid-italic":"fontawesome/solid/italic.svg","fontawesome-solid-j":"fontawesome/solid/j.svg","fontawesome-solid-jar-wheat":"fontawesome/solid/jar-wheat.svg","fontawesome-solid-jar":"fontawesome/solid/jar.svg","fontawesome-solid-jedi":"fontawesome/solid/jedi.svg","fontawesome-solid-jet-fighter-up":"fontawesome/solid/jet-fighter-up.svg","fontawesome-solid-jet-fighter":"fontawesome/solid/jet-fighter.svg","fontawesome-solid-joint":"fontawesome/solid/joint.svg","fontawesome-solid-jug-detergent":"fontawesome/solid/jug-detergent.svg","fontawesome-solid-k":"fontawesome/solid/k.svg","fontawesome-solid-kaaba":"fontawesome/solid/kaaba.svg","fontawesome-solid-key":"fontawesome/solid/key.svg","fontawesome-solid-keyboard":"fontawesome/solid/keyboard.svg","fontawesome-solid-khanda":"fontawesome/solid/khanda.svg","fontawesome-solid-kip-sign":"fontawesome/solid/kip-sign.svg","fontawesome-solid-kit-medical":"fontawesome/solid/kit-medical.svg","fontawesome-solid-kitchen-set":"fontawesome/solid/kitchen-set.svg","fontawesome-solid-kiwi-bird":"fontawesome/solid/kiwi-bird.svg","fontawesome-solid-l":"fontawesome/solid/l.svg","fontawesome-solid-land-mine-on":"fontawesome/solid/land-mine-on.svg","fontawesome-solid-landmark-dome":"fontawesome/solid/landmark-dome.svg","fontawesome-solid-landmark-flag":"fontawesome/solid/landmark-flag.svg","fontawesome-solid-landmark":"fontawesome/solid/landmark.svg","fontawesome-solid-language":"fontawesome/solid/language.svg","fontawesome-solid-laptop-code":"fontawesome/solid/laptop-code.svg","fontawesome-solid-laptop-file":"fontawesome/solid/laptop-file.svg","fontawesome-solid-laptop-medical":"fontawesome/solid/laptop-medical.svg","fontawesome-solid-laptop":"fontawesome/solid/laptop.svg","fontawesome-solid-lari-sign":"fontawesome/solid/lari-sign.svg","fontawesome-solid-layer-group":"fontawesome/solid/layer-group.svg","fontawesome-solid-leaf":"fontawesome/solid/leaf.svg","fontawesome-solid-left-long":"fontawesome/solid/left-long.svg","fontawesome-solid-left-right":"fontawesome/solid/left-right.svg","fontawesome-solid-lemon":"fontawesome/solid/lemon.svg","fontawesome-solid-less-than-equal":"fontawesome/solid/less-than-equal.svg","fontawesome-solid-less-than":"fontawesome/solid/less-than.svg","fontawesome-solid-life-ring":"fontawesome/solid/life-ring.svg","fontawesome-solid-lightbulb":"fontawesome/solid/lightbulb.svg","fontawesome-solid-lines-leaning":"fontawesome/solid/lines-leaning.svg","fontawesome-solid-link-slash":"fontawesome/solid/link-slash.svg","fontawesome-solid-link":"fontawesome/solid/link.svg","fontawesome-solid-lira-sign":"fontawesome/solid/lira-sign.svg","fontawesome-solid-list-check":"fontawesome/solid/list-check.svg","fontawesome-solid-list-ol":"fontawesome/solid/list-ol.svg","fontawesome-solid-list-ul":"fontawesome/solid/list-ul.svg","fontawesome-solid-list":"fontawesome/solid/list.svg","fontawesome-solid-litecoin-sign":"fontawesome/solid/litecoin-sign.svg","fontawesome-solid-location-arrow":"fontawesome/solid/location-arrow.svg","fontawesome-solid-location-crosshairs":"fontawesome/solid/location-crosshairs.svg","fontawesome-solid-location-dot":"fontawesome/solid/location-dot.svg","fontawesome-solid-location-pin-lock":"fontawesome/solid/location-pin-lock.svg","fontawesome-solid-location-pin":"fontawesome/solid/location-pin.svg","fontawesome-solid-lock-open":"fontawesome/solid/lock-open.svg","fontawesome-solid-lock":"fontawesome/solid/lock.svg","fontawesome-solid-locust":"fontawesome/solid/locust.svg","fontawesome-solid-lungs-virus":"fontawesome/solid/lungs-virus.svg","fontawesome-solid-lungs":"fontawesome/solid/lungs.svg","fontawesome-solid-m":"fontawesome/solid/m.svg","fontawesome-solid-magnet":"fontawesome/solid/magnet.svg","fontawesome-solid-magnifying-glass-arrow-right":"fontawesome/solid/magnifying-glass-arrow-right.svg","fontawesome-solid-magnifying-glass-chart":"fontawesome/solid/magnifying-glass-chart.svg","fontawesome-solid-magnifying-glass-dollar":"fontawesome/solid/magnifying-glass-dollar.svg","fontawesome-solid-magnifying-glass-location":"fontawesome/solid/magnifying-glass-location.svg","fontawesome-solid-magnifying-glass-minus":"fontawesome/solid/magnifying-glass-minus.svg","fontawesome-solid-magnifying-glass-plus":"fontawesome/solid/magnifying-glass-plus.svg","fontawesome-solid-magnifying-glass":"fontawesome/solid/magnifying-glass.svg","fontawesome-solid-manat-sign":"fontawesome/solid/manat-sign.svg","fontawesome-solid-map-location-dot":"fontawesome/solid/map-location-dot.svg","fontawesome-solid-map-location":"fontawesome/solid/map-location.svg","fontawesome-solid-map-pin":"fontawesome/solid/map-pin.svg","fontawesome-solid-map":"fontawesome/solid/map.svg","fontawesome-solid-marker":"fontawesome/solid/marker.svg","fontawesome-solid-mars-and-venus-burst":"fontawesome/solid/mars-and-venus-burst.svg","fontawesome-solid-mars-and-venus":"fontawesome/solid/mars-and-venus.svg","fontawesome-solid-mars-double":"fontawesome/solid/mars-double.svg","fontawesome-solid-mars-stroke-right":"fontawesome/solid/mars-stroke-right.svg","fontawesome-solid-mars-stroke-up":"fontawesome/solid/mars-stroke-up.svg","fontawesome-solid-mars-stroke":"fontawesome/solid/mars-stroke.svg","fontawesome-solid-mars":"fontawesome/solid/mars.svg","fontawesome-solid-martini-glass-citrus":"fontawesome/solid/martini-glass-citrus.svg","fontawesome-solid-martini-glass-empty":"fontawesome/solid/martini-glass-empty.svg","fontawesome-solid-martini-glass":"fontawesome/solid/martini-glass.svg","fontawesome-solid-mask-face":"fontawesome/solid/mask-face.svg","fontawesome-solid-mask-ventilator":"fontawesome/solid/mask-ventilator.svg","fontawesome-solid-mask":"fontawesome/solid/mask.svg","fontawesome-solid-masks-theater":"fontawesome/solid/masks-theater.svg","fontawesome-solid-mattress-pillow":"fontawesome/solid/mattress-pillow.svg","fontawesome-solid-maximize":"fontawesome/solid/maximize.svg","fontawesome-solid-medal":"fontawesome/solid/medal.svg","fontawesome-solid-memory":"fontawesome/solid/memory.svg","fontawesome-solid-menorah":"fontawesome/solid/menorah.svg","fontawesome-solid-mercury":"fontawesome/solid/mercury.svg","fontawesome-solid-message":"fontawesome/solid/message.svg","fontawesome-solid-meteor":"fontawesome/solid/meteor.svg","fontawesome-solid-microchip":"fontawesome/solid/microchip.svg","fontawesome-solid-microphone-lines-slash":"fontawesome/solid/microphone-lines-slash.svg","fontawesome-solid-microphone-lines":"fontawesome/solid/microphone-lines.svg","fontawesome-solid-microphone-slash":"fontawesome/solid/microphone-slash.svg","fontawesome-solid-microphone":"fontawesome/solid/microphone.svg","fontawesome-solid-microscope":"fontawesome/solid/microscope.svg","fontawesome-solid-mill-sign":"fontawesome/solid/mill-sign.svg","fontawesome-solid-minimize":"fontawesome/solid/minimize.svg","fontawesome-solid-minus":"fontawesome/solid/minus.svg","fontawesome-solid-mitten":"fontawesome/solid/mitten.svg","fontawesome-solid-mobile-button":"fontawesome/solid/mobile-button.svg","fontawesome-solid-mobile-retro":"fontawesome/solid/mobile-retro.svg","fontawesome-solid-mobile-screen-button":"fontawesome/solid/mobile-screen-button.svg","fontawesome-solid-mobile-screen":"fontawesome/solid/mobile-screen.svg","fontawesome-solid-mobile":"fontawesome/solid/mobile.svg","fontawesome-solid-money-bill-1-wave":"fontawesome/solid/money-bill-1-wave.svg","fontawesome-solid-money-bill-1":"fontawesome/solid/money-bill-1.svg","fontawesome-solid-money-bill-transfer":"fontawesome/solid/money-bill-transfer.svg","fontawesome-solid-money-bill-trend-up":"fontawesome/solid/money-bill-trend-up.svg","fontawesome-solid-money-bill-wave":"fontawesome/solid/money-bill-wave.svg","fontawesome-solid-money-bill-wheat":"fontawesome/solid/money-bill-wheat.svg","fontawesome-solid-money-bill":"fontawesome/solid/money-bill.svg","fontawesome-solid-money-bills":"fontawesome/solid/money-bills.svg","fontawesome-solid-money-check-dollar":"fontawesome/solid/money-check-dollar.svg","fontawesome-solid-money-check":"fontawesome/solid/money-check.svg","fontawesome-solid-monument":"fontawesome/solid/monument.svg","fontawesome-solid-moon":"fontawesome/solid/moon.svg","fontawesome-solid-mortar-pestle":"fontawesome/solid/mortar-pestle.svg","fontawesome-solid-mosque":"fontawesome/solid/mosque.svg","fontawesome-solid-mosquito-net":"fontawesome/solid/mosquito-net.svg","fontawesome-solid-mosquito":"fontawesome/solid/mosquito.svg","fontawesome-solid-motorcycle":"fontawesome/solid/motorcycle.svg","fontawesome-solid-mound":"fontawesome/solid/mound.svg","fontawesome-solid-mountain-city":"fontawesome/solid/mountain-city.svg","fontawesome-solid-mountain-sun":"fontawesome/solid/mountain-sun.svg","fontawesome-solid-mountain":"fontawesome/solid/mountain.svg","fontawesome-solid-mug-hot":"fontawesome/solid/mug-hot.svg","fontawesome-solid-mug-saucer":"fontawesome/solid/mug-saucer.svg","fontawesome-solid-music":"fontawesome/solid/music.svg","fontawesome-solid-n":"fontawesome/solid/n.svg","fontawesome-solid-naira-sign":"fontawesome/solid/naira-sign.svg","fontawesome-solid-network-wired":"fontawesome/solid/network-wired.svg","fontawesome-solid-neuter":"fontawesome/solid/neuter.svg","fontawesome-solid-newspaper":"fontawesome/solid/newspaper.svg","fontawesome-solid-not-equal":"fontawesome/solid/not-equal.svg","fontawesome-solid-notdef":"fontawesome/solid/notdef.svg","fontawesome-solid-note-sticky":"fontawesome/solid/note-sticky.svg","fontawesome-solid-notes-medical":"fontawesome/solid/notes-medical.svg","fontawesome-solid-o":"fontawesome/solid/o.svg","fontawesome-solid-object-group":"fontawesome/solid/object-group.svg","fontawesome-solid-object-ungroup":"fontawesome/solid/object-ungroup.svg","fontawesome-solid-oil-can":"fontawesome/solid/oil-can.svg","fontawesome-solid-oil-well":"fontawesome/solid/oil-well.svg","fontawesome-solid-om":"fontawesome/solid/om.svg","fontawesome-solid-otter":"fontawesome/solid/otter.svg","fontawesome-solid-outdent":"fontawesome/solid/outdent.svg","fontawesome-solid-p":"fontawesome/solid/p.svg","fontawesome-solid-pager":"fontawesome/solid/pager.svg","fontawesome-solid-paint-roller":"fontawesome/solid/paint-roller.svg","fontawesome-solid-paintbrush":"fontawesome/solid/paintbrush.svg","fontawesome-solid-palette":"fontawesome/solid/palette.svg","fontawesome-solid-pallet":"fontawesome/solid/pallet.svg","fontawesome-solid-panorama":"fontawesome/solid/panorama.svg","fontawesome-solid-paper-plane":"fontawesome/solid/paper-plane.svg","fontawesome-solid-paperclip":"fontawesome/solid/paperclip.svg","fontawesome-solid-parachute-box":"fontawesome/solid/parachute-box.svg","fontawesome-solid-paragraph":"fontawesome/solid/paragraph.svg","fontawesome-solid-passport":"fontawesome/solid/passport.svg","fontawesome-solid-paste":"fontawesome/solid/paste.svg","fontawesome-solid-pause":"fontawesome/solid/pause.svg","fontawesome-solid-paw":"fontawesome/solid/paw.svg","fontawesome-solid-peace":"fontawesome/solid/peace.svg","fontawesome-solid-pen-clip":"fontawesome/solid/pen-clip.svg","fontawesome-solid-pen-fancy":"fontawesome/solid/pen-fancy.svg","fontawesome-solid-pen-nib":"fontawesome/solid/pen-nib.svg","fontawesome-solid-pen-ruler":"fontawesome/solid/pen-ruler.svg","fontawesome-solid-pen-to-square":"fontawesome/solid/pen-to-square.svg","fontawesome-solid-pen":"fontawesome/solid/pen.svg","fontawesome-solid-pencil":"fontawesome/solid/pencil.svg","fontawesome-solid-people-arrows":"fontawesome/solid/people-arrows.svg","fontawesome-solid-people-carry-box":"fontawesome/solid/people-carry-box.svg","fontawesome-solid-people-group":"fontawesome/solid/people-group.svg","fontawesome-solid-people-line":"fontawesome/solid/people-line.svg","fontawesome-solid-people-pulling":"fontawesome/solid/people-pulling.svg","fontawesome-solid-people-robbery":"fontawesome/solid/people-robbery.svg","fontawesome-solid-people-roof":"fontawesome/solid/people-roof.svg","fontawesome-solid-pepper-hot":"fontawesome/solid/pepper-hot.svg","fontawesome-solid-percent":"fontawesome/solid/percent.svg","fontawesome-solid-person-arrow-down-to-line":"fontawesome/solid/person-arrow-down-to-line.svg","fontawesome-solid-person-arrow-up-from-line":"fontawesome/solid/person-arrow-up-from-line.svg","fontawesome-solid-person-biking":"fontawesome/solid/person-biking.svg","fontawesome-solid-person-booth":"fontawesome/solid/person-booth.svg","fontawesome-solid-person-breastfeeding":"fontawesome/solid/person-breastfeeding.svg","fontawesome-solid-person-burst":"fontawesome/solid/person-burst.svg","fontawesome-solid-person-cane":"fontawesome/solid/person-cane.svg","fontawesome-solid-person-chalkboard":"fontawesome/solid/person-chalkboard.svg","fontawesome-solid-person-circle-check":"fontawesome/solid/person-circle-check.svg","fontawesome-solid-person-circle-exclamation":"fontawesome/solid/person-circle-exclamation.svg","fontawesome-solid-person-circle-minus":"fontawesome/solid/person-circle-minus.svg","fontawesome-solid-person-circle-plus":"fontawesome/solid/person-circle-plus.svg","fontawesome-solid-person-circle-question":"fontawesome/solid/person-circle-question.svg","fontawesome-solid-person-circle-xmark":"fontawesome/solid/person-circle-xmark.svg","fontawesome-solid-person-digging":"fontawesome/solid/person-digging.svg","fontawesome-solid-person-dots-from-line":"fontawesome/solid/person-dots-from-line.svg","fontawesome-solid-person-dress-burst":"fontawesome/solid/person-dress-burst.svg","fontawesome-solid-person-dress":"fontawesome/solid/person-dress.svg","fontawesome-solid-person-drowning":"fontawesome/solid/person-drowning.svg","fontawesome-solid-person-falling-burst":"fontawesome/solid/person-falling-burst.svg","fontawesome-solid-person-falling":"fontawesome/solid/person-falling.svg","fontawesome-solid-person-half-dress":"fontawesome/solid/person-half-dress.svg","fontawesome-solid-person-harassing":"fontawesome/solid/person-harassing.svg","fontawesome-solid-person-hiking":"fontawesome/solid/person-hiking.svg","fontawesome-solid-person-military-pointing":"fontawesome/solid/person-military-pointing.svg","fontawesome-solid-person-military-rifle":"fontawesome/solid/person-military-rifle.svg","fontawesome-solid-person-military-to-person":"fontawesome/solid/person-military-to-person.svg","fontawesome-solid-person-praying":"fontawesome/solid/person-praying.svg","fontawesome-solid-person-pregnant":"fontawesome/solid/person-pregnant.svg","fontawesome-solid-person-rays":"fontawesome/solid/person-rays.svg","fontawesome-solid-person-rifle":"fontawesome/solid/person-rifle.svg","fontawesome-solid-person-running":"fontawesome/solid/person-running.svg","fontawesome-solid-person-shelter":"fontawesome/solid/person-shelter.svg","fontawesome-solid-person-skating":"fontawesome/solid/person-skating.svg","fontawesome-solid-person-skiing-nordic":"fontawesome/solid/person-skiing-nordic.svg","fontawesome-solid-person-skiing":"fontawesome/solid/person-skiing.svg","fontawesome-solid-person-snowboarding":"fontawesome/solid/person-snowboarding.svg","fontawesome-solid-person-swimming":"fontawesome/solid/person-swimming.svg","fontawesome-solid-person-through-window":"fontawesome/solid/person-through-window.svg","fontawesome-solid-person-walking-arrow-loop-left":"fontawesome/solid/person-walking-arrow-loop-left.svg","fontawesome-solid-person-walking-arrow-right":"fontawesome/solid/person-walking-arrow-right.svg","fontawesome-solid-person-walking-dashed-line-arrow-right":"fontawesome/solid/person-walking-dashed-line-arrow-right.svg","fontawesome-solid-person-walking-luggage":"fontawesome/solid/person-walking-luggage.svg","fontawesome-solid-person-walking-with-cane":"fontawesome/solid/person-walking-with-cane.svg","fontawesome-solid-person-walking":"fontawesome/solid/person-walking.svg","fontawesome-solid-person":"fontawesome/solid/person.svg","fontawesome-solid-peseta-sign":"fontawesome/solid/peseta-sign.svg","fontawesome-solid-peso-sign":"fontawesome/solid/peso-sign.svg","fontawesome-solid-phone-flip":"fontawesome/solid/phone-flip.svg","fontawesome-solid-phone-slash":"fontawesome/solid/phone-slash.svg","fontawesome-solid-phone-volume":"fontawesome/solid/phone-volume.svg","fontawesome-solid-phone":"fontawesome/solid/phone.svg","fontawesome-solid-photo-film":"fontawesome/solid/photo-film.svg","fontawesome-solid-piggy-bank":"fontawesome/solid/piggy-bank.svg","fontawesome-solid-pills":"fontawesome/solid/pills.svg","fontawesome-solid-pizza-slice":"fontawesome/solid/pizza-slice.svg","fontawesome-solid-place-of-worship":"fontawesome/solid/place-of-worship.svg","fontawesome-solid-plane-arrival":"fontawesome/solid/plane-arrival.svg","fontawesome-solid-plane-circle-check":"fontawesome/solid/plane-circle-check.svg","fontawesome-solid-plane-circle-exclamation":"fontawesome/solid/plane-circle-exclamation.svg","fontawesome-solid-plane-circle-xmark":"fontawesome/solid/plane-circle-xmark.svg","fontawesome-solid-plane-departure":"fontawesome/solid/plane-departure.svg","fontawesome-solid-plane-lock":"fontawesome/solid/plane-lock.svg","fontawesome-solid-plane-slash":"fontawesome/solid/plane-slash.svg","fontawesome-solid-plane-up":"fontawesome/solid/plane-up.svg","fontawesome-solid-plane":"fontawesome/solid/plane.svg","fontawesome-solid-plant-wilt":"fontawesome/solid/plant-wilt.svg","fontawesome-solid-plate-wheat":"fontawesome/solid/plate-wheat.svg","fontawesome-solid-play":"fontawesome/solid/play.svg","fontawesome-solid-plug-circle-bolt":"fontawesome/solid/plug-circle-bolt.svg","fontawesome-solid-plug-circle-check":"fontawesome/solid/plug-circle-check.svg","fontawesome-solid-plug-circle-exclamation":"fontawesome/solid/plug-circle-exclamation.svg","fontawesome-solid-plug-circle-minus":"fontawesome/solid/plug-circle-minus.svg","fontawesome-solid-plug-circle-plus":"fontawesome/solid/plug-circle-plus.svg","fontawesome-solid-plug-circle-xmark":"fontawesome/solid/plug-circle-xmark.svg","fontawesome-solid-plug":"fontawesome/solid/plug.svg","fontawesome-solid-plus-minus":"fontawesome/solid/plus-minus.svg","fontawesome-solid-plus":"fontawesome/solid/plus.svg","fontawesome-solid-podcast":"fontawesome/solid/podcast.svg","fontawesome-solid-poo-storm":"fontawesome/solid/poo-storm.svg","fontawesome-solid-poo":"fontawesome/solid/poo.svg","fontawesome-solid-poop":"fontawesome/solid/poop.svg","fontawesome-solid-power-off":"fontawesome/solid/power-off.svg","fontawesome-solid-prescription-bottle-medical":"fontawesome/solid/prescription-bottle-medical.svg","fontawesome-solid-prescription-bottle":"fontawesome/solid/prescription-bottle.svg","fontawesome-solid-prescription":"fontawesome/solid/prescription.svg","fontawesome-solid-print":"fontawesome/solid/print.svg","fontawesome-solid-pump-medical":"fontawesome/solid/pump-medical.svg","fontawesome-solid-pump-soap":"fontawesome/solid/pump-soap.svg","fontawesome-solid-puzzle-piece":"fontawesome/solid/puzzle-piece.svg","fontawesome-solid-q":"fontawesome/solid/q.svg","fontawesome-solid-qrcode":"fontawesome/solid/qrcode.svg","fontawesome-solid-question":"fontawesome/solid/question.svg","fontawesome-solid-quote-left":"fontawesome/solid/quote-left.svg","fontawesome-solid-quote-right":"fontawesome/solid/quote-right.svg","fontawesome-solid-r":"fontawesome/solid/r.svg","fontawesome-solid-radiation":"fontawesome/solid/radiation.svg","fontawesome-solid-radio":"fontawesome/solid/radio.svg","fontawesome-solid-rainbow":"fontawesome/solid/rainbow.svg","fontawesome-solid-ranking-star":"fontawesome/solid/ranking-star.svg","fontawesome-solid-receipt":"fontawesome/solid/receipt.svg","fontawesome-solid-record-vinyl":"fontawesome/solid/record-vinyl.svg","fontawesome-solid-rectangle-ad":"fontawesome/solid/rectangle-ad.svg","fontawesome-solid-rectangle-list":"fontawesome/solid/rectangle-list.svg","fontawesome-solid-rectangle-xmark":"fontawesome/solid/rectangle-xmark.svg","fontawesome-solid-recycle":"fontawesome/solid/recycle.svg","fontawesome-solid-registered":"fontawesome/solid/registered.svg","fontawesome-solid-repeat":"fontawesome/solid/repeat.svg","fontawesome-solid-reply-all":"fontawesome/solid/reply-all.svg","fontawesome-solid-reply":"fontawesome/solid/reply.svg","fontawesome-solid-republican":"fontawesome/solid/republican.svg","fontawesome-solid-restroom":"fontawesome/solid/restroom.svg","fontawesome-solid-retweet":"fontawesome/solid/retweet.svg","fontawesome-solid-ribbon":"fontawesome/solid/ribbon.svg","fontawesome-solid-right-from-bracket":"fontawesome/solid/right-from-bracket.svg","fontawesome-solid-right-left":"fontawesome/solid/right-left.svg","fontawesome-solid-right-long":"fontawesome/solid/right-long.svg","fontawesome-solid-right-to-bracket":"fontawesome/solid/right-to-bracket.svg","fontawesome-solid-ring":"fontawesome/solid/ring.svg","fontawesome-solid-road-barrier":"fontawesome/solid/road-barrier.svg","fontawesome-solid-road-bridge":"fontawesome/solid/road-bridge.svg","fontawesome-solid-road-circle-check":"fontawesome/solid/road-circle-check.svg","fontawesome-solid-road-circle-exclamation":"fontawesome/solid/road-circle-exclamation.svg","fontawesome-solid-road-circle-xmark":"fontawesome/solid/road-circle-xmark.svg","fontawesome-solid-road-lock":"fontawesome/solid/road-lock.svg","fontawesome-solid-road-spikes":"fontawesome/solid/road-spikes.svg","fontawesome-solid-road":"fontawesome/solid/road.svg","fontawesome-solid-robot":"fontawesome/solid/robot.svg","fontawesome-solid-rocket":"fontawesome/solid/rocket.svg","fontawesome-solid-rotate-left":"fontawesome/solid/rotate-left.svg","fontawesome-solid-rotate-right":"fontawesome/solid/rotate-right.svg","fontawesome-solid-rotate":"fontawesome/solid/rotate.svg","fontawesome-solid-route":"fontawesome/solid/route.svg","fontawesome-solid-rss":"fontawesome/solid/rss.svg","fontawesome-solid-ruble-sign":"fontawesome/solid/ruble-sign.svg","fontawesome-solid-rug":"fontawesome/solid/rug.svg","fontawesome-solid-ruler-combined":"fontawesome/solid/ruler-combined.svg","fontawesome-solid-ruler-horizontal":"fontawesome/solid/ruler-horizontal.svg","fontawesome-solid-ruler-vertical":"fontawesome/solid/ruler-vertical.svg","fontawesome-solid-ruler":"fontawesome/solid/ruler.svg","fontawesome-solid-rupee-sign":"fontawesome/solid/rupee-sign.svg","fontawesome-solid-rupiah-sign":"fontawesome/solid/rupiah-sign.svg","fontawesome-solid-s":"fontawesome/solid/s.svg","fontawesome-solid-sack-dollar":"fontawesome/solid/sack-dollar.svg","fontawesome-solid-sack-xmark":"fontawesome/solid/sack-xmark.svg","fontawesome-solid-sailboat":"fontawesome/solid/sailboat.svg","fontawesome-solid-satellite-dish":"fontawesome/solid/satellite-dish.svg","fontawesome-solid-satellite":"fontawesome/solid/satellite.svg","fontawesome-solid-scale-balanced":"fontawesome/solid/scale-balanced.svg","fontawesome-solid-scale-unbalanced-flip":"fontawesome/solid/scale-unbalanced-flip.svg","fontawesome-solid-scale-unbalanced":"fontawesome/solid/scale-unbalanced.svg","fontawesome-solid-school-circle-check":"fontawesome/solid/school-circle-check.svg","fontawesome-solid-school-circle-exclamation":"fontawesome/solid/school-circle-exclamation.svg","fontawesome-solid-school-circle-xmark":"fontawesome/solid/school-circle-xmark.svg","fontawesome-solid-school-flag":"fontawesome/solid/school-flag.svg","fontawesome-solid-school-lock":"fontawesome/solid/school-lock.svg","fontawesome-solid-school":"fontawesome/solid/school.svg","fontawesome-solid-scissors":"fontawesome/solid/scissors.svg","fontawesome-solid-screwdriver-wrench":"fontawesome/solid/screwdriver-wrench.svg","fontawesome-solid-screwdriver":"fontawesome/solid/screwdriver.svg","fontawesome-solid-scroll-torah":"fontawesome/solid/scroll-torah.svg","fontawesome-solid-scroll":"fontawesome/solid/scroll.svg","fontawesome-solid-sd-card":"fontawesome/solid/sd-card.svg","fontawesome-solid-section":"fontawesome/solid/section.svg","fontawesome-solid-seedling":"fontawesome/solid/seedling.svg","fontawesome-solid-server":"fontawesome/solid/server.svg","fontawesome-solid-shapes":"fontawesome/solid/shapes.svg","fontawesome-solid-share-from-square":"fontawesome/solid/share-from-square.svg","fontawesome-solid-share-nodes":"fontawesome/solid/share-nodes.svg","fontawesome-solid-share":"fontawesome/solid/share.svg","fontawesome-solid-sheet-plastic":"fontawesome/solid/sheet-plastic.svg","fontawesome-solid-shekel-sign":"fontawesome/solid/shekel-sign.svg","fontawesome-solid-shield-cat":"fontawesome/solid/shield-cat.svg","fontawesome-solid-shield-dog":"fontawesome/solid/shield-dog.svg","fontawesome-solid-shield-halved":"fontawesome/solid/shield-halved.svg","fontawesome-solid-shield-heart":"fontawesome/solid/shield-heart.svg","fontawesome-solid-shield-virus":"fontawesome/solid/shield-virus.svg","fontawesome-solid-shield":"fontawesome/solid/shield.svg","fontawesome-solid-ship":"fontawesome/solid/ship.svg","fontawesome-solid-shirt":"fontawesome/solid/shirt.svg","fontawesome-solid-shoe-prints":"fontawesome/solid/shoe-prints.svg","fontawesome-solid-shop-lock":"fontawesome/solid/shop-lock.svg","fontawesome-solid-shop-slash":"fontawesome/solid/shop-slash.svg","fontawesome-solid-shop":"fontawesome/solid/shop.svg","fontawesome-solid-shower":"fontawesome/solid/shower.svg","fontawesome-solid-shrimp":"fontawesome/solid/shrimp.svg","fontawesome-solid-shuffle":"fontawesome/solid/shuffle.svg","fontawesome-solid-shuttle-space":"fontawesome/solid/shuttle-space.svg","fontawesome-solid-sign-hanging":"fontawesome/solid/sign-hanging.svg","fontawesome-solid-signal":"fontawesome/solid/signal.svg","fontawesome-solid-signature":"fontawesome/solid/signature.svg","fontawesome-solid-signs-post":"fontawesome/solid/signs-post.svg","fontawesome-solid-sim-card":"fontawesome/solid/sim-card.svg","fontawesome-solid-sink":"fontawesome/solid/sink.svg","fontawesome-solid-sitemap":"fontawesome/solid/sitemap.svg","fontawesome-solid-skull-crossbones":"fontawesome/solid/skull-crossbones.svg","fontawesome-solid-skull":"fontawesome/solid/skull.svg","fontawesome-solid-slash":"fontawesome/solid/slash.svg","fontawesome-solid-sleigh":"fontawesome/solid/sleigh.svg","fontawesome-solid-sliders":"fontawesome/solid/sliders.svg","fontawesome-solid-smog":"fontawesome/solid/smog.svg","fontawesome-solid-smoking":"fontawesome/solid/smoking.svg","fontawesome-solid-snowflake":"fontawesome/solid/snowflake.svg","fontawesome-solid-snowman":"fontawesome/solid/snowman.svg","fontawesome-solid-snowplow":"fontawesome/solid/snowplow.svg","fontawesome-solid-soap":"fontawesome/solid/soap.svg","fontawesome-solid-socks":"fontawesome/solid/socks.svg","fontawesome-solid-solar-panel":"fontawesome/solid/solar-panel.svg","fontawesome-solid-sort-down":"fontawesome/solid/sort-down.svg","fontawesome-solid-sort-up":"fontawesome/solid/sort-up.svg","fontawesome-solid-sort":"fontawesome/solid/sort.svg","fontawesome-solid-spa":"fontawesome/solid/spa.svg","fontawesome-solid-spaghetti-monster-flying":"fontawesome/solid/spaghetti-monster-flying.svg","fontawesome-solid-spell-check":"fontawesome/solid/spell-check.svg","fontawesome-solid-spider":"fontawesome/solid/spider.svg","fontawesome-solid-spinner":"fontawesome/solid/spinner.svg","fontawesome-solid-splotch":"fontawesome/solid/splotch.svg","fontawesome-solid-spoon":"fontawesome/solid/spoon.svg","fontawesome-solid-spray-can-sparkles":"fontawesome/solid/spray-can-sparkles.svg","fontawesome-solid-spray-can":"fontawesome/solid/spray-can.svg","fontawesome-solid-square-arrow-up-right":"fontawesome/solid/square-arrow-up-right.svg","fontawesome-solid-square-caret-down":"fontawesome/solid/square-caret-down.svg","fontawesome-solid-square-caret-left":"fontawesome/solid/square-caret-left.svg","fontawesome-solid-square-caret-right":"fontawesome/solid/square-caret-right.svg","fontawesome-solid-square-caret-up":"fontawesome/solid/square-caret-up.svg","fontawesome-solid-square-check":"fontawesome/solid/square-check.svg","fontawesome-solid-square-envelope":"fontawesome/solid/square-envelope.svg","fontawesome-solid-square-full":"fontawesome/solid/square-full.svg","fontawesome-solid-square-h":"fontawesome/solid/square-h.svg","fontawesome-solid-square-minus":"fontawesome/solid/square-minus.svg","fontawesome-solid-square-nfi":"fontawesome/solid/square-nfi.svg","fontawesome-solid-square-parking":"fontawesome/solid/square-parking.svg","fontawesome-solid-square-pen":"fontawesome/solid/square-pen.svg","fontawesome-solid-square-person-confined":"fontawesome/solid/square-person-confined.svg","fontawesome-solid-square-phone-flip":"fontawesome/solid/square-phone-flip.svg","fontawesome-solid-square-phone":"fontawesome/solid/square-phone.svg","fontawesome-solid-square-plus":"fontawesome/solid/square-plus.svg","fontawesome-solid-square-poll-horizontal":"fontawesome/solid/square-poll-horizontal.svg","fontawesome-solid-square-poll-vertical":"fontawesome/solid/square-poll-vertical.svg","fontawesome-solid-square-root-variable":"fontawesome/solid/square-root-variable.svg","fontawesome-solid-square-rss":"fontawesome/solid/square-rss.svg","fontawesome-solid-square-share-nodes":"fontawesome/solid/square-share-nodes.svg","fontawesome-solid-square-up-right":"fontawesome/solid/square-up-right.svg","fontawesome-solid-square-virus":"fontawesome/solid/square-virus.svg","fontawesome-solid-square-xmark":"fontawesome/solid/square-xmark.svg","fontawesome-solid-square":"fontawesome/solid/square.svg","fontawesome-solid-staff-snake":"fontawesome/solid/staff-snake.svg","fontawesome-solid-stairs":"fontawesome/solid/stairs.svg","fontawesome-solid-stamp":"fontawesome/solid/stamp.svg","fontawesome-solid-stapler":"fontawesome/solid/stapler.svg","fontawesome-solid-star-and-crescent":"fontawesome/solid/star-and-crescent.svg","fontawesome-solid-star-half-stroke":"fontawesome/solid/star-half-stroke.svg","fontawesome-solid-star-half":"fontawesome/solid/star-half.svg","fontawesome-solid-star-of-david":"fontawesome/solid/star-of-david.svg","fontawesome-solid-star-of-life":"fontawesome/solid/star-of-life.svg","fontawesome-solid-star":"fontawesome/solid/star.svg","fontawesome-solid-sterling-sign":"fontawesome/solid/sterling-sign.svg","fontawesome-solid-stethoscope":"fontawesome/solid/stethoscope.svg","fontawesome-solid-stop":"fontawesome/solid/stop.svg","fontawesome-solid-stopwatch-20":"fontawesome/solid/stopwatch-20.svg","fontawesome-solid-stopwatch":"fontawesome/solid/stopwatch.svg","fontawesome-solid-store-slash":"fontawesome/solid/store-slash.svg","fontawesome-solid-store":"fontawesome/solid/store.svg","fontawesome-solid-street-view":"fontawesome/solid/street-view.svg","fontawesome-solid-strikethrough":"fontawesome/solid/strikethrough.svg","fontawesome-solid-stroopwafel":"fontawesome/solid/stroopwafel.svg","fontawesome-solid-subscript":"fontawesome/solid/subscript.svg","fontawesome-solid-suitcase-medical":"fontawesome/solid/suitcase-medical.svg","fontawesome-solid-suitcase-rolling":"fontawesome/solid/suitcase-rolling.svg","fontawesome-solid-suitcase":"fontawesome/solid/suitcase.svg","fontawesome-solid-sun-plant-wilt":"fontawesome/solid/sun-plant-wilt.svg","fontawesome-solid-sun":"fontawesome/solid/sun.svg","fontawesome-solid-superscript":"fontawesome/solid/superscript.svg","fontawesome-solid-swatchbook":"fontawesome/solid/swatchbook.svg","fontawesome-solid-synagogue":"fontawesome/solid/synagogue.svg","fontawesome-solid-syringe":"fontawesome/solid/syringe.svg","fontawesome-solid-t":"fontawesome/solid/t.svg","fontawesome-solid-table-cells-large":"fontawesome/solid/table-cells-large.svg","fontawesome-solid-table-cells":"fontawesome/solid/table-cells.svg","fontawesome-solid-table-columns":"fontawesome/solid/table-columns.svg","fontawesome-solid-table-list":"fontawesome/solid/table-list.svg","fontawesome-solid-table-tennis-paddle-ball":"fontawesome/solid/table-tennis-paddle-ball.svg","fontawesome-solid-table":"fontawesome/solid/table.svg","fontawesome-solid-tablet-button":"fontawesome/solid/tablet-button.svg","fontawesome-solid-tablet-screen-button":"fontawesome/solid/tablet-screen-button.svg","fontawesome-solid-tablet":"fontawesome/solid/tablet.svg","fontawesome-solid-tablets":"fontawesome/solid/tablets.svg","fontawesome-solid-tachograph-digital":"fontawesome/solid/tachograph-digital.svg","fontawesome-solid-tag":"fontawesome/solid/tag.svg","fontawesome-solid-tags":"fontawesome/solid/tags.svg","fontawesome-solid-tape":"fontawesome/solid/tape.svg","fontawesome-solid-tarp-droplet":"fontawesome/solid/tarp-droplet.svg","fontawesome-solid-tarp":"fontawesome/solid/tarp.svg","fontawesome-solid-taxi":"fontawesome/solid/taxi.svg","fontawesome-solid-teeth-open":"fontawesome/solid/teeth-open.svg","fontawesome-solid-teeth":"fontawesome/solid/teeth.svg","fontawesome-solid-temperature-arrow-down":"fontawesome/solid/temperature-arrow-down.svg","fontawesome-solid-temperature-arrow-up":"fontawesome/solid/temperature-arrow-up.svg","fontawesome-solid-temperature-empty":"fontawesome/solid/temperature-empty.svg","fontawesome-solid-temperature-full":"fontawesome/solid/temperature-full.svg","fontawesome-solid-temperature-half":"fontawesome/solid/temperature-half.svg","fontawesome-solid-temperature-high":"fontawesome/solid/temperature-high.svg","fontawesome-solid-temperature-low":"fontawesome/solid/temperature-low.svg","fontawesome-solid-temperature-quarter":"fontawesome/solid/temperature-quarter.svg","fontawesome-solid-temperature-three-quarters":"fontawesome/solid/temperature-three-quarters.svg","fontawesome-solid-tenge-sign":"fontawesome/solid/tenge-sign.svg","fontawesome-solid-tent-arrow-down-to-line":"fontawesome/solid/tent-arrow-down-to-line.svg","fontawesome-solid-tent-arrow-left-right":"fontawesome/solid/tent-arrow-left-right.svg","fontawesome-solid-tent-arrow-turn-left":"fontawesome/solid/tent-arrow-turn-left.svg","fontawesome-solid-tent-arrows-down":"fontawesome/solid/tent-arrows-down.svg","fontawesome-solid-tent":"fontawesome/solid/tent.svg","fontawesome-solid-tents":"fontawesome/solid/tents.svg","fontawesome-solid-terminal":"fontawesome/solid/terminal.svg","fontawesome-solid-text-height":"fontawesome/solid/text-height.svg","fontawesome-solid-text-slash":"fontawesome/solid/text-slash.svg","fontawesome-solid-text-width":"fontawesome/solid/text-width.svg","fontawesome-solid-thermometer":"fontawesome/solid/thermometer.svg","fontawesome-solid-thumbs-down":"fontawesome/solid/thumbs-down.svg","fontawesome-solid-thumbs-up":"fontawesome/solid/thumbs-up.svg","fontawesome-solid-thumbtack":"fontawesome/solid/thumbtack.svg","fontawesome-solid-ticket-simple":"fontawesome/solid/ticket-simple.svg","fontawesome-solid-ticket":"fontawesome/solid/ticket.svg","fontawesome-solid-timeline":"fontawesome/solid/timeline.svg","fontawesome-solid-toggle-off":"fontawesome/solid/toggle-off.svg","fontawesome-solid-toggle-on":"fontawesome/solid/toggle-on.svg","fontawesome-solid-toilet-paper-slash":"fontawesome/solid/toilet-paper-slash.svg","fontawesome-solid-toilet-paper":"fontawesome/solid/toilet-paper.svg","fontawesome-solid-toilet-portable":"fontawesome/solid/toilet-portable.svg","fontawesome-solid-toilet":"fontawesome/solid/toilet.svg","fontawesome-solid-toilets-portable":"fontawesome/solid/toilets-portable.svg","fontawesome-solid-toolbox":"fontawesome/solid/toolbox.svg","fontawesome-solid-tooth":"fontawesome/solid/tooth.svg","fontawesome-solid-torii-gate":"fontawesome/solid/torii-gate.svg","fontawesome-solid-tornado":"fontawesome/solid/tornado.svg","fontawesome-solid-tower-broadcast":"fontawesome/solid/tower-broadcast.svg","fontawesome-solid-tower-cell":"fontawesome/solid/tower-cell.svg","fontawesome-solid-tower-observation":"fontawesome/solid/tower-observation.svg","fontawesome-solid-tractor":"fontawesome/solid/tractor.svg","fontawesome-solid-trademark":"fontawesome/solid/trademark.svg","fontawesome-solid-traffic-light":"fontawesome/solid/traffic-light.svg","fontawesome-solid-trailer":"fontawesome/solid/trailer.svg","fontawesome-solid-train-subway":"fontawesome/solid/train-subway.svg","fontawesome-solid-train-tram":"fontawesome/solid/train-tram.svg","fontawesome-solid-train":"fontawesome/solid/train.svg","fontawesome-solid-transgender":"fontawesome/solid/transgender.svg","fontawesome-solid-trash-arrow-up":"fontawesome/solid/trash-arrow-up.svg","fontawesome-solid-trash-can-arrow-up":"fontawesome/solid/trash-can-arrow-up.svg","fontawesome-solid-trash-can":"fontawesome/solid/trash-can.svg","fontawesome-solid-trash":"fontawesome/solid/trash.svg","fontawesome-solid-tree-city":"fontawesome/solid/tree-city.svg","fontawesome-solid-tree":"fontawesome/solid/tree.svg","fontawesome-solid-triangle-exclamation":"fontawesome/solid/triangle-exclamation.svg","fontawesome-solid-trophy":"fontawesome/solid/trophy.svg","fontawesome-solid-trowel-bricks":"fontawesome/solid/trowel-bricks.svg","fontawesome-solid-trowel":"fontawesome/solid/trowel.svg","fontawesome-solid-truck-arrow-right":"fontawesome/solid/truck-arrow-right.svg","fontawesome-solid-truck-droplet":"fontawesome/solid/truck-droplet.svg","fontawesome-solid-truck-fast":"fontawesome/solid/truck-fast.svg","fontawesome-solid-truck-field-un":"fontawesome/solid/truck-field-un.svg","fontawesome-solid-truck-field":"fontawesome/solid/truck-field.svg","fontawesome-solid-truck-front":"fontawesome/solid/truck-front.svg","fontawesome-solid-truck-medical":"fontawesome/solid/truck-medical.svg","fontawesome-solid-truck-monster":"fontawesome/solid/truck-monster.svg","fontawesome-solid-truck-moving":"fontawesome/solid/truck-moving.svg","fontawesome-solid-truck-pickup":"fontawesome/solid/truck-pickup.svg","fontawesome-solid-truck-plane":"fontawesome/solid/truck-plane.svg","fontawesome-solid-truck-ramp-box":"fontawesome/solid/truck-ramp-box.svg","fontawesome-solid-truck":"fontawesome/solid/truck.svg","fontawesome-solid-tty":"fontawesome/solid/tty.svg","fontawesome-solid-turkish-lira-sign":"fontawesome/solid/turkish-lira-sign.svg","fontawesome-solid-turn-down":"fontawesome/solid/turn-down.svg","fontawesome-solid-turn-up":"fontawesome/solid/turn-up.svg","fontawesome-solid-tv":"fontawesome/solid/tv.svg","fontawesome-solid-u":"fontawesome/solid/u.svg","fontawesome-solid-umbrella-beach":"fontawesome/solid/umbrella-beach.svg","fontawesome-solid-umbrella":"fontawesome/solid/umbrella.svg","fontawesome-solid-underline":"fontawesome/solid/underline.svg","fontawesome-solid-universal-access":"fontawesome/solid/universal-access.svg","fontawesome-solid-unlock-keyhole":"fontawesome/solid/unlock-keyhole.svg","fontawesome-solid-unlock":"fontawesome/solid/unlock.svg","fontawesome-solid-up-down-left-right":"fontawesome/solid/up-down-left-right.svg","fontawesome-solid-up-down":"fontawesome/solid/up-down.svg","fontawesome-solid-up-long":"fontawesome/solid/up-long.svg","fontawesome-solid-up-right-and-down-left-from-center":"fontawesome/solid/up-right-and-down-left-from-center.svg","fontawesome-solid-up-right-from-square":"fontawesome/solid/up-right-from-square.svg","fontawesome-solid-upload":"fontawesome/solid/upload.svg","fontawesome-solid-user-astronaut":"fontawesome/solid/user-astronaut.svg","fontawesome-solid-user-check":"fontawesome/solid/user-check.svg","fontawesome-solid-user-clock":"fontawesome/solid/user-clock.svg","fontawesome-solid-user-doctor":"fontawesome/solid/user-doctor.svg","fontawesome-solid-user-gear":"fontawesome/solid/user-gear.svg","fontawesome-solid-user-graduate":"fontawesome/solid/user-graduate.svg","fontawesome-solid-user-group":"fontawesome/solid/user-group.svg","fontawesome-solid-user-injured":"fontawesome/solid/user-injured.svg","fontawesome-solid-user-large-slash":"fontawesome/solid/user-large-slash.svg","fontawesome-solid-user-large":"fontawesome/solid/user-large.svg","fontawesome-solid-user-lock":"fontawesome/solid/user-lock.svg","fontawesome-solid-user-minus":"fontawesome/solid/user-minus.svg","fontawesome-solid-user-ninja":"fontawesome/solid/user-ninja.svg","fontawesome-solid-user-nurse":"fontawesome/solid/user-nurse.svg","fontawesome-solid-user-pen":"fontawesome/solid/user-pen.svg","fontawesome-solid-user-plus":"fontawesome/solid/user-plus.svg","fontawesome-solid-user-secret":"fontawesome/solid/user-secret.svg","fontawesome-solid-user-shield":"fontawesome/solid/user-shield.svg","fontawesome-solid-user-slash":"fontawesome/solid/user-slash.svg","fontawesome-solid-user-tag":"fontawesome/solid/user-tag.svg","fontawesome-solid-user-tie":"fontawesome/solid/user-tie.svg","fontawesome-solid-user-xmark":"fontawesome/solid/user-xmark.svg","fontawesome-solid-user":"fontawesome/solid/user.svg","fontawesome-solid-users-between-lines":"fontawesome/solid/users-between-lines.svg","fontawesome-solid-users-gear":"fontawesome/solid/users-gear.svg","fontawesome-solid-users-line":"fontawesome/solid/users-line.svg","fontawesome-solid-users-rays":"fontawesome/solid/users-rays.svg","fontawesome-solid-users-rectangle":"fontawesome/solid/users-rectangle.svg","fontawesome-solid-users-slash":"fontawesome/solid/users-slash.svg","fontawesome-solid-users-viewfinder":"fontawesome/solid/users-viewfinder.svg","fontawesome-solid-users":"fontawesome/solid/users.svg","fontawesome-solid-utensils":"fontawesome/solid/utensils.svg","fontawesome-solid-v":"fontawesome/solid/v.svg","fontawesome-solid-van-shuttle":"fontawesome/solid/van-shuttle.svg","fontawesome-solid-vault":"fontawesome/solid/vault.svg","fontawesome-solid-vector-square":"fontawesome/solid/vector-square.svg","fontawesome-solid-venus-double":"fontawesome/solid/venus-double.svg","fontawesome-solid-venus-mars":"fontawesome/solid/venus-mars.svg","fontawesome-solid-venus":"fontawesome/solid/venus.svg","fontawesome-solid-vest-patches":"fontawesome/solid/vest-patches.svg","fontawesome-solid-vest":"fontawesome/solid/vest.svg","fontawesome-solid-vial-circle-check":"fontawesome/solid/vial-circle-check.svg","fontawesome-solid-vial-virus":"fontawesome/solid/vial-virus.svg","fontawesome-solid-vial":"fontawesome/solid/vial.svg","fontawesome-solid-vials":"fontawesome/solid/vials.svg","fontawesome-solid-video-slash":"fontawesome/solid/video-slash.svg","fontawesome-solid-video":"fontawesome/solid/video.svg","fontawesome-solid-vihara":"fontawesome/solid/vihara.svg","fontawesome-solid-virus-covid-slash":"fontawesome/solid/virus-covid-slash.svg","fontawesome-solid-virus-covid":"fontawesome/solid/virus-covid.svg","fontawesome-solid-virus-slash":"fontawesome/solid/virus-slash.svg","fontawesome-solid-virus":"fontawesome/solid/virus.svg","fontawesome-solid-viruses":"fontawesome/solid/viruses.svg","fontawesome-solid-voicemail":"fontawesome/solid/voicemail.svg","fontawesome-solid-volcano":"fontawesome/solid/volcano.svg","fontawesome-solid-volleyball":"fontawesome/solid/volleyball.svg","fontawesome-solid-volume-high":"fontawesome/solid/volume-high.svg","fontawesome-solid-volume-low":"fontawesome/solid/volume-low.svg","fontawesome-solid-volume-off":"fontawesome/solid/volume-off.svg","fontawesome-solid-volume-xmark":"fontawesome/solid/volume-xmark.svg","fontawesome-solid-vr-cardboard":"fontawesome/solid/vr-cardboard.svg","fontawesome-solid-w":"fontawesome/solid/w.svg","fontawesome-solid-walkie-talkie":"fontawesome/solid/walkie-talkie.svg","fontawesome-solid-wallet":"fontawesome/solid/wallet.svg","fontawesome-solid-wand-magic-sparkles":"fontawesome/solid/wand-magic-sparkles.svg","fontawesome-solid-wand-magic":"fontawesome/solid/wand-magic.svg","fontawesome-solid-wand-sparkles":"fontawesome/solid/wand-sparkles.svg","fontawesome-solid-warehouse":"fontawesome/solid/warehouse.svg","fontawesome-solid-water-ladder":"fontawesome/solid/water-ladder.svg","fontawesome-solid-water":"fontawesome/solid/water.svg","fontawesome-solid-wave-square":"fontawesome/solid/wave-square.svg","fontawesome-solid-weight-hanging":"fontawesome/solid/weight-hanging.svg","fontawesome-solid-weight-scale":"fontawesome/solid/weight-scale.svg","fontawesome-solid-wheat-awn-circle-exclamation":"fontawesome/solid/wheat-awn-circle-exclamation.svg","fontawesome-solid-wheat-awn":"fontawesome/solid/wheat-awn.svg","fontawesome-solid-wheelchair-move":"fontawesome/solid/wheelchair-move.svg","fontawesome-solid-wheelchair":"fontawesome/solid/wheelchair.svg","fontawesome-solid-whiskey-glass":"fontawesome/solid/whiskey-glass.svg","fontawesome-solid-wifi":"fontawesome/solid/wifi.svg","fontawesome-solid-wind":"fontawesome/solid/wind.svg","fontawesome-solid-window-maximize":"fontawesome/solid/window-maximize.svg","fontawesome-solid-window-minimize":"fontawesome/solid/window-minimize.svg","fontawesome-solid-window-restore":"fontawesome/solid/window-restore.svg","fontawesome-solid-wine-bottle":"fontawesome/solid/wine-bottle.svg","fontawesome-solid-wine-glass-empty":"fontawesome/solid/wine-glass-empty.svg","fontawesome-solid-wine-glass":"fontawesome/solid/wine-glass.svg","fontawesome-solid-won-sign":"fontawesome/solid/won-sign.svg","fontawesome-solid-worm":"fontawesome/solid/worm.svg","fontawesome-solid-wrench":"fontawesome/solid/wrench.svg","fontawesome-solid-x-ray":"fontawesome/solid/x-ray.svg","fontawesome-solid-x":"fontawesome/solid/x.svg","fontawesome-solid-xmark":"fontawesome/solid/xmark.svg","fontawesome-solid-xmarks-lines":"fontawesome/solid/xmarks-lines.svg","fontawesome-solid-y":"fontawesome/solid/y.svg","fontawesome-solid-yen-sign":"fontawesome/solid/yen-sign.svg","fontawesome-solid-yin-yang":"fontawesome/solid/yin-yang.svg","fontawesome-solid-z":"fontawesome/solid/z.svg","logo":"logo.svg","material-ab-testing":"material/ab-testing.svg","material-abacus":"material/abacus.svg","material-abjad-arabic":"material/abjad-arabic.svg","material-abjad-hebrew":"material/abjad-hebrew.svg","material-abugida-devanagari":"material/abugida-devanagari.svg","material-abugida-thai":"material/abugida-thai.svg","material-access-point-check":"material/access-point-check.svg","material-access-point-minus":"material/access-point-minus.svg","material-access-point-network-off":"material/access-point-network-off.svg","material-access-point-network":"material/access-point-network.svg","material-access-point-off":"material/access-point-off.svg","material-access-point-plus":"material/access-point-plus.svg","material-access-point-remove":"material/access-point-remove.svg","material-access-point":"material/access-point.svg","material-account-alert-outline":"material/account-alert-outline.svg","material-account-alert":"material/account-alert.svg","material-account-arrow-down-outline":"material/account-arrow-down-outline.svg","material-account-arrow-down":"material/account-arrow-down.svg","material-account-arrow-left-outline":"material/account-arrow-left-outline.svg","material-account-arrow-left":"material/account-arrow-left.svg","material-account-arrow-right-outline":"material/account-arrow-right-outline.svg","material-account-arrow-right":"material/account-arrow-right.svg","material-account-arrow-up-outline":"material/account-arrow-up-outline.svg","material-account-arrow-up":"material/account-arrow-up.svg","material-account-badge-outline":"material/account-badge-outline.svg","material-account-badge":"material/account-badge.svg","material-account-box-multiple-outline":"material/account-box-multiple-outline.svg","material-account-box-multiple":"material/account-box-multiple.svg","material-account-box-outline":"material/account-box-outline.svg","material-account-box":"material/account-box.svg","material-account-cancel-outline":"material/account-cancel-outline.svg","material-account-cancel":"material/account-cancel.svg","material-account-card-outline":"material/account-card-outline.svg","material-account-card":"material/account-card.svg","material-account-cash-outline":"material/account-cash-outline.svg","material-account-cash":"material/account-cash.svg","material-account-check-outline":"material/account-check-outline.svg","material-account-check":"material/account-check.svg","material-account-child-circle":"material/account-child-circle.svg","material-account-child-outline":"material/account-child-outline.svg","material-account-child":"material/account-child.svg","material-account-circle-outline":"material/account-circle-outline.svg","material-account-circle":"material/account-circle.svg","material-account-clock-outline":"material/account-clock-outline.svg","material-account-clock":"material/account-clock.svg","material-account-cog-outline":"material/account-cog-outline.svg","material-account-cog":"material/account-cog.svg","material-account-convert-outline":"material/account-convert-outline.svg","material-account-convert":"material/account-convert.svg","material-account-cowboy-hat-outline":"material/account-cowboy-hat-outline.svg","material-account-cowboy-hat":"material/account-cowboy-hat.svg","material-account-credit-card-outline":"material/account-credit-card-outline.svg","material-account-credit-card":"material/account-credit-card.svg","material-account-details-outline":"material/account-details-outline.svg","material-account-details":"material/account-details.svg","material-account-edit-outline":"material/account-edit-outline.svg","material-account-edit":"material/account-edit.svg","material-account-eye-outline":"material/account-eye-outline.svg","material-account-eye":"material/account-eye.svg","material-account-filter-outline":"material/account-filter-outline.svg","material-account-filter":"material/account-filter.svg","material-account-group-outline":"material/account-group-outline.svg","material-account-group":"material/account-group.svg","material-account-hard-hat-outline":"material/account-hard-hat-outline.svg","material-account-hard-hat":"material/account-hard-hat.svg","material-account-heart-outline":"material/account-heart-outline.svg","material-account-heart":"material/account-heart.svg","material-account-injury-outline":"material/account-injury-outline.svg","material-account-injury":"material/account-injury.svg","material-account-key-outline":"material/account-key-outline.svg","material-account-key":"material/account-key.svg","material-account-lock-open-outline":"material/account-lock-open-outline.svg","material-account-lock-open":"material/account-lock-open.svg","material-account-lock-outline":"material/account-lock-outline.svg","material-account-lock":"material/account-lock.svg","material-account-minus-outline":"material/account-minus-outline.svg","material-account-minus":"material/account-minus.svg","material-account-multiple-check-outline":"material/account-multiple-check-outline.svg","material-account-multiple-check":"material/account-multiple-check.svg","material-account-multiple-minus-outline":"material/account-multiple-minus-outline.svg","material-account-multiple-minus":"material/account-multiple-minus.svg","material-account-multiple-outline":"material/account-multiple-outline.svg","material-account-multiple-plus-outline":"material/account-multiple-plus-outline.svg","material-account-multiple-plus":"material/account-multiple-plus.svg","material-account-multiple-remove-outline":"material/account-multiple-remove-outline.svg","material-account-multiple-remove":"material/account-multiple-remove.svg","material-account-multiple":"material/account-multiple.svg","material-account-music-outline":"material/account-music-outline.svg","material-account-music":"material/account-music.svg","material-account-network-off-outline":"material/account-network-off-outline.svg","material-account-network-off":"material/account-network-off.svg","material-account-network-outline":"material/account-network-outline.svg","material-account-network":"material/account-network.svg","material-account-off-outline":"material/account-off-outline.svg","material-account-off":"material/account-off.svg","material-account-outline":"material/account-outline.svg","material-account-plus-outline":"material/account-plus-outline.svg","material-account-plus":"material/account-plus.svg","material-account-question-outline":"material/account-question-outline.svg","material-account-question":"material/account-question.svg","material-account-reactivate-outline":"material/account-reactivate-outline.svg","material-account-reactivate":"material/account-reactivate.svg","material-account-remove-outline":"material/account-remove-outline.svg","material-account-remove":"material/account-remove.svg","material-account-school-outline":"material/account-school-outline.svg","material-account-school":"material/account-school.svg","material-account-search-outline":"material/account-search-outline.svg","material-account-search":"material/account-search.svg","material-account-settings-outline":"material/account-settings-outline.svg","material-account-settings":"material/account-settings.svg","material-account-star-outline":"material/account-star-outline.svg","material-account-star":"material/account-star.svg","material-account-supervisor-circle-outline":"material/account-supervisor-circle-outline.svg","material-account-supervisor-circle":"material/account-supervisor-circle.svg","material-account-supervisor-outline":"material/account-supervisor-outline.svg","material-account-supervisor":"material/account-supervisor.svg","material-account-switch-outline":"material/account-switch-outline.svg","material-account-switch":"material/account-switch.svg","material-account-sync-outline":"material/account-sync-outline.svg","material-account-sync":"material/account-sync.svg","material-account-tie-hat-outline":"material/account-tie-hat-outline.svg","material-account-tie-hat":"material/account-tie-hat.svg","material-account-tie-outline":"material/account-tie-outline.svg","material-account-tie-voice-off-outline":"material/account-tie-voice-off-outline.svg","material-account-tie-voice-off":"material/account-tie-voice-off.svg","material-account-tie-voice-outline":"material/account-tie-voice-outline.svg","material-account-tie-voice":"material/account-tie-voice.svg","material-account-tie-woman":"material/account-tie-woman.svg","material-account-tie":"material/account-tie.svg","material-account-voice-off":"material/account-voice-off.svg","material-account-voice":"material/account-voice.svg","material-account-wrench-outline":"material/account-wrench-outline.svg","material-account-wrench":"material/account-wrench.svg","material-account":"material/account.svg","material-adjust":"material/adjust.svg","material-advertisements-off":"material/advertisements-off.svg","material-advertisements":"material/advertisements.svg","material-air-conditioner":"material/air-conditioner.svg","material-air-filter":"material/air-filter.svg","material-air-horn":"material/air-horn.svg","material-air-humidifier-off":"material/air-humidifier-off.svg","material-air-humidifier":"material/air-humidifier.svg","material-air-purifier-off":"material/air-purifier-off.svg","material-air-purifier":"material/air-purifier.svg","material-airbag":"material/airbag.svg","material-airballoon-outline":"material/airballoon-outline.svg","material-airballoon":"material/airballoon.svg","material-airplane-alert":"material/airplane-alert.svg","material-airplane-check":"material/airplane-check.svg","material-airplane-clock":"material/airplane-clock.svg","material-airplane-cog":"material/airplane-cog.svg","material-airplane-edit":"material/airplane-edit.svg","material-airplane-landing":"material/airplane-landing.svg","material-airplane-marker":"material/airplane-marker.svg","material-airplane-minus":"material/airplane-minus.svg","material-airplane-off":"material/airplane-off.svg","material-airplane-plus":"material/airplane-plus.svg","material-airplane-remove":"material/airplane-remove.svg","material-airplane-search":"material/airplane-search.svg","material-airplane-settings":"material/airplane-settings.svg","material-airplane-takeoff":"material/airplane-takeoff.svg","material-airplane":"material/airplane.svg","material-airport":"material/airport.svg","material-alarm-bell":"material/alarm-bell.svg","material-alarm-check":"material/alarm-check.svg","material-alarm-light-off-outline":"material/alarm-light-off-outline.svg","material-alarm-light-off":"material/alarm-light-off.svg","material-alarm-light-outline":"material/alarm-light-outline.svg","material-alarm-light":"material/alarm-light.svg","material-alarm-multiple":"material/alarm-multiple.svg","material-alarm-note-off":"material/alarm-note-off.svg","material-alarm-note":"material/alarm-note.svg","material-alarm-off":"material/alarm-off.svg","material-alarm-panel-outline":"material/alarm-panel-outline.svg","material-alarm-panel":"material/alarm-panel.svg","material-alarm-plus":"material/alarm-plus.svg","material-alarm-snooze":"material/alarm-snooze.svg","material-alarm":"material/alarm.svg","material-album":"material/album.svg","material-alert-box-outline":"material/alert-box-outline.svg","material-alert-box":"material/alert-box.svg","material-alert-circle-check-outline":"material/alert-circle-check-outline.svg","material-alert-circle-check":"material/alert-circle-check.svg","material-alert-circle-outline":"material/alert-circle-outline.svg","material-alert-circle":"material/alert-circle.svg","material-alert-decagram-outline":"material/alert-decagram-outline.svg","material-alert-decagram":"material/alert-decagram.svg","material-alert-minus-outline":"material/alert-minus-outline.svg","material-alert-minus":"material/alert-minus.svg","material-alert-octagon-outline":"material/alert-octagon-outline.svg","material-alert-octagon":"material/alert-octagon.svg","material-alert-octagram-outline":"material/alert-octagram-outline.svg","material-alert-octagram":"material/alert-octagram.svg","material-alert-outline":"material/alert-outline.svg","material-alert-plus-outline":"material/alert-plus-outline.svg","material-alert-plus":"material/alert-plus.svg","material-alert-remove-outline":"material/alert-remove-outline.svg","material-alert-remove":"material/alert-remove.svg","material-alert-rhombus-outline":"material/alert-rhombus-outline.svg","material-alert-rhombus":"material/alert-rhombus.svg","material-alert":"material/alert.svg","material-alien-outline":"material/alien-outline.svg","material-alien":"material/alien.svg","material-align-horizontal-center":"material/align-horizontal-center.svg","material-align-horizontal-distribute":"material/align-horizontal-distribute.svg","material-align-horizontal-left":"material/align-horizontal-left.svg","material-align-horizontal-right":"material/align-horizontal-right.svg","material-align-vertical-bottom":"material/align-vertical-bottom.svg","material-align-vertical-center":"material/align-vertical-center.svg","material-align-vertical-distribute":"material/align-vertical-distribute.svg","material-align-vertical-top":"material/align-vertical-top.svg","material-all-inclusive-box-outline":"material/all-inclusive-box-outline.svg","material-all-inclusive-box":"material/all-inclusive-box.svg","material-all-inclusive":"material/all-inclusive.svg","material-allergy":"material/allergy.svg","material-alpha-a-box-outline":"material/alpha-a-box-outline.svg","material-alpha-a-box":"material/alpha-a-box.svg","material-alpha-a-circle-outline":"material/alpha-a-circle-outline.svg","material-alpha-a-circle":"material/alpha-a-circle.svg","material-alpha-a":"material/alpha-a.svg","material-alpha-b-box-outline":"material/alpha-b-box-outline.svg","material-alpha-b-box":"material/alpha-b-box.svg","material-alpha-b-circle-outline":"material/alpha-b-circle-outline.svg","material-alpha-b-circle":"material/alpha-b-circle.svg","material-alpha-b":"material/alpha-b.svg","material-alpha-c-box-outline":"material/alpha-c-box-outline.svg","material-alpha-c-box":"material/alpha-c-box.svg","material-alpha-c-circle-outline":"material/alpha-c-circle-outline.svg","material-alpha-c-circle":"material/alpha-c-circle.svg","material-alpha-c":"material/alpha-c.svg","material-alpha-d-box-outline":"material/alpha-d-box-outline.svg","material-alpha-d-box":"material/alpha-d-box.svg","material-alpha-d-circle-outline":"material/alpha-d-circle-outline.svg","material-alpha-d-circle":"material/alpha-d-circle.svg","material-alpha-d":"material/alpha-d.svg","material-alpha-e-box-outline":"material/alpha-e-box-outline.svg","material-alpha-e-box":"material/alpha-e-box.svg","material-alpha-e-circle-outline":"material/alpha-e-circle-outline.svg","material-alpha-e-circle":"material/alpha-e-circle.svg","material-alpha-e":"material/alpha-e.svg","material-alpha-f-box-outline":"material/alpha-f-box-outline.svg","material-alpha-f-box":"material/alpha-f-box.svg","material-alpha-f-circle-outline":"material/alpha-f-circle-outline.svg","material-alpha-f-circle":"material/alpha-f-circle.svg","material-alpha-f":"material/alpha-f.svg","material-alpha-g-box-outline":"material/alpha-g-box-outline.svg","material-alpha-g-box":"material/alpha-g-box.svg","material-alpha-g-circle-outline":"material/alpha-g-circle-outline.svg","material-alpha-g-circle":"material/alpha-g-circle.svg","material-alpha-g":"material/alpha-g.svg","material-alpha-h-box-outline":"material/alpha-h-box-outline.svg","material-alpha-h-box":"material/alpha-h-box.svg","material-alpha-h-circle-outline":"material/alpha-h-circle-outline.svg","material-alpha-h-circle":"material/alpha-h-circle.svg","material-alpha-h":"material/alpha-h.svg","material-alpha-i-box-outline":"material/alpha-i-box-outline.svg","material-alpha-i-box":"material/alpha-i-box.svg","material-alpha-i-circle-outline":"material/alpha-i-circle-outline.svg","material-alpha-i-circle":"material/alpha-i-circle.svg","material-alpha-i":"material/alpha-i.svg","material-alpha-j-box-outline":"material/alpha-j-box-outline.svg","material-alpha-j-box":"material/alpha-j-box.svg","material-alpha-j-circle-outline":"material/alpha-j-circle-outline.svg","material-alpha-j-circle":"material/alpha-j-circle.svg","material-alpha-j":"material/alpha-j.svg","material-alpha-k-box-outline":"material/alpha-k-box-outline.svg","material-alpha-k-box":"material/alpha-k-box.svg","material-alpha-k-circle-outline":"material/alpha-k-circle-outline.svg","material-alpha-k-circle":"material/alpha-k-circle.svg","material-alpha-k":"material/alpha-k.svg","material-alpha-l-box-outline":"material/alpha-l-box-outline.svg","material-alpha-l-box":"material/alpha-l-box.svg","material-alpha-l-circle-outline":"material/alpha-l-circle-outline.svg","material-alpha-l-circle":"material/alpha-l-circle.svg","material-alpha-l":"material/alpha-l.svg","material-alpha-m-box-outline":"material/alpha-m-box-outline.svg","material-alpha-m-box":"material/alpha-m-box.svg","material-alpha-m-circle-outline":"material/alpha-m-circle-outline.svg","material-alpha-m-circle":"material/alpha-m-circle.svg","material-alpha-m":"material/alpha-m.svg","material-alpha-n-box-outline":"material/alpha-n-box-outline.svg","material-alpha-n-box":"material/alpha-n-box.svg","material-alpha-n-circle-outline":"material/alpha-n-circle-outline.svg","material-alpha-n-circle":"material/alpha-n-circle.svg","material-alpha-n":"material/alpha-n.svg","material-alpha-o-box-outline":"material/alpha-o-box-outline.svg","material-alpha-o-box":"material/alpha-o-box.svg","material-alpha-o-circle-outline":"material/alpha-o-circle-outline.svg","material-alpha-o-circle":"material/alpha-o-circle.svg","material-alpha-o":"material/alpha-o.svg","material-alpha-p-box-outline":"material/alpha-p-box-outline.svg","material-alpha-p-box":"material/alpha-p-box.svg","material-alpha-p-circle-outline":"material/alpha-p-circle-outline.svg","material-alpha-p-circle":"material/alpha-p-circle.svg","material-alpha-p":"material/alpha-p.svg","material-alpha-q-box-outline":"material/alpha-q-box-outline.svg","material-alpha-q-box":"material/alpha-q-box.svg","material-alpha-q-circle-outline":"material/alpha-q-circle-outline.svg","material-alpha-q-circle":"material/alpha-q-circle.svg","material-alpha-q":"material/alpha-q.svg","material-alpha-r-box-outline":"material/alpha-r-box-outline.svg","material-alpha-r-box":"material/alpha-r-box.svg","material-alpha-r-circle-outline":"material/alpha-r-circle-outline.svg","material-alpha-r-circle":"material/alpha-r-circle.svg","material-alpha-r":"material/alpha-r.svg","material-alpha-s-box-outline":"material/alpha-s-box-outline.svg","material-alpha-s-box":"material/alpha-s-box.svg","material-alpha-s-circle-outline":"material/alpha-s-circle-outline.svg","material-alpha-s-circle":"material/alpha-s-circle.svg","material-alpha-s":"material/alpha-s.svg","material-alpha-t-box-outline":"material/alpha-t-box-outline.svg","material-alpha-t-box":"material/alpha-t-box.svg","material-alpha-t-circle-outline":"material/alpha-t-circle-outline.svg","material-alpha-t-circle":"material/alpha-t-circle.svg","material-alpha-t":"material/alpha-t.svg","material-alpha-u-box-outline":"material/alpha-u-box-outline.svg","material-alpha-u-box":"material/alpha-u-box.svg","material-alpha-u-circle-outline":"material/alpha-u-circle-outline.svg","material-alpha-u-circle":"material/alpha-u-circle.svg","material-alpha-u":"material/alpha-u.svg","material-alpha-v-box-outline":"material/alpha-v-box-outline.svg","material-alpha-v-box":"material/alpha-v-box.svg","material-alpha-v-circle-outline":"material/alpha-v-circle-outline.svg","material-alpha-v-circle":"material/alpha-v-circle.svg","material-alpha-v":"material/alpha-v.svg","material-alpha-w-box-outline":"material/alpha-w-box-outline.svg","material-alpha-w-box":"material/alpha-w-box.svg","material-alpha-w-circle-outline":"material/alpha-w-circle-outline.svg","material-alpha-w-circle":"material/alpha-w-circle.svg","material-alpha-w":"material/alpha-w.svg","material-alpha-x-box-outline":"material/alpha-x-box-outline.svg","material-alpha-x-box":"material/alpha-x-box.svg","material-alpha-x-circle-outline":"material/alpha-x-circle-outline.svg","material-alpha-x-circle":"material/alpha-x-circle.svg","material-alpha-x":"material/alpha-x.svg","material-alpha-y-box-outline":"material/alpha-y-box-outline.svg","material-alpha-y-box":"material/alpha-y-box.svg","material-alpha-y-circle-outline":"material/alpha-y-circle-outline.svg","material-alpha-y-circle":"material/alpha-y-circle.svg","material-alpha-y":"material/alpha-y.svg","material-alpha-z-box-outline":"material/alpha-z-box-outline.svg","material-alpha-z-box":"material/alpha-z-box.svg","material-alpha-z-circle-outline":"material/alpha-z-circle-outline.svg","material-alpha-z-circle":"material/alpha-z-circle.svg","material-alpha-z":"material/alpha-z.svg","material-alpha":"material/alpha.svg","material-alphabet-aurebesh":"material/alphabet-aurebesh.svg","material-alphabet-cyrillic":"material/alphabet-cyrillic.svg","material-alphabet-greek":"material/alphabet-greek.svg","material-alphabet-latin":"material/alphabet-latin.svg","material-alphabet-piqad":"material/alphabet-piqad.svg","material-alphabet-tengwar":"material/alphabet-tengwar.svg","material-alphabetical-off":"material/alphabetical-off.svg","material-alphabetical-variant-off":"material/alphabetical-variant-off.svg","material-alphabetical-variant":"material/alphabetical-variant.svg","material-alphabetical":"material/alphabetical.svg","material-altimeter":"material/altimeter.svg","material-ambulance":"material/ambulance.svg","material-ammunition":"material/ammunition.svg","material-ampersand":"material/ampersand.svg","material-amplifier-off":"material/amplifier-off.svg","material-amplifier":"material/amplifier.svg","material-anchor":"material/anchor.svg","material-android-studio":"material/android-studio.svg","material-android":"material/android.svg","material-angle-acute":"material/angle-acute.svg","material-angle-obtuse":"material/angle-obtuse.svg","material-angle-right":"material/angle-right.svg","material-angular":"material/angular.svg","material-angularjs":"material/angularjs.svg","material-animation-outline":"material/animation-outline.svg","material-animation-play-outline":"material/animation-play-outline.svg","material-animation-play":"material/animation-play.svg","material-animation":"material/animation.svg","material-ansible":"material/ansible.svg","material-antenna":"material/antenna.svg","material-anvil":"material/anvil.svg","material-apache-kafka":"material/apache-kafka.svg","material-api-off":"material/api-off.svg","material-api":"material/api.svg","material-apple-finder":"material/apple-finder.svg","material-apple-icloud":"material/apple-icloud.svg","material-apple-ios":"material/apple-ios.svg","material-apple-keyboard-caps":"material/apple-keyboard-caps.svg","material-apple-keyboard-command":"material/apple-keyboard-command.svg","material-apple-keyboard-control":"material/apple-keyboard-control.svg","material-apple-keyboard-option":"material/apple-keyboard-option.svg","material-apple-keyboard-shift":"material/apple-keyboard-shift.svg","material-apple-safari":"material/apple-safari.svg","material-apple":"material/apple.svg","material-application-array-outline":"material/application-array-outline.svg","material-application-array":"material/application-array.svg","material-application-braces-outline":"material/application-braces-outline.svg","material-application-braces":"material/application-braces.svg","material-application-brackets-outline":"material/application-brackets-outline.svg","material-application-brackets":"material/application-brackets.svg","material-application-cog-outline":"material/application-cog-outline.svg","material-application-cog":"material/application-cog.svg","material-application-edit-outline":"material/application-edit-outline.svg","material-application-edit":"material/application-edit.svg","material-application-export":"material/application-export.svg","material-application-import":"material/application-import.svg","material-application-outline":"material/application-outline.svg","material-application-parentheses-outline":"material/application-parentheses-outline.svg","material-application-parentheses":"material/application-parentheses.svg","material-application-settings-outline":"material/application-settings-outline.svg","material-application-settings":"material/application-settings.svg","material-application-variable-outline":"material/application-variable-outline.svg","material-application-variable":"material/application-variable.svg","material-application":"material/application.svg","material-approximately-equal-box":"material/approximately-equal-box.svg","material-approximately-equal":"material/approximately-equal.svg","material-apps-box":"material/apps-box.svg","material-apps":"material/apps.svg","material-arch":"material/arch.svg","material-archive-alert-outline":"material/archive-alert-outline.svg","material-archive-alert":"material/archive-alert.svg","material-archive-arrow-down-outline":"material/archive-arrow-down-outline.svg","material-archive-arrow-down":"material/archive-arrow-down.svg","material-archive-arrow-up-outline":"material/archive-arrow-up-outline.svg","material-archive-arrow-up":"material/archive-arrow-up.svg","material-archive-cancel-outline":"material/archive-cancel-outline.svg","material-archive-cancel":"material/archive-cancel.svg","material-archive-check-outline":"material/archive-check-outline.svg","material-archive-check":"material/archive-check.svg","material-archive-clock-outline":"material/archive-clock-outline.svg","material-archive-clock":"material/archive-clock.svg","material-archive-cog-outline":"material/archive-cog-outline.svg","material-archive-cog":"material/archive-cog.svg","material-archive-edit-outline":"material/archive-edit-outline.svg","material-archive-edit":"material/archive-edit.svg","material-archive-eye-outline":"material/archive-eye-outline.svg","material-archive-eye":"material/archive-eye.svg","material-archive-lock-open-outline":"material/archive-lock-open-outline.svg","material-archive-lock-open":"material/archive-lock-open.svg","material-archive-lock-outline":"material/archive-lock-outline.svg","material-archive-lock":"material/archive-lock.svg","material-archive-marker-outline":"material/archive-marker-outline.svg","material-archive-marker":"material/archive-marker.svg","material-archive-minus-outline":"material/archive-minus-outline.svg","material-archive-minus":"material/archive-minus.svg","material-archive-music-outline":"material/archive-music-outline.svg","material-archive-music":"material/archive-music.svg","material-archive-off-outline":"material/archive-off-outline.svg","material-archive-off":"material/archive-off.svg","material-archive-outline":"material/archive-outline.svg","material-archive-plus-outline":"material/archive-plus-outline.svg","material-archive-plus":"material/archive-plus.svg","material-archive-refresh-outline":"material/archive-refresh-outline.svg","material-archive-refresh":"material/archive-refresh.svg","material-archive-remove-outline":"material/archive-remove-outline.svg","material-archive-remove":"material/archive-remove.svg","material-archive-search-outline":"material/archive-search-outline.svg","material-archive-search":"material/archive-search.svg","material-archive-settings-outline":"material/archive-settings-outline.svg","material-archive-settings":"material/archive-settings.svg","material-archive-star-outline":"material/archive-star-outline.svg","material-archive-star":"material/archive-star.svg","material-archive-sync-outline":"material/archive-sync-outline.svg","material-archive-sync":"material/archive-sync.svg","material-archive":"material/archive.svg","material-arm-flex-outline":"material/arm-flex-outline.svg","material-arm-flex":"material/arm-flex.svg","material-arrange-bring-forward":"material/arrange-bring-forward.svg","material-arrange-bring-to-front":"material/arrange-bring-to-front.svg","material-arrange-send-backward":"material/arrange-send-backward.svg","material-arrange-send-to-back":"material/arrange-send-to-back.svg","material-arrow-all":"material/arrow-all.svg","material-arrow-bottom-left-bold-box-outline":"material/arrow-bottom-left-bold-box-outline.svg","material-arrow-bottom-left-bold-box":"material/arrow-bottom-left-bold-box.svg","material-arrow-bottom-left-bold-outline":"material/arrow-bottom-left-bold-outline.svg","material-arrow-bottom-left-thick":"material/arrow-bottom-left-thick.svg","material-arrow-bottom-left-thin-circle-outline":"material/arrow-bottom-left-thin-circle-outline.svg","material-arrow-bottom-left-thin":"material/arrow-bottom-left-thin.svg","material-arrow-bottom-left":"material/arrow-bottom-left.svg","material-arrow-bottom-right-bold-box-outline":"material/arrow-bottom-right-bold-box-outline.svg","material-arrow-bottom-right-bold-box":"material/arrow-bottom-right-bold-box.svg","material-arrow-bottom-right-bold-outline":"material/arrow-bottom-right-bold-outline.svg","material-arrow-bottom-right-thick":"material/arrow-bottom-right-thick.svg","material-arrow-bottom-right-thin-circle-outline":"material/arrow-bottom-right-thin-circle-outline.svg","material-arrow-bottom-right-thin":"material/arrow-bottom-right-thin.svg","material-arrow-bottom-right":"material/arrow-bottom-right.svg","material-arrow-collapse-all":"material/arrow-collapse-all.svg","material-arrow-collapse-down":"material/arrow-collapse-down.svg","material-arrow-collapse-horizontal":"material/arrow-collapse-horizontal.svg","material-arrow-collapse-left":"material/arrow-collapse-left.svg","material-arrow-collapse-right":"material/arrow-collapse-right.svg","material-arrow-collapse-up":"material/arrow-collapse-up.svg","material-arrow-collapse-vertical":"material/arrow-collapse-vertical.svg","material-arrow-collapse":"material/arrow-collapse.svg","material-arrow-decision-auto-outline":"material/arrow-decision-auto-outline.svg","material-arrow-decision-auto":"material/arrow-decision-auto.svg","material-arrow-decision-outline":"material/arrow-decision-outline.svg","material-arrow-decision":"material/arrow-decision.svg","material-arrow-down-bold-box-outline":"material/arrow-down-bold-box-outline.svg","material-arrow-down-bold-box":"material/arrow-down-bold-box.svg","material-arrow-down-bold-circle-outline":"material/arrow-down-bold-circle-outline.svg","material-arrow-down-bold-circle":"material/arrow-down-bold-circle.svg","material-arrow-down-bold-hexagon-outline":"material/arrow-down-bold-hexagon-outline.svg","material-arrow-down-bold-outline":"material/arrow-down-bold-outline.svg","material-arrow-down-bold":"material/arrow-down-bold.svg","material-arrow-down-box":"material/arrow-down-box.svg","material-arrow-down-circle-outline":"material/arrow-down-circle-outline.svg","material-arrow-down-circle":"material/arrow-down-circle.svg","material-arrow-down-drop-circle-outline":"material/arrow-down-drop-circle-outline.svg","material-arrow-down-drop-circle":"material/arrow-down-drop-circle.svg","material-arrow-down-left-bold":"material/arrow-down-left-bold.svg","material-arrow-down-left":"material/arrow-down-left.svg","material-arrow-down-right-bold":"material/arrow-down-right-bold.svg","material-arrow-down-right":"material/arrow-down-right.svg","material-arrow-down-thick":"material/arrow-down-thick.svg","material-arrow-down-thin-circle-outline":"material/arrow-down-thin-circle-outline.svg","material-arrow-down-thin":"material/arrow-down-thin.svg","material-arrow-down":"material/arrow-down.svg","material-arrow-expand-all":"material/arrow-expand-all.svg","material-arrow-expand-down":"material/arrow-expand-down.svg","material-arrow-expand-horizontal":"material/arrow-expand-horizontal.svg","material-arrow-expand-left":"material/arrow-expand-left.svg","material-arrow-expand-right":"material/arrow-expand-right.svg","material-arrow-expand-up":"material/arrow-expand-up.svg","material-arrow-expand-vertical":"material/arrow-expand-vertical.svg","material-arrow-expand":"material/arrow-expand.svg","material-arrow-horizontal-lock":"material/arrow-horizontal-lock.svg","material-arrow-left-bold-box-outline":"material/arrow-left-bold-box-outline.svg","material-arrow-left-bold-box":"material/arrow-left-bold-box.svg","material-arrow-left-bold-circle-outline":"material/arrow-left-bold-circle-outline.svg","material-arrow-left-bold-circle":"material/arrow-left-bold-circle.svg","material-arrow-left-bold-hexagon-outline":"material/arrow-left-bold-hexagon-outline.svg","material-arrow-left-bold-outline":"material/arrow-left-bold-outline.svg","material-arrow-left-bold":"material/arrow-left-bold.svg","material-arrow-left-bottom-bold":"material/arrow-left-bottom-bold.svg","material-arrow-left-bottom":"material/arrow-left-bottom.svg","material-arrow-left-box":"material/arrow-left-box.svg","material-arrow-left-circle-outline":"material/arrow-left-circle-outline.svg","material-arrow-left-circle":"material/arrow-left-circle.svg","material-arrow-left-drop-circle-outline":"material/arrow-left-drop-circle-outline.svg","material-arrow-left-drop-circle":"material/arrow-left-drop-circle.svg","material-arrow-left-right-bold-outline":"material/arrow-left-right-bold-outline.svg","material-arrow-left-right-bold":"material/arrow-left-right-bold.svg","material-arrow-left-right":"material/arrow-left-right.svg","material-arrow-left-thick":"material/arrow-left-thick.svg","material-arrow-left-thin-circle-outline":"material/arrow-left-thin-circle-outline.svg","material-arrow-left-thin":"material/arrow-left-thin.svg","material-arrow-left-top-bold":"material/arrow-left-top-bold.svg","material-arrow-left-top":"material/arrow-left-top.svg","material-arrow-left":"material/arrow-left.svg","material-arrow-projectile-multiple":"material/arrow-projectile-multiple.svg","material-arrow-projectile":"material/arrow-projectile.svg","material-arrow-right-bold-box-outline":"material/arrow-right-bold-box-outline.svg","material-arrow-right-bold-box":"material/arrow-right-bold-box.svg","material-arrow-right-bold-circle-outline":"material/arrow-right-bold-circle-outline.svg","material-arrow-right-bold-circle":"material/arrow-right-bold-circle.svg","material-arrow-right-bold-hexagon-outline":"material/arrow-right-bold-hexagon-outline.svg","material-arrow-right-bold-outline":"material/arrow-right-bold-outline.svg","material-arrow-right-bold":"material/arrow-right-bold.svg","material-arrow-right-bottom-bold":"material/arrow-right-bottom-bold.svg","material-arrow-right-bottom":"material/arrow-right-bottom.svg","material-arrow-right-box":"material/arrow-right-box.svg","material-arrow-right-circle-outline":"material/arrow-right-circle-outline.svg","material-arrow-right-circle":"material/arrow-right-circle.svg","material-arrow-right-drop-circle-outline":"material/arrow-right-drop-circle-outline.svg","material-arrow-right-drop-circle":"material/arrow-right-drop-circle.svg","material-arrow-right-thick":"material/arrow-right-thick.svg","material-arrow-right-thin-circle-outline":"material/arrow-right-thin-circle-outline.svg","material-arrow-right-thin":"material/arrow-right-thin.svg","material-arrow-right-top-bold":"material/arrow-right-top-bold.svg","material-arrow-right-top":"material/arrow-right-top.svg","material-arrow-right":"material/arrow-right.svg","material-arrow-split-horizontal":"material/arrow-split-horizontal.svg","material-arrow-split-vertical":"material/arrow-split-vertical.svg","material-arrow-top-left-bold-box-outline":"material/arrow-top-left-bold-box-outline.svg","material-arrow-top-left-bold-box":"material/arrow-top-left-bold-box.svg","material-arrow-top-left-bold-outline":"material/arrow-top-left-bold-outline.svg","material-arrow-top-left-bottom-right-bold":"material/arrow-top-left-bottom-right-bold.svg","material-arrow-top-left-bottom-right":"material/arrow-top-left-bottom-right.svg","material-arrow-top-left-thick":"material/arrow-top-left-thick.svg","material-arrow-top-left-thin-circle-outline":"material/arrow-top-left-thin-circle-outline.svg","material-arrow-top-left-thin":"material/arrow-top-left-thin.svg","material-arrow-top-left":"material/arrow-top-left.svg","material-arrow-top-right-bold-box-outline":"material/arrow-top-right-bold-box-outline.svg","material-arrow-top-right-bold-box":"material/arrow-top-right-bold-box.svg","material-arrow-top-right-bold-outline":"material/arrow-top-right-bold-outline.svg","material-arrow-top-right-bottom-left-bold":"material/arrow-top-right-bottom-left-bold.svg","material-arrow-top-right-bottom-left":"material/arrow-top-right-bottom-left.svg","material-arrow-top-right-thick":"material/arrow-top-right-thick.svg","material-arrow-top-right-thin-circle-outline":"material/arrow-top-right-thin-circle-outline.svg","material-arrow-top-right-thin":"material/arrow-top-right-thin.svg","material-arrow-top-right":"material/arrow-top-right.svg","material-arrow-u-down-left-bold":"material/arrow-u-down-left-bold.svg","material-arrow-u-down-left":"material/arrow-u-down-left.svg","material-arrow-u-down-right-bold":"material/arrow-u-down-right-bold.svg","material-arrow-u-down-right":"material/arrow-u-down-right.svg","material-arrow-u-left-bottom-bold":"material/arrow-u-left-bottom-bold.svg","material-arrow-u-left-bottom":"material/arrow-u-left-bottom.svg","material-arrow-u-left-top-bold":"material/arrow-u-left-top-bold.svg","material-arrow-u-left-top":"material/arrow-u-left-top.svg","material-arrow-u-right-bottom-bold":"material/arrow-u-right-bottom-bold.svg","material-arrow-u-right-bottom":"material/arrow-u-right-bottom.svg","material-arrow-u-right-top-bold":"material/arrow-u-right-top-bold.svg","material-arrow-u-right-top":"material/arrow-u-right-top.svg","material-arrow-u-up-left-bold":"material/arrow-u-up-left-bold.svg","material-arrow-u-up-left":"material/arrow-u-up-left.svg","material-arrow-u-up-right-bold":"material/arrow-u-up-right-bold.svg","material-arrow-u-up-right":"material/arrow-u-up-right.svg","material-arrow-up-bold-box-outline":"material/arrow-up-bold-box-outline.svg","material-arrow-up-bold-box":"material/arrow-up-bold-box.svg","material-arrow-up-bold-circle-outline":"material/arrow-up-bold-circle-outline.svg","material-arrow-up-bold-circle":"material/arrow-up-bold-circle.svg","material-arrow-up-bold-hexagon-outline":"material/arrow-up-bold-hexagon-outline.svg","material-arrow-up-bold-outline":"material/arrow-up-bold-outline.svg","material-arrow-up-bold":"material/arrow-up-bold.svg","material-arrow-up-box":"material/arrow-up-box.svg","material-arrow-up-circle-outline":"material/arrow-up-circle-outline.svg","material-arrow-up-circle":"material/arrow-up-circle.svg","material-arrow-up-down-bold-outline":"material/arrow-up-down-bold-outline.svg","material-arrow-up-down-bold":"material/arrow-up-down-bold.svg","material-arrow-up-down":"material/arrow-up-down.svg","material-arrow-up-drop-circle-outline":"material/arrow-up-drop-circle-outline.svg","material-arrow-up-drop-circle":"material/arrow-up-drop-circle.svg","material-arrow-up-left-bold":"material/arrow-up-left-bold.svg","material-arrow-up-left":"material/arrow-up-left.svg","material-arrow-up-right-bold":"material/arrow-up-right-bold.svg","material-arrow-up-right":"material/arrow-up-right.svg","material-arrow-up-thick":"material/arrow-up-thick.svg","material-arrow-up-thin-circle-outline":"material/arrow-up-thin-circle-outline.svg","material-arrow-up-thin":"material/arrow-up-thin.svg","material-arrow-up":"material/arrow-up.svg","material-arrow-vertical-lock":"material/arrow-vertical-lock.svg","material-artboard":"material/artboard.svg","material-artstation":"material/artstation.svg","material-aspect-ratio":"material/aspect-ratio.svg","material-assistant":"material/assistant.svg","material-asterisk-circle-outline":"material/asterisk-circle-outline.svg","material-asterisk":"material/asterisk.svg","material-at":"material/at.svg","material-atlassian":"material/atlassian.svg","material-atm":"material/atm.svg","material-atom-variant":"material/atom-variant.svg","material-atom":"material/atom.svg","material-attachment-check":"material/attachment-check.svg","material-attachment-lock":"material/attachment-lock.svg","material-attachment-minus":"material/attachment-minus.svg","material-attachment-off":"material/attachment-off.svg","material-attachment-plus":"material/attachment-plus.svg","material-attachment-remove":"material/attachment-remove.svg","material-attachment":"material/attachment.svg","material-atv":"material/atv.svg","material-audio-input-rca":"material/audio-input-rca.svg","material-audio-input-stereo-minijack":"material/audio-input-stereo-minijack.svg","material-audio-input-xlr":"material/audio-input-xlr.svg","material-audio-video-off":"material/audio-video-off.svg","material-audio-video":"material/audio-video.svg","material-augmented-reality":"material/augmented-reality.svg","material-auto-download":"material/auto-download.svg","material-auto-fix":"material/auto-fix.svg","material-auto-upload":"material/auto-upload.svg","material-autorenew-off":"material/autorenew-off.svg","material-autorenew":"material/autorenew.svg","material-av-timer":"material/av-timer.svg","material-awning-outline":"material/awning-outline.svg","material-awning":"material/awning.svg","material-aws":"material/aws.svg","material-axe-battle":"material/axe-battle.svg","material-axe":"material/axe.svg","material-axis-arrow-info":"material/axis-arrow-info.svg","material-axis-arrow-lock":"material/axis-arrow-lock.svg","material-axis-arrow":"material/axis-arrow.svg","material-axis-lock":"material/axis-lock.svg","material-axis-x-arrow-lock":"material/axis-x-arrow-lock.svg","material-axis-x-arrow":"material/axis-x-arrow.svg","material-axis-x-rotate-clockwise":"material/axis-x-rotate-clockwise.svg","material-axis-x-rotate-counterclockwise":"material/axis-x-rotate-counterclockwise.svg","material-axis-x-y-arrow-lock":"material/axis-x-y-arrow-lock.svg","material-axis-y-arrow-lock":"material/axis-y-arrow-lock.svg","material-axis-y-arrow":"material/axis-y-arrow.svg","material-axis-y-rotate-clockwise":"material/axis-y-rotate-clockwise.svg","material-axis-y-rotate-counterclockwise":"material/axis-y-rotate-counterclockwise.svg","material-axis-z-arrow-lock":"material/axis-z-arrow-lock.svg","material-axis-z-arrow":"material/axis-z-arrow.svg","material-axis-z-rotate-clockwise":"material/axis-z-rotate-clockwise.svg","material-axis-z-rotate-counterclockwise":"material/axis-z-rotate-counterclockwise.svg","material-axis":"material/axis.svg","material-babel":"material/babel.svg","material-baby-bottle-outline":"material/baby-bottle-outline.svg","material-baby-bottle":"material/baby-bottle.svg","material-baby-buggy-off":"material/baby-buggy-off.svg","material-baby-buggy":"material/baby-buggy.svg","material-baby-carriage-off":"material/baby-carriage-off.svg","material-baby-carriage":"material/baby-carriage.svg","material-baby-face-outline":"material/baby-face-outline.svg","material-baby-face":"material/baby-face.svg","material-baby":"material/baby.svg","material-backburger":"material/backburger.svg","material-backspace-outline":"material/backspace-outline.svg","material-backspace-reverse-outline":"material/backspace-reverse-outline.svg","material-backspace-reverse":"material/backspace-reverse.svg","material-backspace":"material/backspace.svg","material-backup-restore":"material/backup-restore.svg","material-bacteria-outline":"material/bacteria-outline.svg","material-bacteria":"material/bacteria.svg","material-badge-account-alert-outline":"material/badge-account-alert-outline.svg","material-badge-account-alert":"material/badge-account-alert.svg","material-badge-account-horizontal-outline":"material/badge-account-horizontal-outline.svg","material-badge-account-horizontal":"material/badge-account-horizontal.svg","material-badge-account-outline":"material/badge-account-outline.svg","material-badge-account":"material/badge-account.svg","material-badminton":"material/badminton.svg","material-bag-carry-on-check":"material/bag-carry-on-check.svg","material-bag-carry-on-off":"material/bag-carry-on-off.svg","material-bag-carry-on":"material/bag-carry-on.svg","material-bag-checked":"material/bag-checked.svg","material-bag-personal-off-outline":"material/bag-personal-off-outline.svg","material-bag-personal-off":"material/bag-personal-off.svg","material-bag-personal-outline":"material/bag-personal-outline.svg","material-bag-personal-tag-outline":"material/bag-personal-tag-outline.svg","material-bag-personal-tag":"material/bag-personal-tag.svg","material-bag-personal":"material/bag-personal.svg","material-bag-suitcase-off-outline":"material/bag-suitcase-off-outline.svg","material-bag-suitcase-off":"material/bag-suitcase-off.svg","material-bag-suitcase-outline":"material/bag-suitcase-outline.svg","material-bag-suitcase":"material/bag-suitcase.svg","material-baguette":"material/baguette.svg","material-balcony":"material/balcony.svg","material-balloon":"material/balloon.svg","material-ballot-outline":"material/ballot-outline.svg","material-ballot-recount-outline":"material/ballot-recount-outline.svg","material-ballot-recount":"material/ballot-recount.svg","material-ballot":"material/ballot.svg","material-bandage":"material/bandage.svg","material-bank-check":"material/bank-check.svg","material-bank-minus":"material/bank-minus.svg","material-bank-off-outline":"material/bank-off-outline.svg","material-bank-off":"material/bank-off.svg","material-bank-outline":"material/bank-outline.svg","material-bank-plus":"material/bank-plus.svg","material-bank-remove":"material/bank-remove.svg","material-bank-transfer-in":"material/bank-transfer-in.svg","material-bank-transfer-out":"material/bank-transfer-out.svg","material-bank-transfer":"material/bank-transfer.svg","material-bank":"material/bank.svg","material-barcode-off":"material/barcode-off.svg","material-barcode-scan":"material/barcode-scan.svg","material-barcode":"material/barcode.svg","material-barley-off":"material/barley-off.svg","material-barley":"material/barley.svg","material-barn":"material/barn.svg","material-barrel-outline":"material/barrel-outline.svg","material-barrel":"material/barrel.svg","material-baseball-bat":"material/baseball-bat.svg","material-baseball-diamond-outline":"material/baseball-diamond-outline.svg","material-baseball-diamond":"material/baseball-diamond.svg","material-baseball":"material/baseball.svg","material-bash":"material/bash.svg","material-basket-check-outline":"material/basket-check-outline.svg","material-basket-check":"material/basket-check.svg","material-basket-fill":"material/basket-fill.svg","material-basket-minus-outline":"material/basket-minus-outline.svg","material-basket-minus":"material/basket-minus.svg","material-basket-off-outline":"material/basket-off-outline.svg","material-basket-off":"material/basket-off.svg","material-basket-outline":"material/basket-outline.svg","material-basket-plus-outline":"material/basket-plus-outline.svg","material-basket-plus":"material/basket-plus.svg","material-basket-remove-outline":"material/basket-remove-outline.svg","material-basket-remove":"material/basket-remove.svg","material-basket-unfill":"material/basket-unfill.svg","material-basket":"material/basket.svg","material-basketball-hoop-outline":"material/basketball-hoop-outline.svg","material-basketball-hoop":"material/basketball-hoop.svg","material-basketball":"material/basketball.svg","material-bat":"material/bat.svg","material-bathtub-outline":"material/bathtub-outline.svg","material-bathtub":"material/bathtub.svg","material-battery-10-bluetooth":"material/battery-10-bluetooth.svg","material-battery-10":"material/battery-10.svg","material-battery-20-bluetooth":"material/battery-20-bluetooth.svg","material-battery-20":"material/battery-20.svg","material-battery-30-bluetooth":"material/battery-30-bluetooth.svg","material-battery-30":"material/battery-30.svg","material-battery-40-bluetooth":"material/battery-40-bluetooth.svg","material-battery-40":"material/battery-40.svg","material-battery-50-bluetooth":"material/battery-50-bluetooth.svg","material-battery-50":"material/battery-50.svg","material-battery-60-bluetooth":"material/battery-60-bluetooth.svg","material-battery-60":"material/battery-60.svg","material-battery-70-bluetooth":"material/battery-70-bluetooth.svg","material-battery-70":"material/battery-70.svg","material-battery-80-bluetooth":"material/battery-80-bluetooth.svg","material-battery-80":"material/battery-80.svg","material-battery-90-bluetooth":"material/battery-90-bluetooth.svg","material-battery-90":"material/battery-90.svg","material-battery-alert-bluetooth":"material/battery-alert-bluetooth.svg","material-battery-alert-variant-outline":"material/battery-alert-variant-outline.svg","material-battery-alert-variant":"material/battery-alert-variant.svg","material-battery-alert":"material/battery-alert.svg","material-battery-arrow-down-outline":"material/battery-arrow-down-outline.svg","material-battery-arrow-down":"material/battery-arrow-down.svg","material-battery-arrow-up-outline":"material/battery-arrow-up-outline.svg","material-battery-arrow-up":"material/battery-arrow-up.svg","material-battery-bluetooth-variant":"material/battery-bluetooth-variant.svg","material-battery-bluetooth":"material/battery-bluetooth.svg","material-battery-charging-10":"material/battery-charging-10.svg","material-battery-charging-100":"material/battery-charging-100.svg","material-battery-charging-20":"material/battery-charging-20.svg","material-battery-charging-30":"material/battery-charging-30.svg","material-battery-charging-40":"material/battery-charging-40.svg","material-battery-charging-50":"material/battery-charging-50.svg","material-battery-charging-60":"material/battery-charging-60.svg","material-battery-charging-70":"material/battery-charging-70.svg","material-battery-charging-80":"material/battery-charging-80.svg","material-battery-charging-90":"material/battery-charging-90.svg","material-battery-charging-high":"material/battery-charging-high.svg","material-battery-charging-low":"material/battery-charging-low.svg","material-battery-charging-medium":"material/battery-charging-medium.svg","material-battery-charging-outline":"material/battery-charging-outline.svg","material-battery-charging-wireless-10":"material/battery-charging-wireless-10.svg","material-battery-charging-wireless-20":"material/battery-charging-wireless-20.svg","material-battery-charging-wireless-30":"material/battery-charging-wireless-30.svg","material-battery-charging-wireless-40":"material/battery-charging-wireless-40.svg","material-battery-charging-wireless-50":"material/battery-charging-wireless-50.svg","material-battery-charging-wireless-60":"material/battery-charging-wireless-60.svg","material-battery-charging-wireless-70":"material/battery-charging-wireless-70.svg","material-battery-charging-wireless-80":"material/battery-charging-wireless-80.svg","material-battery-charging-wireless-90":"material/battery-charging-wireless-90.svg","material-battery-charging-wireless-alert":"material/battery-charging-wireless-alert.svg","material-battery-charging-wireless-outline":"material/battery-charging-wireless-outline.svg","material-battery-charging-wireless":"material/battery-charging-wireless.svg","material-battery-charging":"material/battery-charging.svg","material-battery-check-outline":"material/battery-check-outline.svg","material-battery-check":"material/battery-check.svg","material-battery-clock-outline":"material/battery-clock-outline.svg","material-battery-clock":"material/battery-clock.svg","material-battery-heart-outline":"material/battery-heart-outline.svg","material-battery-heart-variant":"material/battery-heart-variant.svg","material-battery-heart":"material/battery-heart.svg","material-battery-high":"material/battery-high.svg","material-battery-lock-open":"material/battery-lock-open.svg","material-battery-lock":"material/battery-lock.svg","material-battery-low":"material/battery-low.svg","material-battery-medium":"material/battery-medium.svg","material-battery-minus-outline":"material/battery-minus-outline.svg","material-battery-minus-variant":"material/battery-minus-variant.svg","material-battery-minus":"material/battery-minus.svg","material-battery-negative":"material/battery-negative.svg","material-battery-off-outline":"material/battery-off-outline.svg","material-battery-off":"material/battery-off.svg","material-battery-outline":"material/battery-outline.svg","material-battery-plus-outline":"material/battery-plus-outline.svg","material-battery-plus-variant":"material/battery-plus-variant.svg","material-battery-plus":"material/battery-plus.svg","material-battery-positive":"material/battery-positive.svg","material-battery-remove-outline":"material/battery-remove-outline.svg","material-battery-remove":"material/battery-remove.svg","material-battery-sync-outline":"material/battery-sync-outline.svg","material-battery-sync":"material/battery-sync.svg","material-battery-unknown-bluetooth":"material/battery-unknown-bluetooth.svg","material-battery-unknown":"material/battery-unknown.svg","material-battery":"material/battery.svg","material-beach":"material/beach.svg","material-beaker-alert-outline":"material/beaker-alert-outline.svg","material-beaker-alert":"material/beaker-alert.svg","material-beaker-check-outline":"material/beaker-check-outline.svg","material-beaker-check":"material/beaker-check.svg","material-beaker-minus-outline":"material/beaker-minus-outline.svg","material-beaker-minus":"material/beaker-minus.svg","material-beaker-outline":"material/beaker-outline.svg","material-beaker-plus-outline":"material/beaker-plus-outline.svg","material-beaker-plus":"material/beaker-plus.svg","material-beaker-question-outline":"material/beaker-question-outline.svg","material-beaker-question":"material/beaker-question.svg","material-beaker-remove-outline":"material/beaker-remove-outline.svg","material-beaker-remove":"material/beaker-remove.svg","material-beaker":"material/beaker.svg","material-bed-clock":"material/bed-clock.svg","material-bed-double-outline":"material/bed-double-outline.svg","material-bed-double":"material/bed-double.svg","material-bed-empty":"material/bed-empty.svg","material-bed-king-outline":"material/bed-king-outline.svg","material-bed-king":"material/bed-king.svg","material-bed-outline":"material/bed-outline.svg","material-bed-queen-outline":"material/bed-queen-outline.svg","material-bed-queen":"material/bed-queen.svg","material-bed-single-outline":"material/bed-single-outline.svg","material-bed-single":"material/bed-single.svg","material-bed":"material/bed.svg","material-bee-flower":"material/bee-flower.svg","material-bee":"material/bee.svg","material-beehive-off-outline":"material/beehive-off-outline.svg","material-beehive-outline":"material/beehive-outline.svg","material-beekeeper":"material/beekeeper.svg","material-beer-outline":"material/beer-outline.svg","material-beer":"material/beer.svg","material-bell-alert-outline":"material/bell-alert-outline.svg","material-bell-alert":"material/bell-alert.svg","material-bell-badge-outline":"material/bell-badge-outline.svg","material-bell-badge":"material/bell-badge.svg","material-bell-cancel-outline":"material/bell-cancel-outline.svg","material-bell-cancel":"material/bell-cancel.svg","material-bell-check-outline":"material/bell-check-outline.svg","material-bell-check":"material/bell-check.svg","material-bell-circle-outline":"material/bell-circle-outline.svg","material-bell-circle":"material/bell-circle.svg","material-bell-cog-outline":"material/bell-cog-outline.svg","material-bell-cog":"material/bell-cog.svg","material-bell-minus-outline":"material/bell-minus-outline.svg","material-bell-minus":"material/bell-minus.svg","material-bell-off-outline":"material/bell-off-outline.svg","material-bell-off":"material/bell-off.svg","material-bell-outline":"material/bell-outline.svg","material-bell-plus-outline":"material/bell-plus-outline.svg","material-bell-plus":"material/bell-plus.svg","material-bell-remove-outline":"material/bell-remove-outline.svg","material-bell-remove":"material/bell-remove.svg","material-bell-ring-outline":"material/bell-ring-outline.svg","material-bell-ring":"material/bell-ring.svg","material-bell-sleep-outline":"material/bell-sleep-outline.svg","material-bell-sleep":"material/bell-sleep.svg","material-bell":"material/bell.svg","material-beta":"material/beta.svg","material-betamax":"material/betamax.svg","material-biathlon":"material/biathlon.svg","material-bicycle-basket":"material/bicycle-basket.svg","material-bicycle-cargo":"material/bicycle-cargo.svg","material-bicycle-electric":"material/bicycle-electric.svg","material-bicycle-penny-farthing":"material/bicycle-penny-farthing.svg","material-bicycle":"material/bicycle.svg","material-bike-fast":"material/bike-fast.svg","material-bike":"material/bike.svg","material-billboard":"material/billboard.svg","material-billiards-rack":"material/billiards-rack.svg","material-billiards":"material/billiards.svg","material-binoculars":"material/binoculars.svg","material-bio":"material/bio.svg","material-biohazard":"material/biohazard.svg","material-bird":"material/bird.svg","material-bitbucket":"material/bitbucket.svg","material-bitcoin":"material/bitcoin.svg","material-black-mesa":"material/black-mesa.svg","material-blender-outline":"material/blender-outline.svg","material-blender-software":"material/blender-software.svg","material-blender":"material/blender.svg","material-blinds-horizontal-closed":"material/blinds-horizontal-closed.svg","material-blinds-horizontal":"material/blinds-horizontal.svg","material-blinds-open":"material/blinds-open.svg","material-blinds-vertical-closed":"material/blinds-vertical-closed.svg","material-blinds-vertical":"material/blinds-vertical.svg","material-blinds":"material/blinds.svg","material-block-helper":"material/block-helper.svg","material-blood-bag":"material/blood-bag.svg","material-bluetooth-audio":"material/bluetooth-audio.svg","material-bluetooth-connect":"material/bluetooth-connect.svg","material-bluetooth-off":"material/bluetooth-off.svg","material-bluetooth-settings":"material/bluetooth-settings.svg","material-bluetooth-transfer":"material/bluetooth-transfer.svg","material-bluetooth":"material/bluetooth.svg","material-blur-linear":"material/blur-linear.svg","material-blur-off":"material/blur-off.svg","material-blur-radial":"material/blur-radial.svg","material-blur":"material/blur.svg","material-bolt":"material/bolt.svg","material-bomb-off":"material/bomb-off.svg","material-bomb":"material/bomb.svg","material-bone-off":"material/bone-off.svg","material-bone":"material/bone.svg","material-book-account-outline":"material/book-account-outline.svg","material-book-account":"material/book-account.svg","material-book-alert-outline":"material/book-alert-outline.svg","material-book-alert":"material/book-alert.svg","material-book-alphabet":"material/book-alphabet.svg","material-book-arrow-down-outline":"material/book-arrow-down-outline.svg","material-book-arrow-down":"material/book-arrow-down.svg","material-book-arrow-left-outline":"material/book-arrow-left-outline.svg","material-book-arrow-left":"material/book-arrow-left.svg","material-book-arrow-right-outline":"material/book-arrow-right-outline.svg","material-book-arrow-right":"material/book-arrow-right.svg","material-book-arrow-up-outline":"material/book-arrow-up-outline.svg","material-book-arrow-up":"material/book-arrow-up.svg","material-book-cancel-outline":"material/book-cancel-outline.svg","material-book-cancel":"material/book-cancel.svg","material-book-check-outline":"material/book-check-outline.svg","material-book-check":"material/book-check.svg","material-book-clock-outline":"material/book-clock-outline.svg","material-book-clock":"material/book-clock.svg","material-book-cog-outline":"material/book-cog-outline.svg","material-book-cog":"material/book-cog.svg","material-book-cross":"material/book-cross.svg","material-book-edit-outline":"material/book-edit-outline.svg","material-book-edit":"material/book-edit.svg","material-book-education-outline":"material/book-education-outline.svg","material-book-education":"material/book-education.svg","material-book-heart-outline":"material/book-heart-outline.svg","material-book-heart":"material/book-heart.svg","material-book-information-variant":"material/book-information-variant.svg","material-book-lock-open-outline":"material/book-lock-open-outline.svg","material-book-lock-open":"material/book-lock-open.svg","material-book-lock-outline":"material/book-lock-outline.svg","material-book-lock":"material/book-lock.svg","material-book-marker-outline":"material/book-marker-outline.svg","material-book-marker":"material/book-marker.svg","material-book-minus-multiple-outline":"material/book-minus-multiple-outline.svg","material-book-minus-multiple":"material/book-minus-multiple.svg","material-book-minus-outline":"material/book-minus-outline.svg","material-book-minus":"material/book-minus.svg","material-book-multiple-outline":"material/book-multiple-outline.svg","material-book-multiple":"material/book-multiple.svg","material-book-music-outline":"material/book-music-outline.svg","material-book-music":"material/book-music.svg","material-book-off-outline":"material/book-off-outline.svg","material-book-off":"material/book-off.svg","material-book-open-blank-variant":"material/book-open-blank-variant.svg","material-book-open-outline":"material/book-open-outline.svg","material-book-open-page-variant-outline":"material/book-open-page-variant-outline.svg","material-book-open-page-variant":"material/book-open-page-variant.svg","material-book-open-variant":"material/book-open-variant.svg","material-book-open":"material/book-open.svg","material-book-outline":"material/book-outline.svg","material-book-play-outline":"material/book-play-outline.svg","material-book-play":"material/book-play.svg","material-book-plus-multiple-outline":"material/book-plus-multiple-outline.svg","material-book-plus-multiple":"material/book-plus-multiple.svg","material-book-plus-outline":"material/book-plus-outline.svg","material-book-plus":"material/book-plus.svg","material-book-refresh-outline":"material/book-refresh-outline.svg","material-book-refresh":"material/book-refresh.svg","material-book-remove-multiple-outline":"material/book-remove-multiple-outline.svg","material-book-remove-multiple":"material/book-remove-multiple.svg","material-book-remove-outline":"material/book-remove-outline.svg","material-book-remove":"material/book-remove.svg","material-book-search-outline":"material/book-search-outline.svg","material-book-search":"material/book-search.svg","material-book-settings-outline":"material/book-settings-outline.svg","material-book-settings":"material/book-settings.svg","material-book-sync-outline":"material/book-sync-outline.svg","material-book-sync":"material/book-sync.svg","material-book-variant":"material/book-variant.svg","material-book":"material/book.svg","material-bookmark-box-multiple-outline":"material/bookmark-box-multiple-outline.svg","material-bookmark-box-multiple":"material/bookmark-box-multiple.svg","material-bookmark-box-outline":"material/bookmark-box-outline.svg","material-bookmark-box":"material/bookmark-box.svg","material-bookmark-check-outline":"material/bookmark-check-outline.svg","material-bookmark-check":"material/bookmark-check.svg","material-bookmark-minus-outline":"material/bookmark-minus-outline.svg","material-bookmark-minus":"material/bookmark-minus.svg","material-bookmark-multiple-outline":"material/bookmark-multiple-outline.svg","material-bookmark-multiple":"material/bookmark-multiple.svg","material-bookmark-music-outline":"material/bookmark-music-outline.svg","material-bookmark-music":"material/bookmark-music.svg","material-bookmark-off-outline":"material/bookmark-off-outline.svg","material-bookmark-off":"material/bookmark-off.svg","material-bookmark-outline":"material/bookmark-outline.svg","material-bookmark-plus-outline":"material/bookmark-plus-outline.svg","material-bookmark-plus":"material/bookmark-plus.svg","material-bookmark-remove-outline":"material/bookmark-remove-outline.svg","material-bookmark-remove":"material/bookmark-remove.svg","material-bookmark":"material/bookmark.svg","material-bookshelf":"material/bookshelf.svg","material-boom-gate-alert-outline":"material/boom-gate-alert-outline.svg","material-boom-gate-alert":"material/boom-gate-alert.svg","material-boom-gate-arrow-down-outline":"material/boom-gate-arrow-down-outline.svg","material-boom-gate-arrow-down":"material/boom-gate-arrow-down.svg","material-boom-gate-arrow-up-outline":"material/boom-gate-arrow-up-outline.svg","material-boom-gate-arrow-up":"material/boom-gate-arrow-up.svg","material-boom-gate-outline":"material/boom-gate-outline.svg","material-boom-gate-up-outline":"material/boom-gate-up-outline.svg","material-boom-gate-up":"material/boom-gate-up.svg","material-boom-gate":"material/boom-gate.svg","material-boombox":"material/boombox.svg","material-boomerang":"material/boomerang.svg","material-bootstrap":"material/bootstrap.svg","material-border-all-variant":"material/border-all-variant.svg","material-border-all":"material/border-all.svg","material-border-bottom-variant":"material/border-bottom-variant.svg","material-border-bottom":"material/border-bottom.svg","material-border-color":"material/border-color.svg","material-border-horizontal":"material/border-horizontal.svg","material-border-inside":"material/border-inside.svg","material-border-left-variant":"material/border-left-variant.svg","material-border-left":"material/border-left.svg","material-border-none-variant":"material/border-none-variant.svg","material-border-none":"material/border-none.svg","material-border-outside":"material/border-outside.svg","material-border-radius":"material/border-radius.svg","material-border-right-variant":"material/border-right-variant.svg","material-border-right":"material/border-right.svg","material-border-style":"material/border-style.svg","material-border-top-variant":"material/border-top-variant.svg","material-border-top":"material/border-top.svg","material-border-vertical":"material/border-vertical.svg","material-bottle-soda-classic-outline":"material/bottle-soda-classic-outline.svg","material-bottle-soda-classic":"material/bottle-soda-classic.svg","material-bottle-soda-outline":"material/bottle-soda-outline.svg","material-bottle-soda":"material/bottle-soda.svg","material-bottle-tonic-outline":"material/bottle-tonic-outline.svg","material-bottle-tonic-plus-outline":"material/bottle-tonic-plus-outline.svg","material-bottle-tonic-plus":"material/bottle-tonic-plus.svg","material-bottle-tonic-skull-outline":"material/bottle-tonic-skull-outline.svg","material-bottle-tonic-skull":"material/bottle-tonic-skull.svg","material-bottle-tonic":"material/bottle-tonic.svg","material-bottle-wine-outline":"material/bottle-wine-outline.svg","material-bottle-wine":"material/bottle-wine.svg","material-bow-arrow":"material/bow-arrow.svg","material-bow-tie":"material/bow-tie.svg","material-bowl-mix-outline":"material/bowl-mix-outline.svg","material-bowl-mix":"material/bowl-mix.svg","material-bowl-outline":"material/bowl-outline.svg","material-bowl":"material/bowl.svg","material-bowling":"material/bowling.svg","material-box-cutter-off":"material/box-cutter-off.svg","material-box-cutter":"material/box-cutter.svg","material-box-shadow":"material/box-shadow.svg","material-box":"material/box.svg","material-boxing-glove":"material/boxing-glove.svg","material-braille":"material/braille.svg","material-brain":"material/brain.svg","material-bread-slice-outline":"material/bread-slice-outline.svg","material-bread-slice":"material/bread-slice.svg","material-bridge":"material/bridge.svg","material-briefcase-account-outline":"material/briefcase-account-outline.svg","material-briefcase-account":"material/briefcase-account.svg","material-briefcase-arrow-left-right-outline":"material/briefcase-arrow-left-right-outline.svg","material-briefcase-arrow-left-right":"material/briefcase-arrow-left-right.svg","material-briefcase-arrow-up-down-outline":"material/briefcase-arrow-up-down-outline.svg","material-briefcase-arrow-up-down":"material/briefcase-arrow-up-down.svg","material-briefcase-check-outline":"material/briefcase-check-outline.svg","material-briefcase-check":"material/briefcase-check.svg","material-briefcase-clock-outline":"material/briefcase-clock-outline.svg","material-briefcase-clock":"material/briefcase-clock.svg","material-briefcase-download-outline":"material/briefcase-download-outline.svg","material-briefcase-download":"material/briefcase-download.svg","material-briefcase-edit-outline":"material/briefcase-edit-outline.svg","material-briefcase-edit":"material/briefcase-edit.svg","material-briefcase-eye-outline":"material/briefcase-eye-outline.svg","material-briefcase-eye":"material/briefcase-eye.svg","material-briefcase-minus-outline":"material/briefcase-minus-outline.svg","material-briefcase-minus":"material/briefcase-minus.svg","material-briefcase-off-outline":"material/briefcase-off-outline.svg","material-briefcase-off":"material/briefcase-off.svg","material-briefcase-outline":"material/briefcase-outline.svg","material-briefcase-plus-outline":"material/briefcase-plus-outline.svg","material-briefcase-plus":"material/briefcase-plus.svg","material-briefcase-remove-outline":"material/briefcase-remove-outline.svg","material-briefcase-remove":"material/briefcase-remove.svg","material-briefcase-search-outline":"material/briefcase-search-outline.svg","material-briefcase-search":"material/briefcase-search.svg","material-briefcase-upload-outline":"material/briefcase-upload-outline.svg","material-briefcase-upload":"material/briefcase-upload.svg","material-briefcase-variant-off-outline":"material/briefcase-variant-off-outline.svg","material-briefcase-variant-off":"material/briefcase-variant-off.svg","material-briefcase-variant-outline":"material/briefcase-variant-outline.svg","material-briefcase-variant":"material/briefcase-variant.svg","material-briefcase":"material/briefcase.svg","material-brightness-1":"material/brightness-1.svg","material-brightness-2":"material/brightness-2.svg","material-brightness-3":"material/brightness-3.svg","material-brightness-4":"material/brightness-4.svg","material-brightness-5":"material/brightness-5.svg","material-brightness-6":"material/brightness-6.svg","material-brightness-7":"material/brightness-7.svg","material-brightness-auto":"material/brightness-auto.svg","material-brightness-percent":"material/brightness-percent.svg","material-broadcast-off":"material/broadcast-off.svg","material-broadcast":"material/broadcast.svg","material-broom":"material/broom.svg","material-brush-off":"material/brush-off.svg","material-brush-outline":"material/brush-outline.svg","material-brush-variant":"material/brush-variant.svg","material-brush":"material/brush.svg","material-bucket-outline":"material/bucket-outline.svg","material-bucket":"material/bucket.svg","material-buffet":"material/buffet.svg","material-bug-check-outline":"material/bug-check-outline.svg","material-bug-check":"material/bug-check.svg","material-bug-outline":"material/bug-outline.svg","material-bug-pause-outline":"material/bug-pause-outline.svg","material-bug-pause":"material/bug-pause.svg","material-bug-play-outline":"material/bug-play-outline.svg","material-bug-play":"material/bug-play.svg","material-bug-stop-outline":"material/bug-stop-outline.svg","material-bug-stop":"material/bug-stop.svg","material-bug":"material/bug.svg","material-bugle":"material/bugle.svg","material-bulkhead-light":"material/bulkhead-light.svg","material-bulldozer":"material/bulldozer.svg","material-bullet":"material/bullet.svg","material-bulletin-board":"material/bulletin-board.svg","material-bullhorn-outline":"material/bullhorn-outline.svg","material-bullhorn-variant-outline":"material/bullhorn-variant-outline.svg","material-bullhorn-variant":"material/bullhorn-variant.svg","material-bullhorn":"material/bullhorn.svg","material-bullseye-arrow":"material/bullseye-arrow.svg","material-bullseye":"material/bullseye.svg","material-bulma":"material/bulma.svg","material-bunk-bed-outline":"material/bunk-bed-outline.svg","material-bunk-bed":"material/bunk-bed.svg","material-bus-alert":"material/bus-alert.svg","material-bus-articulated-end":"material/bus-articulated-end.svg","material-bus-articulated-front":"material/bus-articulated-front.svg","material-bus-clock":"material/bus-clock.svg","material-bus-double-decker":"material/bus-double-decker.svg","material-bus-electric":"material/bus-electric.svg","material-bus-marker":"material/bus-marker.svg","material-bus-multiple":"material/bus-multiple.svg","material-bus-school":"material/bus-school.svg","material-bus-side":"material/bus-side.svg","material-bus-stop-covered":"material/bus-stop-covered.svg","material-bus-stop-uncovered":"material/bus-stop-uncovered.svg","material-bus-stop":"material/bus-stop.svg","material-bus":"material/bus.svg","material-butterfly-outline":"material/butterfly-outline.svg","material-butterfly":"material/butterfly.svg","material-button-cursor":"material/button-cursor.svg","material-button-pointer":"material/button-pointer.svg","material-cabin-a-frame":"material/cabin-a-frame.svg","material-cable-data":"material/cable-data.svg","material-cached":"material/cached.svg","material-cactus":"material/cactus.svg","material-cake-layered":"material/cake-layered.svg","material-cake-variant-outline":"material/cake-variant-outline.svg","material-cake-variant":"material/cake-variant.svg","material-cake":"material/cake.svg","material-calculator-variant-outline":"material/calculator-variant-outline.svg","material-calculator-variant":"material/calculator-variant.svg","material-calculator":"material/calculator.svg","material-calendar-account-outline":"material/calendar-account-outline.svg","material-calendar-account":"material/calendar-account.svg","material-calendar-alert-outline":"material/calendar-alert-outline.svg","material-calendar-alert":"material/calendar-alert.svg","material-calendar-arrow-left":"material/calendar-arrow-left.svg","material-calendar-arrow-right":"material/calendar-arrow-right.svg","material-calendar-badge-outline":"material/calendar-badge-outline.svg","material-calendar-badge":"material/calendar-badge.svg","material-calendar-blank-multiple":"material/calendar-blank-multiple.svg","material-calendar-blank-outline":"material/calendar-blank-outline.svg","material-calendar-blank":"material/calendar-blank.svg","material-calendar-check-outline":"material/calendar-check-outline.svg","material-calendar-check":"material/calendar-check.svg","material-calendar-clock-outline":"material/calendar-clock-outline.svg","material-calendar-clock":"material/calendar-clock.svg","material-calendar-collapse-horizontal-outline":"material/calendar-collapse-horizontal-outline.svg","material-calendar-collapse-horizontal":"material/calendar-collapse-horizontal.svg","material-calendar-cursor-outline":"material/calendar-cursor-outline.svg","material-calendar-cursor":"material/calendar-cursor.svg","material-calendar-edit-outline":"material/calendar-edit-outline.svg","material-calendar-edit":"material/calendar-edit.svg","material-calendar-end-outline":"material/calendar-end-outline.svg","material-calendar-end":"material/calendar-end.svg","material-calendar-expand-horizontal-outline":"material/calendar-expand-horizontal-outline.svg","material-calendar-expand-horizontal":"material/calendar-expand-horizontal.svg","material-calendar-export-outline":"material/calendar-export-outline.svg","material-calendar-export":"material/calendar-export.svg","material-calendar-filter-outline":"material/calendar-filter-outline.svg","material-calendar-filter":"material/calendar-filter.svg","material-calendar-heart-outline":"material/calendar-heart-outline.svg","material-calendar-heart":"material/calendar-heart.svg","material-calendar-import-outline":"material/calendar-import-outline.svg","material-calendar-import":"material/calendar-import.svg","material-calendar-lock-open-outline":"material/calendar-lock-open-outline.svg","material-calendar-lock-open":"material/calendar-lock-open.svg","material-calendar-lock-outline":"material/calendar-lock-outline.svg","material-calendar-lock":"material/calendar-lock.svg","material-calendar-minus-outline":"material/calendar-minus-outline.svg","material-calendar-minus":"material/calendar-minus.svg","material-calendar-month-outline":"material/calendar-month-outline.svg","material-calendar-month":"material/calendar-month.svg","material-calendar-multiple-check":"material/calendar-multiple-check.svg","material-calendar-multiple":"material/calendar-multiple.svg","material-calendar-multiselect-outline":"material/calendar-multiselect-outline.svg","material-calendar-multiselect":"material/calendar-multiselect.svg","material-calendar-outline":"material/calendar-outline.svg","material-calendar-plus-outline":"material/calendar-plus-outline.svg","material-calendar-plus":"material/calendar-plus.svg","material-calendar-question-outline":"material/calendar-question-outline.svg","material-calendar-question":"material/calendar-question.svg","material-calendar-range-outline":"material/calendar-range-outline.svg","material-calendar-range":"material/calendar-range.svg","material-calendar-refresh-outline":"material/calendar-refresh-outline.svg","material-calendar-refresh":"material/calendar-refresh.svg","material-calendar-remove-outline":"material/calendar-remove-outline.svg","material-calendar-remove":"material/calendar-remove.svg","material-calendar-search-outline":"material/calendar-search-outline.svg","material-calendar-search":"material/calendar-search.svg","material-calendar-star-outline":"material/calendar-star-outline.svg","material-calendar-star":"material/calendar-star.svg","material-calendar-start-outline":"material/calendar-start-outline.svg","material-calendar-start":"material/calendar-start.svg","material-calendar-sync-outline":"material/calendar-sync-outline.svg","material-calendar-sync":"material/calendar-sync.svg","material-calendar-text-outline":"material/calendar-text-outline.svg","material-calendar-text":"material/calendar-text.svg","material-calendar-today-outline":"material/calendar-today-outline.svg","material-calendar-today":"material/calendar-today.svg","material-calendar-week-begin-outline":"material/calendar-week-begin-outline.svg","material-calendar-week-begin":"material/calendar-week-begin.svg","material-calendar-week-outline":"material/calendar-week-outline.svg","material-calendar-week":"material/calendar-week.svg","material-calendar-weekend-outline":"material/calendar-weekend-outline.svg","material-calendar-weekend":"material/calendar-weekend.svg","material-calendar":"material/calendar.svg","material-call-made":"material/call-made.svg","material-call-merge":"material/call-merge.svg","material-call-missed":"material/call-missed.svg","material-call-received":"material/call-received.svg","material-call-split":"material/call-split.svg","material-camcorder-off":"material/camcorder-off.svg","material-camcorder":"material/camcorder.svg","material-camera-account":"material/camera-account.svg","material-camera-burst":"material/camera-burst.svg","material-camera-control":"material/camera-control.svg","material-camera-document-off":"material/camera-document-off.svg","material-camera-document":"material/camera-document.svg","material-camera-enhance-outline":"material/camera-enhance-outline.svg","material-camera-enhance":"material/camera-enhance.svg","material-camera-flip-outline":"material/camera-flip-outline.svg","material-camera-flip":"material/camera-flip.svg","material-camera-front-variant":"material/camera-front-variant.svg","material-camera-front":"material/camera-front.svg","material-camera-gopro":"material/camera-gopro.svg","material-camera-image":"material/camera-image.svg","material-camera-iris":"material/camera-iris.svg","material-camera-lock-outline":"material/camera-lock-outline.svg","material-camera-lock":"material/camera-lock.svg","material-camera-marker-outline":"material/camera-marker-outline.svg","material-camera-marker":"material/camera-marker.svg","material-camera-metering-center":"material/camera-metering-center.svg","material-camera-metering-matrix":"material/camera-metering-matrix.svg","material-camera-metering-partial":"material/camera-metering-partial.svg","material-camera-metering-spot":"material/camera-metering-spot.svg","material-camera-off-outline":"material/camera-off-outline.svg","material-camera-off":"material/camera-off.svg","material-camera-outline":"material/camera-outline.svg","material-camera-party-mode":"material/camera-party-mode.svg","material-camera-plus-outline":"material/camera-plus-outline.svg","material-camera-plus":"material/camera-plus.svg","material-camera-rear-variant":"material/camera-rear-variant.svg","material-camera-rear":"material/camera-rear.svg","material-camera-retake-outline":"material/camera-retake-outline.svg","material-camera-retake":"material/camera-retake.svg","material-camera-switch-outline":"material/camera-switch-outline.svg","material-camera-switch":"material/camera-switch.svg","material-camera-timer":"material/camera-timer.svg","material-camera-wireless-outline":"material/camera-wireless-outline.svg","material-camera-wireless":"material/camera-wireless.svg","material-camera":"material/camera.svg","material-campfire":"material/campfire.svg","material-cancel":"material/cancel.svg","material-candelabra-fire":"material/candelabra-fire.svg","material-candelabra":"material/candelabra.svg","material-candle":"material/candle.svg","material-candy-off-outline":"material/candy-off-outline.svg","material-candy-off":"material/candy-off.svg","material-candy-outline":"material/candy-outline.svg","material-candy":"material/candy.svg","material-candycane":"material/candycane.svg","material-cannabis-off":"material/cannabis-off.svg","material-cannabis":"material/cannabis.svg","material-caps-lock":"material/caps-lock.svg","material-car-2-plus":"material/car-2-plus.svg","material-car-3-plus":"material/car-3-plus.svg","material-car-arrow-left":"material/car-arrow-left.svg","material-car-arrow-right":"material/car-arrow-right.svg","material-car-back":"material/car-back.svg","material-car-battery":"material/car-battery.svg","material-car-brake-abs":"material/car-brake-abs.svg","material-car-brake-alert":"material/car-brake-alert.svg","material-car-brake-fluid-level":"material/car-brake-fluid-level.svg","material-car-brake-hold":"material/car-brake-hold.svg","material-car-brake-low-pressure":"material/car-brake-low-pressure.svg","material-car-brake-parking":"material/car-brake-parking.svg","material-car-brake-retarder":"material/car-brake-retarder.svg","material-car-brake-temperature":"material/car-brake-temperature.svg","material-car-brake-worn-linings":"material/car-brake-worn-linings.svg","material-car-child-seat":"material/car-child-seat.svg","material-car-clock":"material/car-clock.svg","material-car-clutch":"material/car-clutch.svg","material-car-cog":"material/car-cog.svg","material-car-connected":"material/car-connected.svg","material-car-convertible":"material/car-convertible.svg","material-car-coolant-level":"material/car-coolant-level.svg","material-car-cruise-control":"material/car-cruise-control.svg","material-car-defrost-front":"material/car-defrost-front.svg","material-car-defrost-rear":"material/car-defrost-rear.svg","material-car-door-lock":"material/car-door-lock.svg","material-car-door":"material/car-door.svg","material-car-electric-outline":"material/car-electric-outline.svg","material-car-electric":"material/car-electric.svg","material-car-emergency":"material/car-emergency.svg","material-car-esp":"material/car-esp.svg","material-car-estate":"material/car-estate.svg","material-car-hatchback":"material/car-hatchback.svg","material-car-info":"material/car-info.svg","material-car-key":"material/car-key.svg","material-car-lifted-pickup":"material/car-lifted-pickup.svg","material-car-light-alert":"material/car-light-alert.svg","material-car-light-dimmed":"material/car-light-dimmed.svg","material-car-light-fog":"material/car-light-fog.svg","material-car-light-high":"material/car-light-high.svg","material-car-limousine":"material/car-limousine.svg","material-car-multiple":"material/car-multiple.svg","material-car-off":"material/car-off.svg","material-car-outline":"material/car-outline.svg","material-car-parking-lights":"material/car-parking-lights.svg","material-car-pickup":"material/car-pickup.svg","material-car-search-outline":"material/car-search-outline.svg","material-car-search":"material/car-search.svg","material-car-seat-cooler":"material/car-seat-cooler.svg","material-car-seat-heater":"material/car-seat-heater.svg","material-car-seat":"material/car-seat.svg","material-car-select":"material/car-select.svg","material-car-settings":"material/car-settings.svg","material-car-shift-pattern":"material/car-shift-pattern.svg","material-car-side":"material/car-side.svg","material-car-speed-limiter":"material/car-speed-limiter.svg","material-car-sports":"material/car-sports.svg","material-car-tire-alert":"material/car-tire-alert.svg","material-car-traction-control":"material/car-traction-control.svg","material-car-turbocharger":"material/car-turbocharger.svg","material-car-wash":"material/car-wash.svg","material-car-windshield-outline":"material/car-windshield-outline.svg","material-car-windshield":"material/car-windshield.svg","material-car-wireless":"material/car-wireless.svg","material-car-wrench":"material/car-wrench.svg","material-car":"material/car.svg","material-carabiner":"material/carabiner.svg","material-caravan":"material/caravan.svg","material-card-account-details-outline":"material/card-account-details-outline.svg","material-card-account-details-star-outline":"material/card-account-details-star-outline.svg","material-card-account-details-star":"material/card-account-details-star.svg","material-card-account-details":"material/card-account-details.svg","material-card-account-mail-outline":"material/card-account-mail-outline.svg","material-card-account-mail":"material/card-account-mail.svg","material-card-account-phone-outline":"material/card-account-phone-outline.svg","material-card-account-phone":"material/card-account-phone.svg","material-card-bulleted-off-outline":"material/card-bulleted-off-outline.svg","material-card-bulleted-off":"material/card-bulleted-off.svg","material-card-bulleted-outline":"material/card-bulleted-outline.svg","material-card-bulleted-settings-outline":"material/card-bulleted-settings-outline.svg","material-card-bulleted-settings":"material/card-bulleted-settings.svg","material-card-bulleted":"material/card-bulleted.svg","material-card-minus-outline":"material/card-minus-outline.svg","material-card-minus":"material/card-minus.svg","material-card-multiple-outline":"material/card-multiple-outline.svg","material-card-multiple":"material/card-multiple.svg","material-card-off-outline":"material/card-off-outline.svg","material-card-off":"material/card-off.svg","material-card-outline":"material/card-outline.svg","material-card-plus-outline":"material/card-plus-outline.svg","material-card-plus":"material/card-plus.svg","material-card-remove-outline":"material/card-remove-outline.svg","material-card-remove":"material/card-remove.svg","material-card-search-outline":"material/card-search-outline.svg","material-card-search":"material/card-search.svg","material-card-text-outline":"material/card-text-outline.svg","material-card-text":"material/card-text.svg","material-card":"material/card.svg","material-cards-club-outline":"material/cards-club-outline.svg","material-cards-club":"material/cards-club.svg","material-cards-diamond-outline":"material/cards-diamond-outline.svg","material-cards-diamond":"material/cards-diamond.svg","material-cards-heart-outline":"material/cards-heart-outline.svg","material-cards-heart":"material/cards-heart.svg","material-cards-outline":"material/cards-outline.svg","material-cards-playing-club-multiple-outline":"material/cards-playing-club-multiple-outline.svg","material-cards-playing-club-multiple":"material/cards-playing-club-multiple.svg","material-cards-playing-club-outline":"material/cards-playing-club-outline.svg","material-cards-playing-club":"material/cards-playing-club.svg","material-cards-playing-diamond-multiple-outline":"material/cards-playing-diamond-multiple-outline.svg","material-cards-playing-diamond-multiple":"material/cards-playing-diamond-multiple.svg","material-cards-playing-diamond-outline":"material/cards-playing-diamond-outline.svg","material-cards-playing-diamond":"material/cards-playing-diamond.svg","material-cards-playing-heart-multiple-outline":"material/cards-playing-heart-multiple-outline.svg","material-cards-playing-heart-multiple":"material/cards-playing-heart-multiple.svg","material-cards-playing-heart-outline":"material/cards-playing-heart-outline.svg","material-cards-playing-heart":"material/cards-playing-heart.svg","material-cards-playing-outline":"material/cards-playing-outline.svg","material-cards-playing-spade-multiple-outline":"material/cards-playing-spade-multiple-outline.svg","material-cards-playing-spade-multiple":"material/cards-playing-spade-multiple.svg","material-cards-playing-spade-outline":"material/cards-playing-spade-outline.svg","material-cards-playing-spade":"material/cards-playing-spade.svg","material-cards-playing":"material/cards-playing.svg","material-cards-spade-outline":"material/cards-spade-outline.svg","material-cards-spade":"material/cards-spade.svg","material-cards-variant":"material/cards-variant.svg","material-cards":"material/cards.svg","material-carrot":"material/carrot.svg","material-cart-arrow-down":"material/cart-arrow-down.svg","material-cart-arrow-right":"material/cart-arrow-right.svg","material-cart-arrow-up":"material/cart-arrow-up.svg","material-cart-check":"material/cart-check.svg","material-cart-heart":"material/cart-heart.svg","material-cart-minus":"material/cart-minus.svg","material-cart-off":"material/cart-off.svg","material-cart-outline":"material/cart-outline.svg","material-cart-percent":"material/cart-percent.svg","material-cart-plus":"material/cart-plus.svg","material-cart-remove":"material/cart-remove.svg","material-cart-variant":"material/cart-variant.svg","material-cart":"material/cart.svg","material-case-sensitive-alt":"material/case-sensitive-alt.svg","material-cash-100":"material/cash-100.svg","material-cash-check":"material/cash-check.svg","material-cash-clock":"material/cash-clock.svg","material-cash-fast":"material/cash-fast.svg","material-cash-lock-open":"material/cash-lock-open.svg","material-cash-lock":"material/cash-lock.svg","material-cash-marker":"material/cash-marker.svg","material-cash-minus":"material/cash-minus.svg","material-cash-multiple":"material/cash-multiple.svg","material-cash-plus":"material/cash-plus.svg","material-cash-refund":"material/cash-refund.svg","material-cash-register":"material/cash-register.svg","material-cash-remove":"material/cash-remove.svg","material-cash-sync":"material/cash-sync.svg","material-cash":"material/cash.svg","material-cassette":"material/cassette.svg","material-cast-audio-variant":"material/cast-audio-variant.svg","material-cast-audio":"material/cast-audio.svg","material-cast-connected":"material/cast-connected.svg","material-cast-education":"material/cast-education.svg","material-cast-off":"material/cast-off.svg","material-cast-variant":"material/cast-variant.svg","material-cast":"material/cast.svg","material-castle":"material/castle.svg","material-cat":"material/cat.svg","material-cctv-off":"material/cctv-off.svg","material-cctv":"material/cctv.svg","material-ceiling-fan-light":"material/ceiling-fan-light.svg","material-ceiling-fan":"material/ceiling-fan.svg","material-ceiling-light-multiple-outline":"material/ceiling-light-multiple-outline.svg","material-ceiling-light-multiple":"material/ceiling-light-multiple.svg","material-ceiling-light-outline":"material/ceiling-light-outline.svg","material-ceiling-light":"material/ceiling-light.svg","material-cellphone-arrow-down-variant":"material/cellphone-arrow-down-variant.svg","material-cellphone-arrow-down":"material/cellphone-arrow-down.svg","material-cellphone-basic":"material/cellphone-basic.svg","material-cellphone-charging":"material/cellphone-charging.svg","material-cellphone-check":"material/cellphone-check.svg","material-cellphone-cog":"material/cellphone-cog.svg","material-cellphone-dock":"material/cellphone-dock.svg","material-cellphone-information":"material/cellphone-information.svg","material-cellphone-key":"material/cellphone-key.svg","material-cellphone-link-off":"material/cellphone-link-off.svg","material-cellphone-link":"material/cellphone-link.svg","material-cellphone-lock":"material/cellphone-lock.svg","material-cellphone-marker":"material/cellphone-marker.svg","material-cellphone-message-off":"material/cellphone-message-off.svg","material-cellphone-message":"material/cellphone-message.svg","material-cellphone-nfc-off":"material/cellphone-nfc-off.svg","material-cellphone-nfc":"material/cellphone-nfc.svg","material-cellphone-off":"material/cellphone-off.svg","material-cellphone-play":"material/cellphone-play.svg","material-cellphone-remove":"material/cellphone-remove.svg","material-cellphone-screenshot":"material/cellphone-screenshot.svg","material-cellphone-settings":"material/cellphone-settings.svg","material-cellphone-sound":"material/cellphone-sound.svg","material-cellphone-text":"material/cellphone-text.svg","material-cellphone-wireless":"material/cellphone-wireless.svg","material-cellphone":"material/cellphone.svg","material-centos":"material/centos.svg","material-certificate-outline":"material/certificate-outline.svg","material-certificate":"material/certificate.svg","material-chair-rolling":"material/chair-rolling.svg","material-chair-school":"material/chair-school.svg","material-chandelier":"material/chandelier.svg","material-charity":"material/charity.svg","material-chart-arc":"material/chart-arc.svg","material-chart-areaspline-variant":"material/chart-areaspline-variant.svg","material-chart-areaspline":"material/chart-areaspline.svg","material-chart-bar-stacked":"material/chart-bar-stacked.svg","material-chart-bar":"material/chart-bar.svg","material-chart-bell-curve-cumulative":"material/chart-bell-curve-cumulative.svg","material-chart-bell-curve":"material/chart-bell-curve.svg","material-chart-box-outline":"material/chart-box-outline.svg","material-chart-box-plus-outline":"material/chart-box-plus-outline.svg","material-chart-box":"material/chart-box.svg","material-chart-bubble":"material/chart-bubble.svg","material-chart-donut-variant":"material/chart-donut-variant.svg","material-chart-donut":"material/chart-donut.svg","material-chart-gantt":"material/chart-gantt.svg","material-chart-histogram":"material/chart-histogram.svg","material-chart-line-stacked":"material/chart-line-stacked.svg","material-chart-line-variant":"material/chart-line-variant.svg","material-chart-line":"material/chart-line.svg","material-chart-multiline":"material/chart-multiline.svg","material-chart-multiple":"material/chart-multiple.svg","material-chart-pie":"material/chart-pie.svg","material-chart-ppf":"material/chart-ppf.svg","material-chart-sankey-variant":"material/chart-sankey-variant.svg","material-chart-sankey":"material/chart-sankey.svg","material-chart-scatter-plot-hexbin":"material/chart-scatter-plot-hexbin.svg","material-chart-scatter-plot":"material/chart-scatter-plot.svg","material-chart-timeline-variant-shimmer":"material/chart-timeline-variant-shimmer.svg","material-chart-timeline-variant":"material/chart-timeline-variant.svg","material-chart-timeline":"material/chart-timeline.svg","material-chart-tree":"material/chart-tree.svg","material-chart-waterfall":"material/chart-waterfall.svg","material-chat-alert-outline":"material/chat-alert-outline.svg","material-chat-alert":"material/chat-alert.svg","material-chat-minus-outline":"material/chat-minus-outline.svg","material-chat-minus":"material/chat-minus.svg","material-chat-outline":"material/chat-outline.svg","material-chat-plus-outline":"material/chat-plus-outline.svg","material-chat-plus":"material/chat-plus.svg","material-chat-processing-outline":"material/chat-processing-outline.svg","material-chat-processing":"material/chat-processing.svg","material-chat-question-outline":"material/chat-question-outline.svg","material-chat-question":"material/chat-question.svg","material-chat-remove-outline":"material/chat-remove-outline.svg","material-chat-remove":"material/chat-remove.svg","material-chat-sleep-outline":"material/chat-sleep-outline.svg","material-chat-sleep":"material/chat-sleep.svg","material-chat":"material/chat.svg","material-check-all":"material/check-all.svg","material-check-bold":"material/check-bold.svg","material-check-circle-outline":"material/check-circle-outline.svg","material-check-circle":"material/check-circle.svg","material-check-decagram-outline":"material/check-decagram-outline.svg","material-check-decagram":"material/check-decagram.svg","material-check-network-outline":"material/check-network-outline.svg","material-check-network":"material/check-network.svg","material-check-outline":"material/check-outline.svg","material-check-underline-circle-outline":"material/check-underline-circle-outline.svg","material-check-underline-circle":"material/check-underline-circle.svg","material-check-underline":"material/check-underline.svg","material-check":"material/check.svg","material-checkbook":"material/checkbook.svg","material-checkbox-blank-badge-outline":"material/checkbox-blank-badge-outline.svg","material-checkbox-blank-badge":"material/checkbox-blank-badge.svg","material-checkbox-blank-circle-outline":"material/checkbox-blank-circle-outline.svg","material-checkbox-blank-circle":"material/checkbox-blank-circle.svg","material-checkbox-blank-off-outline":"material/checkbox-blank-off-outline.svg","material-checkbox-blank-off":"material/checkbox-blank-off.svg","material-checkbox-blank-outline":"material/checkbox-blank-outline.svg","material-checkbox-blank":"material/checkbox-blank.svg","material-checkbox-intermediate-variant":"material/checkbox-intermediate-variant.svg","material-checkbox-intermediate":"material/checkbox-intermediate.svg","material-checkbox-marked-circle-outline":"material/checkbox-marked-circle-outline.svg","material-checkbox-marked-circle-plus-outline":"material/checkbox-marked-circle-plus-outline.svg","material-checkbox-marked-circle":"material/checkbox-marked-circle.svg","material-checkbox-marked-outline":"material/checkbox-marked-outline.svg","material-checkbox-marked":"material/checkbox-marked.svg","material-checkbox-multiple-blank-circle-outline":"material/checkbox-multiple-blank-circle-outline.svg","material-checkbox-multiple-blank-circle":"material/checkbox-multiple-blank-circle.svg","material-checkbox-multiple-blank-outline":"material/checkbox-multiple-blank-outline.svg","material-checkbox-multiple-blank":"material/checkbox-multiple-blank.svg","material-checkbox-multiple-marked-circle-outline":"material/checkbox-multiple-marked-circle-outline.svg","material-checkbox-multiple-marked-circle":"material/checkbox-multiple-marked-circle.svg","material-checkbox-multiple-marked-outline":"material/checkbox-multiple-marked-outline.svg","material-checkbox-multiple-marked":"material/checkbox-multiple-marked.svg","material-checkbox-multiple-outline":"material/checkbox-multiple-outline.svg","material-checkbox-outline":"material/checkbox-outline.svg","material-checkerboard-minus":"material/checkerboard-minus.svg","material-checkerboard-plus":"material/checkerboard-plus.svg","material-checkerboard-remove":"material/checkerboard-remove.svg","material-checkerboard":"material/checkerboard.svg","material-cheese-off":"material/cheese-off.svg","material-cheese":"material/cheese.svg","material-chef-hat":"material/chef-hat.svg","material-chemical-weapon":"material/chemical-weapon.svg","material-chess-bishop":"material/chess-bishop.svg","material-chess-king":"material/chess-king.svg","material-chess-knight":"material/chess-knight.svg","material-chess-pawn":"material/chess-pawn.svg","material-chess-queen":"material/chess-queen.svg","material-chess-rook":"material/chess-rook.svg","material-chevron-double-down":"material/chevron-double-down.svg","material-chevron-double-left":"material/chevron-double-left.svg","material-chevron-double-right":"material/chevron-double-right.svg","material-chevron-double-up":"material/chevron-double-up.svg","material-chevron-down-box-outline":"material/chevron-down-box-outline.svg","material-chevron-down-box":"material/chevron-down-box.svg","material-chevron-down-circle-outline":"material/chevron-down-circle-outline.svg","material-chevron-down-circle":"material/chevron-down-circle.svg","material-chevron-down":"material/chevron-down.svg","material-chevron-left-box-outline":"material/chevron-left-box-outline.svg","material-chevron-left-box":"material/chevron-left-box.svg","material-chevron-left-circle-outline":"material/chevron-left-circle-outline.svg","material-chevron-left-circle":"material/chevron-left-circle.svg","material-chevron-left":"material/chevron-left.svg","material-chevron-right-box-outline":"material/chevron-right-box-outline.svg","material-chevron-right-box":"material/chevron-right-box.svg","material-chevron-right-circle-outline":"material/chevron-right-circle-outline.svg","material-chevron-right-circle":"material/chevron-right-circle.svg","material-chevron-right":"material/chevron-right.svg","material-chevron-triple-down":"material/chevron-triple-down.svg","material-chevron-triple-left":"material/chevron-triple-left.svg","material-chevron-triple-right":"material/chevron-triple-right.svg","material-chevron-triple-up":"material/chevron-triple-up.svg","material-chevron-up-box-outline":"material/chevron-up-box-outline.svg","material-chevron-up-box":"material/chevron-up-box.svg","material-chevron-up-circle-outline":"material/chevron-up-circle-outline.svg","material-chevron-up-circle":"material/chevron-up-circle.svg","material-chevron-up":"material/chevron-up.svg","material-chili-alert-outline":"material/chili-alert-outline.svg","material-chili-alert":"material/chili-alert.svg","material-chili-hot-outline":"material/chili-hot-outline.svg","material-chili-hot":"material/chili-hot.svg","material-chili-medium-outline":"material/chili-medium-outline.svg","material-chili-medium":"material/chili-medium.svg","material-chili-mild-outline":"material/chili-mild-outline.svg","material-chili-mild":"material/chili-mild.svg","material-chili-off-outline":"material/chili-off-outline.svg","material-chili-off":"material/chili-off.svg","material-chip":"material/chip.svg","material-church-outline":"material/church-outline.svg","material-church":"material/church.svg","material-cigar-off":"material/cigar-off.svg","material-cigar":"material/cigar.svg","material-circle-box-outline":"material/circle-box-outline.svg","material-circle-box":"material/circle-box.svg","material-circle-double":"material/circle-double.svg","material-circle-edit-outline":"material/circle-edit-outline.svg","material-circle-expand":"material/circle-expand.svg","material-circle-half-full":"material/circle-half-full.svg","material-circle-half":"material/circle-half.svg","material-circle-medium":"material/circle-medium.svg","material-circle-multiple-outline":"material/circle-multiple-outline.svg","material-circle-multiple":"material/circle-multiple.svg","material-circle-off-outline":"material/circle-off-outline.svg","material-circle-opacity":"material/circle-opacity.svg","material-circle-outline":"material/circle-outline.svg","material-circle-slice-1":"material/circle-slice-1.svg","material-circle-slice-2":"material/circle-slice-2.svg","material-circle-slice-3":"material/circle-slice-3.svg","material-circle-slice-4":"material/circle-slice-4.svg","material-circle-slice-5":"material/circle-slice-5.svg","material-circle-slice-6":"material/circle-slice-6.svg","material-circle-slice-7":"material/circle-slice-7.svg","material-circle-slice-8":"material/circle-slice-8.svg","material-circle-small":"material/circle-small.svg","material-circle":"material/circle.svg","material-circular-saw":"material/circular-saw.svg","material-city-variant-outline":"material/city-variant-outline.svg","material-city-variant":"material/city-variant.svg","material-city":"material/city.svg","material-clipboard-account-outline":"material/clipboard-account-outline.svg","material-clipboard-account":"material/clipboard-account.svg","material-clipboard-alert-outline":"material/clipboard-alert-outline.svg","material-clipboard-alert":"material/clipboard-alert.svg","material-clipboard-arrow-down-outline":"material/clipboard-arrow-down-outline.svg","material-clipboard-arrow-down":"material/clipboard-arrow-down.svg","material-clipboard-arrow-left-outline":"material/clipboard-arrow-left-outline.svg","material-clipboard-arrow-left":"material/clipboard-arrow-left.svg","material-clipboard-arrow-right-outline":"material/clipboard-arrow-right-outline.svg","material-clipboard-arrow-right":"material/clipboard-arrow-right.svg","material-clipboard-arrow-up-outline":"material/clipboard-arrow-up-outline.svg","material-clipboard-arrow-up":"material/clipboard-arrow-up.svg","material-clipboard-check-multiple-outline":"material/clipboard-check-multiple-outline.svg","material-clipboard-check-multiple":"material/clipboard-check-multiple.svg","material-clipboard-check-outline":"material/clipboard-check-outline.svg","material-clipboard-check":"material/clipboard-check.svg","material-clipboard-clock-outline":"material/clipboard-clock-outline.svg","material-clipboard-clock":"material/clipboard-clock.svg","material-clipboard-edit-outline":"material/clipboard-edit-outline.svg","material-clipboard-edit":"material/clipboard-edit.svg","material-clipboard-file-outline":"material/clipboard-file-outline.svg","material-clipboard-file":"material/clipboard-file.svg","material-clipboard-flow-outline":"material/clipboard-flow-outline.svg","material-clipboard-flow":"material/clipboard-flow.svg","material-clipboard-list-outline":"material/clipboard-list-outline.svg","material-clipboard-list":"material/clipboard-list.svg","material-clipboard-minus-outline":"material/clipboard-minus-outline.svg","material-clipboard-minus":"material/clipboard-minus.svg","material-clipboard-multiple-outline":"material/clipboard-multiple-outline.svg","material-clipboard-multiple":"material/clipboard-multiple.svg","material-clipboard-off-outline":"material/clipboard-off-outline.svg","material-clipboard-off":"material/clipboard-off.svg","material-clipboard-outline":"material/clipboard-outline.svg","material-clipboard-play-multiple-outline":"material/clipboard-play-multiple-outline.svg","material-clipboard-play-multiple":"material/clipboard-play-multiple.svg","material-clipboard-play-outline":"material/clipboard-play-outline.svg","material-clipboard-play":"material/clipboard-play.svg","material-clipboard-plus-outline":"material/clipboard-plus-outline.svg","material-clipboard-plus":"material/clipboard-plus.svg","material-clipboard-pulse-outline":"material/clipboard-pulse-outline.svg","material-clipboard-pulse":"material/clipboard-pulse.svg","material-clipboard-remove-outline":"material/clipboard-remove-outline.svg","material-clipboard-remove":"material/clipboard-remove.svg","material-clipboard-search-outline":"material/clipboard-search-outline.svg","material-clipboard-search":"material/clipboard-search.svg","material-clipboard-text-clock-outline":"material/clipboard-text-clock-outline.svg","material-clipboard-text-clock":"material/clipboard-text-clock.svg","material-clipboard-text-multiple-outline":"material/clipboard-text-multiple-outline.svg","material-clipboard-text-multiple":"material/clipboard-text-multiple.svg","material-clipboard-text-off-outline":"material/clipboard-text-off-outline.svg","material-clipboard-text-off":"material/clipboard-text-off.svg","material-clipboard-text-outline":"material/clipboard-text-outline.svg","material-clipboard-text-play-outline":"material/clipboard-text-play-outline.svg","material-clipboard-text-play":"material/clipboard-text-play.svg","material-clipboard-text-search-outline":"material/clipboard-text-search-outline.svg","material-clipboard-text-search":"material/clipboard-text-search.svg","material-clipboard-text":"material/clipboard-text.svg","material-clipboard":"material/clipboard.svg","material-clippy":"material/clippy.svg","material-clock-alert-outline":"material/clock-alert-outline.svg","material-clock-alert":"material/clock-alert.svg","material-clock-check-outline":"material/clock-check-outline.svg","material-clock-check":"material/clock-check.svg","material-clock-digital":"material/clock-digital.svg","material-clock-edit-outline":"material/clock-edit-outline.svg","material-clock-edit":"material/clock-edit.svg","material-clock-end":"material/clock-end.svg","material-clock-fast":"material/clock-fast.svg","material-clock-in":"material/clock-in.svg","material-clock-minus-outline":"material/clock-minus-outline.svg","material-clock-minus":"material/clock-minus.svg","material-clock-out":"material/clock-out.svg","material-clock-outline":"material/clock-outline.svg","material-clock-plus-outline":"material/clock-plus-outline.svg","material-clock-plus":"material/clock-plus.svg","material-clock-remove-outline":"material/clock-remove-outline.svg","material-clock-remove":"material/clock-remove.svg","material-clock-start":"material/clock-start.svg","material-clock-time-eight-outline":"material/clock-time-eight-outline.svg","material-clock-time-eight":"material/clock-time-eight.svg","material-clock-time-eleven-outline":"material/clock-time-eleven-outline.svg","material-clock-time-eleven":"material/clock-time-eleven.svg","material-clock-time-five-outline":"material/clock-time-five-outline.svg","material-clock-time-five":"material/clock-time-five.svg","material-clock-time-four-outline":"material/clock-time-four-outline.svg","material-clock-time-four":"material/clock-time-four.svg","material-clock-time-nine-outline":"material/clock-time-nine-outline.svg","material-clock-time-nine":"material/clock-time-nine.svg","material-clock-time-one-outline":"material/clock-time-one-outline.svg","material-clock-time-one":"material/clock-time-one.svg","material-clock-time-seven-outline":"material/clock-time-seven-outline.svg","material-clock-time-seven":"material/clock-time-seven.svg","material-clock-time-six-outline":"material/clock-time-six-outline.svg","material-clock-time-six":"material/clock-time-six.svg","material-clock-time-ten-outline":"material/clock-time-ten-outline.svg","material-clock-time-ten":"material/clock-time-ten.svg","material-clock-time-three-outline":"material/clock-time-three-outline.svg","material-clock-time-three":"material/clock-time-three.svg","material-clock-time-twelve-outline":"material/clock-time-twelve-outline.svg","material-clock-time-twelve":"material/clock-time-twelve.svg","material-clock-time-two-outline":"material/clock-time-two-outline.svg","material-clock-time-two":"material/clock-time-two.svg","material-clock":"material/clock.svg","material-close-box-multiple-outline":"material/close-box-multiple-outline.svg","material-close-box-multiple":"material/close-box-multiple.svg","material-close-box-outline":"material/close-box-outline.svg","material-close-box":"material/close-box.svg","material-close-circle-multiple-outline":"material/close-circle-multiple-outline.svg","material-close-circle-multiple":"material/close-circle-multiple.svg","material-close-circle-outline":"material/close-circle-outline.svg","material-close-circle":"material/close-circle.svg","material-close-network-outline":"material/close-network-outline.svg","material-close-network":"material/close-network.svg","material-close-octagon-outline":"material/close-octagon-outline.svg","material-close-octagon":"material/close-octagon.svg","material-close-outline":"material/close-outline.svg","material-close-thick":"material/close-thick.svg","material-close":"material/close.svg","material-closed-caption-outline":"material/closed-caption-outline.svg","material-closed-caption":"material/closed-caption.svg","material-cloud-alert":"material/cloud-alert.svg","material-cloud-braces":"material/cloud-braces.svg","material-cloud-check-outline":"material/cloud-check-outline.svg","material-cloud-check":"material/cloud-check.svg","material-cloud-circle":"material/cloud-circle.svg","material-cloud-download-outline":"material/cloud-download-outline.svg","material-cloud-download":"material/cloud-download.svg","material-cloud-lock-outline":"material/cloud-lock-outline.svg","material-cloud-lock":"material/cloud-lock.svg","material-cloud-off-outline":"material/cloud-off-outline.svg","material-cloud-outline":"material/cloud-outline.svg","material-cloud-percent-outline":"material/cloud-percent-outline.svg","material-cloud-percent":"material/cloud-percent.svg","material-cloud-print-outline":"material/cloud-print-outline.svg","material-cloud-print":"material/cloud-print.svg","material-cloud-question":"material/cloud-question.svg","material-cloud-refresh":"material/cloud-refresh.svg","material-cloud-search-outline":"material/cloud-search-outline.svg","material-cloud-search":"material/cloud-search.svg","material-cloud-sync-outline":"material/cloud-sync-outline.svg","material-cloud-sync":"material/cloud-sync.svg","material-cloud-tags":"material/cloud-tags.svg","material-cloud-upload-outline":"material/cloud-upload-outline.svg","material-cloud-upload":"material/cloud-upload.svg","material-cloud":"material/cloud.svg","material-clouds":"material/clouds.svg","material-clover":"material/clover.svg","material-coach-lamp-variant":"material/coach-lamp-variant.svg","material-coach-lamp":"material/coach-lamp.svg","material-coat-rack":"material/coat-rack.svg","material-code-array":"material/code-array.svg","material-code-braces-box":"material/code-braces-box.svg","material-code-braces":"material/code-braces.svg","material-code-brackets":"material/code-brackets.svg","material-code-equal":"material/code-equal.svg","material-code-greater-than-or-equal":"material/code-greater-than-or-equal.svg","material-code-greater-than":"material/code-greater-than.svg","material-code-json":"material/code-json.svg","material-code-less-than-or-equal":"material/code-less-than-or-equal.svg","material-code-less-than":"material/code-less-than.svg","material-code-not-equal-variant":"material/code-not-equal-variant.svg","material-code-not-equal":"material/code-not-equal.svg","material-code-parentheses-box":"material/code-parentheses-box.svg","material-code-parentheses":"material/code-parentheses.svg","material-code-string":"material/code-string.svg","material-code-tags-check":"material/code-tags-check.svg","material-code-tags":"material/code-tags.svg","material-codepen":"material/codepen.svg","material-coffee-maker-check-outline":"material/coffee-maker-check-outline.svg","material-coffee-maker-check":"material/coffee-maker-check.svg","material-coffee-maker-outline":"material/coffee-maker-outline.svg","material-coffee-maker":"material/coffee-maker.svg","material-coffee-off-outline":"material/coffee-off-outline.svg","material-coffee-off":"material/coffee-off.svg","material-coffee-outline":"material/coffee-outline.svg","material-coffee-to-go-outline":"material/coffee-to-go-outline.svg","material-coffee-to-go":"material/coffee-to-go.svg","material-coffee":"material/coffee.svg","material-coffin":"material/coffin.svg","material-cog-box":"material/cog-box.svg","material-cog-clockwise":"material/cog-clockwise.svg","material-cog-counterclockwise":"material/cog-counterclockwise.svg","material-cog-off-outline":"material/cog-off-outline.svg","material-cog-off":"material/cog-off.svg","material-cog-outline":"material/cog-outline.svg","material-cog-pause-outline":"material/cog-pause-outline.svg","material-cog-pause":"material/cog-pause.svg","material-cog-play-outline":"material/cog-play-outline.svg","material-cog-play":"material/cog-play.svg","material-cog-refresh-outline":"material/cog-refresh-outline.svg","material-cog-refresh":"material/cog-refresh.svg","material-cog-stop-outline":"material/cog-stop-outline.svg","material-cog-stop":"material/cog-stop.svg","material-cog-sync-outline":"material/cog-sync-outline.svg","material-cog-sync":"material/cog-sync.svg","material-cog-transfer-outline":"material/cog-transfer-outline.svg","material-cog-transfer":"material/cog-transfer.svg","material-cog":"material/cog.svg","material-cogs":"material/cogs.svg","material-collage":"material/collage.svg","material-collapse-all-outline":"material/collapse-all-outline.svg","material-collapse-all":"material/collapse-all.svg","material-color-helper":"material/color-helper.svg","material-comma-box-outline":"material/comma-box-outline.svg","material-comma-box":"material/comma-box.svg","material-comma-circle-outline":"material/comma-circle-outline.svg","material-comma-circle":"material/comma-circle.svg","material-comma":"material/comma.svg","material-comment-account-outline":"material/comment-account-outline.svg","material-comment-account":"material/comment-account.svg","material-comment-alert-outline":"material/comment-alert-outline.svg","material-comment-alert":"material/comment-alert.svg","material-comment-arrow-left-outline":"material/comment-arrow-left-outline.svg","material-comment-arrow-left":"material/comment-arrow-left.svg","material-comment-arrow-right-outline":"material/comment-arrow-right-outline.svg","material-comment-arrow-right":"material/comment-arrow-right.svg","material-comment-bookmark-outline":"material/comment-bookmark-outline.svg","material-comment-bookmark":"material/comment-bookmark.svg","material-comment-check-outline":"material/comment-check-outline.svg","material-comment-check":"material/comment-check.svg","material-comment-edit-outline":"material/comment-edit-outline.svg","material-comment-edit":"material/comment-edit.svg","material-comment-eye-outline":"material/comment-eye-outline.svg","material-comment-eye":"material/comment-eye.svg","material-comment-flash-outline":"material/comment-flash-outline.svg","material-comment-flash":"material/comment-flash.svg","material-comment-minus-outline":"material/comment-minus-outline.svg","material-comment-minus":"material/comment-minus.svg","material-comment-multiple-outline":"material/comment-multiple-outline.svg","material-comment-multiple":"material/comment-multiple.svg","material-comment-off-outline":"material/comment-off-outline.svg","material-comment-off":"material/comment-off.svg","material-comment-outline":"material/comment-outline.svg","material-comment-plus-outline":"material/comment-plus-outline.svg","material-comment-plus":"material/comment-plus.svg","material-comment-processing-outline":"material/comment-processing-outline.svg","material-comment-processing":"material/comment-processing.svg","material-comment-question-outline":"material/comment-question-outline.svg","material-comment-question":"material/comment-question.svg","material-comment-quote-outline":"material/comment-quote-outline.svg","material-comment-quote":"material/comment-quote.svg","material-comment-remove-outline":"material/comment-remove-outline.svg","material-comment-remove":"material/comment-remove.svg","material-comment-search-outline":"material/comment-search-outline.svg","material-comment-search":"material/comment-search.svg","material-comment-text-multiple-outline":"material/comment-text-multiple-outline.svg","material-comment-text-multiple":"material/comment-text-multiple.svg","material-comment-text-outline":"material/comment-text-outline.svg","material-comment-text":"material/comment-text.svg","material-comment":"material/comment.svg","material-compare-horizontal":"material/compare-horizontal.svg","material-compare-remove":"material/compare-remove.svg","material-compare-vertical":"material/compare-vertical.svg","material-compare":"material/compare.svg","material-compass-off-outline":"material/compass-off-outline.svg","material-compass-off":"material/compass-off.svg","material-compass-outline":"material/compass-outline.svg","material-compass-rose":"material/compass-rose.svg","material-compass":"material/compass.svg","material-compost":"material/compost.svg","material-cone-off":"material/cone-off.svg","material-cone":"material/cone.svg","material-connection":"material/connection.svg","material-console-line":"material/console-line.svg","material-console-network-outline":"material/console-network-outline.svg","material-console-network":"material/console-network.svg","material-console":"material/console.svg","material-consolidate":"material/consolidate.svg","material-contactless-payment-circle-outline":"material/contactless-payment-circle-outline.svg","material-contactless-payment-circle":"material/contactless-payment-circle.svg","material-contactless-payment":"material/contactless-payment.svg","material-contacts-outline":"material/contacts-outline.svg","material-contacts":"material/contacts.svg","material-contain-end":"material/contain-end.svg","material-contain-start":"material/contain-start.svg","material-contain":"material/contain.svg","material-content-copy":"material/content-copy.svg","material-content-cut":"material/content-cut.svg","material-content-duplicate":"material/content-duplicate.svg","material-content-paste":"material/content-paste.svg","material-content-save-alert-outline":"material/content-save-alert-outline.svg","material-content-save-alert":"material/content-save-alert.svg","material-content-save-all-outline":"material/content-save-all-outline.svg","material-content-save-all":"material/content-save-all.svg","material-content-save-check-outline":"material/content-save-check-outline.svg","material-content-save-check":"material/content-save-check.svg","material-content-save-cog-outline":"material/content-save-cog-outline.svg","material-content-save-cog":"material/content-save-cog.svg","material-content-save-edit-outline":"material/content-save-edit-outline.svg","material-content-save-edit":"material/content-save-edit.svg","material-content-save-minus-outline":"material/content-save-minus-outline.svg","material-content-save-minus":"material/content-save-minus.svg","material-content-save-move-outline":"material/content-save-move-outline.svg","material-content-save-move":"material/content-save-move.svg","material-content-save-off-outline":"material/content-save-off-outline.svg","material-content-save-off":"material/content-save-off.svg","material-content-save-outline":"material/content-save-outline.svg","material-content-save-plus-outline":"material/content-save-plus-outline.svg","material-content-save-plus":"material/content-save-plus.svg","material-content-save-settings-outline":"material/content-save-settings-outline.svg","material-content-save-settings":"material/content-save-settings.svg","material-content-save":"material/content-save.svg","material-contrast-box":"material/contrast-box.svg","material-contrast-circle":"material/contrast-circle.svg","material-contrast":"material/contrast.svg","material-controller-classic-outline":"material/controller-classic-outline.svg","material-controller-classic":"material/controller-classic.svg","material-controller-off":"material/controller-off.svg","material-controller":"material/controller.svg","material-cookie-alert-outline":"material/cookie-alert-outline.svg","material-cookie-alert":"material/cookie-alert.svg","material-cookie-check-outline":"material/cookie-check-outline.svg","material-cookie-check":"material/cookie-check.svg","material-cookie-clock-outline":"material/cookie-clock-outline.svg","material-cookie-clock":"material/cookie-clock.svg","material-cookie-cog-outline":"material/cookie-cog-outline.svg","material-cookie-cog":"material/cookie-cog.svg","material-cookie-edit-outline":"material/cookie-edit-outline.svg","material-cookie-edit":"material/cookie-edit.svg","material-cookie-lock-outline":"material/cookie-lock-outline.svg","material-cookie-lock":"material/cookie-lock.svg","material-cookie-minus-outline":"material/cookie-minus-outline.svg","material-cookie-minus":"material/cookie-minus.svg","material-cookie-off-outline":"material/cookie-off-outline.svg","material-cookie-off":"material/cookie-off.svg","material-cookie-outline":"material/cookie-outline.svg","material-cookie-plus-outline":"material/cookie-plus-outline.svg","material-cookie-plus":"material/cookie-plus.svg","material-cookie-refresh-outline":"material/cookie-refresh-outline.svg","material-cookie-refresh":"material/cookie-refresh.svg","material-cookie-remove-outline":"material/cookie-remove-outline.svg","material-cookie-remove":"material/cookie-remove.svg","material-cookie-settings-outline":"material/cookie-settings-outline.svg","material-cookie-settings":"material/cookie-settings.svg","material-cookie":"material/cookie.svg","material-coolant-temperature":"material/coolant-temperature.svg","material-copyleft":"material/copyleft.svg","material-copyright":"material/copyright.svg","material-cordova":"material/cordova.svg","material-corn-off":"material/corn-off.svg","material-corn":"material/corn.svg","material-cosine-wave":"material/cosine-wave.svg","material-counter":"material/counter.svg","material-countertop-outline":"material/countertop-outline.svg","material-countertop":"material/countertop.svg","material-cow-off":"material/cow-off.svg","material-cow":"material/cow.svg","material-cpu-32-bit":"material/cpu-32-bit.svg","material-cpu-64-bit":"material/cpu-64-bit.svg","material-cradle-outline":"material/cradle-outline.svg","material-cradle":"material/cradle.svg","material-crane":"material/crane.svg","material-creation":"material/creation.svg","material-creative-commons":"material/creative-commons.svg","material-credit-card-check-outline":"material/credit-card-check-outline.svg","material-credit-card-check":"material/credit-card-check.svg","material-credit-card-chip-outline":"material/credit-card-chip-outline.svg","material-credit-card-chip":"material/credit-card-chip.svg","material-credit-card-clock-outline":"material/credit-card-clock-outline.svg","material-credit-card-clock":"material/credit-card-clock.svg","material-credit-card-edit-outline":"material/credit-card-edit-outline.svg","material-credit-card-edit":"material/credit-card-edit.svg","material-credit-card-fast-outline":"material/credit-card-fast-outline.svg","material-credit-card-fast":"material/credit-card-fast.svg","material-credit-card-lock-outline":"material/credit-card-lock-outline.svg","material-credit-card-lock":"material/credit-card-lock.svg","material-credit-card-marker-outline":"material/credit-card-marker-outline.svg","material-credit-card-marker":"material/credit-card-marker.svg","material-credit-card-minus-outline":"material/credit-card-minus-outline.svg","material-credit-card-minus":"material/credit-card-minus.svg","material-credit-card-multiple-outline":"material/credit-card-multiple-outline.svg","material-credit-card-multiple":"material/credit-card-multiple.svg","material-credit-card-off-outline":"material/credit-card-off-outline.svg","material-credit-card-off":"material/credit-card-off.svg","material-credit-card-outline":"material/credit-card-outline.svg","material-credit-card-plus-outline":"material/credit-card-plus-outline.svg","material-credit-card-plus":"material/credit-card-plus.svg","material-credit-card-refresh-outline":"material/credit-card-refresh-outline.svg","material-credit-card-refresh":"material/credit-card-refresh.svg","material-credit-card-refund-outline":"material/credit-card-refund-outline.svg","material-credit-card-refund":"material/credit-card-refund.svg","material-credit-card-remove-outline":"material/credit-card-remove-outline.svg","material-credit-card-remove":"material/credit-card-remove.svg","material-credit-card-scan-outline":"material/credit-card-scan-outline.svg","material-credit-card-scan":"material/credit-card-scan.svg","material-credit-card-search-outline":"material/credit-card-search-outline.svg","material-credit-card-search":"material/credit-card-search.svg","material-credit-card-settings-outline":"material/credit-card-settings-outline.svg","material-credit-card-settings":"material/credit-card-settings.svg","material-credit-card-sync-outline":"material/credit-card-sync-outline.svg","material-credit-card-sync":"material/credit-card-sync.svg","material-credit-card-wireless-off-outline":"material/credit-card-wireless-off-outline.svg","material-credit-card-wireless-off":"material/credit-card-wireless-off.svg","material-credit-card-wireless-outline":"material/credit-card-wireless-outline.svg","material-credit-card-wireless":"material/credit-card-wireless.svg","material-credit-card":"material/credit-card.svg","material-cricket":"material/cricket.svg","material-crop-free":"material/crop-free.svg","material-crop-landscape":"material/crop-landscape.svg","material-crop-portrait":"material/crop-portrait.svg","material-crop-rotate":"material/crop-rotate.svg","material-crop-square":"material/crop-square.svg","material-crop":"material/crop.svg","material-cross-bolnisi":"material/cross-bolnisi.svg","material-cross-celtic":"material/cross-celtic.svg","material-cross-outline":"material/cross-outline.svg","material-cross":"material/cross.svg","material-crosshairs-gps":"material/crosshairs-gps.svg","material-crosshairs-off":"material/crosshairs-off.svg","material-crosshairs-question":"material/crosshairs-question.svg","material-crosshairs":"material/crosshairs.svg","material-crowd":"material/crowd.svg","material-crown-circle-outline":"material/crown-circle-outline.svg","material-crown-circle":"material/crown-circle.svg","material-crown-outline":"material/crown-outline.svg","material-crown":"material/crown.svg","material-cryengine":"material/cryengine.svg","material-crystal-ball":"material/crystal-ball.svg","material-cube-off-outline":"material/cube-off-outline.svg","material-cube-off":"material/cube-off.svg","material-cube-outline":"material/cube-outline.svg","material-cube-scan":"material/cube-scan.svg","material-cube-send":"material/cube-send.svg","material-cube-unfolded":"material/cube-unfolded.svg","material-cube":"material/cube.svg","material-cup-off-outline":"material/cup-off-outline.svg","material-cup-off":"material/cup-off.svg","material-cup-outline":"material/cup-outline.svg","material-cup-water":"material/cup-water.svg","material-cup":"material/cup.svg","material-cupboard-outline":"material/cupboard-outline.svg","material-cupboard":"material/cupboard.svg","material-cupcake":"material/cupcake.svg","material-curling":"material/curling.svg","material-currency-bdt":"material/currency-bdt.svg","material-currency-brl":"material/currency-brl.svg","material-currency-btc":"material/currency-btc.svg","material-currency-cny":"material/currency-cny.svg","material-currency-eth":"material/currency-eth.svg","material-currency-eur-off":"material/currency-eur-off.svg","material-currency-eur":"material/currency-eur.svg","material-currency-fra":"material/currency-fra.svg","material-currency-gbp":"material/currency-gbp.svg","material-currency-ils":"material/currency-ils.svg","material-currency-inr":"material/currency-inr.svg","material-currency-jpy":"material/currency-jpy.svg","material-currency-krw":"material/currency-krw.svg","material-currency-kzt":"material/currency-kzt.svg","material-currency-mnt":"material/currency-mnt.svg","material-currency-ngn":"material/currency-ngn.svg","material-currency-php":"material/currency-php.svg","material-currency-rial":"material/currency-rial.svg","material-currency-rub":"material/currency-rub.svg","material-currency-rupee":"material/currency-rupee.svg","material-currency-sign":"material/currency-sign.svg","material-currency-try":"material/currency-try.svg","material-currency-twd":"material/currency-twd.svg","material-currency-uah":"material/currency-uah.svg","material-currency-usd-off":"material/currency-usd-off.svg","material-currency-usd":"material/currency-usd.svg","material-current-ac":"material/current-ac.svg","material-current-dc":"material/current-dc.svg","material-cursor-default-click-outline":"material/cursor-default-click-outline.svg","material-cursor-default-click":"material/cursor-default-click.svg","material-cursor-default-gesture-outline":"material/cursor-default-gesture-outline.svg","material-cursor-default-gesture":"material/cursor-default-gesture.svg","material-cursor-default-outline":"material/cursor-default-outline.svg","material-cursor-default":"material/cursor-default.svg","material-cursor-move":"material/cursor-move.svg","material-cursor-pointer":"material/cursor-pointer.svg","material-cursor-text":"material/cursor-text.svg","material-curtains-closed":"material/curtains-closed.svg","material-curtains":"material/curtains.svg","material-cylinder-off":"material/cylinder-off.svg","material-cylinder":"material/cylinder.svg","material-dance-ballroom":"material/dance-ballroom.svg","material-dance-pole":"material/dance-pole.svg","material-data-matrix-edit":"material/data-matrix-edit.svg","material-data-matrix-minus":"material/data-matrix-minus.svg","material-data-matrix-plus":"material/data-matrix-plus.svg","material-data-matrix-remove":"material/data-matrix-remove.svg","material-data-matrix-scan":"material/data-matrix-scan.svg","material-data-matrix":"material/data-matrix.svg","material-database-alert-outline":"material/database-alert-outline.svg","material-database-alert":"material/database-alert.svg","material-database-arrow-down-outline":"material/database-arrow-down-outline.svg","material-database-arrow-down":"material/database-arrow-down.svg","material-database-arrow-left-outline":"material/database-arrow-left-outline.svg","material-database-arrow-left":"material/database-arrow-left.svg","material-database-arrow-right-outline":"material/database-arrow-right-outline.svg","material-database-arrow-right":"material/database-arrow-right.svg","material-database-arrow-up-outline":"material/database-arrow-up-outline.svg","material-database-arrow-up":"material/database-arrow-up.svg","material-database-check-outline":"material/database-check-outline.svg","material-database-check":"material/database-check.svg","material-database-clock-outline":"material/database-clock-outline.svg","material-database-clock":"material/database-clock.svg","material-database-cog-outline":"material/database-cog-outline.svg","material-database-cog":"material/database-cog.svg","material-database-edit-outline":"material/database-edit-outline.svg","material-database-edit":"material/database-edit.svg","material-database-export-outline":"material/database-export-outline.svg","material-database-export":"material/database-export.svg","material-database-eye-off-outline":"material/database-eye-off-outline.svg","material-database-eye-off":"material/database-eye-off.svg","material-database-eye-outline":"material/database-eye-outline.svg","material-database-eye":"material/database-eye.svg","material-database-import-outline":"material/database-import-outline.svg","material-database-import":"material/database-import.svg","material-database-lock-outline":"material/database-lock-outline.svg","material-database-lock":"material/database-lock.svg","material-database-marker-outline":"material/database-marker-outline.svg","material-database-marker":"material/database-marker.svg","material-database-minus-outline":"material/database-minus-outline.svg","material-database-minus":"material/database-minus.svg","material-database-off-outline":"material/database-off-outline.svg","material-database-off":"material/database-off.svg","material-database-outline":"material/database-outline.svg","material-database-plus-outline":"material/database-plus-outline.svg","material-database-plus":"material/database-plus.svg","material-database-refresh-outline":"material/database-refresh-outline.svg","material-database-refresh":"material/database-refresh.svg","material-database-remove-outline":"material/database-remove-outline.svg","material-database-remove":"material/database-remove.svg","material-database-search-outline":"material/database-search-outline.svg","material-database-search":"material/database-search.svg","material-database-settings-outline":"material/database-settings-outline.svg","material-database-settings":"material/database-settings.svg","material-database-sync-outline":"material/database-sync-outline.svg","material-database-sync":"material/database-sync.svg","material-database":"material/database.svg","material-death-star-variant":"material/death-star-variant.svg","material-death-star":"material/death-star.svg","material-deathly-hallows":"material/deathly-hallows.svg","material-debian":"material/debian.svg","material-debug-step-into":"material/debug-step-into.svg","material-debug-step-out":"material/debug-step-out.svg","material-debug-step-over":"material/debug-step-over.svg","material-decagram-outline":"material/decagram-outline.svg","material-decagram":"material/decagram.svg","material-decimal-comma-decrease":"material/decimal-comma-decrease.svg","material-decimal-comma-increase":"material/decimal-comma-increase.svg","material-decimal-comma":"material/decimal-comma.svg","material-decimal-decrease":"material/decimal-decrease.svg","material-decimal-increase":"material/decimal-increase.svg","material-decimal":"material/decimal.svg","material-delete-alert-outline":"material/delete-alert-outline.svg","material-delete-alert":"material/delete-alert.svg","material-delete-circle-outline":"material/delete-circle-outline.svg","material-delete-circle":"material/delete-circle.svg","material-delete-clock-outline":"material/delete-clock-outline.svg","material-delete-clock":"material/delete-clock.svg","material-delete-empty-outline":"material/delete-empty-outline.svg","material-delete-empty":"material/delete-empty.svg","material-delete-forever-outline":"material/delete-forever-outline.svg","material-delete-forever":"material/delete-forever.svg","material-delete-off-outline":"material/delete-off-outline.svg","material-delete-off":"material/delete-off.svg","material-delete-outline":"material/delete-outline.svg","material-delete-restore":"material/delete-restore.svg","material-delete-sweep-outline":"material/delete-sweep-outline.svg","material-delete-sweep":"material/delete-sweep.svg","material-delete-variant":"material/delete-variant.svg","material-delete":"material/delete.svg","material-delta":"material/delta.svg","material-desk-lamp-off":"material/desk-lamp-off.svg","material-desk-lamp-on":"material/desk-lamp-on.svg","material-desk-lamp":"material/desk-lamp.svg","material-desk":"material/desk.svg","material-deskphone":"material/deskphone.svg","material-desktop-classic":"material/desktop-classic.svg","material-desktop-tower-monitor":"material/desktop-tower-monitor.svg","material-desktop-tower":"material/desktop-tower.svg","material-details":"material/details.svg","material-dev-to":"material/dev-to.svg","material-developer-board":"material/developer-board.svg","material-deviantart":"material/deviantart.svg","material-devices":"material/devices.svg","material-dharmachakra":"material/dharmachakra.svg","material-diabetes":"material/diabetes.svg","material-dialpad":"material/dialpad.svg","material-diameter-outline":"material/diameter-outline.svg","material-diameter-variant":"material/diameter-variant.svg","material-diameter":"material/diameter.svg","material-diamond-outline":"material/diamond-outline.svg","material-diamond-stone":"material/diamond-stone.svg","material-diamond":"material/diamond.svg","material-dice-1-outline":"material/dice-1-outline.svg","material-dice-1":"material/dice-1.svg","material-dice-2-outline":"material/dice-2-outline.svg","material-dice-2":"material/dice-2.svg","material-dice-3-outline":"material/dice-3-outline.svg","material-dice-3":"material/dice-3.svg","material-dice-4-outline":"material/dice-4-outline.svg","material-dice-4":"material/dice-4.svg","material-dice-5-outline":"material/dice-5-outline.svg","material-dice-5":"material/dice-5.svg","material-dice-6-outline":"material/dice-6-outline.svg","material-dice-6":"material/dice-6.svg","material-dice-d10-outline":"material/dice-d10-outline.svg","material-dice-d10":"material/dice-d10.svg","material-dice-d12-outline":"material/dice-d12-outline.svg","material-dice-d12":"material/dice-d12.svg","material-dice-d20-outline":"material/dice-d20-outline.svg","material-dice-d20":"material/dice-d20.svg","material-dice-d4-outline":"material/dice-d4-outline.svg","material-dice-d4":"material/dice-d4.svg","material-dice-d6-outline":"material/dice-d6-outline.svg","material-dice-d6":"material/dice-d6.svg","material-dice-d8-outline":"material/dice-d8-outline.svg","material-dice-d8":"material/dice-d8.svg","material-dice-multiple-outline":"material/dice-multiple-outline.svg","material-dice-multiple":"material/dice-multiple.svg","material-digital-ocean":"material/digital-ocean.svg","material-dip-switch":"material/dip-switch.svg","material-directions-fork":"material/directions-fork.svg","material-directions":"material/directions.svg","material-disc-alert":"material/disc-alert.svg","material-disc-player":"material/disc-player.svg","material-disc":"material/disc.svg","material-dishwasher-alert":"material/dishwasher-alert.svg","material-dishwasher-off":"material/dishwasher-off.svg","material-dishwasher":"material/dishwasher.svg","material-disqus":"material/disqus.svg","material-distribute-horizontal-center":"material/distribute-horizontal-center.svg","material-distribute-horizontal-left":"material/distribute-horizontal-left.svg","material-distribute-horizontal-right":"material/distribute-horizontal-right.svg","material-distribute-vertical-bottom":"material/distribute-vertical-bottom.svg","material-distribute-vertical-center":"material/distribute-vertical-center.svg","material-distribute-vertical-top":"material/distribute-vertical-top.svg","material-diversify":"material/diversify.svg","material-diving-flippers":"material/diving-flippers.svg","material-diving-helmet":"material/diving-helmet.svg","material-diving-scuba-flag":"material/diving-scuba-flag.svg","material-diving-scuba-mask":"material/diving-scuba-mask.svg","material-diving-scuba-tank-multiple":"material/diving-scuba-tank-multiple.svg","material-diving-scuba-tank":"material/diving-scuba-tank.svg","material-diving-scuba":"material/diving-scuba.svg","material-diving-snorkel":"material/diving-snorkel.svg","material-diving":"material/diving.svg","material-division-box":"material/division-box.svg","material-division":"material/division.svg","material-dlna":"material/dlna.svg","material-dna":"material/dna.svg","material-dns-outline":"material/dns-outline.svg","material-dns":"material/dns.svg","material-dock-bottom":"material/dock-bottom.svg","material-dock-left":"material/dock-left.svg","material-dock-right":"material/dock-right.svg","material-dock-top":"material/dock-top.svg","material-dock-window":"material/dock-window.svg","material-docker":"material/docker.svg","material-doctor":"material/doctor.svg","material-dog-service":"material/dog-service.svg","material-dog-side-off":"material/dog-side-off.svg","material-dog-side":"material/dog-side.svg","material-dog":"material/dog.svg","material-dolby":"material/dolby.svg","material-dolly":"material/dolly.svg","material-dolphin":"material/dolphin.svg","material-domain-off":"material/domain-off.svg","material-domain-plus":"material/domain-plus.svg","material-domain-remove":"material/domain-remove.svg","material-domain":"material/domain.svg","material-dome-light":"material/dome-light.svg","material-domino-mask":"material/domino-mask.svg","material-donkey":"material/donkey.svg","material-door-closed-lock":"material/door-closed-lock.svg","material-door-closed":"material/door-closed.svg","material-door-open":"material/door-open.svg","material-door-sliding-lock":"material/door-sliding-lock.svg","material-door-sliding-open":"material/door-sliding-open.svg","material-door-sliding":"material/door-sliding.svg","material-door":"material/door.svg","material-doorbell-video":"material/doorbell-video.svg","material-doorbell":"material/doorbell.svg","material-dot-net":"material/dot-net.svg","material-dots-circle":"material/dots-circle.svg","material-dots-grid":"material/dots-grid.svg","material-dots-hexagon":"material/dots-hexagon.svg","material-dots-horizontal-circle-outline":"material/dots-horizontal-circle-outline.svg","material-dots-horizontal-circle":"material/dots-horizontal-circle.svg","material-dots-horizontal":"material/dots-horizontal.svg","material-dots-square":"material/dots-square.svg","material-dots-triangle":"material/dots-triangle.svg","material-dots-vertical-circle-outline":"material/dots-vertical-circle-outline.svg","material-dots-vertical-circle":"material/dots-vertical-circle.svg","material-dots-vertical":"material/dots-vertical.svg","material-download-box-outline":"material/download-box-outline.svg","material-download-box":"material/download-box.svg","material-download-circle-outline":"material/download-circle-outline.svg","material-download-circle":"material/download-circle.svg","material-download-lock-outline":"material/download-lock-outline.svg","material-download-lock":"material/download-lock.svg","material-download-multiple":"material/download-multiple.svg","material-download-network-outline":"material/download-network-outline.svg","material-download-network":"material/download-network.svg","material-download-off-outline":"material/download-off-outline.svg","material-download-off":"material/download-off.svg","material-download-outline":"material/download-outline.svg","material-download":"material/download.svg","material-drag-horizontal-variant":"material/drag-horizontal-variant.svg","material-drag-horizontal":"material/drag-horizontal.svg","material-drag-variant":"material/drag-variant.svg","material-drag-vertical-variant":"material/drag-vertical-variant.svg","material-drag-vertical":"material/drag-vertical.svg","material-drag":"material/drag.svg","material-drama-masks":"material/drama-masks.svg","material-draw-pen":"material/draw-pen.svg","material-draw":"material/draw.svg","material-drawing-box":"material/drawing-box.svg","material-drawing":"material/drawing.svg","material-dresser-outline":"material/dresser-outline.svg","material-dresser":"material/dresser.svg","material-drone":"material/drone.svg","material-dropbox":"material/dropbox.svg","material-drupal":"material/drupal.svg","material-duck":"material/duck.svg","material-dumbbell":"material/dumbbell.svg","material-dump-truck":"material/dump-truck.svg","material-ear-hearing-loop":"material/ear-hearing-loop.svg","material-ear-hearing-off":"material/ear-hearing-off.svg","material-ear-hearing":"material/ear-hearing.svg","material-earbuds-off-outline":"material/earbuds-off-outline.svg","material-earbuds-off":"material/earbuds-off.svg","material-earbuds-outline":"material/earbuds-outline.svg","material-earbuds":"material/earbuds.svg","material-earth-arrow-right":"material/earth-arrow-right.svg","material-earth-box-minus":"material/earth-box-minus.svg","material-earth-box-off":"material/earth-box-off.svg","material-earth-box-plus":"material/earth-box-plus.svg","material-earth-box-remove":"material/earth-box-remove.svg","material-earth-box":"material/earth-box.svg","material-earth-minus":"material/earth-minus.svg","material-earth-off":"material/earth-off.svg","material-earth-plus":"material/earth-plus.svg","material-earth-remove":"material/earth-remove.svg","material-earth":"material/earth.svg","material-egg-easter":"material/egg-easter.svg","material-egg-fried":"material/egg-fried.svg","material-egg-off-outline":"material/egg-off-outline.svg","material-egg-off":"material/egg-off.svg","material-egg-outline":"material/egg-outline.svg","material-egg":"material/egg.svg","material-eiffel-tower":"material/eiffel-tower.svg","material-eight-track":"material/eight-track.svg","material-eject-circle-outline":"material/eject-circle-outline.svg","material-eject-circle":"material/eject-circle.svg","material-eject-outline":"material/eject-outline.svg","material-eject":"material/eject.svg","material-electric-switch-closed":"material/electric-switch-closed.svg","material-electric-switch":"material/electric-switch.svg","material-electron-framework":"material/electron-framework.svg","material-elephant":"material/elephant.svg","material-elevation-decline":"material/elevation-decline.svg","material-elevation-rise":"material/elevation-rise.svg","material-elevator-down":"material/elevator-down.svg","material-elevator-passenger-off-outline":"material/elevator-passenger-off-outline.svg","material-elevator-passenger-off":"material/elevator-passenger-off.svg","material-elevator-passenger-outline":"material/elevator-passenger-outline.svg","material-elevator-passenger":"material/elevator-passenger.svg","material-elevator-up":"material/elevator-up.svg","material-elevator":"material/elevator.svg","material-ellipse-outline":"material/ellipse-outline.svg","material-ellipse":"material/ellipse.svg","material-email-alert-outline":"material/email-alert-outline.svg","material-email-alert":"material/email-alert.svg","material-email-arrow-left-outline":"material/email-arrow-left-outline.svg","material-email-arrow-left":"material/email-arrow-left.svg","material-email-arrow-right-outline":"material/email-arrow-right-outline.svg","material-email-arrow-right":"material/email-arrow-right.svg","material-email-box":"material/email-box.svg","material-email-check-outline":"material/email-check-outline.svg","material-email-check":"material/email-check.svg","material-email-edit-outline":"material/email-edit-outline.svg","material-email-edit":"material/email-edit.svg","material-email-fast-outline":"material/email-fast-outline.svg","material-email-fast":"material/email-fast.svg","material-email-lock-outline":"material/email-lock-outline.svg","material-email-lock":"material/email-lock.svg","material-email-mark-as-unread":"material/email-mark-as-unread.svg","material-email-minus-outline":"material/email-minus-outline.svg","material-email-minus":"material/email-minus.svg","material-email-multiple-outline":"material/email-multiple-outline.svg","material-email-multiple":"material/email-multiple.svg","material-email-newsletter":"material/email-newsletter.svg","material-email-off-outline":"material/email-off-outline.svg","material-email-off":"material/email-off.svg","material-email-open-multiple-outline":"material/email-open-multiple-outline.svg","material-email-open-multiple":"material/email-open-multiple.svg","material-email-open-outline":"material/email-open-outline.svg","material-email-open":"material/email-open.svg","material-email-outline":"material/email-outline.svg","material-email-plus-outline":"material/email-plus-outline.svg","material-email-plus":"material/email-plus.svg","material-email-remove-outline":"material/email-remove-outline.svg","material-email-remove":"material/email-remove.svg","material-email-seal-outline":"material/email-seal-outline.svg","material-email-seal":"material/email-seal.svg","material-email-search-outline":"material/email-search-outline.svg","material-email-search":"material/email-search.svg","material-email-sync-outline":"material/email-sync-outline.svg","material-email-sync":"material/email-sync.svg","material-email-variant":"material/email-variant.svg","material-email":"material/email.svg","material-ember":"material/ember.svg","material-emby":"material/emby.svg","material-emoticon-angry-outline":"material/emoticon-angry-outline.svg","material-emoticon-angry":"material/emoticon-angry.svg","material-emoticon-confused-outline":"material/emoticon-confused-outline.svg","material-emoticon-confused":"material/emoticon-confused.svg","material-emoticon-cool-outline":"material/emoticon-cool-outline.svg","material-emoticon-cool":"material/emoticon-cool.svg","material-emoticon-cry-outline":"material/emoticon-cry-outline.svg","material-emoticon-cry":"material/emoticon-cry.svg","material-emoticon-dead-outline":"material/emoticon-dead-outline.svg","material-emoticon-dead":"material/emoticon-dead.svg","material-emoticon-devil-outline":"material/emoticon-devil-outline.svg","material-emoticon-devil":"material/emoticon-devil.svg","material-emoticon-excited-outline":"material/emoticon-excited-outline.svg","material-emoticon-excited":"material/emoticon-excited.svg","material-emoticon-frown-outline":"material/emoticon-frown-outline.svg","material-emoticon-frown":"material/emoticon-frown.svg","material-emoticon-happy-outline":"material/emoticon-happy-outline.svg","material-emoticon-happy":"material/emoticon-happy.svg","material-emoticon-kiss-outline":"material/emoticon-kiss-outline.svg","material-emoticon-kiss":"material/emoticon-kiss.svg","material-emoticon-lol-outline":"material/emoticon-lol-outline.svg","material-emoticon-lol":"material/emoticon-lol.svg","material-emoticon-neutral-outline":"material/emoticon-neutral-outline.svg","material-emoticon-neutral":"material/emoticon-neutral.svg","material-emoticon-outline":"material/emoticon-outline.svg","material-emoticon-poop-outline":"material/emoticon-poop-outline.svg","material-emoticon-poop":"material/emoticon-poop.svg","material-emoticon-sad-outline":"material/emoticon-sad-outline.svg","material-emoticon-sad":"material/emoticon-sad.svg","material-emoticon-sick-outline":"material/emoticon-sick-outline.svg","material-emoticon-sick":"material/emoticon-sick.svg","material-emoticon-tongue-outline":"material/emoticon-tongue-outline.svg","material-emoticon-tongue":"material/emoticon-tongue.svg","material-emoticon-wink-outline":"material/emoticon-wink-outline.svg","material-emoticon-wink":"material/emoticon-wink.svg","material-emoticon":"material/emoticon.svg","material-engine-off-outline":"material/engine-off-outline.svg","material-engine-off":"material/engine-off.svg","material-engine-outline":"material/engine-outline.svg","material-engine":"material/engine.svg","material-epsilon":"material/epsilon.svg","material-equal-box":"material/equal-box.svg","material-equal":"material/equal.svg","material-equalizer-outline":"material/equalizer-outline.svg","material-equalizer":"material/equalizer.svg","material-eraser-variant":"material/eraser-variant.svg","material-eraser":"material/eraser.svg","material-escalator-box":"material/escalator-box.svg","material-escalator-down":"material/escalator-down.svg","material-escalator-up":"material/escalator-up.svg","material-escalator":"material/escalator.svg","material-eslint":"material/eslint.svg","material-et":"material/et.svg","material-ethereum":"material/ethereum.svg","material-ethernet-cable-off":"material/ethernet-cable-off.svg","material-ethernet-cable":"material/ethernet-cable.svg","material-ethernet":"material/ethernet.svg","material-ev-plug-ccs1":"material/ev-plug-ccs1.svg","material-ev-plug-ccs2":"material/ev-plug-ccs2.svg","material-ev-plug-chademo":"material/ev-plug-chademo.svg","material-ev-plug-tesla":"material/ev-plug-tesla.svg","material-ev-plug-type1":"material/ev-plug-type1.svg","material-ev-plug-type2":"material/ev-plug-type2.svg","material-ev-station":"material/ev-station.svg","material-evernote":"material/evernote.svg","material-excavator":"material/excavator.svg","material-exclamation-thick":"material/exclamation-thick.svg","material-exclamation":"material/exclamation.svg","material-exit-run":"material/exit-run.svg","material-exit-to-app":"material/exit-to-app.svg","material-expand-all-outline":"material/expand-all-outline.svg","material-expand-all":"material/expand-all.svg","material-expansion-card-variant":"material/expansion-card-variant.svg","material-expansion-card":"material/expansion-card.svg","material-exponent-box":"material/exponent-box.svg","material-exponent":"material/exponent.svg","material-export-variant":"material/export-variant.svg","material-export":"material/export.svg","material-eye-arrow-left-outline":"material/eye-arrow-left-outline.svg","material-eye-arrow-left":"material/eye-arrow-left.svg","material-eye-arrow-right-outline":"material/eye-arrow-right-outline.svg","material-eye-arrow-right":"material/eye-arrow-right.svg","material-eye-check-outline":"material/eye-check-outline.svg","material-eye-check":"material/eye-check.svg","material-eye-circle-outline":"material/eye-circle-outline.svg","material-eye-circle":"material/eye-circle.svg","material-eye-minus-outline":"material/eye-minus-outline.svg","material-eye-minus":"material/eye-minus.svg","material-eye-off-outline":"material/eye-off-outline.svg","material-eye-off":"material/eye-off.svg","material-eye-outline":"material/eye-outline.svg","material-eye-plus-outline":"material/eye-plus-outline.svg","material-eye-plus":"material/eye-plus.svg","material-eye-refresh-outline":"material/eye-refresh-outline.svg","material-eye-refresh":"material/eye-refresh.svg","material-eye-remove-outline":"material/eye-remove-outline.svg","material-eye-remove":"material/eye-remove.svg","material-eye-settings-outline":"material/eye-settings-outline.svg","material-eye-settings":"material/eye-settings.svg","material-eye":"material/eye.svg","material-eyedropper-minus":"material/eyedropper-minus.svg","material-eyedropper-off":"material/eyedropper-off.svg","material-eyedropper-plus":"material/eyedropper-plus.svg","material-eyedropper-remove":"material/eyedropper-remove.svg","material-eyedropper-variant":"material/eyedropper-variant.svg","material-eyedropper":"material/eyedropper.svg","material-face-agent":"material/face-agent.svg","material-face-man-outline":"material/face-man-outline.svg","material-face-man-profile":"material/face-man-profile.svg","material-face-man-shimmer-outline":"material/face-man-shimmer-outline.svg","material-face-man-shimmer":"material/face-man-shimmer.svg","material-face-man":"material/face-man.svg","material-face-mask-outline":"material/face-mask-outline.svg","material-face-mask":"material/face-mask.svg","material-face-recognition":"material/face-recognition.svg","material-face-woman-outline":"material/face-woman-outline.svg","material-face-woman-profile":"material/face-woman-profile.svg","material-face-woman-shimmer-outline":"material/face-woman-shimmer-outline.svg","material-face-woman-shimmer":"material/face-woman-shimmer.svg","material-face-woman":"material/face-woman.svg","material-facebook-gaming":"material/facebook-gaming.svg","material-facebook-messenger":"material/facebook-messenger.svg","material-facebook-workplace":"material/facebook-workplace.svg","material-facebook":"material/facebook.svg","material-factory":"material/factory.svg","material-family-tree":"material/family-tree.svg","material-fan-alert":"material/fan-alert.svg","material-fan-auto":"material/fan-auto.svg","material-fan-chevron-down":"material/fan-chevron-down.svg","material-fan-chevron-up":"material/fan-chevron-up.svg","material-fan-clock":"material/fan-clock.svg","material-fan-minus":"material/fan-minus.svg","material-fan-off":"material/fan-off.svg","material-fan-plus":"material/fan-plus.svg","material-fan-remove":"material/fan-remove.svg","material-fan-speed-1":"material/fan-speed-1.svg","material-fan-speed-2":"material/fan-speed-2.svg","material-fan-speed-3":"material/fan-speed-3.svg","material-fan":"material/fan.svg","material-fast-forward-10":"material/fast-forward-10.svg","material-fast-forward-15":"material/fast-forward-15.svg","material-fast-forward-30":"material/fast-forward-30.svg","material-fast-forward-45":"material/fast-forward-45.svg","material-fast-forward-5":"material/fast-forward-5.svg","material-fast-forward-60":"material/fast-forward-60.svg","material-fast-forward-outline":"material/fast-forward-outline.svg","material-fast-forward":"material/fast-forward.svg","material-faucet-variant":"material/faucet-variant.svg","material-faucet":"material/faucet.svg","material-fax":"material/fax.svg","material-feather":"material/feather.svg","material-feature-search-outline":"material/feature-search-outline.svg","material-feature-search":"material/feature-search.svg","material-fedora":"material/fedora.svg","material-fence-electric":"material/fence-electric.svg","material-fence":"material/fence.svg","material-fencing":"material/fencing.svg","material-ferris-wheel":"material/ferris-wheel.svg","material-ferry":"material/ferry.svg","material-file-account-outline":"material/file-account-outline.svg","material-file-account":"material/file-account.svg","material-file-alert-outline":"material/file-alert-outline.svg","material-file-alert":"material/file-alert.svg","material-file-arrow-left-right-outline":"material/file-arrow-left-right-outline.svg","material-file-arrow-left-right":"material/file-arrow-left-right.svg","material-file-arrow-up-down-outline":"material/file-arrow-up-down-outline.svg","material-file-arrow-up-down":"material/file-arrow-up-down.svg","material-file-cabinet":"material/file-cabinet.svg","material-file-cad-box":"material/file-cad-box.svg","material-file-cad":"material/file-cad.svg","material-file-cancel-outline":"material/file-cancel-outline.svg","material-file-cancel":"material/file-cancel.svg","material-file-certificate-outline":"material/file-certificate-outline.svg","material-file-certificate":"material/file-certificate.svg","material-file-chart-check-outline":"material/file-chart-check-outline.svg","material-file-chart-check":"material/file-chart-check.svg","material-file-chart-outline":"material/file-chart-outline.svg","material-file-chart":"material/file-chart.svg","material-file-check-outline":"material/file-check-outline.svg","material-file-check":"material/file-check.svg","material-file-clock-outline":"material/file-clock-outline.svg","material-file-clock":"material/file-clock.svg","material-file-cloud-outline":"material/file-cloud-outline.svg","material-file-cloud":"material/file-cloud.svg","material-file-code-outline":"material/file-code-outline.svg","material-file-code":"material/file-code.svg","material-file-cog-outline":"material/file-cog-outline.svg","material-file-cog":"material/file-cog.svg","material-file-compare":"material/file-compare.svg","material-file-delimited-outline":"material/file-delimited-outline.svg","material-file-delimited":"material/file-delimited.svg","material-file-document-alert-outline":"material/file-document-alert-outline.svg","material-file-document-alert":"material/file-document-alert.svg","material-file-document-check-outline":"material/file-document-check-outline.svg","material-file-document-check":"material/file-document-check.svg","material-file-document-edit-outline":"material/file-document-edit-outline.svg","material-file-document-edit":"material/file-document-edit.svg","material-file-document-minus-outline":"material/file-document-minus-outline.svg","material-file-document-minus":"material/file-document-minus.svg","material-file-document-multiple-outline":"material/file-document-multiple-outline.svg","material-file-document-multiple":"material/file-document-multiple.svg","material-file-document-outline":"material/file-document-outline.svg","material-file-document-plus-outline":"material/file-document-plus-outline.svg","material-file-document-plus":"material/file-document-plus.svg","material-file-document-remove-outline":"material/file-document-remove-outline.svg","material-file-document-remove":"material/file-document-remove.svg","material-file-document":"material/file-document.svg","material-file-download-outline":"material/file-download-outline.svg","material-file-download":"material/file-download.svg","material-file-edit-outline":"material/file-edit-outline.svg","material-file-edit":"material/file-edit.svg","material-file-excel-box-outline":"material/file-excel-box-outline.svg","material-file-excel-box":"material/file-excel-box.svg","material-file-excel-outline":"material/file-excel-outline.svg","material-file-excel":"material/file-excel.svg","material-file-export-outline":"material/file-export-outline.svg","material-file-export":"material/file-export.svg","material-file-eye-outline":"material/file-eye-outline.svg","material-file-eye":"material/file-eye.svg","material-file-find-outline":"material/file-find-outline.svg","material-file-find":"material/file-find.svg","material-file-gif-box":"material/file-gif-box.svg","material-file-hidden":"material/file-hidden.svg","material-file-image-marker-outline":"material/file-image-marker-outline.svg","material-file-image-marker":"material/file-image-marker.svg","material-file-image-minus-outline":"material/file-image-minus-outline.svg","material-file-image-minus":"material/file-image-minus.svg","material-file-image-outline":"material/file-image-outline.svg","material-file-image-plus-outline":"material/file-image-plus-outline.svg","material-file-image-plus":"material/file-image-plus.svg","material-file-image-remove-outline":"material/file-image-remove-outline.svg","material-file-image-remove":"material/file-image-remove.svg","material-file-image":"material/file-image.svg","material-file-import-outline":"material/file-import-outline.svg","material-file-import":"material/file-import.svg","material-file-jpg-box":"material/file-jpg-box.svg","material-file-key-outline":"material/file-key-outline.svg","material-file-key":"material/file-key.svg","material-file-link-outline":"material/file-link-outline.svg","material-file-link":"material/file-link.svg","material-file-lock-open-outline":"material/file-lock-open-outline.svg","material-file-lock-open":"material/file-lock-open.svg","material-file-lock-outline":"material/file-lock-outline.svg","material-file-lock":"material/file-lock.svg","material-file-marker-outline":"material/file-marker-outline.svg","material-file-marker":"material/file-marker.svg","material-file-minus-outline":"material/file-minus-outline.svg","material-file-minus":"material/file-minus.svg","material-file-move-outline":"material/file-move-outline.svg","material-file-move":"material/file-move.svg","material-file-multiple-outline":"material/file-multiple-outline.svg","material-file-multiple":"material/file-multiple.svg","material-file-music-outline":"material/file-music-outline.svg","material-file-music":"material/file-music.svg","material-file-outline":"material/file-outline.svg","material-file-pdf-box":"material/file-pdf-box.svg","material-file-percent-outline":"material/file-percent-outline.svg","material-file-percent":"material/file-percent.svg","material-file-phone-outline":"material/file-phone-outline.svg","material-file-phone":"material/file-phone.svg","material-file-plus-outline":"material/file-plus-outline.svg","material-file-plus":"material/file-plus.svg","material-file-png-box":"material/file-png-box.svg","material-file-powerpoint-box-outline":"material/file-powerpoint-box-outline.svg","material-file-powerpoint-box":"material/file-powerpoint-box.svg","material-file-powerpoint-outline":"material/file-powerpoint-outline.svg","material-file-powerpoint":"material/file-powerpoint.svg","material-file-presentation-box":"material/file-presentation-box.svg","material-file-question-outline":"material/file-question-outline.svg","material-file-question":"material/file-question.svg","material-file-refresh-outline":"material/file-refresh-outline.svg","material-file-refresh":"material/file-refresh.svg","material-file-remove-outline":"material/file-remove-outline.svg","material-file-remove":"material/file-remove.svg","material-file-replace-outline":"material/file-replace-outline.svg","material-file-replace":"material/file-replace.svg","material-file-restore-outline":"material/file-restore-outline.svg","material-file-restore":"material/file-restore.svg","material-file-rotate-left-outline":"material/file-rotate-left-outline.svg","material-file-rotate-left":"material/file-rotate-left.svg","material-file-rotate-right-outline":"material/file-rotate-right-outline.svg","material-file-rotate-right":"material/file-rotate-right.svg","material-file-search-outline":"material/file-search-outline.svg","material-file-search":"material/file-search.svg","material-file-send-outline":"material/file-send-outline.svg","material-file-send":"material/file-send.svg","material-file-settings-outline":"material/file-settings-outline.svg","material-file-settings":"material/file-settings.svg","material-file-sign":"material/file-sign.svg","material-file-star-outline":"material/file-star-outline.svg","material-file-star":"material/file-star.svg","material-file-swap-outline":"material/file-swap-outline.svg","material-file-swap":"material/file-swap.svg","material-file-sync-outline":"material/file-sync-outline.svg","material-file-sync":"material/file-sync.svg","material-file-table-box-multiple-outline":"material/file-table-box-multiple-outline.svg","material-file-table-box-multiple":"material/file-table-box-multiple.svg","material-file-table-box-outline":"material/file-table-box-outline.svg","material-file-table-box":"material/file-table-box.svg","material-file-table-outline":"material/file-table-outline.svg","material-file-table":"material/file-table.svg","material-file-tree-outline":"material/file-tree-outline.svg","material-file-tree":"material/file-tree.svg","material-file-undo-outline":"material/file-undo-outline.svg","material-file-undo":"material/file-undo.svg","material-file-upload-outline":"material/file-upload-outline.svg","material-file-upload":"material/file-upload.svg","material-file-video-outline":"material/file-video-outline.svg","material-file-video":"material/file-video.svg","material-file-word-box-outline":"material/file-word-box-outline.svg","material-file-word-box":"material/file-word-box.svg","material-file-word-outline":"material/file-word-outline.svg","material-file-word":"material/file-word.svg","material-file-xml-box":"material/file-xml-box.svg","material-file":"material/file.svg","material-film":"material/film.svg","material-filmstrip-box-multiple":"material/filmstrip-box-multiple.svg","material-filmstrip-box":"material/filmstrip-box.svg","material-filmstrip-off":"material/filmstrip-off.svg","material-filmstrip":"material/filmstrip.svg","material-filter-check-outline":"material/filter-check-outline.svg","material-filter-check":"material/filter-check.svg","material-filter-cog-outline":"material/filter-cog-outline.svg","material-filter-cog":"material/filter-cog.svg","material-filter-menu-outline":"material/filter-menu-outline.svg","material-filter-menu":"material/filter-menu.svg","material-filter-minus-outline":"material/filter-minus-outline.svg","material-filter-minus":"material/filter-minus.svg","material-filter-multiple-outline":"material/filter-multiple-outline.svg","material-filter-multiple":"material/filter-multiple.svg","material-filter-off-outline":"material/filter-off-outline.svg","material-filter-off":"material/filter-off.svg","material-filter-outline":"material/filter-outline.svg","material-filter-plus-outline":"material/filter-plus-outline.svg","material-filter-plus":"material/filter-plus.svg","material-filter-remove-outline":"material/filter-remove-outline.svg","material-filter-remove":"material/filter-remove.svg","material-filter-settings-outline":"material/filter-settings-outline.svg","material-filter-settings":"material/filter-settings.svg","material-filter-variant-minus":"material/filter-variant-minus.svg","material-filter-variant-plus":"material/filter-variant-plus.svg","material-filter-variant-remove":"material/filter-variant-remove.svg","material-filter-variant":"material/filter-variant.svg","material-filter":"material/filter.svg","material-finance":"material/finance.svg","material-find-replace":"material/find-replace.svg","material-fingerprint-off":"material/fingerprint-off.svg","material-fingerprint":"material/fingerprint.svg","material-fire-alert":"material/fire-alert.svg","material-fire-circle":"material/fire-circle.svg","material-fire-extinguisher":"material/fire-extinguisher.svg","material-fire-hydrant-alert":"material/fire-hydrant-alert.svg","material-fire-hydrant-off":"material/fire-hydrant-off.svg","material-fire-hydrant":"material/fire-hydrant.svg","material-fire-off":"material/fire-off.svg","material-fire-truck":"material/fire-truck.svg","material-fire":"material/fire.svg","material-firebase":"material/firebase.svg","material-firefox":"material/firefox.svg","material-fireplace-off":"material/fireplace-off.svg","material-fireplace":"material/fireplace.svg","material-firewire":"material/firewire.svg","material-firework-off":"material/firework-off.svg","material-firework":"material/firework.svg","material-fish-off":"material/fish-off.svg","material-fish":"material/fish.svg","material-fishbowl-outline":"material/fishbowl-outline.svg","material-fishbowl":"material/fishbowl.svg","material-fit-to-page-outline":"material/fit-to-page-outline.svg","material-fit-to-page":"material/fit-to-page.svg","material-fit-to-screen-outline":"material/fit-to-screen-outline.svg","material-fit-to-screen":"material/fit-to-screen.svg","material-flag-checkered":"material/flag-checkered.svg","material-flag-minus-outline":"material/flag-minus-outline.svg","material-flag-minus":"material/flag-minus.svg","material-flag-off-outline":"material/flag-off-outline.svg","material-flag-off":"material/flag-off.svg","material-flag-outline":"material/flag-outline.svg","material-flag-plus-outline":"material/flag-plus-outline.svg","material-flag-plus":"material/flag-plus.svg","material-flag-remove-outline":"material/flag-remove-outline.svg","material-flag-remove":"material/flag-remove.svg","material-flag-triangle":"material/flag-triangle.svg","material-flag-variant-minus-outline":"material/flag-variant-minus-outline.svg","material-flag-variant-minus":"material/flag-variant-minus.svg","material-flag-variant-off-outline":"material/flag-variant-off-outline.svg","material-flag-variant-off":"material/flag-variant-off.svg","material-flag-variant-outline":"material/flag-variant-outline.svg","material-flag-variant-plus-outline":"material/flag-variant-plus-outline.svg","material-flag-variant-plus":"material/flag-variant-plus.svg","material-flag-variant-remove-outline":"material/flag-variant-remove-outline.svg","material-flag-variant-remove":"material/flag-variant-remove.svg","material-flag-variant":"material/flag-variant.svg","material-flag":"material/flag.svg","material-flare":"material/flare.svg","material-flash-alert-outline":"material/flash-alert-outline.svg","material-flash-alert":"material/flash-alert.svg","material-flash-auto":"material/flash-auto.svg","material-flash-off-outline":"material/flash-off-outline.svg","material-flash-off":"material/flash-off.svg","material-flash-outline":"material/flash-outline.svg","material-flash-red-eye":"material/flash-red-eye.svg","material-flash-triangle-outline":"material/flash-triangle-outline.svg","material-flash-triangle":"material/flash-triangle.svg","material-flash":"material/flash.svg","material-flashlight-off":"material/flashlight-off.svg","material-flashlight":"material/flashlight.svg","material-flask-empty-minus-outline":"material/flask-empty-minus-outline.svg","material-flask-empty-minus":"material/flask-empty-minus.svg","material-flask-empty-off-outline":"material/flask-empty-off-outline.svg","material-flask-empty-off":"material/flask-empty-off.svg","material-flask-empty-outline":"material/flask-empty-outline.svg","material-flask-empty-plus-outline":"material/flask-empty-plus-outline.svg","material-flask-empty-plus":"material/flask-empty-plus.svg","material-flask-empty-remove-outline":"material/flask-empty-remove-outline.svg","material-flask-empty-remove":"material/flask-empty-remove.svg","material-flask-empty":"material/flask-empty.svg","material-flask-minus-outline":"material/flask-minus-outline.svg","material-flask-minus":"material/flask-minus.svg","material-flask-off-outline":"material/flask-off-outline.svg","material-flask-off":"material/flask-off.svg","material-flask-outline":"material/flask-outline.svg","material-flask-plus-outline":"material/flask-plus-outline.svg","material-flask-plus":"material/flask-plus.svg","material-flask-remove-outline":"material/flask-remove-outline.svg","material-flask-remove":"material/flask-remove.svg","material-flask-round-bottom-empty-outline":"material/flask-round-bottom-empty-outline.svg","material-flask-round-bottom-empty":"material/flask-round-bottom-empty.svg","material-flask-round-bottom-outline":"material/flask-round-bottom-outline.svg","material-flask-round-bottom":"material/flask-round-bottom.svg","material-flask":"material/flask.svg","material-fleur-de-lis":"material/fleur-de-lis.svg","material-flip-horizontal":"material/flip-horizontal.svg","material-flip-to-back":"material/flip-to-back.svg","material-flip-to-front":"material/flip-to-front.svg","material-flip-vertical":"material/flip-vertical.svg","material-floor-lamp-dual-outline":"material/floor-lamp-dual-outline.svg","material-floor-lamp-dual":"material/floor-lamp-dual.svg","material-floor-lamp-outline":"material/floor-lamp-outline.svg","material-floor-lamp-torchiere-outline":"material/floor-lamp-torchiere-outline.svg","material-floor-lamp-torchiere-variant-outline":"material/floor-lamp-torchiere-variant-outline.svg","material-floor-lamp-torchiere-variant":"material/floor-lamp-torchiere-variant.svg","material-floor-lamp-torchiere":"material/floor-lamp-torchiere.svg","material-floor-lamp":"material/floor-lamp.svg","material-floor-plan":"material/floor-plan.svg","material-floppy-variant":"material/floppy-variant.svg","material-floppy":"material/floppy.svg","material-flower-outline":"material/flower-outline.svg","material-flower-pollen-outline":"material/flower-pollen-outline.svg","material-flower-pollen":"material/flower-pollen.svg","material-flower-poppy":"material/flower-poppy.svg","material-flower-tulip-outline":"material/flower-tulip-outline.svg","material-flower-tulip":"material/flower-tulip.svg","material-flower":"material/flower.svg","material-focus-auto":"material/focus-auto.svg","material-focus-field-horizontal":"material/focus-field-horizontal.svg","material-focus-field-vertical":"material/focus-field-vertical.svg","material-focus-field":"material/focus-field.svg","material-folder-account-outline":"material/folder-account-outline.svg","material-folder-account":"material/folder-account.svg","material-folder-alert-outline":"material/folder-alert-outline.svg","material-folder-alert":"material/folder-alert.svg","material-folder-arrow-down-outline":"material/folder-arrow-down-outline.svg","material-folder-arrow-down":"material/folder-arrow-down.svg","material-folder-arrow-left-outline":"material/folder-arrow-left-outline.svg","material-folder-arrow-left-right-outline":"material/folder-arrow-left-right-outline.svg","material-folder-arrow-left-right":"material/folder-arrow-left-right.svg","material-folder-arrow-left":"material/folder-arrow-left.svg","material-folder-arrow-right-outline":"material/folder-arrow-right-outline.svg","material-folder-arrow-right":"material/folder-arrow-right.svg","material-folder-arrow-up-down-outline":"material/folder-arrow-up-down-outline.svg","material-folder-arrow-up-down":"material/folder-arrow-up-down.svg","material-folder-arrow-up-outline":"material/folder-arrow-up-outline.svg","material-folder-arrow-up":"material/folder-arrow-up.svg","material-folder-cancel-outline":"material/folder-cancel-outline.svg","material-folder-cancel":"material/folder-cancel.svg","material-folder-check-outline":"material/folder-check-outline.svg","material-folder-check":"material/folder-check.svg","material-folder-clock-outline":"material/folder-clock-outline.svg","material-folder-clock":"material/folder-clock.svg","material-folder-cog-outline":"material/folder-cog-outline.svg","material-folder-cog":"material/folder-cog.svg","material-folder-download-outline":"material/folder-download-outline.svg","material-folder-download":"material/folder-download.svg","material-folder-edit-outline":"material/folder-edit-outline.svg","material-folder-edit":"material/folder-edit.svg","material-folder-eye-outline":"material/folder-eye-outline.svg","material-folder-eye":"material/folder-eye.svg","material-folder-file-outline":"material/folder-file-outline.svg","material-folder-file":"material/folder-file.svg","material-folder-google-drive":"material/folder-google-drive.svg","material-folder-heart-outline":"material/folder-heart-outline.svg","material-folder-heart":"material/folder-heart.svg","material-folder-hidden":"material/folder-hidden.svg","material-folder-home-outline":"material/folder-home-outline.svg","material-folder-home":"material/folder-home.svg","material-folder-image":"material/folder-image.svg","material-folder-information-outline":"material/folder-information-outline.svg","material-folder-information":"material/folder-information.svg","material-folder-key-network-outline":"material/folder-key-network-outline.svg","material-folder-key-network":"material/folder-key-network.svg","material-folder-key-outline":"material/folder-key-outline.svg","material-folder-key":"material/folder-key.svg","material-folder-lock-open-outline":"material/folder-lock-open-outline.svg","material-folder-lock-open":"material/folder-lock-open.svg","material-folder-lock-outline":"material/folder-lock-outline.svg","material-folder-lock":"material/folder-lock.svg","material-folder-marker-outline":"material/folder-marker-outline.svg","material-folder-marker":"material/folder-marker.svg","material-folder-minus-outline":"material/folder-minus-outline.svg","material-folder-minus":"material/folder-minus.svg","material-folder-move-outline":"material/folder-move-outline.svg","material-folder-move":"material/folder-move.svg","material-folder-multiple-image":"material/folder-multiple-image.svg","material-folder-multiple-outline":"material/folder-multiple-outline.svg","material-folder-multiple-plus-outline":"material/folder-multiple-plus-outline.svg","material-folder-multiple-plus":"material/folder-multiple-plus.svg","material-folder-multiple":"material/folder-multiple.svg","material-folder-music-outline":"material/folder-music-outline.svg","material-folder-music":"material/folder-music.svg","material-folder-network-outline":"material/folder-network-outline.svg","material-folder-network":"material/folder-network.svg","material-folder-off-outline":"material/folder-off-outline.svg","material-folder-off":"material/folder-off.svg","material-folder-open-outline":"material/folder-open-outline.svg","material-folder-open":"material/folder-open.svg","material-folder-outline":"material/folder-outline.svg","material-folder-play-outline":"material/folder-play-outline.svg","material-folder-play":"material/folder-play.svg","material-folder-plus-outline":"material/folder-plus-outline.svg","material-folder-plus":"material/folder-plus.svg","material-folder-pound-outline":"material/folder-pound-outline.svg","material-folder-pound":"material/folder-pound.svg","material-folder-question-outline":"material/folder-question-outline.svg","material-folder-question":"material/folder-question.svg","material-folder-refresh-outline":"material/folder-refresh-outline.svg","material-folder-refresh":"material/folder-refresh.svg","material-folder-remove-outline":"material/folder-remove-outline.svg","material-folder-remove":"material/folder-remove.svg","material-folder-search-outline":"material/folder-search-outline.svg","material-folder-search":"material/folder-search.svg","material-folder-settings-outline":"material/folder-settings-outline.svg","material-folder-settings":"material/folder-settings.svg","material-folder-star-multiple-outline":"material/folder-star-multiple-outline.svg","material-folder-star-multiple":"material/folder-star-multiple.svg","material-folder-star-outline":"material/folder-star-outline.svg","material-folder-star":"material/folder-star.svg","material-folder-swap-outline":"material/folder-swap-outline.svg","material-folder-swap":"material/folder-swap.svg","material-folder-sync-outline":"material/folder-sync-outline.svg","material-folder-sync":"material/folder-sync.svg","material-folder-table-outline":"material/folder-table-outline.svg","material-folder-table":"material/folder-table.svg","material-folder-text-outline":"material/folder-text-outline.svg","material-folder-text":"material/folder-text.svg","material-folder-upload-outline":"material/folder-upload-outline.svg","material-folder-upload":"material/folder-upload.svg","material-folder-wrench-outline":"material/folder-wrench-outline.svg","material-folder-wrench":"material/folder-wrench.svg","material-folder-zip-outline":"material/folder-zip-outline.svg","material-folder-zip":"material/folder-zip.svg","material-folder":"material/folder.svg","material-font-awesome":"material/font-awesome.svg","material-food-apple-outline":"material/food-apple-outline.svg","material-food-apple":"material/food-apple.svg","material-food-croissant":"material/food-croissant.svg","material-food-drumstick-off-outline":"material/food-drumstick-off-outline.svg","material-food-drumstick-off":"material/food-drumstick-off.svg","material-food-drumstick-outline":"material/food-drumstick-outline.svg","material-food-drumstick":"material/food-drumstick.svg","material-food-fork-drink":"material/food-fork-drink.svg","material-food-halal":"material/food-halal.svg","material-food-hot-dog":"material/food-hot-dog.svg","material-food-kosher":"material/food-kosher.svg","material-food-off-outline":"material/food-off-outline.svg","material-food-off":"material/food-off.svg","material-food-outline":"material/food-outline.svg","material-food-steak-off":"material/food-steak-off.svg","material-food-steak":"material/food-steak.svg","material-food-takeout-box-outline":"material/food-takeout-box-outline.svg","material-food-takeout-box":"material/food-takeout-box.svg","material-food-turkey":"material/food-turkey.svg","material-food-variant-off":"material/food-variant-off.svg","material-food-variant":"material/food-variant.svg","material-food":"material/food.svg","material-foot-print":"material/foot-print.svg","material-football-australian":"material/football-australian.svg","material-football-helmet":"material/football-helmet.svg","material-football":"material/football.svg","material-forest":"material/forest.svg","material-forklift":"material/forklift.svg","material-form-dropdown":"material/form-dropdown.svg","material-form-select":"material/form-select.svg","material-form-textarea":"material/form-textarea.svg","material-form-textbox-lock":"material/form-textbox-lock.svg","material-form-textbox-password":"material/form-textbox-password.svg","material-form-textbox":"material/form-textbox.svg","material-format-align-bottom":"material/format-align-bottom.svg","material-format-align-center":"material/format-align-center.svg","material-format-align-justify":"material/format-align-justify.svg","material-format-align-left":"material/format-align-left.svg","material-format-align-middle":"material/format-align-middle.svg","material-format-align-right":"material/format-align-right.svg","material-format-align-top":"material/format-align-top.svg","material-format-annotation-minus":"material/format-annotation-minus.svg","material-format-annotation-plus":"material/format-annotation-plus.svg","material-format-bold":"material/format-bold.svg","material-format-clear":"material/format-clear.svg","material-format-color-fill":"material/format-color-fill.svg","material-format-color-highlight":"material/format-color-highlight.svg","material-format-color-marker-cancel":"material/format-color-marker-cancel.svg","material-format-color-text":"material/format-color-text.svg","material-format-columns":"material/format-columns.svg","material-format-float-center":"material/format-float-center.svg","material-format-float-left":"material/format-float-left.svg","material-format-float-none":"material/format-float-none.svg","material-format-float-right":"material/format-float-right.svg","material-format-font-size-decrease":"material/format-font-size-decrease.svg","material-format-font-size-increase":"material/format-font-size-increase.svg","material-format-font":"material/format-font.svg","material-format-header-1":"material/format-header-1.svg","material-format-header-2":"material/format-header-2.svg","material-format-header-3":"material/format-header-3.svg","material-format-header-4":"material/format-header-4.svg","material-format-header-5":"material/format-header-5.svg","material-format-header-6":"material/format-header-6.svg","material-format-header-decrease":"material/format-header-decrease.svg","material-format-header-equal":"material/format-header-equal.svg","material-format-header-increase":"material/format-header-increase.svg","material-format-header-pound":"material/format-header-pound.svg","material-format-horizontal-align-center":"material/format-horizontal-align-center.svg","material-format-horizontal-align-left":"material/format-horizontal-align-left.svg","material-format-horizontal-align-right":"material/format-horizontal-align-right.svg","material-format-indent-decrease":"material/format-indent-decrease.svg","material-format-indent-increase":"material/format-indent-increase.svg","material-format-italic":"material/format-italic.svg","material-format-letter-case-lower":"material/format-letter-case-lower.svg","material-format-letter-case-upper":"material/format-letter-case-upper.svg","material-format-letter-case":"material/format-letter-case.svg","material-format-letter-ends-with":"material/format-letter-ends-with.svg","material-format-letter-matches":"material/format-letter-matches.svg","material-format-letter-spacing-variant":"material/format-letter-spacing-variant.svg","material-format-letter-spacing":"material/format-letter-spacing.svg","material-format-letter-starts-with":"material/format-letter-starts-with.svg","material-format-line-height":"material/format-line-height.svg","material-format-line-spacing":"material/format-line-spacing.svg","material-format-line-style":"material/format-line-style.svg","material-format-line-weight":"material/format-line-weight.svg","material-format-list-bulleted-square":"material/format-list-bulleted-square.svg","material-format-list-bulleted-triangle":"material/format-list-bulleted-triangle.svg","material-format-list-bulleted-type":"material/format-list-bulleted-type.svg","material-format-list-bulleted":"material/format-list-bulleted.svg","material-format-list-checkbox":"material/format-list-checkbox.svg","material-format-list-checks":"material/format-list-checks.svg","material-format-list-group-plus":"material/format-list-group-plus.svg","material-format-list-group":"material/format-list-group.svg","material-format-list-numbered-rtl":"material/format-list-numbered-rtl.svg","material-format-list-numbered":"material/format-list-numbered.svg","material-format-list-text":"material/format-list-text.svg","material-format-overline":"material/format-overline.svg","material-format-page-break":"material/format-page-break.svg","material-format-page-split":"material/format-page-split.svg","material-format-paint":"material/format-paint.svg","material-format-paragraph-spacing":"material/format-paragraph-spacing.svg","material-format-paragraph":"material/format-paragraph.svg","material-format-pilcrow-arrow-left":"material/format-pilcrow-arrow-left.svg","material-format-pilcrow-arrow-right":"material/format-pilcrow-arrow-right.svg","material-format-pilcrow":"material/format-pilcrow.svg","material-format-quote-close-outline":"material/format-quote-close-outline.svg","material-format-quote-close":"material/format-quote-close.svg","material-format-quote-open-outline":"material/format-quote-open-outline.svg","material-format-quote-open":"material/format-quote-open.svg","material-format-rotate-90":"material/format-rotate-90.svg","material-format-section":"material/format-section.svg","material-format-size":"material/format-size.svg","material-format-strikethrough-variant":"material/format-strikethrough-variant.svg","material-format-strikethrough":"material/format-strikethrough.svg","material-format-subscript":"material/format-subscript.svg","material-format-superscript":"material/format-superscript.svg","material-format-text-rotation-angle-down":"material/format-text-rotation-angle-down.svg","material-format-text-rotation-angle-up":"material/format-text-rotation-angle-up.svg","material-format-text-rotation-down-vertical":"material/format-text-rotation-down-vertical.svg","material-format-text-rotation-down":"material/format-text-rotation-down.svg","material-format-text-rotation-none":"material/format-text-rotation-none.svg","material-format-text-rotation-up":"material/format-text-rotation-up.svg","material-format-text-rotation-vertical":"material/format-text-rotation-vertical.svg","material-format-text-variant-outline":"material/format-text-variant-outline.svg","material-format-text-variant":"material/format-text-variant.svg","material-format-text-wrapping-clip":"material/format-text-wrapping-clip.svg","material-format-text-wrapping-overflow":"material/format-text-wrapping-overflow.svg","material-format-text-wrapping-wrap":"material/format-text-wrapping-wrap.svg","material-format-text":"material/format-text.svg","material-format-textbox":"material/format-textbox.svg","material-format-title":"material/format-title.svg","material-format-underline-wavy":"material/format-underline-wavy.svg","material-format-underline":"material/format-underline.svg","material-format-vertical-align-bottom":"material/format-vertical-align-bottom.svg","material-format-vertical-align-center":"material/format-vertical-align-center.svg","material-format-vertical-align-top":"material/format-vertical-align-top.svg","material-format-wrap-inline":"material/format-wrap-inline.svg","material-format-wrap-square":"material/format-wrap-square.svg","material-format-wrap-tight":"material/format-wrap-tight.svg","material-format-wrap-top-bottom":"material/format-wrap-top-bottom.svg","material-forum-minus-outline":"material/forum-minus-outline.svg","material-forum-minus":"material/forum-minus.svg","material-forum-outline":"material/forum-outline.svg","material-forum-plus-outline":"material/forum-plus-outline.svg","material-forum-plus":"material/forum-plus.svg","material-forum-remove-outline":"material/forum-remove-outline.svg","material-forum-remove":"material/forum-remove.svg","material-forum":"material/forum.svg","material-forward":"material/forward.svg","material-forwardburger":"material/forwardburger.svg","material-fountain-pen-tip":"material/fountain-pen-tip.svg","material-fountain-pen":"material/fountain-pen.svg","material-fountain":"material/fountain.svg","material-fraction-one-half":"material/fraction-one-half.svg","material-freebsd":"material/freebsd.svg","material-french-fries":"material/french-fries.svg","material-frequently-asked-questions":"material/frequently-asked-questions.svg","material-fridge-alert-outline":"material/fridge-alert-outline.svg","material-fridge-alert":"material/fridge-alert.svg","material-fridge-bottom":"material/fridge-bottom.svg","material-fridge-industrial-alert-outline":"material/fridge-industrial-alert-outline.svg","material-fridge-industrial-alert":"material/fridge-industrial-alert.svg","material-fridge-industrial-off-outline":"material/fridge-industrial-off-outline.svg","material-fridge-industrial-off":"material/fridge-industrial-off.svg","material-fridge-industrial-outline":"material/fridge-industrial-outline.svg","material-fridge-industrial":"material/fridge-industrial.svg","material-fridge-off-outline":"material/fridge-off-outline.svg","material-fridge-off":"material/fridge-off.svg","material-fridge-outline":"material/fridge-outline.svg","material-fridge-top":"material/fridge-top.svg","material-fridge-variant-alert-outline":"material/fridge-variant-alert-outline.svg","material-fridge-variant-alert":"material/fridge-variant-alert.svg","material-fridge-variant-off-outline":"material/fridge-variant-off-outline.svg","material-fridge-variant-off":"material/fridge-variant-off.svg","material-fridge-variant-outline":"material/fridge-variant-outline.svg","material-fridge-variant":"material/fridge-variant.svg","material-fridge":"material/fridge.svg","material-fruit-cherries-off":"material/fruit-cherries-off.svg","material-fruit-cherries":"material/fruit-cherries.svg","material-fruit-citrus-off":"material/fruit-citrus-off.svg","material-fruit-citrus":"material/fruit-citrus.svg","material-fruit-grapes-outline":"material/fruit-grapes-outline.svg","material-fruit-grapes":"material/fruit-grapes.svg","material-fruit-pear":"material/fruit-pear.svg","material-fruit-pineapple":"material/fruit-pineapple.svg","material-fruit-watermelon":"material/fruit-watermelon.svg","material-fuel-cell":"material/fuel-cell.svg","material-fuel":"material/fuel.svg","material-fullscreen-exit":"material/fullscreen-exit.svg","material-fullscreen":"material/fullscreen.svg","material-function-variant":"material/function-variant.svg","material-function":"material/function.svg","material-furigana-horizontal":"material/furigana-horizontal.svg","material-furigana-vertical":"material/furigana-vertical.svg","material-fuse-alert":"material/fuse-alert.svg","material-fuse-blade":"material/fuse-blade.svg","material-fuse-off":"material/fuse-off.svg","material-fuse":"material/fuse.svg","material-gamepad-circle-down":"material/gamepad-circle-down.svg","material-gamepad-circle-left":"material/gamepad-circle-left.svg","material-gamepad-circle-outline":"material/gamepad-circle-outline.svg","material-gamepad-circle-right":"material/gamepad-circle-right.svg","material-gamepad-circle-up":"material/gamepad-circle-up.svg","material-gamepad-circle":"material/gamepad-circle.svg","material-gamepad-down":"material/gamepad-down.svg","material-gamepad-left":"material/gamepad-left.svg","material-gamepad-outline":"material/gamepad-outline.svg","material-gamepad-right":"material/gamepad-right.svg","material-gamepad-round-down":"material/gamepad-round-down.svg","material-gamepad-round-left":"material/gamepad-round-left.svg","material-gamepad-round-outline":"material/gamepad-round-outline.svg","material-gamepad-round-right":"material/gamepad-round-right.svg","material-gamepad-round-up":"material/gamepad-round-up.svg","material-gamepad-round":"material/gamepad-round.svg","material-gamepad-square-outline":"material/gamepad-square-outline.svg","material-gamepad-square":"material/gamepad-square.svg","material-gamepad-up":"material/gamepad-up.svg","material-gamepad-variant-outline":"material/gamepad-variant-outline.svg","material-gamepad-variant":"material/gamepad-variant.svg","material-gamepad":"material/gamepad.svg","material-gamma":"material/gamma.svg","material-gantry-crane":"material/gantry-crane.svg","material-garage-alert-variant":"material/garage-alert-variant.svg","material-garage-alert":"material/garage-alert.svg","material-garage-lock":"material/garage-lock.svg","material-garage-open-variant":"material/garage-open-variant.svg","material-garage-open":"material/garage-open.svg","material-garage-variant-lock":"material/garage-variant-lock.svg","material-garage-variant":"material/garage-variant.svg","material-garage":"material/garage.svg","material-gas-burner":"material/gas-burner.svg","material-gas-cylinder":"material/gas-cylinder.svg","material-gas-station-off-outline":"material/gas-station-off-outline.svg","material-gas-station-off":"material/gas-station-off.svg","material-gas-station-outline":"material/gas-station-outline.svg","material-gas-station":"material/gas-station.svg","material-gate-alert":"material/gate-alert.svg","material-gate-and":"material/gate-and.svg","material-gate-arrow-left":"material/gate-arrow-left.svg","material-gate-arrow-right":"material/gate-arrow-right.svg","material-gate-buffer":"material/gate-buffer.svg","material-gate-nand":"material/gate-nand.svg","material-gate-nor":"material/gate-nor.svg","material-gate-not":"material/gate-not.svg","material-gate-open":"material/gate-open.svg","material-gate-or":"material/gate-or.svg","material-gate-xnor":"material/gate-xnor.svg","material-gate-xor":"material/gate-xor.svg","material-gate":"material/gate.svg","material-gatsby":"material/gatsby.svg","material-gauge-empty":"material/gauge-empty.svg","material-gauge-full":"material/gauge-full.svg","material-gauge-low":"material/gauge-low.svg","material-gauge":"material/gauge.svg","material-gavel":"material/gavel.svg","material-gender-female":"material/gender-female.svg","material-gender-male-female-variant":"material/gender-male-female-variant.svg","material-gender-male-female":"material/gender-male-female.svg","material-gender-male":"material/gender-male.svg","material-gender-non-binary":"material/gender-non-binary.svg","material-gender-transgender":"material/gender-transgender.svg","material-gentoo":"material/gentoo.svg","material-gesture-double-tap":"material/gesture-double-tap.svg","material-gesture-pinch":"material/gesture-pinch.svg","material-gesture-spread":"material/gesture-spread.svg","material-gesture-swipe-down":"material/gesture-swipe-down.svg","material-gesture-swipe-horizontal":"material/gesture-swipe-horizontal.svg","material-gesture-swipe-left":"material/gesture-swipe-left.svg","material-gesture-swipe-right":"material/gesture-swipe-right.svg","material-gesture-swipe-up":"material/gesture-swipe-up.svg","material-gesture-swipe-vertical":"material/gesture-swipe-vertical.svg","material-gesture-swipe":"material/gesture-swipe.svg","material-gesture-tap-box":"material/gesture-tap-box.svg","material-gesture-tap-button":"material/gesture-tap-button.svg","material-gesture-tap-hold":"material/gesture-tap-hold.svg","material-gesture-tap":"material/gesture-tap.svg","material-gesture-two-double-tap":"material/gesture-two-double-tap.svg","material-gesture-two-tap":"material/gesture-two-tap.svg","material-gesture":"material/gesture.svg","material-ghost-off-outline":"material/ghost-off-outline.svg","material-ghost-off":"material/ghost-off.svg","material-ghost-outline":"material/ghost-outline.svg","material-ghost":"material/ghost.svg","material-gift-off-outline":"material/gift-off-outline.svg","material-gift-off":"material/gift-off.svg","material-gift-open-outline":"material/gift-open-outline.svg","material-gift-open":"material/gift-open.svg","material-gift-outline":"material/gift-outline.svg","material-gift":"material/gift.svg","material-git":"material/git.svg","material-github":"material/github.svg","material-gitlab":"material/gitlab.svg","material-glass-cocktail-off":"material/glass-cocktail-off.svg","material-glass-cocktail":"material/glass-cocktail.svg","material-glass-flute":"material/glass-flute.svg","material-glass-fragile":"material/glass-fragile.svg","material-glass-mug-off":"material/glass-mug-off.svg","material-glass-mug-variant-off":"material/glass-mug-variant-off.svg","material-glass-mug-variant":"material/glass-mug-variant.svg","material-glass-mug":"material/glass-mug.svg","material-glass-pint-outline":"material/glass-pint-outline.svg","material-glass-stange":"material/glass-stange.svg","material-glass-tulip":"material/glass-tulip.svg","material-glass-wine":"material/glass-wine.svg","material-glasses":"material/glasses.svg","material-globe-light-outline":"material/globe-light-outline.svg","material-globe-light":"material/globe-light.svg","material-globe-model":"material/globe-model.svg","material-gmail":"material/gmail.svg","material-gnome":"material/gnome.svg","material-go-kart-track":"material/go-kart-track.svg","material-go-kart":"material/go-kart.svg","material-gog":"material/gog.svg","material-gold":"material/gold.svg","material-golf-cart":"material/golf-cart.svg","material-golf-tee":"material/golf-tee.svg","material-golf":"material/golf.svg","material-gondola":"material/gondola.svg","material-goodreads":"material/goodreads.svg","material-google-ads":"material/google-ads.svg","material-google-analytics":"material/google-analytics.svg","material-google-assistant":"material/google-assistant.svg","material-google-cardboard":"material/google-cardboard.svg","material-google-chrome":"material/google-chrome.svg","material-google-circles-communities":"material/google-circles-communities.svg","material-google-circles-extended":"material/google-circles-extended.svg","material-google-circles-group":"material/google-circles-group.svg","material-google-circles":"material/google-circles.svg","material-google-classroom":"material/google-classroom.svg","material-google-cloud":"material/google-cloud.svg","material-google-downasaur":"material/google-downasaur.svg","material-google-drive":"material/google-drive.svg","material-google-earth":"material/google-earth.svg","material-google-fit":"material/google-fit.svg","material-google-glass":"material/google-glass.svg","material-google-hangouts":"material/google-hangouts.svg","material-google-keep":"material/google-keep.svg","material-google-lens":"material/google-lens.svg","material-google-maps":"material/google-maps.svg","material-google-my-business":"material/google-my-business.svg","material-google-nearby":"material/google-nearby.svg","material-google-play":"material/google-play.svg","material-google-plus":"material/google-plus.svg","material-google-podcast":"material/google-podcast.svg","material-google-spreadsheet":"material/google-spreadsheet.svg","material-google-street-view":"material/google-street-view.svg","material-google-translate":"material/google-translate.svg","material-google":"material/google.svg","material-gradient-horizontal":"material/gradient-horizontal.svg","material-gradient-vertical":"material/gradient-vertical.svg","material-grain":"material/grain.svg","material-graph-outline":"material/graph-outline.svg","material-graph":"material/graph.svg","material-graphql":"material/graphql.svg","material-grass":"material/grass.svg","material-grave-stone":"material/grave-stone.svg","material-grease-pencil":"material/grease-pencil.svg","material-greater-than-or-equal":"material/greater-than-or-equal.svg","material-greater-than":"material/greater-than.svg","material-greenhouse":"material/greenhouse.svg","material-grid-large":"material/grid-large.svg","material-grid-off":"material/grid-off.svg","material-grid":"material/grid.svg","material-grill-outline":"material/grill-outline.svg","material-grill":"material/grill.svg","material-group":"material/group.svg","material-guitar-acoustic":"material/guitar-acoustic.svg","material-guitar-electric":"material/guitar-electric.svg","material-guitar-pick-outline":"material/guitar-pick-outline.svg","material-guitar-pick":"material/guitar-pick.svg","material-guy-fawkes-mask":"material/guy-fawkes-mask.svg","material-gymnastics":"material/gymnastics.svg","material-hail":"material/hail.svg","material-hair-dryer-outline":"material/hair-dryer-outline.svg","material-hair-dryer":"material/hair-dryer.svg","material-halloween":"material/halloween.svg","material-hamburger-check":"material/hamburger-check.svg","material-hamburger-minus":"material/hamburger-minus.svg","material-hamburger-off":"material/hamburger-off.svg","material-hamburger-plus":"material/hamburger-plus.svg","material-hamburger-remove":"material/hamburger-remove.svg","material-hamburger":"material/hamburger.svg","material-hammer-screwdriver":"material/hammer-screwdriver.svg","material-hammer-sickle":"material/hammer-sickle.svg","material-hammer-wrench":"material/hammer-wrench.svg","material-hammer":"material/hammer.svg","material-hand-back-left-off-outline":"material/hand-back-left-off-outline.svg","material-hand-back-left-off":"material/hand-back-left-off.svg","material-hand-back-left-outline":"material/hand-back-left-outline.svg","material-hand-back-left":"material/hand-back-left.svg","material-hand-back-right-off-outline":"material/hand-back-right-off-outline.svg","material-hand-back-right-off":"material/hand-back-right-off.svg","material-hand-back-right-outline":"material/hand-back-right-outline.svg","material-hand-back-right":"material/hand-back-right.svg","material-hand-clap-off":"material/hand-clap-off.svg","material-hand-clap":"material/hand-clap.svg","material-hand-coin-outline":"material/hand-coin-outline.svg","material-hand-coin":"material/hand-coin.svg","material-hand-cycle":"material/hand-cycle.svg","material-hand-extended-outline":"material/hand-extended-outline.svg","material-hand-extended":"material/hand-extended.svg","material-hand-front-left-outline":"material/hand-front-left-outline.svg","material-hand-front-left":"material/hand-front-left.svg","material-hand-front-right-outline":"material/hand-front-right-outline.svg","material-hand-front-right":"material/hand-front-right.svg","material-hand-heart-outline":"material/hand-heart-outline.svg","material-hand-heart":"material/hand-heart.svg","material-hand-okay":"material/hand-okay.svg","material-hand-peace-variant":"material/hand-peace-variant.svg","material-hand-peace":"material/hand-peace.svg","material-hand-pointing-down":"material/hand-pointing-down.svg","material-hand-pointing-left":"material/hand-pointing-left.svg","material-hand-pointing-right":"material/hand-pointing-right.svg","material-hand-pointing-up":"material/hand-pointing-up.svg","material-hand-saw":"material/hand-saw.svg","material-hand-wash-outline":"material/hand-wash-outline.svg","material-hand-wash":"material/hand-wash.svg","material-hand-water":"material/hand-water.svg","material-hand-wave-outline":"material/hand-wave-outline.svg","material-hand-wave":"material/hand-wave.svg","material-handball":"material/handball.svg","material-handcuffs":"material/handcuffs.svg","material-hands-pray":"material/hands-pray.svg","material-handshake-outline":"material/handshake-outline.svg","material-handshake":"material/handshake.svg","material-hanger":"material/hanger.svg","material-hard-hat":"material/hard-hat.svg","material-harddisk-plus":"material/harddisk-plus.svg","material-harddisk-remove":"material/harddisk-remove.svg","material-harddisk":"material/harddisk.svg","material-hat-fedora":"material/hat-fedora.svg","material-hazard-lights":"material/hazard-lights.svg","material-hdmi-port":"material/hdmi-port.svg","material-hdr-off":"material/hdr-off.svg","material-hdr":"material/hdr.svg","material-head-alert-outline":"material/head-alert-outline.svg","material-head-alert":"material/head-alert.svg","material-head-check-outline":"material/head-check-outline.svg","material-head-check":"material/head-check.svg","material-head-cog-outline":"material/head-cog-outline.svg","material-head-cog":"material/head-cog.svg","material-head-dots-horizontal-outline":"material/head-dots-horizontal-outline.svg","material-head-dots-horizontal":"material/head-dots-horizontal.svg","material-head-flash-outline":"material/head-flash-outline.svg","material-head-flash":"material/head-flash.svg","material-head-heart-outline":"material/head-heart-outline.svg","material-head-heart":"material/head-heart.svg","material-head-lightbulb-outline":"material/head-lightbulb-outline.svg","material-head-lightbulb":"material/head-lightbulb.svg","material-head-minus-outline":"material/head-minus-outline.svg","material-head-minus":"material/head-minus.svg","material-head-outline":"material/head-outline.svg","material-head-plus-outline":"material/head-plus-outline.svg","material-head-plus":"material/head-plus.svg","material-head-question-outline":"material/head-question-outline.svg","material-head-question":"material/head-question.svg","material-head-remove-outline":"material/head-remove-outline.svg","material-head-remove":"material/head-remove.svg","material-head-snowflake-outline":"material/head-snowflake-outline.svg","material-head-snowflake":"material/head-snowflake.svg","material-head-sync-outline":"material/head-sync-outline.svg","material-head-sync":"material/head-sync.svg","material-head":"material/head.svg","material-headphones-bluetooth":"material/headphones-bluetooth.svg","material-headphones-box":"material/headphones-box.svg","material-headphones-off":"material/headphones-off.svg","material-headphones-settings":"material/headphones-settings.svg","material-headphones":"material/headphones.svg","material-headset-dock":"material/headset-dock.svg","material-headset-off":"material/headset-off.svg","material-headset":"material/headset.svg","material-heart-box-outline":"material/heart-box-outline.svg","material-heart-box":"material/heart-box.svg","material-heart-broken-outline":"material/heart-broken-outline.svg","material-heart-broken":"material/heart-broken.svg","material-heart-circle-outline":"material/heart-circle-outline.svg","material-heart-circle":"material/heart-circle.svg","material-heart-cog-outline":"material/heart-cog-outline.svg","material-heart-cog":"material/heart-cog.svg","material-heart-flash":"material/heart-flash.svg","material-heart-half-full":"material/heart-half-full.svg","material-heart-half-outline":"material/heart-half-outline.svg","material-heart-half":"material/heart-half.svg","material-heart-minus-outline":"material/heart-minus-outline.svg","material-heart-minus":"material/heart-minus.svg","material-heart-multiple-outline":"material/heart-multiple-outline.svg","material-heart-multiple":"material/heart-multiple.svg","material-heart-off-outline":"material/heart-off-outline.svg","material-heart-off":"material/heart-off.svg","material-heart-outline":"material/heart-outline.svg","material-heart-plus-outline":"material/heart-plus-outline.svg","material-heart-plus":"material/heart-plus.svg","material-heart-pulse":"material/heart-pulse.svg","material-heart-remove-outline":"material/heart-remove-outline.svg","material-heart-remove":"material/heart-remove.svg","material-heart-settings-outline":"material/heart-settings-outline.svg","material-heart-settings":"material/heart-settings.svg","material-heart":"material/heart.svg","material-heat-pump-outline":"material/heat-pump-outline.svg","material-heat-pump":"material/heat-pump.svg","material-heat-wave":"material/heat-wave.svg","material-heating-coil":"material/heating-coil.svg","material-helicopter":"material/helicopter.svg","material-help-box":"material/help-box.svg","material-help-circle-outline":"material/help-circle-outline.svg","material-help-circle":"material/help-circle.svg","material-help-network-outline":"material/help-network-outline.svg","material-help-network":"material/help-network.svg","material-help-rhombus-outline":"material/help-rhombus-outline.svg","material-help-rhombus":"material/help-rhombus.svg","material-help":"material/help.svg","material-hexadecimal":"material/hexadecimal.svg","material-hexagon-multiple-outline":"material/hexagon-multiple-outline.svg","material-hexagon-multiple":"material/hexagon-multiple.svg","material-hexagon-outline":"material/hexagon-outline.svg","material-hexagon-slice-1":"material/hexagon-slice-1.svg","material-hexagon-slice-2":"material/hexagon-slice-2.svg","material-hexagon-slice-3":"material/hexagon-slice-3.svg","material-hexagon-slice-4":"material/hexagon-slice-4.svg","material-hexagon-slice-5":"material/hexagon-slice-5.svg","material-hexagon-slice-6":"material/hexagon-slice-6.svg","material-hexagon":"material/hexagon.svg","material-hexagram-outline":"material/hexagram-outline.svg","material-hexagram":"material/hexagram.svg","material-high-definition-box":"material/high-definition-box.svg","material-high-definition":"material/high-definition.svg","material-highway":"material/highway.svg","material-hiking":"material/hiking.svg","material-history":"material/history.svg","material-hockey-puck":"material/hockey-puck.svg","material-hockey-sticks":"material/hockey-sticks.svg","material-hololens":"material/hololens.svg","material-home-account":"material/home-account.svg","material-home-alert-outline":"material/home-alert-outline.svg","material-home-alert":"material/home-alert.svg","material-home-analytics":"material/home-analytics.svg","material-home-assistant":"material/home-assistant.svg","material-home-automation":"material/home-automation.svg","material-home-battery-outline":"material/home-battery-outline.svg","material-home-battery":"material/home-battery.svg","material-home-circle-outline":"material/home-circle-outline.svg","material-home-circle":"material/home-circle.svg","material-home-city-outline":"material/home-city-outline.svg","material-home-city":"material/home-city.svg","material-home-clock-outline":"material/home-clock-outline.svg","material-home-clock":"material/home-clock.svg","material-home-edit-outline":"material/home-edit-outline.svg","material-home-edit":"material/home-edit.svg","material-home-export-outline":"material/home-export-outline.svg","material-home-flood":"material/home-flood.svg","material-home-floor-0":"material/home-floor-0.svg","material-home-floor-1":"material/home-floor-1.svg","material-home-floor-2":"material/home-floor-2.svg","material-home-floor-3":"material/home-floor-3.svg","material-home-floor-a":"material/home-floor-a.svg","material-home-floor-b":"material/home-floor-b.svg","material-home-floor-g":"material/home-floor-g.svg","material-home-floor-l":"material/home-floor-l.svg","material-home-floor-negative-1":"material/home-floor-negative-1.svg","material-home-group-minus":"material/home-group-minus.svg","material-home-group-plus":"material/home-group-plus.svg","material-home-group-remove":"material/home-group-remove.svg","material-home-group":"material/home-group.svg","material-home-heart":"material/home-heart.svg","material-home-import-outline":"material/home-import-outline.svg","material-home-lightbulb-outline":"material/home-lightbulb-outline.svg","material-home-lightbulb":"material/home-lightbulb.svg","material-home-lightning-bolt-outline":"material/home-lightning-bolt-outline.svg","material-home-lightning-bolt":"material/home-lightning-bolt.svg","material-home-lock-open":"material/home-lock-open.svg","material-home-lock":"material/home-lock.svg","material-home-map-marker":"material/home-map-marker.svg","material-home-minus-outline":"material/home-minus-outline.svg","material-home-minus":"material/home-minus.svg","material-home-modern":"material/home-modern.svg","material-home-off-outline":"material/home-off-outline.svg","material-home-off":"material/home-off.svg","material-home-outline":"material/home-outline.svg","material-home-plus-outline":"material/home-plus-outline.svg","material-home-plus":"material/home-plus.svg","material-home-remove-outline":"material/home-remove-outline.svg","material-home-remove":"material/home-remove.svg","material-home-roof":"material/home-roof.svg","material-home-search-outline":"material/home-search-outline.svg","material-home-search":"material/home-search.svg","material-home-silo-outline":"material/home-silo-outline.svg","material-home-silo":"material/home-silo.svg","material-home-switch-outline":"material/home-switch-outline.svg","material-home-switch":"material/home-switch.svg","material-home-thermometer-outline":"material/home-thermometer-outline.svg","material-home-thermometer":"material/home-thermometer.svg","material-home-variant-outline":"material/home-variant-outline.svg","material-home-variant":"material/home-variant.svg","material-home":"material/home.svg","material-hook-off":"material/hook-off.svg","material-hook":"material/hook.svg","material-hoop-house":"material/hoop-house.svg","material-hops":"material/hops.svg","material-horizontal-rotate-clockwise":"material/horizontal-rotate-clockwise.svg","material-horizontal-rotate-counterclockwise":"material/horizontal-rotate-counterclockwise.svg","material-horse-human":"material/horse-human.svg","material-horse-variant-fast":"material/horse-variant-fast.svg","material-horse-variant":"material/horse-variant.svg","material-horse":"material/horse.svg","material-horseshoe":"material/horseshoe.svg","material-hospital-box-outline":"material/hospital-box-outline.svg","material-hospital-box":"material/hospital-box.svg","material-hospital-building":"material/hospital-building.svg","material-hospital-marker":"material/hospital-marker.svg","material-hospital":"material/hospital.svg","material-hot-tub":"material/hot-tub.svg","material-hours-24":"material/hours-24.svg","material-hubspot":"material/hubspot.svg","material-hulu":"material/hulu.svg","material-human-baby-changing-table":"material/human-baby-changing-table.svg","material-human-cane":"material/human-cane.svg","material-human-capacity-decrease":"material/human-capacity-decrease.svg","material-human-capacity-increase":"material/human-capacity-increase.svg","material-human-child":"material/human-child.svg","material-human-dolly":"material/human-dolly.svg","material-human-edit":"material/human-edit.svg","material-human-female-boy":"material/human-female-boy.svg","material-human-female-dance":"material/human-female-dance.svg","material-human-female-female":"material/human-female-female.svg","material-human-female-girl":"material/human-female-girl.svg","material-human-female":"material/human-female.svg","material-human-greeting-proximity":"material/human-greeting-proximity.svg","material-human-greeting-variant":"material/human-greeting-variant.svg","material-human-greeting":"material/human-greeting.svg","material-human-handsdown":"material/human-handsdown.svg","material-human-handsup":"material/human-handsup.svg","material-human-male-board-poll":"material/human-male-board-poll.svg","material-human-male-board":"material/human-male-board.svg","material-human-male-boy":"material/human-male-boy.svg","material-human-male-child":"material/human-male-child.svg","material-human-male-female-child":"material/human-male-female-child.svg","material-human-male-female":"material/human-male-female.svg","material-human-male-girl":"material/human-male-girl.svg","material-human-male-height-variant":"material/human-male-height-variant.svg","material-human-male-height":"material/human-male-height.svg","material-human-male-male":"material/human-male-male.svg","material-human-male":"material/human-male.svg","material-human-non-binary":"material/human-non-binary.svg","material-human-pregnant":"material/human-pregnant.svg","material-human-queue":"material/human-queue.svg","material-human-scooter":"material/human-scooter.svg","material-human-walker":"material/human-walker.svg","material-human-wheelchair":"material/human-wheelchair.svg","material-human-white-cane":"material/human-white-cane.svg","material-human":"material/human.svg","material-humble-bundle":"material/humble-bundle.svg","material-hvac-off":"material/hvac-off.svg","material-hvac":"material/hvac.svg","material-hydraulic-oil-level":"material/hydraulic-oil-level.svg","material-hydraulic-oil-temperature":"material/hydraulic-oil-temperature.svg","material-hydro-power":"material/hydro-power.svg","material-hydrogen-station":"material/hydrogen-station.svg","material-ice-cream-off":"material/ice-cream-off.svg","material-ice-cream":"material/ice-cream.svg","material-ice-pop":"material/ice-pop.svg","material-id-card":"material/id-card.svg","material-identifier":"material/identifier.svg","material-ideogram-cjk-variant":"material/ideogram-cjk-variant.svg","material-ideogram-cjk":"material/ideogram-cjk.svg","material-image-album":"material/image-album.svg","material-image-area-close":"material/image-area-close.svg","material-image-area":"material/image-area.svg","material-image-auto-adjust":"material/image-auto-adjust.svg","material-image-broken-variant":"material/image-broken-variant.svg","material-image-broken":"material/image-broken.svg","material-image-check-outline":"material/image-check-outline.svg","material-image-check":"material/image-check.svg","material-image-edit-outline":"material/image-edit-outline.svg","material-image-edit":"material/image-edit.svg","material-image-filter-black-white":"material/image-filter-black-white.svg","material-image-filter-center-focus-strong-outline":"material/image-filter-center-focus-strong-outline.svg","material-image-filter-center-focus-strong":"material/image-filter-center-focus-strong.svg","material-image-filter-center-focus-weak":"material/image-filter-center-focus-weak.svg","material-image-filter-center-focus":"material/image-filter-center-focus.svg","material-image-filter-drama":"material/image-filter-drama.svg","material-image-filter-frames":"material/image-filter-frames.svg","material-image-filter-hdr":"material/image-filter-hdr.svg","material-image-filter-none":"material/image-filter-none.svg","material-image-filter-tilt-shift":"material/image-filter-tilt-shift.svg","material-image-filter-vintage":"material/image-filter-vintage.svg","material-image-frame":"material/image-frame.svg","material-image-lock-outline":"material/image-lock-outline.svg","material-image-lock":"material/image-lock.svg","material-image-marker-outline":"material/image-marker-outline.svg","material-image-marker":"material/image-marker.svg","material-image-minus-outline":"material/image-minus-outline.svg","material-image-minus":"material/image-minus.svg","material-image-move":"material/image-move.svg","material-image-multiple-outline":"material/image-multiple-outline.svg","material-image-multiple":"material/image-multiple.svg","material-image-off-outline":"material/image-off-outline.svg","material-image-off":"material/image-off.svg","material-image-outline":"material/image-outline.svg","material-image-plus-outline":"material/image-plus-outline.svg","material-image-plus":"material/image-plus.svg","material-image-refresh-outline":"material/image-refresh-outline.svg","material-image-refresh":"material/image-refresh.svg","material-image-remove-outline":"material/image-remove-outline.svg","material-image-remove":"material/image-remove.svg","material-image-search-outline":"material/image-search-outline.svg","material-image-search":"material/image-search.svg","material-image-size-select-actual":"material/image-size-select-actual.svg","material-image-size-select-large":"material/image-size-select-large.svg","material-image-size-select-small":"material/image-size-select-small.svg","material-image-sync-outline":"material/image-sync-outline.svg","material-image-sync":"material/image-sync.svg","material-image-text":"material/image-text.svg","material-image":"material/image.svg","material-import":"material/import.svg","material-inbox-arrow-down-outline":"material/inbox-arrow-down-outline.svg","material-inbox-arrow-down":"material/inbox-arrow-down.svg","material-inbox-arrow-up-outline":"material/inbox-arrow-up-outline.svg","material-inbox-arrow-up":"material/inbox-arrow-up.svg","material-inbox-full-outline":"material/inbox-full-outline.svg","material-inbox-full":"material/inbox-full.svg","material-inbox-multiple-outline":"material/inbox-multiple-outline.svg","material-inbox-multiple":"material/inbox-multiple.svg","material-inbox-outline":"material/inbox-outline.svg","material-inbox-remove-outline":"material/inbox-remove-outline.svg","material-inbox-remove":"material/inbox-remove.svg","material-inbox":"material/inbox.svg","material-incognito-circle-off":"material/incognito-circle-off.svg","material-incognito-circle":"material/incognito-circle.svg","material-incognito-off":"material/incognito-off.svg","material-incognito":"material/incognito.svg","material-induction":"material/induction.svg","material-infinity":"material/infinity.svg","material-information-off-outline":"material/information-off-outline.svg","material-information-off":"material/information-off.svg","material-information-outline":"material/information-outline.svg","material-information-variant":"material/information-variant.svg","material-information":"material/information.svg","material-instagram":"material/instagram.svg","material-instrument-triangle":"material/instrument-triangle.svg","material-integrated-circuit-chip":"material/integrated-circuit-chip.svg","material-invert-colors-off":"material/invert-colors-off.svg","material-invert-colors":"material/invert-colors.svg","material-iobroker":"material/iobroker.svg","material-ip-network-outline":"material/ip-network-outline.svg","material-ip-network":"material/ip-network.svg","material-ip-outline":"material/ip-outline.svg","material-ip":"material/ip.svg","material-ipod":"material/ipod.svg","material-iron-board":"material/iron-board.svg","material-iron-outline":"material/iron-outline.svg","material-iron":"material/iron.svg","material-island":"material/island.svg","material-iv-bag":"material/iv-bag.svg","material-jabber":"material/jabber.svg","material-jeepney":"material/jeepney.svg","material-jellyfish-outline":"material/jellyfish-outline.svg","material-jellyfish":"material/jellyfish.svg","material-jira":"material/jira.svg","material-jquery":"material/jquery.svg","material-jsfiddle":"material/jsfiddle.svg","material-jump-rope":"material/jump-rope.svg","material-kabaddi":"material/kabaddi.svg","material-kangaroo":"material/kangaroo.svg","material-karate":"material/karate.svg","material-kayaking":"material/kayaking.svg","material-keg":"material/keg.svg","material-kettle-alert-outline":"material/kettle-alert-outline.svg","material-kettle-alert":"material/kettle-alert.svg","material-kettle-off-outline":"material/kettle-off-outline.svg","material-kettle-off":"material/kettle-off.svg","material-kettle-outline":"material/kettle-outline.svg","material-kettle-pour-over":"material/kettle-pour-over.svg","material-kettle-steam-outline":"material/kettle-steam-outline.svg","material-kettle-steam":"material/kettle-steam.svg","material-kettle":"material/kettle.svg","material-kettlebell":"material/kettlebell.svg","material-key-alert-outline":"material/key-alert-outline.svg","material-key-alert":"material/key-alert.svg","material-key-arrow-right":"material/key-arrow-right.svg","material-key-chain-variant":"material/key-chain-variant.svg","material-key-chain":"material/key-chain.svg","material-key-change":"material/key-change.svg","material-key-link":"material/key-link.svg","material-key-minus":"material/key-minus.svg","material-key-outline":"material/key-outline.svg","material-key-plus":"material/key-plus.svg","material-key-remove":"material/key-remove.svg","material-key-star":"material/key-star.svg","material-key-variant":"material/key-variant.svg","material-key-wireless":"material/key-wireless.svg","material-key":"material/key.svg","material-keyboard-backspace":"material/keyboard-backspace.svg","material-keyboard-caps":"material/keyboard-caps.svg","material-keyboard-close":"material/keyboard-close.svg","material-keyboard-esc":"material/keyboard-esc.svg","material-keyboard-f1":"material/keyboard-f1.svg","material-keyboard-f10":"material/keyboard-f10.svg","material-keyboard-f11":"material/keyboard-f11.svg","material-keyboard-f12":"material/keyboard-f12.svg","material-keyboard-f2":"material/keyboard-f2.svg","material-keyboard-f3":"material/keyboard-f3.svg","material-keyboard-f4":"material/keyboard-f4.svg","material-keyboard-f5":"material/keyboard-f5.svg","material-keyboard-f6":"material/keyboard-f6.svg","material-keyboard-f7":"material/keyboard-f7.svg","material-keyboard-f8":"material/keyboard-f8.svg","material-keyboard-f9":"material/keyboard-f9.svg","material-keyboard-off-outline":"material/keyboard-off-outline.svg","material-keyboard-off":"material/keyboard-off.svg","material-keyboard-outline":"material/keyboard-outline.svg","material-keyboard-return":"material/keyboard-return.svg","material-keyboard-settings-outline":"material/keyboard-settings-outline.svg","material-keyboard-settings":"material/keyboard-settings.svg","material-keyboard-space":"material/keyboard-space.svg","material-keyboard-tab-reverse":"material/keyboard-tab-reverse.svg","material-keyboard-tab":"material/keyboard-tab.svg","material-keyboard-variant":"material/keyboard-variant.svg","material-keyboard":"material/keyboard.svg","material-khanda":"material/khanda.svg","material-kickstarter":"material/kickstarter.svg","material-kite-outline":"material/kite-outline.svg","material-kite":"material/kite.svg","material-kitesurfing":"material/kitesurfing.svg","material-klingon":"material/klingon.svg","material-knife-military":"material/knife-military.svg","material-knife":"material/knife.svg","material-knob":"material/knob.svg","material-koala":"material/koala.svg","material-kodi":"material/kodi.svg","material-kubernetes":"material/kubernetes.svg","material-label-multiple-outline":"material/label-multiple-outline.svg","material-label-multiple":"material/label-multiple.svg","material-label-off-outline":"material/label-off-outline.svg","material-label-off":"material/label-off.svg","material-label-outline":"material/label-outline.svg","material-label-percent-outline":"material/label-percent-outline.svg","material-label-percent":"material/label-percent.svg","material-label-variant-outline":"material/label-variant-outline.svg","material-label-variant":"material/label-variant.svg","material-label":"material/label.svg","material-ladder":"material/ladder.svg","material-ladybug":"material/ladybug.svg","material-lambda":"material/lambda.svg","material-lamp-outline":"material/lamp-outline.svg","material-lamp":"material/lamp.svg","material-lamps-outline":"material/lamps-outline.svg","material-lamps":"material/lamps.svg","material-lan-check":"material/lan-check.svg","material-lan-connect":"material/lan-connect.svg","material-lan-disconnect":"material/lan-disconnect.svg","material-lan-pending":"material/lan-pending.svg","material-lan":"material/lan.svg","material-land-fields":"material/land-fields.svg","material-land-plots-circle-variant":"material/land-plots-circle-variant.svg","material-land-plots-circle":"material/land-plots-circle.svg","material-land-plots":"material/land-plots.svg","material-land-rows-horizontal":"material/land-rows-horizontal.svg","material-land-rows-vertical":"material/land-rows-vertical.svg","material-landslide-outline":"material/landslide-outline.svg","material-landslide":"material/landslide.svg","material-language-c":"material/language-c.svg","material-language-cpp":"material/language-cpp.svg","material-language-csharp":"material/language-csharp.svg","material-language-css3":"material/language-css3.svg","material-language-fortran":"material/language-fortran.svg","material-language-go":"material/language-go.svg","material-language-haskell":"material/language-haskell.svg","material-language-html5":"material/language-html5.svg","material-language-java":"material/language-java.svg","material-language-javascript":"material/language-javascript.svg","material-language-kotlin":"material/language-kotlin.svg","material-language-lua":"material/language-lua.svg","material-language-markdown-outline":"material/language-markdown-outline.svg","material-language-markdown":"material/language-markdown.svg","material-language-php":"material/language-php.svg","material-language-python":"material/language-python.svg","material-language-r":"material/language-r.svg","material-language-ruby-on-rails":"material/language-ruby-on-rails.svg","material-language-ruby":"material/language-ruby.svg","material-language-rust":"material/language-rust.svg","material-language-swift":"material/language-swift.svg","material-language-typescript":"material/language-typescript.svg","material-language-xaml":"material/language-xaml.svg","material-laptop-account":"material/laptop-account.svg","material-laptop-off":"material/laptop-off.svg","material-laptop":"material/laptop.svg","material-laravel":"material/laravel.svg","material-laser-pointer":"material/laser-pointer.svg","material-lasso":"material/lasso.svg","material-lastpass":"material/lastpass.svg","material-latitude":"material/latitude.svg","material-launch":"material/launch.svg","material-lava-lamp":"material/lava-lamp.svg","material-layers-edit":"material/layers-edit.svg","material-layers-minus":"material/layers-minus.svg","material-layers-off-outline":"material/layers-off-outline.svg","material-layers-off":"material/layers-off.svg","material-layers-outline":"material/layers-outline.svg","material-layers-plus":"material/layers-plus.svg","material-layers-remove":"material/layers-remove.svg","material-layers-search-outline":"material/layers-search-outline.svg","material-layers-search":"material/layers-search.svg","material-layers-triple-outline":"material/layers-triple-outline.svg","material-layers-triple":"material/layers-triple.svg","material-layers":"material/layers.svg","material-lead-pencil":"material/lead-pencil.svg","material-leaf-circle-outline":"material/leaf-circle-outline.svg","material-leaf-circle":"material/leaf-circle.svg","material-leaf-maple-off":"material/leaf-maple-off.svg","material-leaf-maple":"material/leaf-maple.svg","material-leaf-off":"material/leaf-off.svg","material-leaf":"material/leaf.svg","material-leak-off":"material/leak-off.svg","material-leak":"material/leak.svg","material-lectern":"material/lectern.svg","material-led-off":"material/led-off.svg","material-led-on":"material/led-on.svg","material-led-outline":"material/led-outline.svg","material-led-strip-variant-off":"material/led-strip-variant-off.svg","material-led-strip-variant":"material/led-strip-variant.svg","material-led-strip":"material/led-strip.svg","material-led-variant-off":"material/led-variant-off.svg","material-led-variant-on":"material/led-variant-on.svg","material-led-variant-outline":"material/led-variant-outline.svg","material-leek":"material/leek.svg","material-less-than-or-equal":"material/less-than-or-equal.svg","material-less-than":"material/less-than.svg","material-library-outline":"material/library-outline.svg","material-library-shelves":"material/library-shelves.svg","material-library":"material/library.svg","material-license":"material/license.svg","material-lifebuoy":"material/lifebuoy.svg","material-light-flood-down":"material/light-flood-down.svg","material-light-flood-up":"material/light-flood-up.svg","material-light-recessed":"material/light-recessed.svg","material-light-switch-off":"material/light-switch-off.svg","material-light-switch":"material/light-switch.svg","material-lightbulb-alert-outline":"material/lightbulb-alert-outline.svg","material-lightbulb-alert":"material/lightbulb-alert.svg","material-lightbulb-auto-outline":"material/lightbulb-auto-outline.svg","material-lightbulb-auto":"material/lightbulb-auto.svg","material-lightbulb-cfl-off":"material/lightbulb-cfl-off.svg","material-lightbulb-cfl-spiral-off":"material/lightbulb-cfl-spiral-off.svg","material-lightbulb-cfl-spiral":"material/lightbulb-cfl-spiral.svg","material-lightbulb-cfl":"material/lightbulb-cfl.svg","material-lightbulb-fluorescent-tube-outline":"material/lightbulb-fluorescent-tube-outline.svg","material-lightbulb-fluorescent-tube":"material/lightbulb-fluorescent-tube.svg","material-lightbulb-group-off-outline":"material/lightbulb-group-off-outline.svg","material-lightbulb-group-off":"material/lightbulb-group-off.svg","material-lightbulb-group-outline":"material/lightbulb-group-outline.svg","material-lightbulb-group":"material/lightbulb-group.svg","material-lightbulb-multiple-off-outline":"material/lightbulb-multiple-off-outline.svg","material-lightbulb-multiple-off":"material/lightbulb-multiple-off.svg","material-lightbulb-multiple-outline":"material/lightbulb-multiple-outline.svg","material-lightbulb-multiple":"material/lightbulb-multiple.svg","material-lightbulb-night-outline":"material/lightbulb-night-outline.svg","material-lightbulb-night":"material/lightbulb-night.svg","material-lightbulb-off-outline":"material/lightbulb-off-outline.svg","material-lightbulb-off":"material/lightbulb-off.svg","material-lightbulb-on-10":"material/lightbulb-on-10.svg","material-lightbulb-on-20":"material/lightbulb-on-20.svg","material-lightbulb-on-30":"material/lightbulb-on-30.svg","material-lightbulb-on-40":"material/lightbulb-on-40.svg","material-lightbulb-on-50":"material/lightbulb-on-50.svg","material-lightbulb-on-60":"material/lightbulb-on-60.svg","material-lightbulb-on-70":"material/lightbulb-on-70.svg","material-lightbulb-on-80":"material/lightbulb-on-80.svg","material-lightbulb-on-90":"material/lightbulb-on-90.svg","material-lightbulb-on-outline":"material/lightbulb-on-outline.svg","material-lightbulb-on":"material/lightbulb-on.svg","material-lightbulb-outline":"material/lightbulb-outline.svg","material-lightbulb-question-outline":"material/lightbulb-question-outline.svg","material-lightbulb-question":"material/lightbulb-question.svg","material-lightbulb-spot-off":"material/lightbulb-spot-off.svg","material-lightbulb-spot":"material/lightbulb-spot.svg","material-lightbulb-variant-outline":"material/lightbulb-variant-outline.svg","material-lightbulb-variant":"material/lightbulb-variant.svg","material-lightbulb":"material/lightbulb.svg","material-lighthouse-on":"material/lighthouse-on.svg","material-lighthouse":"material/lighthouse.svg","material-lightning-bolt-circle":"material/lightning-bolt-circle.svg","material-lightning-bolt-outline":"material/lightning-bolt-outline.svg","material-lightning-bolt":"material/lightning-bolt.svg","material-line-scan":"material/line-scan.svg","material-lingerie":"material/lingerie.svg","material-link-box-outline":"material/link-box-outline.svg","material-link-box-variant-outline":"material/link-box-variant-outline.svg","material-link-box-variant":"material/link-box-variant.svg","material-link-box":"material/link-box.svg","material-link-lock":"material/link-lock.svg","material-link-off":"material/link-off.svg","material-link-plus":"material/link-plus.svg","material-link-variant-minus":"material/link-variant-minus.svg","material-link-variant-off":"material/link-variant-off.svg","material-link-variant-plus":"material/link-variant-plus.svg","material-link-variant-remove":"material/link-variant-remove.svg","material-link-variant":"material/link-variant.svg","material-link":"material/link.svg","material-linkedin":"material/linkedin.svg","material-linux-mint":"material/linux-mint.svg","material-linux":"material/linux.svg","material-lipstick":"material/lipstick.svg","material-liquid-spot":"material/liquid-spot.svg","material-liquor":"material/liquor.svg","material-list-box-outline":"material/list-box-outline.svg","material-list-box":"material/list-box.svg","material-list-status":"material/list-status.svg","material-litecoin":"material/litecoin.svg","material-loading":"material/loading.svg","material-location-enter":"material/location-enter.svg","material-location-exit":"material/location-exit.svg","material-lock-alert-outline":"material/lock-alert-outline.svg","material-lock-alert":"material/lock-alert.svg","material-lock-check-outline":"material/lock-check-outline.svg","material-lock-check":"material/lock-check.svg","material-lock-clock":"material/lock-clock.svg","material-lock-minus-outline":"material/lock-minus-outline.svg","material-lock-minus":"material/lock-minus.svg","material-lock-off-outline":"material/lock-off-outline.svg","material-lock-off":"material/lock-off.svg","material-lock-open-alert-outline":"material/lock-open-alert-outline.svg","material-lock-open-alert":"material/lock-open-alert.svg","material-lock-open-check-outline":"material/lock-open-check-outline.svg","material-lock-open-check":"material/lock-open-check.svg","material-lock-open-minus-outline":"material/lock-open-minus-outline.svg","material-lock-open-minus":"material/lock-open-minus.svg","material-lock-open-outline":"material/lock-open-outline.svg","material-lock-open-plus-outline":"material/lock-open-plus-outline.svg","material-lock-open-plus":"material/lock-open-plus.svg","material-lock-open-remove-outline":"material/lock-open-remove-outline.svg","material-lock-open-remove":"material/lock-open-remove.svg","material-lock-open-variant-outline":"material/lock-open-variant-outline.svg","material-lock-open-variant":"material/lock-open-variant.svg","material-lock-open":"material/lock-open.svg","material-lock-outline":"material/lock-outline.svg","material-lock-pattern":"material/lock-pattern.svg","material-lock-plus-outline":"material/lock-plus-outline.svg","material-lock-plus":"material/lock-plus.svg","material-lock-question":"material/lock-question.svg","material-lock-remove-outline":"material/lock-remove-outline.svg","material-lock-remove":"material/lock-remove.svg","material-lock-reset":"material/lock-reset.svg","material-lock-smart":"material/lock-smart.svg","material-lock":"material/lock.svg","material-locker-multiple":"material/locker-multiple.svg","material-locker":"material/locker.svg","material-login-variant":"material/login-variant.svg","material-login":"material/login.svg","material-logout-variant":"material/logout-variant.svg","material-logout":"material/logout.svg","material-longitude":"material/longitude.svg","material-looks":"material/looks.svg","material-lotion-outline":"material/lotion-outline.svg","material-lotion-plus-outline":"material/lotion-plus-outline.svg","material-lotion-plus":"material/lotion-plus.svg","material-lotion":"material/lotion.svg","material-loupe":"material/loupe.svg","material-lumx":"material/lumx.svg","material-lungs":"material/lungs.svg","material-mace":"material/mace.svg","material-magazine-pistol":"material/magazine-pistol.svg","material-magazine-rifle":"material/magazine-rifle.svg","material-magic-staff":"material/magic-staff.svg","material-magnet-on":"material/magnet-on.svg","material-magnet":"material/magnet.svg","material-magnify-close":"material/magnify-close.svg","material-magnify-expand":"material/magnify-expand.svg","material-magnify-minus-cursor":"material/magnify-minus-cursor.svg","material-magnify-minus-outline":"material/magnify-minus-outline.svg","material-magnify-minus":"material/magnify-minus.svg","material-magnify-plus-cursor":"material/magnify-plus-cursor.svg","material-magnify-plus-outline":"material/magnify-plus-outline.svg","material-magnify-plus":"material/magnify-plus.svg","material-magnify-remove-cursor":"material/magnify-remove-cursor.svg","material-magnify-remove-outline":"material/magnify-remove-outline.svg","material-magnify-scan":"material/magnify-scan.svg","material-magnify":"material/magnify.svg","material-mail":"material/mail.svg","material-mailbox-open-outline":"material/mailbox-open-outline.svg","material-mailbox-open-up-outline":"material/mailbox-open-up-outline.svg","material-mailbox-open-up":"material/mailbox-open-up.svg","material-mailbox-open":"material/mailbox-open.svg","material-mailbox-outline":"material/mailbox-outline.svg","material-mailbox-up-outline":"material/mailbox-up-outline.svg","material-mailbox-up":"material/mailbox-up.svg","material-mailbox":"material/mailbox.svg","material-manjaro":"material/manjaro.svg","material-map-check-outline":"material/map-check-outline.svg","material-map-check":"material/map-check.svg","material-map-clock-outline":"material/map-clock-outline.svg","material-map-clock":"material/map-clock.svg","material-map-legend":"material/map-legend.svg","material-map-marker-account-outline":"material/map-marker-account-outline.svg","material-map-marker-account":"material/map-marker-account.svg","material-map-marker-alert-outline":"material/map-marker-alert-outline.svg","material-map-marker-alert":"material/map-marker-alert.svg","material-map-marker-check-outline":"material/map-marker-check-outline.svg","material-map-marker-check":"material/map-marker-check.svg","material-map-marker-circle":"material/map-marker-circle.svg","material-map-marker-distance":"material/map-marker-distance.svg","material-map-marker-down":"material/map-marker-down.svg","material-map-marker-left-outline":"material/map-marker-left-outline.svg","material-map-marker-left":"material/map-marker-left.svg","material-map-marker-minus-outline":"material/map-marker-minus-outline.svg","material-map-marker-minus":"material/map-marker-minus.svg","material-map-marker-multiple-outline":"material/map-marker-multiple-outline.svg","material-map-marker-multiple":"material/map-marker-multiple.svg","material-map-marker-off-outline":"material/map-marker-off-outline.svg","material-map-marker-off":"material/map-marker-off.svg","material-map-marker-outline":"material/map-marker-outline.svg","material-map-marker-path":"material/map-marker-path.svg","material-map-marker-plus-outline":"material/map-marker-plus-outline.svg","material-map-marker-plus":"material/map-marker-plus.svg","material-map-marker-question-outline":"material/map-marker-question-outline.svg","material-map-marker-question":"material/map-marker-question.svg","material-map-marker-radius-outline":"material/map-marker-radius-outline.svg","material-map-marker-radius":"material/map-marker-radius.svg","material-map-marker-remove-outline":"material/map-marker-remove-outline.svg","material-map-marker-remove-variant":"material/map-marker-remove-variant.svg","material-map-marker-remove":"material/map-marker-remove.svg","material-map-marker-right-outline":"material/map-marker-right-outline.svg","material-map-marker-right":"material/map-marker-right.svg","material-map-marker-star-outline":"material/map-marker-star-outline.svg","material-map-marker-star":"material/map-marker-star.svg","material-map-marker-up":"material/map-marker-up.svg","material-map-marker":"material/map-marker.svg","material-map-minus":"material/map-minus.svg","material-map-outline":"material/map-outline.svg","material-map-plus":"material/map-plus.svg","material-map-search-outline":"material/map-search-outline.svg","material-map-search":"material/map-search.svg","material-map":"material/map.svg","material-mapbox":"material/mapbox.svg","material-margin":"material/margin.svg","material-marker-cancel":"material/marker-cancel.svg","material-marker-check":"material/marker-check.svg","material-marker":"material/marker.svg","material-mastodon":"material/mastodon.svg","material-material-design":"material/material-design.svg","material-material-ui":"material/material-ui.svg","material-math-compass":"material/math-compass.svg","material-math-cos":"material/math-cos.svg","material-math-integral-box":"material/math-integral-box.svg","material-math-integral":"material/math-integral.svg","material-math-log":"material/math-log.svg","material-math-norm-box":"material/math-norm-box.svg","material-math-norm":"material/math-norm.svg","material-math-sin":"material/math-sin.svg","material-math-tan":"material/math-tan.svg","material-matrix":"material/matrix.svg","material-medal-outline":"material/medal-outline.svg","material-medal":"material/medal.svg","material-medical-bag":"material/medical-bag.svg","material-medical-cotton-swab":"material/medical-cotton-swab.svg","material-medication-outline":"material/medication-outline.svg","material-medication":"material/medication.svg","material-meditation":"material/meditation.svg","material-memory":"material/memory.svg","material-menorah-fire":"material/menorah-fire.svg","material-menorah":"material/menorah.svg","material-menu-down-outline":"material/menu-down-outline.svg","material-menu-down":"material/menu-down.svg","material-menu-left-outline":"material/menu-left-outline.svg","material-menu-left":"material/menu-left.svg","material-menu-open":"material/menu-open.svg","material-menu-right-outline":"material/menu-right-outline.svg","material-menu-right":"material/menu-right.svg","material-menu-swap-outline":"material/menu-swap-outline.svg","material-menu-swap":"material/menu-swap.svg","material-menu-up-outline":"material/menu-up-outline.svg","material-menu-up":"material/menu-up.svg","material-menu":"material/menu.svg","material-merge":"material/merge.svg","material-message-alert-outline":"material/message-alert-outline.svg","material-message-alert":"material/message-alert.svg","material-message-arrow-left-outline":"material/message-arrow-left-outline.svg","material-message-arrow-left":"material/message-arrow-left.svg","material-message-arrow-right-outline":"material/message-arrow-right-outline.svg","material-message-arrow-right":"material/message-arrow-right.svg","material-message-badge-outline":"material/message-badge-outline.svg","material-message-badge":"material/message-badge.svg","material-message-bookmark-outline":"material/message-bookmark-outline.svg","material-message-bookmark":"material/message-bookmark.svg","material-message-bulleted-off":"material/message-bulleted-off.svg","material-message-bulleted":"material/message-bulleted.svg","material-message-check-outline":"material/message-check-outline.svg","material-message-check":"material/message-check.svg","material-message-cog-outline":"material/message-cog-outline.svg","material-message-cog":"material/message-cog.svg","material-message-draw":"material/message-draw.svg","material-message-fast-outline":"material/message-fast-outline.svg","material-message-fast":"material/message-fast.svg","material-message-flash-outline":"material/message-flash-outline.svg","material-message-flash":"material/message-flash.svg","material-message-image-outline":"material/message-image-outline.svg","material-message-image":"material/message-image.svg","material-message-lock-outline":"material/message-lock-outline.svg","material-message-lock":"material/message-lock.svg","material-message-minus-outline":"material/message-minus-outline.svg","material-message-minus":"material/message-minus.svg","material-message-off-outline":"material/message-off-outline.svg","material-message-off":"material/message-off.svg","material-message-outline":"material/message-outline.svg","material-message-plus-outline":"material/message-plus-outline.svg","material-message-plus":"material/message-plus.svg","material-message-processing-outline":"material/message-processing-outline.svg","material-message-processing":"material/message-processing.svg","material-message-question-outline":"material/message-question-outline.svg","material-message-question":"material/message-question.svg","material-message-reply-outline":"material/message-reply-outline.svg","material-message-reply-text-outline":"material/message-reply-text-outline.svg","material-message-reply-text":"material/message-reply-text.svg","material-message-reply":"material/message-reply.svg","material-message-settings-outline":"material/message-settings-outline.svg","material-message-settings":"material/message-settings.svg","material-message-star-outline":"material/message-star-outline.svg","material-message-star":"material/message-star.svg","material-message-text-clock-outline":"material/message-text-clock-outline.svg","material-message-text-clock":"material/message-text-clock.svg","material-message-text-fast-outline":"material/message-text-fast-outline.svg","material-message-text-fast":"material/message-text-fast.svg","material-message-text-lock-outline":"material/message-text-lock-outline.svg","material-message-text-lock":"material/message-text-lock.svg","material-message-text-outline":"material/message-text-outline.svg","material-message-text":"material/message-text.svg","material-message-video":"material/message-video.svg","material-message":"material/message.svg","material-meteor":"material/meteor.svg","material-meter-electric-outline":"material/meter-electric-outline.svg","material-meter-electric":"material/meter-electric.svg","material-meter-gas-outline":"material/meter-gas-outline.svg","material-meter-gas":"material/meter-gas.svg","material-metronome-tick":"material/metronome-tick.svg","material-metronome":"material/metronome.svg","material-micro-sd":"material/micro-sd.svg","material-microphone-message-off":"material/microphone-message-off.svg","material-microphone-message":"material/microphone-message.svg","material-microphone-minus":"material/microphone-minus.svg","material-microphone-off":"material/microphone-off.svg","material-microphone-outline":"material/microphone-outline.svg","material-microphone-plus":"material/microphone-plus.svg","material-microphone-question-outline":"material/microphone-question-outline.svg","material-microphone-question":"material/microphone-question.svg","material-microphone-settings":"material/microphone-settings.svg","material-microphone-variant-off":"material/microphone-variant-off.svg","material-microphone-variant":"material/microphone-variant.svg","material-microphone":"material/microphone.svg","material-microscope":"material/microscope.svg","material-microsoft-access":"material/microsoft-access.svg","material-microsoft-azure-devops":"material/microsoft-azure-devops.svg","material-microsoft-azure":"material/microsoft-azure.svg","material-microsoft-bing":"material/microsoft-bing.svg","material-microsoft-dynamics-365":"material/microsoft-dynamics-365.svg","material-microsoft-edge":"material/microsoft-edge.svg","material-microsoft-excel":"material/microsoft-excel.svg","material-microsoft-internet-explorer":"material/microsoft-internet-explorer.svg","material-microsoft-office":"material/microsoft-office.svg","material-microsoft-onedrive":"material/microsoft-onedrive.svg","material-microsoft-onenote":"material/microsoft-onenote.svg","material-microsoft-outlook":"material/microsoft-outlook.svg","material-microsoft-powerpoint":"material/microsoft-powerpoint.svg","material-microsoft-sharepoint":"material/microsoft-sharepoint.svg","material-microsoft-teams":"material/microsoft-teams.svg","material-microsoft-visual-studio-code":"material/microsoft-visual-studio-code.svg","material-microsoft-visual-studio":"material/microsoft-visual-studio.svg","material-microsoft-windows-classic":"material/microsoft-windows-classic.svg","material-microsoft-windows":"material/microsoft-windows.svg","material-microsoft-word":"material/microsoft-word.svg","material-microsoft-xbox-controller-battery-alert":"material/microsoft-xbox-controller-battery-alert.svg","material-microsoft-xbox-controller-battery-charging":"material/microsoft-xbox-controller-battery-charging.svg","material-microsoft-xbox-controller-battery-empty":"material/microsoft-xbox-controller-battery-empty.svg","material-microsoft-xbox-controller-battery-full":"material/microsoft-xbox-controller-battery-full.svg","material-microsoft-xbox-controller-battery-low":"material/microsoft-xbox-controller-battery-low.svg","material-microsoft-xbox-controller-battery-medium":"material/microsoft-xbox-controller-battery-medium.svg","material-microsoft-xbox-controller-battery-unknown":"material/microsoft-xbox-controller-battery-unknown.svg","material-microsoft-xbox-controller-menu":"material/microsoft-xbox-controller-menu.svg","material-microsoft-xbox-controller-off":"material/microsoft-xbox-controller-off.svg","material-microsoft-xbox-controller-view":"material/microsoft-xbox-controller-view.svg","material-microsoft-xbox-controller":"material/microsoft-xbox-controller.svg","material-microsoft-xbox":"material/microsoft-xbox.svg","material-microsoft":"material/microsoft.svg","material-microwave-off":"material/microwave-off.svg","material-microwave":"material/microwave.svg","material-middleware-outline":"material/middleware-outline.svg","material-middleware":"material/middleware.svg","material-midi-port":"material/midi-port.svg","material-midi":"material/midi.svg","material-mine":"material/mine.svg","material-minecraft":"material/minecraft.svg","material-mini-sd":"material/mini-sd.svg","material-minidisc":"material/minidisc.svg","material-minus-box-multiple-outline":"material/minus-box-multiple-outline.svg","material-minus-box-multiple":"material/minus-box-multiple.svg","material-minus-box-outline":"material/minus-box-outline.svg","material-minus-box":"material/minus-box.svg","material-minus-circle-multiple-outline":"material/minus-circle-multiple-outline.svg","material-minus-circle-multiple":"material/minus-circle-multiple.svg","material-minus-circle-off-outline":"material/minus-circle-off-outline.svg","material-minus-circle-off":"material/minus-circle-off.svg","material-minus-circle-outline":"material/minus-circle-outline.svg","material-minus-circle":"material/minus-circle.svg","material-minus-network-outline":"material/minus-network-outline.svg","material-minus-network":"material/minus-network.svg","material-minus-thick":"material/minus-thick.svg","material-minus":"material/minus.svg","material-mirror-rectangle":"material/mirror-rectangle.svg","material-mirror-variant":"material/mirror-variant.svg","material-mirror":"material/mirror.svg","material-mixed-martial-arts":"material/mixed-martial-arts.svg","material-mixed-reality":"material/mixed-reality.svg","material-molecule-co":"material/molecule-co.svg","material-molecule-co2":"material/molecule-co2.svg","material-molecule":"material/molecule.svg","material-monitor-account":"material/monitor-account.svg","material-monitor-arrow-down-variant":"material/monitor-arrow-down-variant.svg","material-monitor-arrow-down":"material/monitor-arrow-down.svg","material-monitor-cellphone-star":"material/monitor-cellphone-star.svg","material-monitor-cellphone":"material/monitor-cellphone.svg","material-monitor-dashboard":"material/monitor-dashboard.svg","material-monitor-edit":"material/monitor-edit.svg","material-monitor-eye":"material/monitor-eye.svg","material-monitor-lock":"material/monitor-lock.svg","material-monitor-multiple":"material/monitor-multiple.svg","material-monitor-off":"material/monitor-off.svg","material-monitor-screenshot":"material/monitor-screenshot.svg","material-monitor-share":"material/monitor-share.svg","material-monitor-shimmer":"material/monitor-shimmer.svg","material-monitor-small":"material/monitor-small.svg","material-monitor-speaker-off":"material/monitor-speaker-off.svg","material-monitor-speaker":"material/monitor-speaker.svg","material-monitor-star":"material/monitor-star.svg","material-monitor":"material/monitor.svg","material-moon-first-quarter":"material/moon-first-quarter.svg","material-moon-full":"material/moon-full.svg","material-moon-last-quarter":"material/moon-last-quarter.svg","material-moon-new":"material/moon-new.svg","material-moon-waning-crescent":"material/moon-waning-crescent.svg","material-moon-waning-gibbous":"material/moon-waning-gibbous.svg","material-moon-waxing-crescent":"material/moon-waxing-crescent.svg","material-moon-waxing-gibbous":"material/moon-waxing-gibbous.svg","material-moped-electric-outline":"material/moped-electric-outline.svg","material-moped-electric":"material/moped-electric.svg","material-moped-outline":"material/moped-outline.svg","material-moped":"material/moped.svg","material-more":"material/more.svg","material-mortar-pestle-plus":"material/mortar-pestle-plus.svg","material-mortar-pestle":"material/mortar-pestle.svg","material-mosque-outline":"material/mosque-outline.svg","material-mosque":"material/mosque.svg","material-mother-heart":"material/mother-heart.svg","material-mother-nurse":"material/mother-nurse.svg","material-motion-outline":"material/motion-outline.svg","material-motion-pause-outline":"material/motion-pause-outline.svg","material-motion-pause":"material/motion-pause.svg","material-motion-play-outline":"material/motion-play-outline.svg","material-motion-play":"material/motion-play.svg","material-motion-sensor-off":"material/motion-sensor-off.svg","material-motion-sensor":"material/motion-sensor.svg","material-motion":"material/motion.svg","material-motorbike-electric":"material/motorbike-electric.svg","material-motorbike-off":"material/motorbike-off.svg","material-motorbike":"material/motorbike.svg","material-mouse-bluetooth":"material/mouse-bluetooth.svg","material-mouse-move-down":"material/mouse-move-down.svg","material-mouse-move-up":"material/mouse-move-up.svg","material-mouse-move-vertical":"material/mouse-move-vertical.svg","material-mouse-off":"material/mouse-off.svg","material-mouse-variant-off":"material/mouse-variant-off.svg","material-mouse-variant":"material/mouse-variant.svg","material-mouse":"material/mouse.svg","material-move-resize-variant":"material/move-resize-variant.svg","material-move-resize":"material/move-resize.svg","material-movie-check-outline":"material/movie-check-outline.svg","material-movie-check":"material/movie-check.svg","material-movie-cog-outline":"material/movie-cog-outline.svg","material-movie-cog":"material/movie-cog.svg","material-movie-edit-outline":"material/movie-edit-outline.svg","material-movie-edit":"material/movie-edit.svg","material-movie-filter-outline":"material/movie-filter-outline.svg","material-movie-filter":"material/movie-filter.svg","material-movie-minus-outline":"material/movie-minus-outline.svg","material-movie-minus":"material/movie-minus.svg","material-movie-off-outline":"material/movie-off-outline.svg","material-movie-off":"material/movie-off.svg","material-movie-open-check-outline":"material/movie-open-check-outline.svg","material-movie-open-check":"material/movie-open-check.svg","material-movie-open-cog-outline":"material/movie-open-cog-outline.svg","material-movie-open-cog":"material/movie-open-cog.svg","material-movie-open-edit-outline":"material/movie-open-edit-outline.svg","material-movie-open-edit":"material/movie-open-edit.svg","material-movie-open-minus-outline":"material/movie-open-minus-outline.svg","material-movie-open-minus":"material/movie-open-minus.svg","material-movie-open-off-outline":"material/movie-open-off-outline.svg","material-movie-open-off":"material/movie-open-off.svg","material-movie-open-outline":"material/movie-open-outline.svg","material-movie-open-play-outline":"material/movie-open-play-outline.svg","material-movie-open-play":"material/movie-open-play.svg","material-movie-open-plus-outline":"material/movie-open-plus-outline.svg","material-movie-open-plus":"material/movie-open-plus.svg","material-movie-open-remove-outline":"material/movie-open-remove-outline.svg","material-movie-open-remove":"material/movie-open-remove.svg","material-movie-open-settings-outline":"material/movie-open-settings-outline.svg","material-movie-open-settings":"material/movie-open-settings.svg","material-movie-open-star-outline":"material/movie-open-star-outline.svg","material-movie-open-star":"material/movie-open-star.svg","material-movie-open":"material/movie-open.svg","material-movie-outline":"material/movie-outline.svg","material-movie-play-outline":"material/movie-play-outline.svg","material-movie-play":"material/movie-play.svg","material-movie-plus-outline":"material/movie-plus-outline.svg","material-movie-plus":"material/movie-plus.svg","material-movie-remove-outline":"material/movie-remove-outline.svg","material-movie-remove":"material/movie-remove.svg","material-movie-roll":"material/movie-roll.svg","material-movie-search-outline":"material/movie-search-outline.svg","material-movie-search":"material/movie-search.svg","material-movie-settings-outline":"material/movie-settings-outline.svg","material-movie-settings":"material/movie-settings.svg","material-movie-star-outline":"material/movie-star-outline.svg","material-movie-star":"material/movie-star.svg","material-movie":"material/movie.svg","material-mower-bag-on":"material/mower-bag-on.svg","material-mower-bag":"material/mower-bag.svg","material-mower-on":"material/mower-on.svg","material-mower":"material/mower.svg","material-muffin":"material/muffin.svg","material-multicast":"material/multicast.svg","material-multimedia":"material/multimedia.svg","material-multiplication-box":"material/multiplication-box.svg","material-multiplication":"material/multiplication.svg","material-mushroom-off-outline":"material/mushroom-off-outline.svg","material-mushroom-off":"material/mushroom-off.svg","material-mushroom-outline":"material/mushroom-outline.svg","material-mushroom":"material/mushroom.svg","material-music-accidental-double-flat":"material/music-accidental-double-flat.svg","material-music-accidental-double-sharp":"material/music-accidental-double-sharp.svg","material-music-accidental-flat":"material/music-accidental-flat.svg","material-music-accidental-natural":"material/music-accidental-natural.svg","material-music-accidental-sharp":"material/music-accidental-sharp.svg","material-music-box-multiple-outline":"material/music-box-multiple-outline.svg","material-music-box-multiple":"material/music-box-multiple.svg","material-music-box-outline":"material/music-box-outline.svg","material-music-box":"material/music-box.svg","material-music-circle-outline":"material/music-circle-outline.svg","material-music-circle":"material/music-circle.svg","material-music-clef-alto":"material/music-clef-alto.svg","material-music-clef-bass":"material/music-clef-bass.svg","material-music-clef-treble":"material/music-clef-treble.svg","material-music-note-bluetooth-off":"material/music-note-bluetooth-off.svg","material-music-note-bluetooth":"material/music-note-bluetooth.svg","material-music-note-eighth-dotted":"material/music-note-eighth-dotted.svg","material-music-note-eighth":"material/music-note-eighth.svg","material-music-note-half-dotted":"material/music-note-half-dotted.svg","material-music-note-half":"material/music-note-half.svg","material-music-note-minus":"material/music-note-minus.svg","material-music-note-off-outline":"material/music-note-off-outline.svg","material-music-note-off":"material/music-note-off.svg","material-music-note-outline":"material/music-note-outline.svg","material-music-note-plus":"material/music-note-plus.svg","material-music-note-quarter-dotted":"material/music-note-quarter-dotted.svg","material-music-note-quarter":"material/music-note-quarter.svg","material-music-note-sixteenth-dotted":"material/music-note-sixteenth-dotted.svg","material-music-note-sixteenth":"material/music-note-sixteenth.svg","material-music-note-whole-dotted":"material/music-note-whole-dotted.svg","material-music-note-whole":"material/music-note-whole.svg","material-music-note":"material/music-note.svg","material-music-off":"material/music-off.svg","material-music-rest-eighth":"material/music-rest-eighth.svg","material-music-rest-half":"material/music-rest-half.svg","material-music-rest-quarter":"material/music-rest-quarter.svg","material-music-rest-sixteenth":"material/music-rest-sixteenth.svg","material-music-rest-whole":"material/music-rest-whole.svg","material-music":"material/music.svg","material-mustache":"material/mustache.svg","material-nail":"material/nail.svg","material-nas":"material/nas.svg","material-nativescript":"material/nativescript.svg","material-nature-people":"material/nature-people.svg","material-nature":"material/nature.svg","material-navigation-outline":"material/navigation-outline.svg","material-navigation-variant-outline":"material/navigation-variant-outline.svg","material-navigation-variant":"material/navigation-variant.svg","material-navigation":"material/navigation.svg","material-near-me":"material/near-me.svg","material-necklace":"material/necklace.svg","material-needle-off":"material/needle-off.svg","material-needle":"material/needle.svg","material-netflix":"material/netflix.svg","material-network-off-outline":"material/network-off-outline.svg","material-network-off":"material/network-off.svg","material-network-outline":"material/network-outline.svg","material-network-pos":"material/network-pos.svg","material-network-strength-1-alert":"material/network-strength-1-alert.svg","material-network-strength-1":"material/network-strength-1.svg","material-network-strength-2-alert":"material/network-strength-2-alert.svg","material-network-strength-2":"material/network-strength-2.svg","material-network-strength-3-alert":"material/network-strength-3-alert.svg","material-network-strength-3":"material/network-strength-3.svg","material-network-strength-4-alert":"material/network-strength-4-alert.svg","material-network-strength-4-cog":"material/network-strength-4-cog.svg","material-network-strength-4":"material/network-strength-4.svg","material-network-strength-off-outline":"material/network-strength-off-outline.svg","material-network-strength-off":"material/network-strength-off.svg","material-network-strength-outline":"material/network-strength-outline.svg","material-network":"material/network.svg","material-new-box":"material/new-box.svg","material-newspaper-check":"material/newspaper-check.svg","material-newspaper-minus":"material/newspaper-minus.svg","material-newspaper-plus":"material/newspaper-plus.svg","material-newspaper-remove":"material/newspaper-remove.svg","material-newspaper-variant-multiple-outline":"material/newspaper-variant-multiple-outline.svg","material-newspaper-variant-multiple":"material/newspaper-variant-multiple.svg","material-newspaper-variant-outline":"material/newspaper-variant-outline.svg","material-newspaper-variant":"material/newspaper-variant.svg","material-newspaper":"material/newspaper.svg","material-nfc-search-variant":"material/nfc-search-variant.svg","material-nfc-tap":"material/nfc-tap.svg","material-nfc-variant-off":"material/nfc-variant-off.svg","material-nfc-variant":"material/nfc-variant.svg","material-nfc":"material/nfc.svg","material-ninja":"material/ninja.svg","material-nintendo-game-boy":"material/nintendo-game-boy.svg","material-nintendo-switch":"material/nintendo-switch.svg","material-nintendo-wii":"material/nintendo-wii.svg","material-nintendo-wiiu":"material/nintendo-wiiu.svg","material-nix":"material/nix.svg","material-nodejs":"material/nodejs.svg","material-noodles":"material/noodles.svg","material-not-equal-variant":"material/not-equal-variant.svg","material-not-equal":"material/not-equal.svg","material-note-alert-outline":"material/note-alert-outline.svg","material-note-alert":"material/note-alert.svg","material-note-check-outline":"material/note-check-outline.svg","material-note-check":"material/note-check.svg","material-note-edit-outline":"material/note-edit-outline.svg","material-note-edit":"material/note-edit.svg","material-note-minus-outline":"material/note-minus-outline.svg","material-note-minus":"material/note-minus.svg","material-note-multiple-outline":"material/note-multiple-outline.svg","material-note-multiple":"material/note-multiple.svg","material-note-off-outline":"material/note-off-outline.svg","material-note-off":"material/note-off.svg","material-note-outline":"material/note-outline.svg","material-note-plus-outline":"material/note-plus-outline.svg","material-note-plus":"material/note-plus.svg","material-note-remove-outline":"material/note-remove-outline.svg","material-note-remove":"material/note-remove.svg","material-note-search-outline":"material/note-search-outline.svg","material-note-search":"material/note-search.svg","material-note-text-outline":"material/note-text-outline.svg","material-note-text":"material/note-text.svg","material-note":"material/note.svg","material-notebook-check-outline":"material/notebook-check-outline.svg","material-notebook-check":"material/notebook-check.svg","material-notebook-edit-outline":"material/notebook-edit-outline.svg","material-notebook-edit":"material/notebook-edit.svg","material-notebook-heart-outline":"material/notebook-heart-outline.svg","material-notebook-heart":"material/notebook-heart.svg","material-notebook-minus-outline":"material/notebook-minus-outline.svg","material-notebook-minus":"material/notebook-minus.svg","material-notebook-multiple":"material/notebook-multiple.svg","material-notebook-outline":"material/notebook-outline.svg","material-notebook-plus-outline":"material/notebook-plus-outline.svg","material-notebook-plus":"material/notebook-plus.svg","material-notebook-remove-outline":"material/notebook-remove-outline.svg","material-notebook-remove":"material/notebook-remove.svg","material-notebook":"material/notebook.svg","material-notification-clear-all":"material/notification-clear-all.svg","material-npm":"material/npm.svg","material-nuke":"material/nuke.svg","material-null":"material/null.svg","material-numeric-0-box-multiple-outline":"material/numeric-0-box-multiple-outline.svg","material-numeric-0-box-multiple":"material/numeric-0-box-multiple.svg","material-numeric-0-box-outline":"material/numeric-0-box-outline.svg","material-numeric-0-box":"material/numeric-0-box.svg","material-numeric-0-circle-outline":"material/numeric-0-circle-outline.svg","material-numeric-0-circle":"material/numeric-0-circle.svg","material-numeric-0":"material/numeric-0.svg","material-numeric-1-box-multiple-outline":"material/numeric-1-box-multiple-outline.svg","material-numeric-1-box-multiple":"material/numeric-1-box-multiple.svg","material-numeric-1-box-outline":"material/numeric-1-box-outline.svg","material-numeric-1-box":"material/numeric-1-box.svg","material-numeric-1-circle-outline":"material/numeric-1-circle-outline.svg","material-numeric-1-circle":"material/numeric-1-circle.svg","material-numeric-1":"material/numeric-1.svg","material-numeric-10-box-multiple-outline":"material/numeric-10-box-multiple-outline.svg","material-numeric-10-box-multiple":"material/numeric-10-box-multiple.svg","material-numeric-10-box-outline":"material/numeric-10-box-outline.svg","material-numeric-10-box":"material/numeric-10-box.svg","material-numeric-10-circle-outline":"material/numeric-10-circle-outline.svg","material-numeric-10-circle":"material/numeric-10-circle.svg","material-numeric-10":"material/numeric-10.svg","material-numeric-2-box-multiple-outline":"material/numeric-2-box-multiple-outline.svg","material-numeric-2-box-multiple":"material/numeric-2-box-multiple.svg","material-numeric-2-box-outline":"material/numeric-2-box-outline.svg","material-numeric-2-box":"material/numeric-2-box.svg","material-numeric-2-circle-outline":"material/numeric-2-circle-outline.svg","material-numeric-2-circle":"material/numeric-2-circle.svg","material-numeric-2":"material/numeric-2.svg","material-numeric-3-box-multiple-outline":"material/numeric-3-box-multiple-outline.svg","material-numeric-3-box-multiple":"material/numeric-3-box-multiple.svg","material-numeric-3-box-outline":"material/numeric-3-box-outline.svg","material-numeric-3-box":"material/numeric-3-box.svg","material-numeric-3-circle-outline":"material/numeric-3-circle-outline.svg","material-numeric-3-circle":"material/numeric-3-circle.svg","material-numeric-3":"material/numeric-3.svg","material-numeric-4-box-multiple-outline":"material/numeric-4-box-multiple-outline.svg","material-numeric-4-box-multiple":"material/numeric-4-box-multiple.svg","material-numeric-4-box-outline":"material/numeric-4-box-outline.svg","material-numeric-4-box":"material/numeric-4-box.svg","material-numeric-4-circle-outline":"material/numeric-4-circle-outline.svg","material-numeric-4-circle":"material/numeric-4-circle.svg","material-numeric-4":"material/numeric-4.svg","material-numeric-5-box-multiple-outline":"material/numeric-5-box-multiple-outline.svg","material-numeric-5-box-multiple":"material/numeric-5-box-multiple.svg","material-numeric-5-box-outline":"material/numeric-5-box-outline.svg","material-numeric-5-box":"material/numeric-5-box.svg","material-numeric-5-circle-outline":"material/numeric-5-circle-outline.svg","material-numeric-5-circle":"material/numeric-5-circle.svg","material-numeric-5":"material/numeric-5.svg","material-numeric-6-box-multiple-outline":"material/numeric-6-box-multiple-outline.svg","material-numeric-6-box-multiple":"material/numeric-6-box-multiple.svg","material-numeric-6-box-outline":"material/numeric-6-box-outline.svg","material-numeric-6-box":"material/numeric-6-box.svg","material-numeric-6-circle-outline":"material/numeric-6-circle-outline.svg","material-numeric-6-circle":"material/numeric-6-circle.svg","material-numeric-6":"material/numeric-6.svg","material-numeric-7-box-multiple-outline":"material/numeric-7-box-multiple-outline.svg","material-numeric-7-box-multiple":"material/numeric-7-box-multiple.svg","material-numeric-7-box-outline":"material/numeric-7-box-outline.svg","material-numeric-7-box":"material/numeric-7-box.svg","material-numeric-7-circle-outline":"material/numeric-7-circle-outline.svg","material-numeric-7-circle":"material/numeric-7-circle.svg","material-numeric-7":"material/numeric-7.svg","material-numeric-8-box-multiple-outline":"material/numeric-8-box-multiple-outline.svg","material-numeric-8-box-multiple":"material/numeric-8-box-multiple.svg","material-numeric-8-box-outline":"material/numeric-8-box-outline.svg","material-numeric-8-box":"material/numeric-8-box.svg","material-numeric-8-circle-outline":"material/numeric-8-circle-outline.svg","material-numeric-8-circle":"material/numeric-8-circle.svg","material-numeric-8":"material/numeric-8.svg","material-numeric-9-box-multiple-outline":"material/numeric-9-box-multiple-outline.svg","material-numeric-9-box-multiple":"material/numeric-9-box-multiple.svg","material-numeric-9-box-outline":"material/numeric-9-box-outline.svg","material-numeric-9-box":"material/numeric-9-box.svg","material-numeric-9-circle-outline":"material/numeric-9-circle-outline.svg","material-numeric-9-circle":"material/numeric-9-circle.svg","material-numeric-9-plus-box-multiple-outline":"material/numeric-9-plus-box-multiple-outline.svg","material-numeric-9-plus-box-multiple":"material/numeric-9-plus-box-multiple.svg","material-numeric-9-plus-box-outline":"material/numeric-9-plus-box-outline.svg","material-numeric-9-plus-box":"material/numeric-9-plus-box.svg","material-numeric-9-plus-circle-outline":"material/numeric-9-plus-circle-outline.svg","material-numeric-9-plus-circle":"material/numeric-9-plus-circle.svg","material-numeric-9-plus":"material/numeric-9-plus.svg","material-numeric-9":"material/numeric-9.svg","material-numeric-negative-1":"material/numeric-negative-1.svg","material-numeric-off":"material/numeric-off.svg","material-numeric-positive-1":"material/numeric-positive-1.svg","material-numeric":"material/numeric.svg","material-nut":"material/nut.svg","material-nutrition":"material/nutrition.svg","material-nuxt":"material/nuxt.svg","material-oar":"material/oar.svg","material-ocarina":"material/ocarina.svg","material-oci":"material/oci.svg","material-ocr":"material/ocr.svg","material-octagon-outline":"material/octagon-outline.svg","material-octagon":"material/octagon.svg","material-octagram-outline":"material/octagram-outline.svg","material-octagram":"material/octagram.svg","material-octahedron-off":"material/octahedron-off.svg","material-octahedron":"material/octahedron.svg","material-odnoklassniki":"material/odnoklassniki.svg","material-offer":"material/offer.svg","material-office-building-cog-outline":"material/office-building-cog-outline.svg","material-office-building-cog":"material/office-building-cog.svg","material-office-building-marker-outline":"material/office-building-marker-outline.svg","material-office-building-marker":"material/office-building-marker.svg","material-office-building-minus-outline":"material/office-building-minus-outline.svg","material-office-building-minus":"material/office-building-minus.svg","material-office-building-outline":"material/office-building-outline.svg","material-office-building-plus-outline":"material/office-building-plus-outline.svg","material-office-building-plus":"material/office-building-plus.svg","material-office-building-remove-outline":"material/office-building-remove-outline.svg","material-office-building-remove":"material/office-building-remove.svg","material-office-building":"material/office-building.svg","material-oil-lamp":"material/oil-lamp.svg","material-oil-level":"material/oil-level.svg","material-oil-temperature":"material/oil-temperature.svg","material-oil":"material/oil.svg","material-om":"material/om.svg","material-omega":"material/omega.svg","material-one-up":"material/one-up.svg","material-onepassword":"material/onepassword.svg","material-opacity":"material/opacity.svg","material-open-in-app":"material/open-in-app.svg","material-open-in-new":"material/open-in-new.svg","material-open-source-initiative":"material/open-source-initiative.svg","material-openid":"material/openid.svg","material-opera":"material/opera.svg","material-orbit-variant":"material/orbit-variant.svg","material-orbit":"material/orbit.svg","material-order-alphabetical-ascending":"material/order-alphabetical-ascending.svg","material-order-alphabetical-descending":"material/order-alphabetical-descending.svg","material-order-bool-ascending-variant":"material/order-bool-ascending-variant.svg","material-order-bool-ascending":"material/order-bool-ascending.svg","material-order-bool-descending-variant":"material/order-bool-descending-variant.svg","material-order-bool-descending":"material/order-bool-descending.svg","material-order-numeric-ascending":"material/order-numeric-ascending.svg","material-order-numeric-descending":"material/order-numeric-descending.svg","material-origin":"material/origin.svg","material-ornament-variant":"material/ornament-variant.svg","material-ornament":"material/ornament.svg","material-outdoor-lamp":"material/outdoor-lamp.svg","material-overscan":"material/overscan.svg","material-owl":"material/owl.svg","material-pac-man":"material/pac-man.svg","material-package-check":"material/package-check.svg","material-package-down":"material/package-down.svg","material-package-up":"material/package-up.svg","material-package-variant-closed-check":"material/package-variant-closed-check.svg","material-package-variant-closed-minus":"material/package-variant-closed-minus.svg","material-package-variant-closed-plus":"material/package-variant-closed-plus.svg","material-package-variant-closed-remove":"material/package-variant-closed-remove.svg","material-package-variant-closed":"material/package-variant-closed.svg","material-package-variant-minus":"material/package-variant-minus.svg","material-package-variant-plus":"material/package-variant-plus.svg","material-package-variant-remove":"material/package-variant-remove.svg","material-package-variant":"material/package-variant.svg","material-package":"material/package.svg","material-page-first":"material/page-first.svg","material-page-last":"material/page-last.svg","material-page-layout-body":"material/page-layout-body.svg","material-page-layout-footer":"material/page-layout-footer.svg","material-page-layout-header-footer":"material/page-layout-header-footer.svg","material-page-layout-header":"material/page-layout-header.svg","material-page-layout-sidebar-left":"material/page-layout-sidebar-left.svg","material-page-layout-sidebar-right":"material/page-layout-sidebar-right.svg","material-page-next-outline":"material/page-next-outline.svg","material-page-next":"material/page-next.svg","material-page-previous-outline":"material/page-previous-outline.svg","material-page-previous":"material/page-previous.svg","material-pail-minus-outline":"material/pail-minus-outline.svg","material-pail-minus":"material/pail-minus.svg","material-pail-off-outline":"material/pail-off-outline.svg","material-pail-off":"material/pail-off.svg","material-pail-outline":"material/pail-outline.svg","material-pail-plus-outline":"material/pail-plus-outline.svg","material-pail-plus":"material/pail-plus.svg","material-pail-remove-outline":"material/pail-remove-outline.svg","material-pail-remove":"material/pail-remove.svg","material-pail":"material/pail.svg","material-palette-advanced":"material/palette-advanced.svg","material-palette-outline":"material/palette-outline.svg","material-palette-swatch-outline":"material/palette-swatch-outline.svg","material-palette-swatch-variant":"material/palette-swatch-variant.svg","material-palette-swatch":"material/palette-swatch.svg","material-palette":"material/palette.svg","material-palm-tree":"material/palm-tree.svg","material-pan-bottom-left":"material/pan-bottom-left.svg","material-pan-bottom-right":"material/pan-bottom-right.svg","material-pan-down":"material/pan-down.svg","material-pan-horizontal":"material/pan-horizontal.svg","material-pan-left":"material/pan-left.svg","material-pan-right":"material/pan-right.svg","material-pan-top-left":"material/pan-top-left.svg","material-pan-top-right":"material/pan-top-right.svg","material-pan-up":"material/pan-up.svg","material-pan-vertical":"material/pan-vertical.svg","material-pan":"material/pan.svg","material-panda":"material/panda.svg","material-pandora":"material/pandora.svg","material-panorama-fisheye":"material/panorama-fisheye.svg","material-panorama-horizontal-outline":"material/panorama-horizontal-outline.svg","material-panorama-horizontal":"material/panorama-horizontal.svg","material-panorama-outline":"material/panorama-outline.svg","material-panorama-sphere-outline":"material/panorama-sphere-outline.svg","material-panorama-sphere":"material/panorama-sphere.svg","material-panorama-variant-outline":"material/panorama-variant-outline.svg","material-panorama-variant":"material/panorama-variant.svg","material-panorama-vertical-outline":"material/panorama-vertical-outline.svg","material-panorama-vertical":"material/panorama-vertical.svg","material-panorama-wide-angle-outline":"material/panorama-wide-angle-outline.svg","material-panorama-wide-angle":"material/panorama-wide-angle.svg","material-panorama":"material/panorama.svg","material-paper-cut-vertical":"material/paper-cut-vertical.svg","material-paper-roll-outline":"material/paper-roll-outline.svg","material-paper-roll":"material/paper-roll.svg","material-paperclip-check":"material/paperclip-check.svg","material-paperclip-lock":"material/paperclip-lock.svg","material-paperclip-minus":"material/paperclip-minus.svg","material-paperclip-off":"material/paperclip-off.svg","material-paperclip-plus":"material/paperclip-plus.svg","material-paperclip-remove":"material/paperclip-remove.svg","material-paperclip":"material/paperclip.svg","material-parachute-outline":"material/parachute-outline.svg","material-parachute":"material/parachute.svg","material-paragliding":"material/paragliding.svg","material-parking":"material/parking.svg","material-party-popper":"material/party-popper.svg","material-passport-biometric":"material/passport-biometric.svg","material-passport":"material/passport.svg","material-pasta":"material/pasta.svg","material-patio-heater":"material/patio-heater.svg","material-patreon":"material/patreon.svg","material-pause-box-outline":"material/pause-box-outline.svg","material-pause-box":"material/pause-box.svg","material-pause-circle-outline":"material/pause-circle-outline.svg","material-pause-circle":"material/pause-circle.svg","material-pause-octagon-outline":"material/pause-octagon-outline.svg","material-pause-octagon":"material/pause-octagon.svg","material-pause":"material/pause.svg","material-paw-off-outline":"material/paw-off-outline.svg","material-paw-off":"material/paw-off.svg","material-paw-outline":"material/paw-outline.svg","material-paw":"material/paw.svg","material-peace":"material/peace.svg","material-peanut-off-outline":"material/peanut-off-outline.svg","material-peanut-off":"material/peanut-off.svg","material-peanut-outline":"material/peanut-outline.svg","material-peanut":"material/peanut.svg","material-pen-lock":"material/pen-lock.svg","material-pen-minus":"material/pen-minus.svg","material-pen-off":"material/pen-off.svg","material-pen-plus":"material/pen-plus.svg","material-pen-remove":"material/pen-remove.svg","material-pen":"material/pen.svg","material-pencil-box-multiple-outline":"material/pencil-box-multiple-outline.svg","material-pencil-box-multiple":"material/pencil-box-multiple.svg","material-pencil-box-outline":"material/pencil-box-outline.svg","material-pencil-box":"material/pencil-box.svg","material-pencil-circle-outline":"material/pencil-circle-outline.svg","material-pencil-circle":"material/pencil-circle.svg","material-pencil-lock-outline":"material/pencil-lock-outline.svg","material-pencil-lock":"material/pencil-lock.svg","material-pencil-minus-outline":"material/pencil-minus-outline.svg","material-pencil-minus":"material/pencil-minus.svg","material-pencil-off-outline":"material/pencil-off-outline.svg","material-pencil-off":"material/pencil-off.svg","material-pencil-outline":"material/pencil-outline.svg","material-pencil-plus-outline":"material/pencil-plus-outline.svg","material-pencil-plus":"material/pencil-plus.svg","material-pencil-remove-outline":"material/pencil-remove-outline.svg","material-pencil-remove":"material/pencil-remove.svg","material-pencil-ruler":"material/pencil-ruler.svg","material-pencil":"material/pencil.svg","material-penguin":"material/penguin.svg","material-pentagon-outline":"material/pentagon-outline.svg","material-pentagon":"material/pentagon.svg","material-pentagram":"material/pentagram.svg","material-percent-box-outline":"material/percent-box-outline.svg","material-percent-box":"material/percent-box.svg","material-percent-circle-outline":"material/percent-circle-outline.svg","material-percent-circle":"material/percent-circle.svg","material-percent-outline":"material/percent-outline.svg","material-percent":"material/percent.svg","material-periodic-table":"material/periodic-table.svg","material-perspective-less":"material/perspective-less.svg","material-perspective-more":"material/perspective-more.svg","material-ph":"material/ph.svg","material-phone-alert-outline":"material/phone-alert-outline.svg","material-phone-alert":"material/phone-alert.svg","material-phone-bluetooth-outline":"material/phone-bluetooth-outline.svg","material-phone-bluetooth":"material/phone-bluetooth.svg","material-phone-cancel-outline":"material/phone-cancel-outline.svg","material-phone-cancel":"material/phone-cancel.svg","material-phone-check-outline":"material/phone-check-outline.svg","material-phone-check":"material/phone-check.svg","material-phone-classic-off":"material/phone-classic-off.svg","material-phone-classic":"material/phone-classic.svg","material-phone-clock":"material/phone-clock.svg","material-phone-dial-outline":"material/phone-dial-outline.svg","material-phone-dial":"material/phone-dial.svg","material-phone-forward-outline":"material/phone-forward-outline.svg","material-phone-forward":"material/phone-forward.svg","material-phone-hangup-outline":"material/phone-hangup-outline.svg","material-phone-hangup":"material/phone-hangup.svg","material-phone-in-talk-outline":"material/phone-in-talk-outline.svg","material-phone-in-talk":"material/phone-in-talk.svg","material-phone-incoming-outgoing-outline":"material/phone-incoming-outgoing-outline.svg","material-phone-incoming-outgoing":"material/phone-incoming-outgoing.svg","material-phone-incoming-outline":"material/phone-incoming-outline.svg","material-phone-incoming":"material/phone-incoming.svg","material-phone-lock-outline":"material/phone-lock-outline.svg","material-phone-lock":"material/phone-lock.svg","material-phone-log-outline":"material/phone-log-outline.svg","material-phone-log":"material/phone-log.svg","material-phone-message-outline":"material/phone-message-outline.svg","material-phone-message":"material/phone-message.svg","material-phone-minus-outline":"material/phone-minus-outline.svg","material-phone-minus":"material/phone-minus.svg","material-phone-missed-outline":"material/phone-missed-outline.svg","material-phone-missed":"material/phone-missed.svg","material-phone-off-outline":"material/phone-off-outline.svg","material-phone-off":"material/phone-off.svg","material-phone-outgoing-outline":"material/phone-outgoing-outline.svg","material-phone-outgoing":"material/phone-outgoing.svg","material-phone-outline":"material/phone-outline.svg","material-phone-paused-outline":"material/phone-paused-outline.svg","material-phone-paused":"material/phone-paused.svg","material-phone-plus-outline":"material/phone-plus-outline.svg","material-phone-plus":"material/phone-plus.svg","material-phone-refresh-outline":"material/phone-refresh-outline.svg","material-phone-refresh":"material/phone-refresh.svg","material-phone-remove-outline":"material/phone-remove-outline.svg","material-phone-remove":"material/phone-remove.svg","material-phone-return-outline":"material/phone-return-outline.svg","material-phone-return":"material/phone-return.svg","material-phone-ring-outline":"material/phone-ring-outline.svg","material-phone-ring":"material/phone-ring.svg","material-phone-rotate-landscape":"material/phone-rotate-landscape.svg","material-phone-rotate-portrait":"material/phone-rotate-portrait.svg","material-phone-settings-outline":"material/phone-settings-outline.svg","material-phone-settings":"material/phone-settings.svg","material-phone-sync-outline":"material/phone-sync-outline.svg","material-phone-sync":"material/phone-sync.svg","material-phone-voip":"material/phone-voip.svg","material-phone":"material/phone.svg","material-pi-box":"material/pi-box.svg","material-pi-hole":"material/pi-hole.svg","material-pi":"material/pi.svg","material-piano-off":"material/piano-off.svg","material-piano":"material/piano.svg","material-pickaxe":"material/pickaxe.svg","material-picture-in-picture-bottom-right-outline":"material/picture-in-picture-bottom-right-outline.svg","material-picture-in-picture-bottom-right":"material/picture-in-picture-bottom-right.svg","material-picture-in-picture-top-right-outline":"material/picture-in-picture-top-right-outline.svg","material-picture-in-picture-top-right":"material/picture-in-picture-top-right.svg","material-pier-crane":"material/pier-crane.svg","material-pier":"material/pier.svg","material-pig-variant-outline":"material/pig-variant-outline.svg","material-pig-variant":"material/pig-variant.svg","material-pig":"material/pig.svg","material-piggy-bank-outline":"material/piggy-bank-outline.svg","material-piggy-bank":"material/piggy-bank.svg","material-pill-multiple":"material/pill-multiple.svg","material-pill-off":"material/pill-off.svg","material-pill":"material/pill.svg","material-pillar":"material/pillar.svg","material-pin-off-outline":"material/pin-off-outline.svg","material-pin-off":"material/pin-off.svg","material-pin-outline":"material/pin-outline.svg","material-pin":"material/pin.svg","material-pine-tree-box":"material/pine-tree-box.svg","material-pine-tree-fire":"material/pine-tree-fire.svg","material-pine-tree":"material/pine-tree.svg","material-pinterest":"material/pinterest.svg","material-pinwheel-outline":"material/pinwheel-outline.svg","material-pinwheel":"material/pinwheel.svg","material-pipe-disconnected":"material/pipe-disconnected.svg","material-pipe-leak":"material/pipe-leak.svg","material-pipe-valve":"material/pipe-valve.svg","material-pipe-wrench":"material/pipe-wrench.svg","material-pipe":"material/pipe.svg","material-pirate":"material/pirate.svg","material-pistol":"material/pistol.svg","material-piston":"material/piston.svg","material-pitchfork":"material/pitchfork.svg","material-pizza":"material/pizza.svg","material-plane-car":"material/plane-car.svg","material-plane-train":"material/plane-train.svg","material-play-box-lock-open-outline":"material/play-box-lock-open-outline.svg","material-play-box-lock-open":"material/play-box-lock-open.svg","material-play-box-lock-outline":"material/play-box-lock-outline.svg","material-play-box-lock":"material/play-box-lock.svg","material-play-box-multiple-outline":"material/play-box-multiple-outline.svg","material-play-box-multiple":"material/play-box-multiple.svg","material-play-box-outline":"material/play-box-outline.svg","material-play-box":"material/play-box.svg","material-play-circle-outline":"material/play-circle-outline.svg","material-play-circle":"material/play-circle.svg","material-play-network-outline":"material/play-network-outline.svg","material-play-network":"material/play-network.svg","material-play-outline":"material/play-outline.svg","material-play-pause":"material/play-pause.svg","material-play-protected-content":"material/play-protected-content.svg","material-play-speed":"material/play-speed.svg","material-play":"material/play.svg","material-playlist-check":"material/playlist-check.svg","material-playlist-edit":"material/playlist-edit.svg","material-playlist-minus":"material/playlist-minus.svg","material-playlist-music-outline":"material/playlist-music-outline.svg","material-playlist-music":"material/playlist-music.svg","material-playlist-play":"material/playlist-play.svg","material-playlist-plus":"material/playlist-plus.svg","material-playlist-remove":"material/playlist-remove.svg","material-playlist-star":"material/playlist-star.svg","material-plex":"material/plex.svg","material-pliers":"material/pliers.svg","material-plus-box-multiple-outline":"material/plus-box-multiple-outline.svg","material-plus-box-multiple":"material/plus-box-multiple.svg","material-plus-box-outline":"material/plus-box-outline.svg","material-plus-box":"material/plus-box.svg","material-plus-circle-multiple-outline":"material/plus-circle-multiple-outline.svg","material-plus-circle-multiple":"material/plus-circle-multiple.svg","material-plus-circle-outline":"material/plus-circle-outline.svg","material-plus-circle":"material/plus-circle.svg","material-plus-lock-open":"material/plus-lock-open.svg","material-plus-lock":"material/plus-lock.svg","material-plus-minus-box":"material/plus-minus-box.svg","material-plus-minus-variant":"material/plus-minus-variant.svg","material-plus-minus":"material/plus-minus.svg","material-plus-network-outline":"material/plus-network-outline.svg","material-plus-network":"material/plus-network.svg","material-plus-outline":"material/plus-outline.svg","material-plus-thick":"material/plus-thick.svg","material-plus":"material/plus.svg","material-podcast":"material/podcast.svg","material-podium-bronze":"material/podium-bronze.svg","material-podium-gold":"material/podium-gold.svg","material-podium-silver":"material/podium-silver.svg","material-podium":"material/podium.svg","material-point-of-sale":"material/point-of-sale.svg","material-pokeball":"material/pokeball.svg","material-pokemon-go":"material/pokemon-go.svg","material-poker-chip":"material/poker-chip.svg","material-polaroid":"material/polaroid.svg","material-police-badge-outline":"material/police-badge-outline.svg","material-police-badge":"material/police-badge.svg","material-police-station":"material/police-station.svg","material-poll":"material/poll.svg","material-polo":"material/polo.svg","material-polymer":"material/polymer.svg","material-pool-thermometer":"material/pool-thermometer.svg","material-pool":"material/pool.svg","material-popcorn":"material/popcorn.svg","material-post-lamp":"material/post-lamp.svg","material-post-outline":"material/post-outline.svg","material-post":"material/post.svg","material-postage-stamp":"material/postage-stamp.svg","material-pot-mix-outline":"material/pot-mix-outline.svg","material-pot-mix":"material/pot-mix.svg","material-pot-outline":"material/pot-outline.svg","material-pot-steam-outline":"material/pot-steam-outline.svg","material-pot-steam":"material/pot-steam.svg","material-pot":"material/pot.svg","material-pound-box-outline":"material/pound-box-outline.svg","material-pound-box":"material/pound-box.svg","material-pound":"material/pound.svg","material-power-cycle":"material/power-cycle.svg","material-power-off":"material/power-off.svg","material-power-on":"material/power-on.svg","material-power-plug-off-outline":"material/power-plug-off-outline.svg","material-power-plug-off":"material/power-plug-off.svg","material-power-plug-outline":"material/power-plug-outline.svg","material-power-plug":"material/power-plug.svg","material-power-settings":"material/power-settings.svg","material-power-sleep":"material/power-sleep.svg","material-power-socket-au":"material/power-socket-au.svg","material-power-socket-ch":"material/power-socket-ch.svg","material-power-socket-de":"material/power-socket-de.svg","material-power-socket-eu":"material/power-socket-eu.svg","material-power-socket-fr":"material/power-socket-fr.svg","material-power-socket-it":"material/power-socket-it.svg","material-power-socket-jp":"material/power-socket-jp.svg","material-power-socket-uk":"material/power-socket-uk.svg","material-power-socket-us":"material/power-socket-us.svg","material-power-socket":"material/power-socket.svg","material-power-standby":"material/power-standby.svg","material-power":"material/power.svg","material-powershell":"material/powershell.svg","material-prescription":"material/prescription.svg","material-presentation-play":"material/presentation-play.svg","material-presentation":"material/presentation.svg","material-pretzel":"material/pretzel.svg","material-printer-3d-nozzle-alert-outline":"material/printer-3d-nozzle-alert-outline.svg","material-printer-3d-nozzle-alert":"material/printer-3d-nozzle-alert.svg","material-printer-3d-nozzle-heat-outline":"material/printer-3d-nozzle-heat-outline.svg","material-printer-3d-nozzle-heat":"material/printer-3d-nozzle-heat.svg","material-printer-3d-nozzle-off-outline":"material/printer-3d-nozzle-off-outline.svg","material-printer-3d-nozzle-off":"material/printer-3d-nozzle-off.svg","material-printer-3d-nozzle-outline":"material/printer-3d-nozzle-outline.svg","material-printer-3d-nozzle":"material/printer-3d-nozzle.svg","material-printer-3d-off":"material/printer-3d-off.svg","material-printer-3d":"material/printer-3d.svg","material-printer-alert":"material/printer-alert.svg","material-printer-check":"material/printer-check.svg","material-printer-eye":"material/printer-eye.svg","material-printer-off-outline":"material/printer-off-outline.svg","material-printer-off":"material/printer-off.svg","material-printer-outline":"material/printer-outline.svg","material-printer-pos":"material/printer-pos.svg","material-printer-search":"material/printer-search.svg","material-printer-settings":"material/printer-settings.svg","material-printer-wireless":"material/printer-wireless.svg","material-printer":"material/printer.svg","material-priority-high":"material/priority-high.svg","material-priority-low":"material/priority-low.svg","material-professional-hexagon":"material/professional-hexagon.svg","material-progress-alert":"material/progress-alert.svg","material-progress-check":"material/progress-check.svg","material-progress-clock":"material/progress-clock.svg","material-progress-close":"material/progress-close.svg","material-progress-download":"material/progress-download.svg","material-progress-helper":"material/progress-helper.svg","material-progress-pencil":"material/progress-pencil.svg","material-progress-question":"material/progress-question.svg","material-progress-star":"material/progress-star.svg","material-progress-upload":"material/progress-upload.svg","material-progress-wrench":"material/progress-wrench.svg","material-projector-off":"material/projector-off.svg","material-projector-screen-off-outline":"material/projector-screen-off-outline.svg","material-projector-screen-off":"material/projector-screen-off.svg","material-projector-screen-outline":"material/projector-screen-outline.svg","material-projector-screen-variant-off-outline":"material/projector-screen-variant-off-outline.svg","material-projector-screen-variant-off":"material/projector-screen-variant-off.svg","material-projector-screen-variant-outline":"material/projector-screen-variant-outline.svg","material-projector-screen-variant":"material/projector-screen-variant.svg","material-projector-screen":"material/projector-screen.svg","material-projector":"material/projector.svg","material-propane-tank-outline":"material/propane-tank-outline.svg","material-propane-tank":"material/propane-tank.svg","material-protocol":"material/protocol.svg","material-publish-off":"material/publish-off.svg","material-publish":"material/publish.svg","material-pulse":"material/pulse.svg","material-pump-off":"material/pump-off.svg","material-pump":"material/pump.svg","material-pumpkin":"material/pumpkin.svg","material-purse-outline":"material/purse-outline.svg","material-purse":"material/purse.svg","material-puzzle-check-outline":"material/puzzle-check-outline.svg","material-puzzle-check":"material/puzzle-check.svg","material-puzzle-edit-outline":"material/puzzle-edit-outline.svg","material-puzzle-edit":"material/puzzle-edit.svg","material-puzzle-heart-outline":"material/puzzle-heart-outline.svg","material-puzzle-heart":"material/puzzle-heart.svg","material-puzzle-minus-outline":"material/puzzle-minus-outline.svg","material-puzzle-minus":"material/puzzle-minus.svg","material-puzzle-outline":"material/puzzle-outline.svg","material-puzzle-plus-outline":"material/puzzle-plus-outline.svg","material-puzzle-plus":"material/puzzle-plus.svg","material-puzzle-remove-outline":"material/puzzle-remove-outline.svg","material-puzzle-remove":"material/puzzle-remove.svg","material-puzzle-star-outline":"material/puzzle-star-outline.svg","material-puzzle-star":"material/puzzle-star.svg","material-puzzle":"material/puzzle.svg","material-pyramid-off":"material/pyramid-off.svg","material-pyramid":"material/pyramid.svg","material-qi":"material/qi.svg","material-qqchat":"material/qqchat.svg","material-qrcode-edit":"material/qrcode-edit.svg","material-qrcode-minus":"material/qrcode-minus.svg","material-qrcode-plus":"material/qrcode-plus.svg","material-qrcode-remove":"material/qrcode-remove.svg","material-qrcode-scan":"material/qrcode-scan.svg","material-qrcode":"material/qrcode.svg","material-quadcopter":"material/quadcopter.svg","material-quality-high":"material/quality-high.svg","material-quality-low":"material/quality-low.svg","material-quality-medium":"material/quality-medium.svg","material-quora":"material/quora.svg","material-rabbit-variant-outline":"material/rabbit-variant-outline.svg","material-rabbit-variant":"material/rabbit-variant.svg","material-rabbit":"material/rabbit.svg","material-racing-helmet":"material/racing-helmet.svg","material-racquetball":"material/racquetball.svg","material-radar":"material/radar.svg","material-radiator-disabled":"material/radiator-disabled.svg","material-radiator-off":"material/radiator-off.svg","material-radiator":"material/radiator.svg","material-radio-am":"material/radio-am.svg","material-radio-fm":"material/radio-fm.svg","material-radio-handheld":"material/radio-handheld.svg","material-radio-off":"material/radio-off.svg","material-radio-tower":"material/radio-tower.svg","material-radio":"material/radio.svg","material-radioactive-circle-outline":"material/radioactive-circle-outline.svg","material-radioactive-circle":"material/radioactive-circle.svg","material-radioactive-off":"material/radioactive-off.svg","material-radioactive":"material/radioactive.svg","material-radiobox-blank":"material/radiobox-blank.svg","material-radiobox-marked":"material/radiobox-marked.svg","material-radiology-box-outline":"material/radiology-box-outline.svg","material-radiology-box":"material/radiology-box.svg","material-radius-outline":"material/radius-outline.svg","material-radius":"material/radius.svg","material-railroad-light":"material/railroad-light.svg","material-rake":"material/rake.svg","material-raspberry-pi":"material/raspberry-pi.svg","material-raw-off":"material/raw-off.svg","material-raw":"material/raw.svg","material-ray-end-arrow":"material/ray-end-arrow.svg","material-ray-end":"material/ray-end.svg","material-ray-start-arrow":"material/ray-start-arrow.svg","material-ray-start-end":"material/ray-start-end.svg","material-ray-start-vertex-end":"material/ray-start-vertex-end.svg","material-ray-start":"material/ray-start.svg","material-ray-vertex":"material/ray-vertex.svg","material-razor-double-edge":"material/razor-double-edge.svg","material-razor-single-edge":"material/razor-single-edge.svg","material-react":"material/react.svg","material-read":"material/read.svg","material-receipt-outline":"material/receipt-outline.svg","material-receipt-text-check-outline":"material/receipt-text-check-outline.svg","material-receipt-text-check":"material/receipt-text-check.svg","material-receipt-text-minus-outline":"material/receipt-text-minus-outline.svg","material-receipt-text-minus":"material/receipt-text-minus.svg","material-receipt-text-outline":"material/receipt-text-outline.svg","material-receipt-text-plus-outline":"material/receipt-text-plus-outline.svg","material-receipt-text-plus":"material/receipt-text-plus.svg","material-receipt-text-remove-outline":"material/receipt-text-remove-outline.svg","material-receipt-text-remove":"material/receipt-text-remove.svg","material-receipt-text":"material/receipt-text.svg","material-receipt":"material/receipt.svg","material-record-circle-outline":"material/record-circle-outline.svg","material-record-circle":"material/record-circle.svg","material-record-player":"material/record-player.svg","material-record-rec":"material/record-rec.svg","material-record":"material/record.svg","material-rectangle-outline":"material/rectangle-outline.svg","material-rectangle":"material/rectangle.svg","material-recycle-variant":"material/recycle-variant.svg","material-recycle":"material/recycle.svg","material-reddit":"material/reddit.svg","material-redhat":"material/redhat.svg","material-redo-variant":"material/redo-variant.svg","material-redo":"material/redo.svg","material-reflect-horizontal":"material/reflect-horizontal.svg","material-reflect-vertical":"material/reflect-vertical.svg","material-refresh-auto":"material/refresh-auto.svg","material-refresh-circle":"material/refresh-circle.svg","material-refresh":"material/refresh.svg","material-regex":"material/regex.svg","material-registered-trademark":"material/registered-trademark.svg","material-reiterate":"material/reiterate.svg","material-relation-many-to-many":"material/relation-many-to-many.svg","material-relation-many-to-one-or-many":"material/relation-many-to-one-or-many.svg","material-relation-many-to-one":"material/relation-many-to-one.svg","material-relation-many-to-only-one":"material/relation-many-to-only-one.svg","material-relation-many-to-zero-or-many":"material/relation-many-to-zero-or-many.svg","material-relation-many-to-zero-or-one":"material/relation-many-to-zero-or-one.svg","material-relation-one-or-many-to-many":"material/relation-one-or-many-to-many.svg","material-relation-one-or-many-to-one-or-many":"material/relation-one-or-many-to-one-or-many.svg","material-relation-one-or-many-to-one":"material/relation-one-or-many-to-one.svg","material-relation-one-or-many-to-only-one":"material/relation-one-or-many-to-only-one.svg","material-relation-one-or-many-to-zero-or-many":"material/relation-one-or-many-to-zero-or-many.svg","material-relation-one-or-many-to-zero-or-one":"material/relation-one-or-many-to-zero-or-one.svg","material-relation-one-to-many":"material/relation-one-to-many.svg","material-relation-one-to-one-or-many":"material/relation-one-to-one-or-many.svg","material-relation-one-to-one":"material/relation-one-to-one.svg","material-relation-one-to-only-one":"material/relation-one-to-only-one.svg","material-relation-one-to-zero-or-many":"material/relation-one-to-zero-or-many.svg","material-relation-one-to-zero-or-one":"material/relation-one-to-zero-or-one.svg","material-relation-only-one-to-many":"material/relation-only-one-to-many.svg","material-relation-only-one-to-one-or-many":"material/relation-only-one-to-one-or-many.svg","material-relation-only-one-to-one":"material/relation-only-one-to-one.svg","material-relation-only-one-to-only-one":"material/relation-only-one-to-only-one.svg","material-relation-only-one-to-zero-or-many":"material/relation-only-one-to-zero-or-many.svg","material-relation-only-one-to-zero-or-one":"material/relation-only-one-to-zero-or-one.svg","material-relation-zero-or-many-to-many":"material/relation-zero-or-many-to-many.svg","material-relation-zero-or-many-to-one-or-many":"material/relation-zero-or-many-to-one-or-many.svg","material-relation-zero-or-many-to-one":"material/relation-zero-or-many-to-one.svg","material-relation-zero-or-many-to-only-one":"material/relation-zero-or-many-to-only-one.svg","material-relation-zero-or-many-to-zero-or-many":"material/relation-zero-or-many-to-zero-or-many.svg","material-relation-zero-or-many-to-zero-or-one":"material/relation-zero-or-many-to-zero-or-one.svg","material-relation-zero-or-one-to-many":"material/relation-zero-or-one-to-many.svg","material-relation-zero-or-one-to-one-or-many":"material/relation-zero-or-one-to-one-or-many.svg","material-relation-zero-or-one-to-one":"material/relation-zero-or-one-to-one.svg","material-relation-zero-or-one-to-only-one":"material/relation-zero-or-one-to-only-one.svg","material-relation-zero-or-one-to-zero-or-many":"material/relation-zero-or-one-to-zero-or-many.svg","material-relation-zero-or-one-to-zero-or-one":"material/relation-zero-or-one-to-zero-or-one.svg","material-relative-scale":"material/relative-scale.svg","material-reload-alert":"material/reload-alert.svg","material-reload":"material/reload.svg","material-reminder":"material/reminder.svg","material-remote-desktop":"material/remote-desktop.svg","material-remote-off":"material/remote-off.svg","material-remote-tv-off":"material/remote-tv-off.svg","material-remote-tv":"material/remote-tv.svg","material-remote":"material/remote.svg","material-rename-box":"material/rename-box.svg","material-reorder-horizontal":"material/reorder-horizontal.svg","material-reorder-vertical":"material/reorder-vertical.svg","material-repeat-off":"material/repeat-off.svg","material-repeat-once":"material/repeat-once.svg","material-repeat-variant":"material/repeat-variant.svg","material-repeat":"material/repeat.svg","material-replay":"material/replay.svg","material-reply-all-outline":"material/reply-all-outline.svg","material-reply-all":"material/reply-all.svg","material-reply-circle":"material/reply-circle.svg","material-reply-outline":"material/reply-outline.svg","material-reply":"material/reply.svg","material-reproduction":"material/reproduction.svg","material-resistor-nodes":"material/resistor-nodes.svg","material-resistor":"material/resistor.svg","material-resize-bottom-right":"material/resize-bottom-right.svg","material-resize":"material/resize.svg","material-responsive":"material/responsive.svg","material-restart-alert":"material/restart-alert.svg","material-restart-off":"material/restart-off.svg","material-restart":"material/restart.svg","material-restore-alert":"material/restore-alert.svg","material-restore":"material/restore.svg","material-rewind-10":"material/rewind-10.svg","material-rewind-15":"material/rewind-15.svg","material-rewind-30":"material/rewind-30.svg","material-rewind-45":"material/rewind-45.svg","material-rewind-5":"material/rewind-5.svg","material-rewind-60":"material/rewind-60.svg","material-rewind-outline":"material/rewind-outline.svg","material-rewind":"material/rewind.svg","material-rhombus-medium-outline":"material/rhombus-medium-outline.svg","material-rhombus-medium":"material/rhombus-medium.svg","material-rhombus-outline":"material/rhombus-outline.svg","material-rhombus-split-outline":"material/rhombus-split-outline.svg","material-rhombus-split":"material/rhombus-split.svg","material-rhombus":"material/rhombus.svg","material-ribbon":"material/ribbon.svg","material-rice":"material/rice.svg","material-rickshaw-electric":"material/rickshaw-electric.svg","material-rickshaw":"material/rickshaw.svg","material-ring":"material/ring.svg","material-rivet":"material/rivet.svg","material-road-variant":"material/road-variant.svg","material-road":"material/road.svg","material-robber":"material/robber.svg","material-robot-angry-outline":"material/robot-angry-outline.svg","material-robot-angry":"material/robot-angry.svg","material-robot-confused-outline":"material/robot-confused-outline.svg","material-robot-confused":"material/robot-confused.svg","material-robot-dead-outline":"material/robot-dead-outline.svg","material-robot-dead":"material/robot-dead.svg","material-robot-excited-outline":"material/robot-excited-outline.svg","material-robot-excited":"material/robot-excited.svg","material-robot-happy-outline":"material/robot-happy-outline.svg","material-robot-happy":"material/robot-happy.svg","material-robot-industrial-outline":"material/robot-industrial-outline.svg","material-robot-industrial":"material/robot-industrial.svg","material-robot-love-outline":"material/robot-love-outline.svg","material-robot-love":"material/robot-love.svg","material-robot-mower-outline":"material/robot-mower-outline.svg","material-robot-mower":"material/robot-mower.svg","material-robot-off-outline":"material/robot-off-outline.svg","material-robot-off":"material/robot-off.svg","material-robot-outline":"material/robot-outline.svg","material-robot-vacuum-alert":"material/robot-vacuum-alert.svg","material-robot-vacuum-variant-alert":"material/robot-vacuum-variant-alert.svg","material-robot-vacuum-variant":"material/robot-vacuum-variant.svg","material-robot-vacuum":"material/robot-vacuum.svg","material-robot":"material/robot.svg","material-rocket-launch-outline":"material/rocket-launch-outline.svg","material-rocket-launch":"material/rocket-launch.svg","material-rocket-outline":"material/rocket-outline.svg","material-rocket":"material/rocket.svg","material-rodent":"material/rodent.svg","material-roller-shade-closed":"material/roller-shade-closed.svg","material-roller-shade":"material/roller-shade.svg","material-roller-skate-off":"material/roller-skate-off.svg","material-roller-skate":"material/roller-skate.svg","material-rollerblade-off":"material/rollerblade-off.svg","material-rollerblade":"material/rollerblade.svg","material-rollupjs":"material/rollupjs.svg","material-rolodex-outline":"material/rolodex-outline.svg","material-rolodex":"material/rolodex.svg","material-roman-numeral-1":"material/roman-numeral-1.svg","material-roman-numeral-10":"material/roman-numeral-10.svg","material-roman-numeral-2":"material/roman-numeral-2.svg","material-roman-numeral-3":"material/roman-numeral-3.svg","material-roman-numeral-4":"material/roman-numeral-4.svg","material-roman-numeral-5":"material/roman-numeral-5.svg","material-roman-numeral-6":"material/roman-numeral-6.svg","material-roman-numeral-7":"material/roman-numeral-7.svg","material-roman-numeral-8":"material/roman-numeral-8.svg","material-roman-numeral-9":"material/roman-numeral-9.svg","material-room-service-outline":"material/room-service-outline.svg","material-room-service":"material/room-service.svg","material-rotate-360":"material/rotate-360.svg","material-rotate-3d-variant":"material/rotate-3d-variant.svg","material-rotate-3d":"material/rotate-3d.svg","material-rotate-left-variant":"material/rotate-left-variant.svg","material-rotate-left":"material/rotate-left.svg","material-rotate-orbit":"material/rotate-orbit.svg","material-rotate-right-variant":"material/rotate-right-variant.svg","material-rotate-right":"material/rotate-right.svg","material-rounded-corner":"material/rounded-corner.svg","material-router-network":"material/router-network.svg","material-router-wireless-off":"material/router-wireless-off.svg","material-router-wireless-settings":"material/router-wireless-settings.svg","material-router-wireless":"material/router-wireless.svg","material-router":"material/router.svg","material-routes-clock":"material/routes-clock.svg","material-routes":"material/routes.svg","material-rowing":"material/rowing.svg","material-rss-box":"material/rss-box.svg","material-rss-off":"material/rss-off.svg","material-rss":"material/rss.svg","material-rug":"material/rug.svg","material-rugby":"material/rugby.svg","material-ruler-square-compass":"material/ruler-square-compass.svg","material-ruler-square":"material/ruler-square.svg","material-ruler":"material/ruler.svg","material-run-fast":"material/run-fast.svg","material-run":"material/run.svg","material-rv-truck":"material/rv-truck.svg","material-sack-percent":"material/sack-percent.svg","material-sack":"material/sack.svg","material-safe-square-outline":"material/safe-square-outline.svg","material-safe-square":"material/safe-square.svg","material-safe":"material/safe.svg","material-safety-goggles":"material/safety-goggles.svg","material-sail-boat-sink":"material/sail-boat-sink.svg","material-sail-boat":"material/sail-boat.svg","material-sale-outline":"material/sale-outline.svg","material-sale":"material/sale.svg","material-salesforce":"material/salesforce.svg","material-sass":"material/sass.svg","material-satellite-uplink":"material/satellite-uplink.svg","material-satellite-variant":"material/satellite-variant.svg","material-satellite":"material/satellite.svg","material-sausage-off":"material/sausage-off.svg","material-sausage":"material/sausage.svg","material-saw-blade":"material/saw-blade.svg","material-sawtooth-wave":"material/sawtooth-wave.svg","material-saxophone":"material/saxophone.svg","material-scale-balance":"material/scale-balance.svg","material-scale-bathroom":"material/scale-bathroom.svg","material-scale-off":"material/scale-off.svg","material-scale-unbalanced":"material/scale-unbalanced.svg","material-scale":"material/scale.svg","material-scan-helper":"material/scan-helper.svg","material-scanner-off":"material/scanner-off.svg","material-scanner":"material/scanner.svg","material-scatter-plot-outline":"material/scatter-plot-outline.svg","material-scatter-plot":"material/scatter-plot.svg","material-scent-off":"material/scent-off.svg","material-scent":"material/scent.svg","material-school-outline":"material/school-outline.svg","material-school":"material/school.svg","material-scissors-cutting":"material/scissors-cutting.svg","material-scooter-electric":"material/scooter-electric.svg","material-scooter":"material/scooter.svg","material-scoreboard-outline":"material/scoreboard-outline.svg","material-scoreboard":"material/scoreboard.svg","material-screen-rotation-lock":"material/screen-rotation-lock.svg","material-screen-rotation":"material/screen-rotation.svg","material-screw-flat-top":"material/screw-flat-top.svg","material-screw-lag":"material/screw-lag.svg","material-screw-machine-flat-top":"material/screw-machine-flat-top.svg","material-screw-machine-round-top":"material/screw-machine-round-top.svg","material-screw-round-top":"material/screw-round-top.svg","material-screwdriver":"material/screwdriver.svg","material-script-outline":"material/script-outline.svg","material-script-text-key-outline":"material/script-text-key-outline.svg","material-script-text-key":"material/script-text-key.svg","material-script-text-outline":"material/script-text-outline.svg","material-script-text-play-outline":"material/script-text-play-outline.svg","material-script-text-play":"material/script-text-play.svg","material-script-text":"material/script-text.svg","material-script":"material/script.svg","material-sd":"material/sd.svg","material-seal-variant":"material/seal-variant.svg","material-seal":"material/seal.svg","material-search-web":"material/search-web.svg","material-seat-flat-angled":"material/seat-flat-angled.svg","material-seat-flat":"material/seat-flat.svg","material-seat-individual-suite":"material/seat-individual-suite.svg","material-seat-legroom-extra":"material/seat-legroom-extra.svg","material-seat-legroom-normal":"material/seat-legroom-normal.svg","material-seat-legroom-reduced":"material/seat-legroom-reduced.svg","material-seat-outline":"material/seat-outline.svg","material-seat-passenger":"material/seat-passenger.svg","material-seat-recline-extra":"material/seat-recline-extra.svg","material-seat-recline-normal":"material/seat-recline-normal.svg","material-seat":"material/seat.svg","material-seatbelt":"material/seatbelt.svg","material-security-network":"material/security-network.svg","material-security":"material/security.svg","material-seed-off-outline":"material/seed-off-outline.svg","material-seed-off":"material/seed-off.svg","material-seed-outline":"material/seed-outline.svg","material-seed-plus-outline":"material/seed-plus-outline.svg","material-seed-plus":"material/seed-plus.svg","material-seed":"material/seed.svg","material-seesaw":"material/seesaw.svg","material-segment":"material/segment.svg","material-select-all":"material/select-all.svg","material-select-arrow-down":"material/select-arrow-down.svg","material-select-arrow-up":"material/select-arrow-up.svg","material-select-color":"material/select-color.svg","material-select-compare":"material/select-compare.svg","material-select-drag":"material/select-drag.svg","material-select-group":"material/select-group.svg","material-select-inverse":"material/select-inverse.svg","material-select-marker":"material/select-marker.svg","material-select-multiple-marker":"material/select-multiple-marker.svg","material-select-multiple":"material/select-multiple.svg","material-select-off":"material/select-off.svg","material-select-place":"material/select-place.svg","material-select-remove":"material/select-remove.svg","material-select-search":"material/select-search.svg","material-select":"material/select.svg","material-selection-drag":"material/selection-drag.svg","material-selection-ellipse-arrow-inside":"material/selection-ellipse-arrow-inside.svg","material-selection-ellipse-remove":"material/selection-ellipse-remove.svg","material-selection-ellipse":"material/selection-ellipse.svg","material-selection-marker":"material/selection-marker.svg","material-selection-multiple-marker":"material/selection-multiple-marker.svg","material-selection-multiple":"material/selection-multiple.svg","material-selection-off":"material/selection-off.svg","material-selection-remove":"material/selection-remove.svg","material-selection-search":"material/selection-search.svg","material-selection":"material/selection.svg","material-semantic-web":"material/semantic-web.svg","material-send-check-outline":"material/send-check-outline.svg","material-send-check":"material/send-check.svg","material-send-circle-outline":"material/send-circle-outline.svg","material-send-circle":"material/send-circle.svg","material-send-clock-outline":"material/send-clock-outline.svg","material-send-clock":"material/send-clock.svg","material-send-lock-outline":"material/send-lock-outline.svg","material-send-lock":"material/send-lock.svg","material-send-outline":"material/send-outline.svg","material-send":"material/send.svg","material-serial-port":"material/serial-port.svg","material-server-minus":"material/server-minus.svg","material-server-network-off":"material/server-network-off.svg","material-server-network":"material/server-network.svg","material-server-off":"material/server-off.svg","material-server-plus":"material/server-plus.svg","material-server-remove":"material/server-remove.svg","material-server-security":"material/server-security.svg","material-server":"material/server.svg","material-set-all":"material/set-all.svg","material-set-center-right":"material/set-center-right.svg","material-set-center":"material/set-center.svg","material-set-left-center":"material/set-left-center.svg","material-set-left-right":"material/set-left-right.svg","material-set-left":"material/set-left.svg","material-set-merge":"material/set-merge.svg","material-set-none":"material/set-none.svg","material-set-right":"material/set-right.svg","material-set-split":"material/set-split.svg","material-set-square":"material/set-square.svg","material-set-top-box":"material/set-top-box.svg","material-settings-helper":"material/settings-helper.svg","material-shaker-outline":"material/shaker-outline.svg","material-shaker":"material/shaker.svg","material-shape-circle-plus":"material/shape-circle-plus.svg","material-shape-outline":"material/shape-outline.svg","material-shape-oval-plus":"material/shape-oval-plus.svg","material-shape-plus":"material/shape-plus.svg","material-shape-polygon-plus":"material/shape-polygon-plus.svg","material-shape-rectangle-plus":"material/shape-rectangle-plus.svg","material-shape-square-plus":"material/shape-square-plus.svg","material-shape-square-rounded-plus":"material/shape-square-rounded-plus.svg","material-shape":"material/shape.svg","material-share-all-outline":"material/share-all-outline.svg","material-share-all":"material/share-all.svg","material-share-circle":"material/share-circle.svg","material-share-off-outline":"material/share-off-outline.svg","material-share-off":"material/share-off.svg","material-share-outline":"material/share-outline.svg","material-share-variant-outline":"material/share-variant-outline.svg","material-share-variant":"material/share-variant.svg","material-share":"material/share.svg","material-shark-fin-outline":"material/shark-fin-outline.svg","material-shark-fin":"material/shark-fin.svg","material-shark-off":"material/shark-off.svg","material-shark":"material/shark.svg","material-sheep":"material/sheep.svg","material-shield-account-outline":"material/shield-account-outline.svg","material-shield-account-variant-outline":"material/shield-account-variant-outline.svg","material-shield-account-variant":"material/shield-account-variant.svg","material-shield-account":"material/shield-account.svg","material-shield-airplane-outline":"material/shield-airplane-outline.svg","material-shield-airplane":"material/shield-airplane.svg","material-shield-alert-outline":"material/shield-alert-outline.svg","material-shield-alert":"material/shield-alert.svg","material-shield-bug-outline":"material/shield-bug-outline.svg","material-shield-bug":"material/shield-bug.svg","material-shield-car":"material/shield-car.svg","material-shield-check-outline":"material/shield-check-outline.svg","material-shield-check":"material/shield-check.svg","material-shield-cross-outline":"material/shield-cross-outline.svg","material-shield-cross":"material/shield-cross.svg","material-shield-crown-outline":"material/shield-crown-outline.svg","material-shield-crown":"material/shield-crown.svg","material-shield-edit-outline":"material/shield-edit-outline.svg","material-shield-edit":"material/shield-edit.svg","material-shield-half-full":"material/shield-half-full.svg","material-shield-half":"material/shield-half.svg","material-shield-home-outline":"material/shield-home-outline.svg","material-shield-home":"material/shield-home.svg","material-shield-key-outline":"material/shield-key-outline.svg","material-shield-key":"material/shield-key.svg","material-shield-link-variant-outline":"material/shield-link-variant-outline.svg","material-shield-link-variant":"material/shield-link-variant.svg","material-shield-lock-open-outline":"material/shield-lock-open-outline.svg","material-shield-lock-open":"material/shield-lock-open.svg","material-shield-lock-outline":"material/shield-lock-outline.svg","material-shield-lock":"material/shield-lock.svg","material-shield-moon-outline":"material/shield-moon-outline.svg","material-shield-moon":"material/shield-moon.svg","material-shield-off-outline":"material/shield-off-outline.svg","material-shield-off":"material/shield-off.svg","material-shield-outline":"material/shield-outline.svg","material-shield-plus-outline":"material/shield-plus-outline.svg","material-shield-plus":"material/shield-plus.svg","material-shield-refresh-outline":"material/shield-refresh-outline.svg","material-shield-refresh":"material/shield-refresh.svg","material-shield-remove-outline":"material/shield-remove-outline.svg","material-shield-remove":"material/shield-remove.svg","material-shield-search":"material/shield-search.svg","material-shield-star-outline":"material/shield-star-outline.svg","material-shield-star":"material/shield-star.svg","material-shield-sun-outline":"material/shield-sun-outline.svg","material-shield-sun":"material/shield-sun.svg","material-shield-sword-outline":"material/shield-sword-outline.svg","material-shield-sword":"material/shield-sword.svg","material-shield-sync-outline":"material/shield-sync-outline.svg","material-shield-sync":"material/shield-sync.svg","material-shield":"material/shield.svg","material-shimmer":"material/shimmer.svg","material-ship-wheel":"material/ship-wheel.svg","material-shipping-pallet":"material/shipping-pallet.svg","material-shoe-ballet":"material/shoe-ballet.svg","material-shoe-cleat":"material/shoe-cleat.svg","material-shoe-formal":"material/shoe-formal.svg","material-shoe-heel":"material/shoe-heel.svg","material-shoe-print":"material/shoe-print.svg","material-shoe-sneaker":"material/shoe-sneaker.svg","material-shopping-music":"material/shopping-music.svg","material-shopping-outline":"material/shopping-outline.svg","material-shopping-search-outline":"material/shopping-search-outline.svg","material-shopping-search":"material/shopping-search.svg","material-shopping":"material/shopping.svg","material-shore":"material/shore.svg","material-shovel-off":"material/shovel-off.svg","material-shovel":"material/shovel.svg","material-shower-head":"material/shower-head.svg","material-shower":"material/shower.svg","material-shredder":"material/shredder.svg","material-shuffle-disabled":"material/shuffle-disabled.svg","material-shuffle-variant":"material/shuffle-variant.svg","material-shuffle":"material/shuffle.svg","material-shuriken":"material/shuriken.svg","material-sickle":"material/sickle.svg","material-sigma-lower":"material/sigma-lower.svg","material-sigma":"material/sigma.svg","material-sign-caution":"material/sign-caution.svg","material-sign-direction-minus":"material/sign-direction-minus.svg","material-sign-direction-plus":"material/sign-direction-plus.svg","material-sign-direction-remove":"material/sign-direction-remove.svg","material-sign-direction":"material/sign-direction.svg","material-sign-language-outline":"material/sign-language-outline.svg","material-sign-language":"material/sign-language.svg","material-sign-pole":"material/sign-pole.svg","material-sign-real-estate":"material/sign-real-estate.svg","material-sign-text":"material/sign-text.svg","material-sign-yield":"material/sign-yield.svg","material-signal-2g":"material/signal-2g.svg","material-signal-3g":"material/signal-3g.svg","material-signal-4g":"material/signal-4g.svg","material-signal-5g":"material/signal-5g.svg","material-signal-cellular-1":"material/signal-cellular-1.svg","material-signal-cellular-2":"material/signal-cellular-2.svg","material-signal-cellular-3":"material/signal-cellular-3.svg","material-signal-cellular-outline":"material/signal-cellular-outline.svg","material-signal-distance-variant":"material/signal-distance-variant.svg","material-signal-hspa-plus":"material/signal-hspa-plus.svg","material-signal-hspa":"material/signal-hspa.svg","material-signal-off":"material/signal-off.svg","material-signal-variant":"material/signal-variant.svg","material-signal":"material/signal.svg","material-signature-freehand":"material/signature-freehand.svg","material-signature-image":"material/signature-image.svg","material-signature-text":"material/signature-text.svg","material-signature":"material/signature.svg","material-silo-outline":"material/silo-outline.svg","material-silo":"material/silo.svg","material-silverware-clean":"material/silverware-clean.svg","material-silverware-fork-knife":"material/silverware-fork-knife.svg","material-silverware-fork":"material/silverware-fork.svg","material-silverware-spoon":"material/silverware-spoon.svg","material-silverware-variant":"material/silverware-variant.svg","material-silverware":"material/silverware.svg","material-sim-alert-outline":"material/sim-alert-outline.svg","material-sim-alert":"material/sim-alert.svg","material-sim-off-outline":"material/sim-off-outline.svg","material-sim-off":"material/sim-off.svg","material-sim-outline":"material/sim-outline.svg","material-sim":"material/sim.svg","material-simple-icons":"material/simple-icons.svg","material-sina-weibo":"material/sina-weibo.svg","material-sine-wave":"material/sine-wave.svg","material-sitemap-outline":"material/sitemap-outline.svg","material-sitemap":"material/sitemap.svg","material-size-l":"material/size-l.svg","material-size-m":"material/size-m.svg","material-size-s":"material/size-s.svg","material-size-xl":"material/size-xl.svg","material-size-xs":"material/size-xs.svg","material-size-xxl":"material/size-xxl.svg","material-size-xxs":"material/size-xxs.svg","material-size-xxxl":"material/size-xxxl.svg","material-skate-off":"material/skate-off.svg","material-skate":"material/skate.svg","material-skateboard":"material/skateboard.svg","material-skateboarding":"material/skateboarding.svg","material-skew-less":"material/skew-less.svg","material-skew-more":"material/skew-more.svg","material-ski-cross-country":"material/ski-cross-country.svg","material-ski-water":"material/ski-water.svg","material-ski":"material/ski.svg","material-skip-backward-outline":"material/skip-backward-outline.svg","material-skip-backward":"material/skip-backward.svg","material-skip-forward-outline":"material/skip-forward-outline.svg","material-skip-forward":"material/skip-forward.svg","material-skip-next-circle-outline":"material/skip-next-circle-outline.svg","material-skip-next-circle":"material/skip-next-circle.svg","material-skip-next-outline":"material/skip-next-outline.svg","material-skip-next":"material/skip-next.svg","material-skip-previous-circle-outline":"material/skip-previous-circle-outline.svg","material-skip-previous-circle":"material/skip-previous-circle.svg","material-skip-previous-outline":"material/skip-previous-outline.svg","material-skip-previous":"material/skip-previous.svg","material-skull-crossbones-outline":"material/skull-crossbones-outline.svg","material-skull-crossbones":"material/skull-crossbones.svg","material-skull-outline":"material/skull-outline.svg","material-skull-scan-outline":"material/skull-scan-outline.svg","material-skull-scan":"material/skull-scan.svg","material-skull":"material/skull.svg","material-skype-business":"material/skype-business.svg","material-skype":"material/skype.svg","material-slack":"material/slack.svg","material-slash-forward-box":"material/slash-forward-box.svg","material-slash-forward":"material/slash-forward.svg","material-sledding":"material/sledding.svg","material-sleep-off":"material/sleep-off.svg","material-sleep":"material/sleep.svg","material-slide":"material/slide.svg","material-slope-downhill":"material/slope-downhill.svg","material-slope-uphill":"material/slope-uphill.svg","material-slot-machine-outline":"material/slot-machine-outline.svg","material-slot-machine":"material/slot-machine.svg","material-smart-card-off-outline":"material/smart-card-off-outline.svg","material-smart-card-off":"material/smart-card-off.svg","material-smart-card-outline":"material/smart-card-outline.svg","material-smart-card-reader-outline":"material/smart-card-reader-outline.svg","material-smart-card-reader":"material/smart-card-reader.svg","material-smart-card":"material/smart-card.svg","material-smog":"material/smog.svg","material-smoke-detector-alert-outline":"material/smoke-detector-alert-outline.svg","material-smoke-detector-alert":"material/smoke-detector-alert.svg","material-smoke-detector-off-outline":"material/smoke-detector-off-outline.svg","material-smoke-detector-off":"material/smoke-detector-off.svg","material-smoke-detector-outline":"material/smoke-detector-outline.svg","material-smoke-detector-variant-alert":"material/smoke-detector-variant-alert.svg","material-smoke-detector-variant-off":"material/smoke-detector-variant-off.svg","material-smoke-detector-variant":"material/smoke-detector-variant.svg","material-smoke-detector":"material/smoke-detector.svg","material-smoke":"material/smoke.svg","material-smoking-off":"material/smoking-off.svg","material-smoking-pipe-off":"material/smoking-pipe-off.svg","material-smoking-pipe":"material/smoking-pipe.svg","material-smoking":"material/smoking.svg","material-snail":"material/snail.svg","material-snake":"material/snake.svg","material-snapchat":"material/snapchat.svg","material-snowboard":"material/snowboard.svg","material-snowflake-alert":"material/snowflake-alert.svg","material-snowflake-check":"material/snowflake-check.svg","material-snowflake-melt":"material/snowflake-melt.svg","material-snowflake-off":"material/snowflake-off.svg","material-snowflake-thermometer":"material/snowflake-thermometer.svg","material-snowflake-variant":"material/snowflake-variant.svg","material-snowflake":"material/snowflake.svg","material-snowman":"material/snowman.svg","material-snowmobile":"material/snowmobile.svg","material-snowshoeing":"material/snowshoeing.svg","material-soccer-field":"material/soccer-field.svg","material-soccer":"material/soccer.svg","material-social-distance-2-meters":"material/social-distance-2-meters.svg","material-social-distance-6-feet":"material/social-distance-6-feet.svg","material-sofa-outline":"material/sofa-outline.svg","material-sofa-single-outline":"material/sofa-single-outline.svg","material-sofa-single":"material/sofa-single.svg","material-sofa":"material/sofa.svg","material-solar-panel-large":"material/solar-panel-large.svg","material-solar-panel":"material/solar-panel.svg","material-solar-power-variant-outline":"material/solar-power-variant-outline.svg","material-solar-power-variant":"material/solar-power-variant.svg","material-solar-power":"material/solar-power.svg","material-soldering-iron":"material/soldering-iron.svg","material-solid":"material/solid.svg","material-sony-playstation":"material/sony-playstation.svg","material-sort-alphabetical-ascending-variant":"material/sort-alphabetical-ascending-variant.svg","material-sort-alphabetical-ascending":"material/sort-alphabetical-ascending.svg","material-sort-alphabetical-descending-variant":"material/sort-alphabetical-descending-variant.svg","material-sort-alphabetical-descending":"material/sort-alphabetical-descending.svg","material-sort-alphabetical-variant":"material/sort-alphabetical-variant.svg","material-sort-ascending":"material/sort-ascending.svg","material-sort-bool-ascending-variant":"material/sort-bool-ascending-variant.svg","material-sort-bool-ascending":"material/sort-bool-ascending.svg","material-sort-bool-descending-variant":"material/sort-bool-descending-variant.svg","material-sort-bool-descending":"material/sort-bool-descending.svg","material-sort-calendar-ascending":"material/sort-calendar-ascending.svg","material-sort-calendar-descending":"material/sort-calendar-descending.svg","material-sort-clock-ascending-outline":"material/sort-clock-ascending-outline.svg","material-sort-clock-ascending":"material/sort-clock-ascending.svg","material-sort-clock-descending-outline":"material/sort-clock-descending-outline.svg","material-sort-clock-descending":"material/sort-clock-descending.svg","material-sort-descending":"material/sort-descending.svg","material-sort-numeric-ascending-variant":"material/sort-numeric-ascending-variant.svg","material-sort-numeric-ascending":"material/sort-numeric-ascending.svg","material-sort-numeric-descending-variant":"material/sort-numeric-descending-variant.svg","material-sort-numeric-descending":"material/sort-numeric-descending.svg","material-sort-numeric-variant":"material/sort-numeric-variant.svg","material-sort-reverse-variant":"material/sort-reverse-variant.svg","material-sort-variant-lock-open":"material/sort-variant-lock-open.svg","material-sort-variant-lock":"material/sort-variant-lock.svg","material-sort-variant-off":"material/sort-variant-off.svg","material-sort-variant-remove":"material/sort-variant-remove.svg","material-sort-variant":"material/sort-variant.svg","material-sort":"material/sort.svg","material-soundbar":"material/soundbar.svg","material-soundcloud":"material/soundcloud.svg","material-source-branch-check":"material/source-branch-check.svg","material-source-branch-minus":"material/source-branch-minus.svg","material-source-branch-plus":"material/source-branch-plus.svg","material-source-branch-refresh":"material/source-branch-refresh.svg","material-source-branch-remove":"material/source-branch-remove.svg","material-source-branch-sync":"material/source-branch-sync.svg","material-source-branch":"material/source-branch.svg","material-source-commit-end-local":"material/source-commit-end-local.svg","material-source-commit-end":"material/source-commit-end.svg","material-source-commit-local":"material/source-commit-local.svg","material-source-commit-next-local":"material/source-commit-next-local.svg","material-source-commit-start-next-local":"material/source-commit-start-next-local.svg","material-source-commit-start":"material/source-commit-start.svg","material-source-commit":"material/source-commit.svg","material-source-fork":"material/source-fork.svg","material-source-merge":"material/source-merge.svg","material-source-pull":"material/source-pull.svg","material-source-repository-multiple":"material/source-repository-multiple.svg","material-source-repository":"material/source-repository.svg","material-soy-sauce-off":"material/soy-sauce-off.svg","material-soy-sauce":"material/soy-sauce.svg","material-spa-outline":"material/spa-outline.svg","material-spa":"material/spa.svg","material-space-invaders":"material/space-invaders.svg","material-space-station":"material/space-station.svg","material-spade":"material/spade.svg","material-speaker-bluetooth":"material/speaker-bluetooth.svg","material-speaker-message":"material/speaker-message.svg","material-speaker-multiple":"material/speaker-multiple.svg","material-speaker-off":"material/speaker-off.svg","material-speaker-pause":"material/speaker-pause.svg","material-speaker-play":"material/speaker-play.svg","material-speaker-stop":"material/speaker-stop.svg","material-speaker-wireless":"material/speaker-wireless.svg","material-speaker":"material/speaker.svg","material-spear":"material/spear.svg","material-speedometer-medium":"material/speedometer-medium.svg","material-speedometer-slow":"material/speedometer-slow.svg","material-speedometer":"material/speedometer.svg","material-spellcheck":"material/spellcheck.svg","material-sphere-off":"material/sphere-off.svg","material-sphere":"material/sphere.svg","material-spider-thread":"material/spider-thread.svg","material-spider-web":"material/spider-web.svg","material-spider":"material/spider.svg","material-spirit-level":"material/spirit-level.svg","material-spoon-sugar":"material/spoon-sugar.svg","material-spotify":"material/spotify.svg","material-spotlight-beam":"material/spotlight-beam.svg","material-spotlight":"material/spotlight.svg","material-spray-bottle":"material/spray-bottle.svg","material-spray":"material/spray.svg","material-sprinkler-fire":"material/sprinkler-fire.svg","material-sprinkler-variant":"material/sprinkler-variant.svg","material-sprinkler":"material/sprinkler.svg","material-sprout-outline":"material/sprout-outline.svg","material-sprout":"material/sprout.svg","material-square-circle":"material/square-circle.svg","material-square-edit-outline":"material/square-edit-outline.svg","material-square-medium-outline":"material/square-medium-outline.svg","material-square-medium":"material/square-medium.svg","material-square-off-outline":"material/square-off-outline.svg","material-square-off":"material/square-off.svg","material-square-opacity":"material/square-opacity.svg","material-square-outline":"material/square-outline.svg","material-square-root-box":"material/square-root-box.svg","material-square-root":"material/square-root.svg","material-square-rounded-badge-outline":"material/square-rounded-badge-outline.svg","material-square-rounded-badge":"material/square-rounded-badge.svg","material-square-rounded-outline":"material/square-rounded-outline.svg","material-square-rounded":"material/square-rounded.svg","material-square-small":"material/square-small.svg","material-square-wave":"material/square-wave.svg","material-square":"material/square.svg","material-squeegee":"material/squeegee.svg","material-ssh":"material/ssh.svg","material-stack-exchange":"material/stack-exchange.svg","material-stack-overflow":"material/stack-overflow.svg","material-stackpath":"material/stackpath.svg","material-stadium-outline":"material/stadium-outline.svg","material-stadium-variant":"material/stadium-variant.svg","material-stadium":"material/stadium.svg","material-stairs-box":"material/stairs-box.svg","material-stairs-down":"material/stairs-down.svg","material-stairs-up":"material/stairs-up.svg","material-stairs":"material/stairs.svg","material-stamper":"material/stamper.svg","material-standard-definition":"material/standard-definition.svg","material-star-box-multiple-outline":"material/star-box-multiple-outline.svg","material-star-box-multiple":"material/star-box-multiple.svg","material-star-box-outline":"material/star-box-outline.svg","material-star-box":"material/star-box.svg","material-star-check-outline":"material/star-check-outline.svg","material-star-check":"material/star-check.svg","material-star-circle-outline":"material/star-circle-outline.svg","material-star-circle":"material/star-circle.svg","material-star-cog-outline":"material/star-cog-outline.svg","material-star-cog":"material/star-cog.svg","material-star-crescent":"material/star-crescent.svg","material-star-david":"material/star-david.svg","material-star-face":"material/star-face.svg","material-star-four-points-outline":"material/star-four-points-outline.svg","material-star-four-points":"material/star-four-points.svg","material-star-half-full":"material/star-half-full.svg","material-star-half":"material/star-half.svg","material-star-minus-outline":"material/star-minus-outline.svg","material-star-minus":"material/star-minus.svg","material-star-off-outline":"material/star-off-outline.svg","material-star-off":"material/star-off.svg","material-star-outline":"material/star-outline.svg","material-star-plus-outline":"material/star-plus-outline.svg","material-star-plus":"material/star-plus.svg","material-star-remove-outline":"material/star-remove-outline.svg","material-star-remove":"material/star-remove.svg","material-star-settings-outline":"material/star-settings-outline.svg","material-star-settings":"material/star-settings.svg","material-star-shooting-outline":"material/star-shooting-outline.svg","material-star-shooting":"material/star-shooting.svg","material-star-three-points-outline":"material/star-three-points-outline.svg","material-star-three-points":"material/star-three-points.svg","material-star":"material/star.svg","material-state-machine":"material/state-machine.svg","material-steam":"material/steam.svg","material-steering-off":"material/steering-off.svg","material-steering":"material/steering.svg","material-step-backward-2":"material/step-backward-2.svg","material-step-backward":"material/step-backward.svg","material-step-forward-2":"material/step-forward-2.svg","material-step-forward":"material/step-forward.svg","material-stethoscope":"material/stethoscope.svg","material-sticker-alert-outline":"material/sticker-alert-outline.svg","material-sticker-alert":"material/sticker-alert.svg","material-sticker-check-outline":"material/sticker-check-outline.svg","material-sticker-check":"material/sticker-check.svg","material-sticker-circle-outline":"material/sticker-circle-outline.svg","material-sticker-emoji":"material/sticker-emoji.svg","material-sticker-minus-outline":"material/sticker-minus-outline.svg","material-sticker-minus":"material/sticker-minus.svg","material-sticker-outline":"material/sticker-outline.svg","material-sticker-plus-outline":"material/sticker-plus-outline.svg","material-sticker-plus":"material/sticker-plus.svg","material-sticker-remove-outline":"material/sticker-remove-outline.svg","material-sticker-remove":"material/sticker-remove.svg","material-sticker-text-outline":"material/sticker-text-outline.svg","material-sticker-text":"material/sticker-text.svg","material-sticker":"material/sticker.svg","material-stocking":"material/stocking.svg","material-stomach":"material/stomach.svg","material-stool-outline":"material/stool-outline.svg","material-stool":"material/stool.svg","material-stop-circle-outline":"material/stop-circle-outline.svg","material-stop-circle":"material/stop-circle.svg","material-stop":"material/stop.svg","material-storage-tank-outline":"material/storage-tank-outline.svg","material-storage-tank":"material/storage-tank.svg","material-store-24-hour":"material/store-24-hour.svg","material-store-alert-outline":"material/store-alert-outline.svg","material-store-alert":"material/store-alert.svg","material-store-check-outline":"material/store-check-outline.svg","material-store-check":"material/store-check.svg","material-store-clock-outline":"material/store-clock-outline.svg","material-store-clock":"material/store-clock.svg","material-store-cog-outline":"material/store-cog-outline.svg","material-store-cog":"material/store-cog.svg","material-store-edit-outline":"material/store-edit-outline.svg","material-store-edit":"material/store-edit.svg","material-store-marker-outline":"material/store-marker-outline.svg","material-store-marker":"material/store-marker.svg","material-store-minus-outline":"material/store-minus-outline.svg","material-store-minus":"material/store-minus.svg","material-store-off-outline":"material/store-off-outline.svg","material-store-off":"material/store-off.svg","material-store-outline":"material/store-outline.svg","material-store-plus-outline":"material/store-plus-outline.svg","material-store-plus":"material/store-plus.svg","material-store-remove-outline":"material/store-remove-outline.svg","material-store-remove":"material/store-remove.svg","material-store-search-outline":"material/store-search-outline.svg","material-store-search":"material/store-search.svg","material-store-settings-outline":"material/store-settings-outline.svg","material-store-settings":"material/store-settings.svg","material-store":"material/store.svg","material-storefront-check-outline":"material/storefront-check-outline.svg","material-storefront-check":"material/storefront-check.svg","material-storefront-edit-outline":"material/storefront-edit-outline.svg","material-storefront-edit":"material/storefront-edit.svg","material-storefront-minus-outline":"material/storefront-minus-outline.svg","material-storefront-minus":"material/storefront-minus.svg","material-storefront-outline":"material/storefront-outline.svg","material-storefront-plus-outline":"material/storefront-plus-outline.svg","material-storefront-plus":"material/storefront-plus.svg","material-storefront-remove-outline":"material/storefront-remove-outline.svg","material-storefront-remove":"material/storefront-remove.svg","material-storefront":"material/storefront.svg","material-stove":"material/stove.svg","material-strategy":"material/strategy.svg","material-stretch-to-page-outline":"material/stretch-to-page-outline.svg","material-stretch-to-page":"material/stretch-to-page.svg","material-string-lights-off":"material/string-lights-off.svg","material-string-lights":"material/string-lights.svg","material-subdirectory-arrow-left":"material/subdirectory-arrow-left.svg","material-subdirectory-arrow-right":"material/subdirectory-arrow-right.svg","material-submarine":"material/submarine.svg","material-subtitles-outline":"material/subtitles-outline.svg","material-subtitles":"material/subtitles.svg","material-subway-alert-variant":"material/subway-alert-variant.svg","material-subway-variant":"material/subway-variant.svg","material-subway":"material/subway.svg","material-summit":"material/summit.svg","material-sun-angle-outline":"material/sun-angle-outline.svg","material-sun-angle":"material/sun-angle.svg","material-sun-clock-outline":"material/sun-clock-outline.svg","material-sun-clock":"material/sun-clock.svg","material-sun-compass":"material/sun-compass.svg","material-sun-snowflake-variant":"material/sun-snowflake-variant.svg","material-sun-snowflake":"material/sun-snowflake.svg","material-sun-thermometer-outline":"material/sun-thermometer-outline.svg","material-sun-thermometer":"material/sun-thermometer.svg","material-sun-wireless-outline":"material/sun-wireless-outline.svg","material-sun-wireless":"material/sun-wireless.svg","material-sunglasses":"material/sunglasses.svg","material-surfing":"material/surfing.svg","material-surround-sound-2-0":"material/surround-sound-2-0.svg","material-surround-sound-2-1":"material/surround-sound-2-1.svg","material-surround-sound-3-1":"material/surround-sound-3-1.svg","material-surround-sound-5-1-2":"material/surround-sound-5-1-2.svg","material-surround-sound-5-1":"material/surround-sound-5-1.svg","material-surround-sound-7-1":"material/surround-sound-7-1.svg","material-surround-sound":"material/surround-sound.svg","material-svg":"material/svg.svg","material-swap-horizontal-bold":"material/swap-horizontal-bold.svg","material-swap-horizontal-circle-outline":"material/swap-horizontal-circle-outline.svg","material-swap-horizontal-circle":"material/swap-horizontal-circle.svg","material-swap-horizontal-variant":"material/swap-horizontal-variant.svg","material-swap-horizontal":"material/swap-horizontal.svg","material-swap-vertical-bold":"material/swap-vertical-bold.svg","material-swap-vertical-circle-outline":"material/swap-vertical-circle-outline.svg","material-swap-vertical-circle":"material/swap-vertical-circle.svg","material-swap-vertical-variant":"material/swap-vertical-variant.svg","material-swap-vertical":"material/swap-vertical.svg","material-swim":"material/swim.svg","material-switch":"material/switch.svg","material-sword-cross":"material/sword-cross.svg","material-sword":"material/sword.svg","material-syllabary-hangul":"material/syllabary-hangul.svg","material-syllabary-hiragana":"material/syllabary-hiragana.svg","material-syllabary-katakana-halfwidth":"material/syllabary-katakana-halfwidth.svg","material-syllabary-katakana":"material/syllabary-katakana.svg","material-symbol":"material/symbol.svg","material-symfony":"material/symfony.svg","material-synagogue-outline":"material/synagogue-outline.svg","material-synagogue":"material/synagogue.svg","material-sync-alert":"material/sync-alert.svg","material-sync-circle":"material/sync-circle.svg","material-sync-off":"material/sync-off.svg","material-sync":"material/sync.svg","material-tab-minus":"material/tab-minus.svg","material-tab-plus":"material/tab-plus.svg","material-tab-remove":"material/tab-remove.svg","material-tab-search":"material/tab-search.svg","material-tab-unselected":"material/tab-unselected.svg","material-tab":"material/tab.svg","material-table-account":"material/table-account.svg","material-table-alert":"material/table-alert.svg","material-table-arrow-down":"material/table-arrow-down.svg","material-table-arrow-left":"material/table-arrow-left.svg","material-table-arrow-right":"material/table-arrow-right.svg","material-table-arrow-up":"material/table-arrow-up.svg","material-table-border":"material/table-border.svg","material-table-cancel":"material/table-cancel.svg","material-table-chair":"material/table-chair.svg","material-table-check":"material/table-check.svg","material-table-clock":"material/table-clock.svg","material-table-cog":"material/table-cog.svg","material-table-column-plus-after":"material/table-column-plus-after.svg","material-table-column-plus-before":"material/table-column-plus-before.svg","material-table-column-remove":"material/table-column-remove.svg","material-table-column-width":"material/table-column-width.svg","material-table-column":"material/table-column.svg","material-table-edit":"material/table-edit.svg","material-table-eye-off":"material/table-eye-off.svg","material-table-eye":"material/table-eye.svg","material-table-filter":"material/table-filter.svg","material-table-furniture":"material/table-furniture.svg","material-table-headers-eye-off":"material/table-headers-eye-off.svg","material-table-headers-eye":"material/table-headers-eye.svg","material-table-heart":"material/table-heart.svg","material-table-key":"material/table-key.svg","material-table-large-plus":"material/table-large-plus.svg","material-table-large-remove":"material/table-large-remove.svg","material-table-large":"material/table-large.svg","material-table-lock":"material/table-lock.svg","material-table-merge-cells":"material/table-merge-cells.svg","material-table-minus":"material/table-minus.svg","material-table-multiple":"material/table-multiple.svg","material-table-network":"material/table-network.svg","material-table-of-contents":"material/table-of-contents.svg","material-table-off":"material/table-off.svg","material-table-picnic":"material/table-picnic.svg","material-table-pivot":"material/table-pivot.svg","material-table-plus":"material/table-plus.svg","material-table-question":"material/table-question.svg","material-table-refresh":"material/table-refresh.svg","material-table-remove":"material/table-remove.svg","material-table-row-height":"material/table-row-height.svg","material-table-row-plus-after":"material/table-row-plus-after.svg","material-table-row-plus-before":"material/table-row-plus-before.svg","material-table-row-remove":"material/table-row-remove.svg","material-table-row":"material/table-row.svg","material-table-search":"material/table-search.svg","material-table-settings":"material/table-settings.svg","material-table-split-cell":"material/table-split-cell.svg","material-table-star":"material/table-star.svg","material-table-sync":"material/table-sync.svg","material-table-tennis":"material/table-tennis.svg","material-table":"material/table.svg","material-tablet-cellphone":"material/tablet-cellphone.svg","material-tablet-dashboard":"material/tablet-dashboard.svg","material-tablet":"material/tablet.svg","material-taco":"material/taco.svg","material-tag-arrow-down-outline":"material/tag-arrow-down-outline.svg","material-tag-arrow-down":"material/tag-arrow-down.svg","material-tag-arrow-left-outline":"material/tag-arrow-left-outline.svg","material-tag-arrow-left":"material/tag-arrow-left.svg","material-tag-arrow-right-outline":"material/tag-arrow-right-outline.svg","material-tag-arrow-right":"material/tag-arrow-right.svg","material-tag-arrow-up-outline":"material/tag-arrow-up-outline.svg","material-tag-arrow-up":"material/tag-arrow-up.svg","material-tag-check-outline":"material/tag-check-outline.svg","material-tag-check":"material/tag-check.svg","material-tag-faces":"material/tag-faces.svg","material-tag-heart-outline":"material/tag-heart-outline.svg","material-tag-heart":"material/tag-heart.svg","material-tag-minus-outline":"material/tag-minus-outline.svg","material-tag-minus":"material/tag-minus.svg","material-tag-multiple-outline":"material/tag-multiple-outline.svg","material-tag-multiple":"material/tag-multiple.svg","material-tag-off-outline":"material/tag-off-outline.svg","material-tag-off":"material/tag-off.svg","material-tag-outline":"material/tag-outline.svg","material-tag-plus-outline":"material/tag-plus-outline.svg","material-tag-plus":"material/tag-plus.svg","material-tag-remove-outline":"material/tag-remove-outline.svg","material-tag-remove":"material/tag-remove.svg","material-tag-search-outline":"material/tag-search-outline.svg","material-tag-search":"material/tag-search.svg","material-tag-text-outline":"material/tag-text-outline.svg","material-tag-text":"material/tag-text.svg","material-tag":"material/tag.svg","material-tailwind":"material/tailwind.svg","material-tally-mark-1":"material/tally-mark-1.svg","material-tally-mark-2":"material/tally-mark-2.svg","material-tally-mark-3":"material/tally-mark-3.svg","material-tally-mark-4":"material/tally-mark-4.svg","material-tally-mark-5":"material/tally-mark-5.svg","material-tangram":"material/tangram.svg","material-tank":"material/tank.svg","material-tanker-truck":"material/tanker-truck.svg","material-tape-drive":"material/tape-drive.svg","material-tape-measure":"material/tape-measure.svg","material-target-account":"material/target-account.svg","material-target-variant":"material/target-variant.svg","material-target":"material/target.svg","material-taxi":"material/taxi.svg","material-tea-outline":"material/tea-outline.svg","material-tea":"material/tea.svg","material-teamviewer":"material/teamviewer.svg","material-teddy-bear":"material/teddy-bear.svg","material-telescope":"material/telescope.svg","material-television-ambient-light":"material/television-ambient-light.svg","material-television-box":"material/television-box.svg","material-television-classic-off":"material/television-classic-off.svg","material-television-classic":"material/television-classic.svg","material-television-guide":"material/television-guide.svg","material-television-off":"material/television-off.svg","material-television-pause":"material/television-pause.svg","material-television-play":"material/television-play.svg","material-television-shimmer":"material/television-shimmer.svg","material-television-speaker-off":"material/television-speaker-off.svg","material-television-speaker":"material/television-speaker.svg","material-television-stop":"material/television-stop.svg","material-television":"material/television.svg","material-temperature-celsius":"material/temperature-celsius.svg","material-temperature-fahrenheit":"material/temperature-fahrenheit.svg","material-temperature-kelvin":"material/temperature-kelvin.svg","material-temple-buddhist-outline":"material/temple-buddhist-outline.svg","material-temple-buddhist":"material/temple-buddhist.svg","material-temple-hindu-outline":"material/temple-hindu-outline.svg","material-temple-hindu":"material/temple-hindu.svg","material-tennis-ball":"material/tennis-ball.svg","material-tennis":"material/tennis.svg","material-tent":"material/tent.svg","material-terraform":"material/terraform.svg","material-terrain":"material/terrain.svg","material-test-tube-empty":"material/test-tube-empty.svg","material-test-tube-off":"material/test-tube-off.svg","material-test-tube":"material/test-tube.svg","material-text-account":"material/text-account.svg","material-text-box-check-outline":"material/text-box-check-outline.svg","material-text-box-check":"material/text-box-check.svg","material-text-box-edit-outline":"material/text-box-edit-outline.svg","material-text-box-edit":"material/text-box-edit.svg","material-text-box-minus-outline":"material/text-box-minus-outline.svg","material-text-box-minus":"material/text-box-minus.svg","material-text-box-multiple-outline":"material/text-box-multiple-outline.svg","material-text-box-multiple":"material/text-box-multiple.svg","material-text-box-outline":"material/text-box-outline.svg","material-text-box-plus-outline":"material/text-box-plus-outline.svg","material-text-box-plus":"material/text-box-plus.svg","material-text-box-remove-outline":"material/text-box-remove-outline.svg","material-text-box-remove":"material/text-box-remove.svg","material-text-box-search-outline":"material/text-box-search-outline.svg","material-text-box-search":"material/text-box-search.svg","material-text-box":"material/text-box.svg","material-text-long":"material/text-long.svg","material-text-recognition":"material/text-recognition.svg","material-text-search-variant":"material/text-search-variant.svg","material-text-search":"material/text-search.svg","material-text-shadow":"material/text-shadow.svg","material-text-short":"material/text-short.svg","material-text":"material/text.svg","material-texture-box":"material/texture-box.svg","material-texture":"material/texture.svg","material-theater":"material/theater.svg","material-theme-light-dark":"material/theme-light-dark.svg","material-thermometer-alert":"material/thermometer-alert.svg","material-thermometer-auto":"material/thermometer-auto.svg","material-thermometer-bluetooth":"material/thermometer-bluetooth.svg","material-thermometer-check":"material/thermometer-check.svg","material-thermometer-chevron-down":"material/thermometer-chevron-down.svg","material-thermometer-chevron-up":"material/thermometer-chevron-up.svg","material-thermometer-high":"material/thermometer-high.svg","material-thermometer-lines":"material/thermometer-lines.svg","material-thermometer-low":"material/thermometer-low.svg","material-thermometer-minus":"material/thermometer-minus.svg","material-thermometer-off":"material/thermometer-off.svg","material-thermometer-plus":"material/thermometer-plus.svg","material-thermometer-probe-off":"material/thermometer-probe-off.svg","material-thermometer-probe":"material/thermometer-probe.svg","material-thermometer-water":"material/thermometer-water.svg","material-thermometer":"material/thermometer.svg","material-thermostat-auto":"material/thermostat-auto.svg","material-thermostat-box-auto":"material/thermostat-box-auto.svg","material-thermostat-box":"material/thermostat-box.svg","material-thermostat":"material/thermostat.svg","material-thought-bubble-outline":"material/thought-bubble-outline.svg","material-thought-bubble":"material/thought-bubble.svg","material-thumb-down-outline":"material/thumb-down-outline.svg","material-thumb-down":"material/thumb-down.svg","material-thumb-up-outline":"material/thumb-up-outline.svg","material-thumb-up":"material/thumb-up.svg","material-thumbs-up-down-outline":"material/thumbs-up-down-outline.svg","material-thumbs-up-down":"material/thumbs-up-down.svg","material-ticket-account":"material/ticket-account.svg","material-ticket-confirmation-outline":"material/ticket-confirmation-outline.svg","material-ticket-confirmation":"material/ticket-confirmation.svg","material-ticket-outline":"material/ticket-outline.svg","material-ticket-percent-outline":"material/ticket-percent-outline.svg","material-ticket-percent":"material/ticket-percent.svg","material-ticket":"material/ticket.svg","material-tie":"material/tie.svg","material-tilde-off":"material/tilde-off.svg","material-tilde":"material/tilde.svg","material-timelapse":"material/timelapse.svg","material-timeline-alert-outline":"material/timeline-alert-outline.svg","material-timeline-alert":"material/timeline-alert.svg","material-timeline-check-outline":"material/timeline-check-outline.svg","material-timeline-check":"material/timeline-check.svg","material-timeline-clock-outline":"material/timeline-clock-outline.svg","material-timeline-clock":"material/timeline-clock.svg","material-timeline-minus-outline":"material/timeline-minus-outline.svg","material-timeline-minus":"material/timeline-minus.svg","material-timeline-outline":"material/timeline-outline.svg","material-timeline-plus-outline":"material/timeline-plus-outline.svg","material-timeline-plus":"material/timeline-plus.svg","material-timeline-question-outline":"material/timeline-question-outline.svg","material-timeline-question":"material/timeline-question.svg","material-timeline-remove-outline":"material/timeline-remove-outline.svg","material-timeline-remove":"material/timeline-remove.svg","material-timeline-text-outline":"material/timeline-text-outline.svg","material-timeline-text":"material/timeline-text.svg","material-timeline":"material/timeline.svg","material-timer-10":"material/timer-10.svg","material-timer-3":"material/timer-3.svg","material-timer-alert-outline":"material/timer-alert-outline.svg","material-timer-alert":"material/timer-alert.svg","material-timer-cancel-outline":"material/timer-cancel-outline.svg","material-timer-cancel":"material/timer-cancel.svg","material-timer-check-outline":"material/timer-check-outline.svg","material-timer-check":"material/timer-check.svg","material-timer-cog-outline":"material/timer-cog-outline.svg","material-timer-cog":"material/timer-cog.svg","material-timer-edit-outline":"material/timer-edit-outline.svg","material-timer-edit":"material/timer-edit.svg","material-timer-lock-open-outline":"material/timer-lock-open-outline.svg","material-timer-lock-open":"material/timer-lock-open.svg","material-timer-lock-outline":"material/timer-lock-outline.svg","material-timer-lock":"material/timer-lock.svg","material-timer-marker-outline":"material/timer-marker-outline.svg","material-timer-marker":"material/timer-marker.svg","material-timer-minus-outline":"material/timer-minus-outline.svg","material-timer-minus":"material/timer-minus.svg","material-timer-music-outline":"material/timer-music-outline.svg","material-timer-music":"material/timer-music.svg","material-timer-off-outline":"material/timer-off-outline.svg","material-timer-off":"material/timer-off.svg","material-timer-outline":"material/timer-outline.svg","material-timer-pause-outline":"material/timer-pause-outline.svg","material-timer-pause":"material/timer-pause.svg","material-timer-play-outline":"material/timer-play-outline.svg","material-timer-play":"material/timer-play.svg","material-timer-plus-outline":"material/timer-plus-outline.svg","material-timer-plus":"material/timer-plus.svg","material-timer-refresh-outline":"material/timer-refresh-outline.svg","material-timer-refresh":"material/timer-refresh.svg","material-timer-remove-outline":"material/timer-remove-outline.svg","material-timer-remove":"material/timer-remove.svg","material-timer-sand-complete":"material/timer-sand-complete.svg","material-timer-sand-empty":"material/timer-sand-empty.svg","material-timer-sand-full":"material/timer-sand-full.svg","material-timer-sand-paused":"material/timer-sand-paused.svg","material-timer-sand":"material/timer-sand.svg","material-timer-settings-outline":"material/timer-settings-outline.svg","material-timer-settings":"material/timer-settings.svg","material-timer-star-outline":"material/timer-star-outline.svg","material-timer-star":"material/timer-star.svg","material-timer-stop-outline":"material/timer-stop-outline.svg","material-timer-stop":"material/timer-stop.svg","material-timer-sync-outline":"material/timer-sync-outline.svg","material-timer-sync":"material/timer-sync.svg","material-timer":"material/timer.svg","material-timetable":"material/timetable.svg","material-tire":"material/tire.svg","material-toaster-off":"material/toaster-off.svg","material-toaster-oven":"material/toaster-oven.svg","material-toaster":"material/toaster.svg","material-toggle-switch-off-outline":"material/toggle-switch-off-outline.svg","material-toggle-switch-off":"material/toggle-switch-off.svg","material-toggle-switch-outline":"material/toggle-switch-outline.svg","material-toggle-switch-variant-off":"material/toggle-switch-variant-off.svg","material-toggle-switch-variant":"material/toggle-switch-variant.svg","material-toggle-switch":"material/toggle-switch.svg","material-toilet":"material/toilet.svg","material-toolbox-outline":"material/toolbox-outline.svg","material-toolbox":"material/toolbox.svg","material-tools":"material/tools.svg","material-tooltip-account":"material/tooltip-account.svg","material-tooltip-cellphone":"material/tooltip-cellphone.svg","material-tooltip-check-outline":"material/tooltip-check-outline.svg","material-tooltip-check":"material/tooltip-check.svg","material-tooltip-edit-outline":"material/tooltip-edit-outline.svg","material-tooltip-edit":"material/tooltip-edit.svg","material-tooltip-image-outline":"material/tooltip-image-outline.svg","material-tooltip-image":"material/tooltip-image.svg","material-tooltip-minus-outline":"material/tooltip-minus-outline.svg","material-tooltip-minus":"material/tooltip-minus.svg","material-tooltip-outline":"material/tooltip-outline.svg","material-tooltip-plus-outline":"material/tooltip-plus-outline.svg","material-tooltip-plus":"material/tooltip-plus.svg","material-tooltip-remove-outline":"material/tooltip-remove-outline.svg","material-tooltip-remove":"material/tooltip-remove.svg","material-tooltip-text-outline":"material/tooltip-text-outline.svg","material-tooltip-text":"material/tooltip-text.svg","material-tooltip":"material/tooltip.svg","material-tooth-outline":"material/tooth-outline.svg","material-tooth":"material/tooth.svg","material-toothbrush-electric":"material/toothbrush-electric.svg","material-toothbrush-paste":"material/toothbrush-paste.svg","material-toothbrush":"material/toothbrush.svg","material-torch":"material/torch.svg","material-tortoise":"material/tortoise.svg","material-toslink":"material/toslink.svg","material-tournament":"material/tournament.svg","material-tow-truck":"material/tow-truck.svg","material-tower-beach":"material/tower-beach.svg","material-tower-fire":"material/tower-fire.svg","material-town-hall":"material/town-hall.svg","material-toy-brick-marker-outline":"material/toy-brick-marker-outline.svg","material-toy-brick-marker":"material/toy-brick-marker.svg","material-toy-brick-minus-outline":"material/toy-brick-minus-outline.svg","material-toy-brick-minus":"material/toy-brick-minus.svg","material-toy-brick-outline":"material/toy-brick-outline.svg","material-toy-brick-plus-outline":"material/toy-brick-plus-outline.svg","material-toy-brick-plus":"material/toy-brick-plus.svg","material-toy-brick-remove-outline":"material/toy-brick-remove-outline.svg","material-toy-brick-remove":"material/toy-brick-remove.svg","material-toy-brick-search-outline":"material/toy-brick-search-outline.svg","material-toy-brick-search":"material/toy-brick-search.svg","material-toy-brick":"material/toy-brick.svg","material-track-light-off":"material/track-light-off.svg","material-track-light":"material/track-light.svg","material-trackpad-lock":"material/trackpad-lock.svg","material-trackpad":"material/trackpad.svg","material-tractor-variant":"material/tractor-variant.svg","material-tractor":"material/tractor.svg","material-trademark":"material/trademark.svg","material-traffic-cone":"material/traffic-cone.svg","material-traffic-light-outline":"material/traffic-light-outline.svg","material-traffic-light":"material/traffic-light.svg","material-train-car-autorack":"material/train-car-autorack.svg","material-train-car-box-full":"material/train-car-box-full.svg","material-train-car-box-open":"material/train-car-box-open.svg","material-train-car-box":"material/train-car-box.svg","material-train-car-caboose":"material/train-car-caboose.svg","material-train-car-centerbeam-full":"material/train-car-centerbeam-full.svg","material-train-car-centerbeam":"material/train-car-centerbeam.svg","material-train-car-container":"material/train-car-container.svg","material-train-car-flatbed-car":"material/train-car-flatbed-car.svg","material-train-car-flatbed-tank":"material/train-car-flatbed-tank.svg","material-train-car-flatbed":"material/train-car-flatbed.svg","material-train-car-gondola-full":"material/train-car-gondola-full.svg","material-train-car-gondola":"material/train-car-gondola.svg","material-train-car-hopper-covered":"material/train-car-hopper-covered.svg","material-train-car-hopper-full":"material/train-car-hopper-full.svg","material-train-car-hopper":"material/train-car-hopper.svg","material-train-car-intermodal":"material/train-car-intermodal.svg","material-train-car-passenger-door-open":"material/train-car-passenger-door-open.svg","material-train-car-passenger-door":"material/train-car-passenger-door.svg","material-train-car-passenger-variant":"material/train-car-passenger-variant.svg","material-train-car-passenger":"material/train-car-passenger.svg","material-train-car-tank":"material/train-car-tank.svg","material-train-car":"material/train-car.svg","material-train-variant":"material/train-variant.svg","material-train":"material/train.svg","material-tram-side":"material/tram-side.svg","material-tram":"material/tram.svg","material-transcribe-close":"material/transcribe-close.svg","material-transcribe":"material/transcribe.svg","material-transfer-down":"material/transfer-down.svg","material-transfer-left":"material/transfer-left.svg","material-transfer-right":"material/transfer-right.svg","material-transfer-up":"material/transfer-up.svg","material-transfer":"material/transfer.svg","material-transit-connection-horizontal":"material/transit-connection-horizontal.svg","material-transit-connection-variant":"material/transit-connection-variant.svg","material-transit-connection":"material/transit-connection.svg","material-transit-detour":"material/transit-detour.svg","material-transit-skip":"material/transit-skip.svg","material-transit-transfer":"material/transit-transfer.svg","material-transition-masked":"material/transition-masked.svg","material-transition":"material/transition.svg","material-translate-off":"material/translate-off.svg","material-translate-variant":"material/translate-variant.svg","material-translate":"material/translate.svg","material-transmission-tower-export":"material/transmission-tower-export.svg","material-transmission-tower-import":"material/transmission-tower-import.svg","material-transmission-tower-off":"material/transmission-tower-off.svg","material-transmission-tower":"material/transmission-tower.svg","material-trash-can-outline":"material/trash-can-outline.svg","material-trash-can":"material/trash-can.svg","material-tray-alert":"material/tray-alert.svg","material-tray-arrow-down":"material/tray-arrow-down.svg","material-tray-arrow-up":"material/tray-arrow-up.svg","material-tray-full":"material/tray-full.svg","material-tray-minus":"material/tray-minus.svg","material-tray-plus":"material/tray-plus.svg","material-tray-remove":"material/tray-remove.svg","material-tray":"material/tray.svg","material-treasure-chest":"material/treasure-chest.svg","material-tree-outline":"material/tree-outline.svg","material-tree":"material/tree.svg","material-trello":"material/trello.svg","material-trending-down":"material/trending-down.svg","material-trending-neutral":"material/trending-neutral.svg","material-trending-up":"material/trending-up.svg","material-triangle-outline":"material/triangle-outline.svg","material-triangle-small-down":"material/triangle-small-down.svg","material-triangle-small-up":"material/triangle-small-up.svg","material-triangle-wave":"material/triangle-wave.svg","material-triangle":"material/triangle.svg","material-triforce":"material/triforce.svg","material-trophy-award":"material/trophy-award.svg","material-trophy-broken":"material/trophy-broken.svg","material-trophy-outline":"material/trophy-outline.svg","material-trophy-variant-outline":"material/trophy-variant-outline.svg","material-trophy-variant":"material/trophy-variant.svg","material-trophy":"material/trophy.svg","material-truck-alert-outline":"material/truck-alert-outline.svg","material-truck-alert":"material/truck-alert.svg","material-truck-cargo-container":"material/truck-cargo-container.svg","material-truck-check-outline":"material/truck-check-outline.svg","material-truck-check":"material/truck-check.svg","material-truck-delivery-outline":"material/truck-delivery-outline.svg","material-truck-delivery":"material/truck-delivery.svg","material-truck-fast-outline":"material/truck-fast-outline.svg","material-truck-fast":"material/truck-fast.svg","material-truck-flatbed":"material/truck-flatbed.svg","material-truck-minus-outline":"material/truck-minus-outline.svg","material-truck-minus":"material/truck-minus.svg","material-truck-outline":"material/truck-outline.svg","material-truck-plus-outline":"material/truck-plus-outline.svg","material-truck-plus":"material/truck-plus.svg","material-truck-remove-outline":"material/truck-remove-outline.svg","material-truck-remove":"material/truck-remove.svg","material-truck-snowflake":"material/truck-snowflake.svg","material-truck-trailer":"material/truck-trailer.svg","material-truck":"material/truck.svg","material-trumpet":"material/trumpet.svg","material-tshirt-crew-outline":"material/tshirt-crew-outline.svg","material-tshirt-crew":"material/tshirt-crew.svg","material-tshirt-v-outline":"material/tshirt-v-outline.svg","material-tshirt-v":"material/tshirt-v.svg","material-tsunami":"material/tsunami.svg","material-tumble-dryer-alert":"material/tumble-dryer-alert.svg","material-tumble-dryer-off":"material/tumble-dryer-off.svg","material-tumble-dryer":"material/tumble-dryer.svg","material-tune-variant":"material/tune-variant.svg","material-tune-vertical-variant":"material/tune-vertical-variant.svg","material-tune-vertical":"material/tune-vertical.svg","material-tune":"material/tune.svg","material-tunnel-outline":"material/tunnel-outline.svg","material-tunnel":"material/tunnel.svg","material-turbine":"material/turbine.svg","material-turkey":"material/turkey.svg","material-turnstile-outline":"material/turnstile-outline.svg","material-turnstile":"material/turnstile.svg","material-turtle":"material/turtle.svg","material-twitch":"material/twitch.svg","material-twitter":"material/twitter.svg","material-two-factor-authentication":"material/two-factor-authentication.svg","material-typewriter":"material/typewriter.svg","material-ubisoft":"material/ubisoft.svg","material-ubuntu":"material/ubuntu.svg","material-ufo-outline":"material/ufo-outline.svg","material-ufo":"material/ufo.svg","material-ultra-high-definition":"material/ultra-high-definition.svg","material-umbraco":"material/umbraco.svg","material-umbrella-beach-outline":"material/umbrella-beach-outline.svg","material-umbrella-beach":"material/umbrella-beach.svg","material-umbrella-closed-outline":"material/umbrella-closed-outline.svg","material-umbrella-closed-variant":"material/umbrella-closed-variant.svg","material-umbrella-closed":"material/umbrella-closed.svg","material-umbrella-outline":"material/umbrella-outline.svg","material-umbrella":"material/umbrella.svg","material-undo-variant":"material/undo-variant.svg","material-undo":"material/undo.svg","material-unfold-less-horizontal":"material/unfold-less-horizontal.svg","material-unfold-less-vertical":"material/unfold-less-vertical.svg","material-unfold-more-horizontal":"material/unfold-more-horizontal.svg","material-unfold-more-vertical":"material/unfold-more-vertical.svg","material-ungroup":"material/ungroup.svg","material-unicode":"material/unicode.svg","material-unicorn-variant":"material/unicorn-variant.svg","material-unicorn":"material/unicorn.svg","material-unicycle":"material/unicycle.svg","material-unity":"material/unity.svg","material-unreal":"material/unreal.svg","material-update":"material/update.svg","material-upload-lock-outline":"material/upload-lock-outline.svg","material-upload-lock":"material/upload-lock.svg","material-upload-multiple":"material/upload-multiple.svg","material-upload-network-outline":"material/upload-network-outline.svg","material-upload-network":"material/upload-network.svg","material-upload-off-outline":"material/upload-off-outline.svg","material-upload-off":"material/upload-off.svg","material-upload-outline":"material/upload-outline.svg","material-upload":"material/upload.svg","material-usb-flash-drive-outline":"material/usb-flash-drive-outline.svg","material-usb-flash-drive":"material/usb-flash-drive.svg","material-usb-port":"material/usb-port.svg","material-usb":"material/usb.svg","material-vacuum-outline":"material/vacuum-outline.svg","material-vacuum":"material/vacuum.svg","material-valve-closed":"material/valve-closed.svg","material-valve-open":"material/valve-open.svg","material-valve":"material/valve.svg","material-van-passenger":"material/van-passenger.svg","material-van-utility":"material/van-utility.svg","material-vanish-quarter":"material/vanish-quarter.svg","material-vanish":"material/vanish.svg","material-vanity-light":"material/vanity-light.svg","material-variable-box":"material/variable-box.svg","material-variable":"material/variable.svg","material-vector-arrange-above":"material/vector-arrange-above.svg","material-vector-arrange-below":"material/vector-arrange-below.svg","material-vector-bezier":"material/vector-bezier.svg","material-vector-circle-variant":"material/vector-circle-variant.svg","material-vector-circle":"material/vector-circle.svg","material-vector-combine":"material/vector-combine.svg","material-vector-curve":"material/vector-curve.svg","material-vector-difference-ab":"material/vector-difference-ab.svg","material-vector-difference-ba":"material/vector-difference-ba.svg","material-vector-difference":"material/vector-difference.svg","material-vector-ellipse":"material/vector-ellipse.svg","material-vector-intersection":"material/vector-intersection.svg","material-vector-line":"material/vector-line.svg","material-vector-link":"material/vector-link.svg","material-vector-point-edit":"material/vector-point-edit.svg","material-vector-point-minus":"material/vector-point-minus.svg","material-vector-point-plus":"material/vector-point-plus.svg","material-vector-point-select":"material/vector-point-select.svg","material-vector-point":"material/vector-point.svg","material-vector-polygon-variant":"material/vector-polygon-variant.svg","material-vector-polygon":"material/vector-polygon.svg","material-vector-polyline-edit":"material/vector-polyline-edit.svg","material-vector-polyline-minus":"material/vector-polyline-minus.svg","material-vector-polyline-plus":"material/vector-polyline-plus.svg","material-vector-polyline-remove":"material/vector-polyline-remove.svg","material-vector-polyline":"material/vector-polyline.svg","material-vector-radius":"material/vector-radius.svg","material-vector-rectangle":"material/vector-rectangle.svg","material-vector-selection":"material/vector-selection.svg","material-vector-square-close":"material/vector-square-close.svg","material-vector-square-edit":"material/vector-square-edit.svg","material-vector-square-minus":"material/vector-square-minus.svg","material-vector-square-open":"material/vector-square-open.svg","material-vector-square-plus":"material/vector-square-plus.svg","material-vector-square-remove":"material/vector-square-remove.svg","material-vector-square":"material/vector-square.svg","material-vector-triangle":"material/vector-triangle.svg","material-vector-union":"material/vector-union.svg","material-vhs":"material/vhs.svg","material-vibrate-off":"material/vibrate-off.svg","material-vibrate":"material/vibrate.svg","material-video-2d":"material/video-2d.svg","material-video-3d-off":"material/video-3d-off.svg","material-video-3d-variant":"material/video-3d-variant.svg","material-video-3d":"material/video-3d.svg","material-video-4k-box":"material/video-4k-box.svg","material-video-account":"material/video-account.svg","material-video-box-off":"material/video-box-off.svg","material-video-box":"material/video-box.svg","material-video-check-outline":"material/video-check-outline.svg","material-video-check":"material/video-check.svg","material-video-high-definition":"material/video-high-definition.svg","material-video-image":"material/video-image.svg","material-video-input-antenna":"material/video-input-antenna.svg","material-video-input-component":"material/video-input-component.svg","material-video-input-hdmi":"material/video-input-hdmi.svg","material-video-input-scart":"material/video-input-scart.svg","material-video-input-svideo":"material/video-input-svideo.svg","material-video-marker-outline":"material/video-marker-outline.svg","material-video-marker":"material/video-marker.svg","material-video-minus-outline":"material/video-minus-outline.svg","material-video-minus":"material/video-minus.svg","material-video-off-outline":"material/video-off-outline.svg","material-video-off":"material/video-off.svg","material-video-outline":"material/video-outline.svg","material-video-plus-outline":"material/video-plus-outline.svg","material-video-plus":"material/video-plus.svg","material-video-stabilization":"material/video-stabilization.svg","material-video-switch-outline":"material/video-switch-outline.svg","material-video-switch":"material/video-switch.svg","material-video-vintage":"material/video-vintage.svg","material-video-wireless-outline":"material/video-wireless-outline.svg","material-video-wireless":"material/video-wireless.svg","material-video":"material/video.svg","material-view-agenda-outline":"material/view-agenda-outline.svg","material-view-agenda":"material/view-agenda.svg","material-view-array-outline":"material/view-array-outline.svg","material-view-array":"material/view-array.svg","material-view-carousel-outline":"material/view-carousel-outline.svg","material-view-carousel":"material/view-carousel.svg","material-view-column-outline":"material/view-column-outline.svg","material-view-column":"material/view-column.svg","material-view-comfy-outline":"material/view-comfy-outline.svg","material-view-comfy":"material/view-comfy.svg","material-view-compact-outline":"material/view-compact-outline.svg","material-view-compact":"material/view-compact.svg","material-view-dashboard-edit-outline":"material/view-dashboard-edit-outline.svg","material-view-dashboard-edit":"material/view-dashboard-edit.svg","material-view-dashboard-outline":"material/view-dashboard-outline.svg","material-view-dashboard-variant-outline":"material/view-dashboard-variant-outline.svg","material-view-dashboard-variant":"material/view-dashboard-variant.svg","material-view-dashboard":"material/view-dashboard.svg","material-view-day-outline":"material/view-day-outline.svg","material-view-day":"material/view-day.svg","material-view-gallery-outline":"material/view-gallery-outline.svg","material-view-gallery":"material/view-gallery.svg","material-view-grid-outline":"material/view-grid-outline.svg","material-view-grid-plus-outline":"material/view-grid-plus-outline.svg","material-view-grid-plus":"material/view-grid-plus.svg","material-view-grid":"material/view-grid.svg","material-view-headline":"material/view-headline.svg","material-view-list-outline":"material/view-list-outline.svg","material-view-list":"material/view-list.svg","material-view-module-outline":"material/view-module-outline.svg","material-view-module":"material/view-module.svg","material-view-parallel-outline":"material/view-parallel-outline.svg","material-view-parallel":"material/view-parallel.svg","material-view-quilt-outline":"material/view-quilt-outline.svg","material-view-quilt":"material/view-quilt.svg","material-view-sequential-outline":"material/view-sequential-outline.svg","material-view-sequential":"material/view-sequential.svg","material-view-split-horizontal":"material/view-split-horizontal.svg","material-view-split-vertical":"material/view-split-vertical.svg","material-view-stream-outline":"material/view-stream-outline.svg","material-view-stream":"material/view-stream.svg","material-view-week-outline":"material/view-week-outline.svg","material-view-week":"material/view-week.svg","material-vimeo":"material/vimeo.svg","material-violin":"material/violin.svg","material-virtual-reality":"material/virtual-reality.svg","material-virus-off-outline":"material/virus-off-outline.svg","material-virus-off":"material/virus-off.svg","material-virus-outline":"material/virus-outline.svg","material-virus":"material/virus.svg","material-vlc":"material/vlc.svg","material-voicemail":"material/voicemail.svg","material-volcano-outline":"material/volcano-outline.svg","material-volcano":"material/volcano.svg","material-volleyball":"material/volleyball.svg","material-volume-equal":"material/volume-equal.svg","material-volume-high":"material/volume-high.svg","material-volume-low":"material/volume-low.svg","material-volume-medium":"material/volume-medium.svg","material-volume-minus":"material/volume-minus.svg","material-volume-mute":"material/volume-mute.svg","material-volume-off":"material/volume-off.svg","material-volume-plus":"material/volume-plus.svg","material-volume-source":"material/volume-source.svg","material-volume-variant-off":"material/volume-variant-off.svg","material-volume-vibrate":"material/volume-vibrate.svg","material-vote-outline":"material/vote-outline.svg","material-vote":"material/vote.svg","material-vpn":"material/vpn.svg","material-vuejs":"material/vuejs.svg","material-vuetify":"material/vuetify.svg","material-walk":"material/walk.svg","material-wall-fire":"material/wall-fire.svg","material-wall-sconce-flat-outline":"material/wall-sconce-flat-outline.svg","material-wall-sconce-flat-variant-outline":"material/wall-sconce-flat-variant-outline.svg","material-wall-sconce-flat-variant":"material/wall-sconce-flat-variant.svg","material-wall-sconce-flat":"material/wall-sconce-flat.svg","material-wall-sconce-outline":"material/wall-sconce-outline.svg","material-wall-sconce-round-outline":"material/wall-sconce-round-outline.svg","material-wall-sconce-round-variant-outline":"material/wall-sconce-round-variant-outline.svg","material-wall-sconce-round-variant":"material/wall-sconce-round-variant.svg","material-wall-sconce-round":"material/wall-sconce-round.svg","material-wall-sconce":"material/wall-sconce.svg","material-wall":"material/wall.svg","material-wallet-giftcard":"material/wallet-giftcard.svg","material-wallet-membership":"material/wallet-membership.svg","material-wallet-outline":"material/wallet-outline.svg","material-wallet-plus-outline":"material/wallet-plus-outline.svg","material-wallet-plus":"material/wallet-plus.svg","material-wallet-travel":"material/wallet-travel.svg","material-wallet":"material/wallet.svg","material-wallpaper":"material/wallpaper.svg","material-wan":"material/wan.svg","material-wardrobe-outline":"material/wardrobe-outline.svg","material-wardrobe":"material/wardrobe.svg","material-warehouse":"material/warehouse.svg","material-washing-machine-alert":"material/washing-machine-alert.svg","material-washing-machine-off":"material/washing-machine-off.svg","material-washing-machine":"material/washing-machine.svg","material-watch-export-variant":"material/watch-export-variant.svg","material-watch-export":"material/watch-export.svg","material-watch-import-variant":"material/watch-import-variant.svg","material-watch-import":"material/watch-import.svg","material-watch-variant":"material/watch-variant.svg","material-watch-vibrate-off":"material/watch-vibrate-off.svg","material-watch-vibrate":"material/watch-vibrate.svg","material-watch":"material/watch.svg","material-water-alert-outline":"material/water-alert-outline.svg","material-water-alert":"material/water-alert.svg","material-water-boiler-alert":"material/water-boiler-alert.svg","material-water-boiler-auto":"material/water-boiler-auto.svg","material-water-boiler-off":"material/water-boiler-off.svg","material-water-boiler":"material/water-boiler.svg","material-water-check-outline":"material/water-check-outline.svg","material-water-check":"material/water-check.svg","material-water-circle":"material/water-circle.svg","material-water-minus-outline":"material/water-minus-outline.svg","material-water-minus":"material/water-minus.svg","material-water-off-outline":"material/water-off-outline.svg","material-water-off":"material/water-off.svg","material-water-opacity":"material/water-opacity.svg","material-water-outline":"material/water-outline.svg","material-water-percent-alert":"material/water-percent-alert.svg","material-water-percent":"material/water-percent.svg","material-water-plus-outline":"material/water-plus-outline.svg","material-water-plus":"material/water-plus.svg","material-water-polo":"material/water-polo.svg","material-water-pump-off":"material/water-pump-off.svg","material-water-pump":"material/water-pump.svg","material-water-remove-outline":"material/water-remove-outline.svg","material-water-remove":"material/water-remove.svg","material-water-sync":"material/water-sync.svg","material-water-thermometer-outline":"material/water-thermometer-outline.svg","material-water-thermometer":"material/water-thermometer.svg","material-water-well-outline":"material/water-well-outline.svg","material-water-well":"material/water-well.svg","material-water":"material/water.svg","material-waterfall":"material/waterfall.svg","material-watering-can-outline":"material/watering-can-outline.svg","material-watering-can":"material/watering-can.svg","material-watermark":"material/watermark.svg","material-wave":"material/wave.svg","material-waveform":"material/waveform.svg","material-waves-arrow-left":"material/waves-arrow-left.svg","material-waves-arrow-right":"material/waves-arrow-right.svg","material-waves-arrow-up":"material/waves-arrow-up.svg","material-waves":"material/waves.svg","material-waze":"material/waze.svg","material-weather-cloudy-alert":"material/weather-cloudy-alert.svg","material-weather-cloudy-arrow-right":"material/weather-cloudy-arrow-right.svg","material-weather-cloudy-clock":"material/weather-cloudy-clock.svg","material-weather-cloudy":"material/weather-cloudy.svg","material-weather-dust":"material/weather-dust.svg","material-weather-fog":"material/weather-fog.svg","material-weather-hail":"material/weather-hail.svg","material-weather-hazy":"material/weather-hazy.svg","material-weather-hurricane":"material/weather-hurricane.svg","material-weather-lightning-rainy":"material/weather-lightning-rainy.svg","material-weather-lightning":"material/weather-lightning.svg","material-weather-night-partly-cloudy":"material/weather-night-partly-cloudy.svg","material-weather-night":"material/weather-night.svg","material-weather-partly-cloudy":"material/weather-partly-cloudy.svg","material-weather-partly-lightning":"material/weather-partly-lightning.svg","material-weather-partly-rainy":"material/weather-partly-rainy.svg","material-weather-partly-snowy-rainy":"material/weather-partly-snowy-rainy.svg","material-weather-partly-snowy":"material/weather-partly-snowy.svg","material-weather-pouring":"material/weather-pouring.svg","material-weather-rainy":"material/weather-rainy.svg","material-weather-snowy-heavy":"material/weather-snowy-heavy.svg","material-weather-snowy-rainy":"material/weather-snowy-rainy.svg","material-weather-snowy":"material/weather-snowy.svg","material-weather-sunny-alert":"material/weather-sunny-alert.svg","material-weather-sunny-off":"material/weather-sunny-off.svg","material-weather-sunny":"material/weather-sunny.svg","material-weather-sunset-down":"material/weather-sunset-down.svg","material-weather-sunset-up":"material/weather-sunset-up.svg","material-weather-sunset":"material/weather-sunset.svg","material-weather-tornado":"material/weather-tornado.svg","material-weather-windy-variant":"material/weather-windy-variant.svg","material-weather-windy":"material/weather-windy.svg","material-web-box":"material/web-box.svg","material-web-cancel":"material/web-cancel.svg","material-web-check":"material/web-check.svg","material-web-clock":"material/web-clock.svg","material-web-minus":"material/web-minus.svg","material-web-off":"material/web-off.svg","material-web-plus":"material/web-plus.svg","material-web-refresh":"material/web-refresh.svg","material-web-remove":"material/web-remove.svg","material-web-sync":"material/web-sync.svg","material-web":"material/web.svg","material-webcam-off":"material/webcam-off.svg","material-webcam":"material/webcam.svg","material-webhook":"material/webhook.svg","material-webpack":"material/webpack.svg","material-webrtc":"material/webrtc.svg","material-wechat":"material/wechat.svg","material-weight-gram":"material/weight-gram.svg","material-weight-kilogram":"material/weight-kilogram.svg","material-weight-lifter":"material/weight-lifter.svg","material-weight-pound":"material/weight-pound.svg","material-weight":"material/weight.svg","material-whatsapp":"material/whatsapp.svg","material-wheel-barrow":"material/wheel-barrow.svg","material-wheelchair-accessibility":"material/wheelchair-accessibility.svg","material-wheelchair":"material/wheelchair.svg","material-whistle-outline":"material/whistle-outline.svg","material-whistle":"material/whistle.svg","material-white-balance-auto":"material/white-balance-auto.svg","material-white-balance-incandescent":"material/white-balance-incandescent.svg","material-white-balance-iridescent":"material/white-balance-iridescent.svg","material-white-balance-sunny":"material/white-balance-sunny.svg","material-widgets-outline":"material/widgets-outline.svg","material-widgets":"material/widgets.svg","material-wifi-alert":"material/wifi-alert.svg","material-wifi-arrow-down":"material/wifi-arrow-down.svg","material-wifi-arrow-left-right":"material/wifi-arrow-left-right.svg","material-wifi-arrow-left":"material/wifi-arrow-left.svg","material-wifi-arrow-right":"material/wifi-arrow-right.svg","material-wifi-arrow-up-down":"material/wifi-arrow-up-down.svg","material-wifi-arrow-up":"material/wifi-arrow-up.svg","material-wifi-cancel":"material/wifi-cancel.svg","material-wifi-check":"material/wifi-check.svg","material-wifi-cog":"material/wifi-cog.svg","material-wifi-lock-open":"material/wifi-lock-open.svg","material-wifi-lock":"material/wifi-lock.svg","material-wifi-marker":"material/wifi-marker.svg","material-wifi-minus":"material/wifi-minus.svg","material-wifi-off":"material/wifi-off.svg","material-wifi-plus":"material/wifi-plus.svg","material-wifi-refresh":"material/wifi-refresh.svg","material-wifi-remove":"material/wifi-remove.svg","material-wifi-settings":"material/wifi-settings.svg","material-wifi-star":"material/wifi-star.svg","material-wifi-strength-1-alert":"material/wifi-strength-1-alert.svg","material-wifi-strength-1-lock-open":"material/wifi-strength-1-lock-open.svg","material-wifi-strength-1-lock":"material/wifi-strength-1-lock.svg","material-wifi-strength-1":"material/wifi-strength-1.svg","material-wifi-strength-2-alert":"material/wifi-strength-2-alert.svg","material-wifi-strength-2-lock-open":"material/wifi-strength-2-lock-open.svg","material-wifi-strength-2-lock":"material/wifi-strength-2-lock.svg","material-wifi-strength-2":"material/wifi-strength-2.svg","material-wifi-strength-3-alert":"material/wifi-strength-3-alert.svg","material-wifi-strength-3-lock-open":"material/wifi-strength-3-lock-open.svg","material-wifi-strength-3-lock":"material/wifi-strength-3-lock.svg","material-wifi-strength-3":"material/wifi-strength-3.svg","material-wifi-strength-4-alert":"material/wifi-strength-4-alert.svg","material-wifi-strength-4-lock-open":"material/wifi-strength-4-lock-open.svg","material-wifi-strength-4-lock":"material/wifi-strength-4-lock.svg","material-wifi-strength-4":"material/wifi-strength-4.svg","material-wifi-strength-alert-outline":"material/wifi-strength-alert-outline.svg","material-wifi-strength-lock-open-outline":"material/wifi-strength-lock-open-outline.svg","material-wifi-strength-lock-outline":"material/wifi-strength-lock-outline.svg","material-wifi-strength-off-outline":"material/wifi-strength-off-outline.svg","material-wifi-strength-off":"material/wifi-strength-off.svg","material-wifi-strength-outline":"material/wifi-strength-outline.svg","material-wifi-sync":"material/wifi-sync.svg","material-wifi":"material/wifi.svg","material-wikipedia":"material/wikipedia.svg","material-wind-power-outline":"material/wind-power-outline.svg","material-wind-power":"material/wind-power.svg","material-wind-turbine-alert":"material/wind-turbine-alert.svg","material-wind-turbine-check":"material/wind-turbine-check.svg","material-wind-turbine":"material/wind-turbine.svg","material-window-close":"material/window-close.svg","material-window-closed-variant":"material/window-closed-variant.svg","material-window-closed":"material/window-closed.svg","material-window-maximize":"material/window-maximize.svg","material-window-minimize":"material/window-minimize.svg","material-window-open-variant":"material/window-open-variant.svg","material-window-open":"material/window-open.svg","material-window-restore":"material/window-restore.svg","material-window-shutter-alert":"material/window-shutter-alert.svg","material-window-shutter-auto":"material/window-shutter-auto.svg","material-window-shutter-cog":"material/window-shutter-cog.svg","material-window-shutter-open":"material/window-shutter-open.svg","material-window-shutter-settings":"material/window-shutter-settings.svg","material-window-shutter":"material/window-shutter.svg","material-windsock":"material/windsock.svg","material-wiper-wash-alert":"material/wiper-wash-alert.svg","material-wiper-wash":"material/wiper-wash.svg","material-wiper":"material/wiper.svg","material-wizard-hat":"material/wizard-hat.svg","material-wordpress":"material/wordpress.svg","material-wrap-disabled":"material/wrap-disabled.svg","material-wrap":"material/wrap.svg","material-wrench-check-outline":"material/wrench-check-outline.svg","material-wrench-check":"material/wrench-check.svg","material-wrench-clock-outline":"material/wrench-clock-outline.svg","material-wrench-clock":"material/wrench-clock.svg","material-wrench-cog-outline":"material/wrench-cog-outline.svg","material-wrench-cog":"material/wrench-cog.svg","material-wrench-outline":"material/wrench-outline.svg","material-wrench":"material/wrench.svg","material-xamarin":"material/xamarin.svg","material-xml":"material/xml.svg","material-xmpp":"material/xmpp.svg","material-yahoo":"material/yahoo.svg","material-yeast":"material/yeast.svg","material-yin-yang":"material/yin-yang.svg","material-yoga":"material/yoga.svg","material-youtube-gaming":"material/youtube-gaming.svg","material-youtube-studio":"material/youtube-studio.svg","material-youtube-subscription":"material/youtube-subscription.svg","material-youtube-tv":"material/youtube-tv.svg","material-youtube":"material/youtube.svg","material-yurt":"material/yurt.svg","material-z-wave":"material/z-wave.svg","material-zend":"material/zend.svg","material-zigbee":"material/zigbee.svg","material-zip-box-outline":"material/zip-box-outline.svg","material-zip-box":"material/zip-box.svg","material-zip-disk":"material/zip-disk.svg","material-zodiac-aquarius":"material/zodiac-aquarius.svg","material-zodiac-aries":"material/zodiac-aries.svg","material-zodiac-cancer":"material/zodiac-cancer.svg","material-zodiac-capricorn":"material/zodiac-capricorn.svg","material-zodiac-gemini":"material/zodiac-gemini.svg","material-zodiac-leo":"material/zodiac-leo.svg","material-zodiac-libra":"material/zodiac-libra.svg","material-zodiac-pisces":"material/zodiac-pisces.svg","material-zodiac-sagittarius":"material/zodiac-sagittarius.svg","material-zodiac-scorpio":"material/zodiac-scorpio.svg","material-zodiac-taurus":"material/zodiac-taurus.svg","material-zodiac-virgo":"material/zodiac-virgo.svg","octicons-accessibility-16":"octicons/accessibility-16.svg","octicons-alert-16":"octicons/alert-16.svg","octicons-alert-24":"octicons/alert-24.svg","octicons-alert-fill-12":"octicons/alert-fill-12.svg","octicons-apps-16":"octicons/apps-16.svg","octicons-archive-16":"octicons/archive-16.svg","octicons-archive-24":"octicons/archive-24.svg","octicons-arrow-both-16":"octicons/arrow-both-16.svg","octicons-arrow-both-24":"octicons/arrow-both-24.svg","octicons-arrow-down-16":"octicons/arrow-down-16.svg","octicons-arrow-down-24":"octicons/arrow-down-24.svg","octicons-arrow-down-left-24":"octicons/arrow-down-left-24.svg","octicons-arrow-down-right-24":"octicons/arrow-down-right-24.svg","octicons-arrow-left-16":"octicons/arrow-left-16.svg","octicons-arrow-left-24":"octicons/arrow-left-24.svg","octicons-arrow-right-16":"octicons/arrow-right-16.svg","octicons-arrow-right-24":"octicons/arrow-right-24.svg","octicons-arrow-switch-16":"octicons/arrow-switch-16.svg","octicons-arrow-switch-24":"octicons/arrow-switch-24.svg","octicons-arrow-up-16":"octicons/arrow-up-16.svg","octicons-arrow-up-24":"octicons/arrow-up-24.svg","octicons-arrow-up-left-24":"octicons/arrow-up-left-24.svg","octicons-arrow-up-right-24":"octicons/arrow-up-right-24.svg","octicons-beaker-16":"octicons/beaker-16.svg","octicons-beaker-24":"octicons/beaker-24.svg","octicons-bell-16":"octicons/bell-16.svg","octicons-bell-24":"octicons/bell-24.svg","octicons-bell-fill-16":"octicons/bell-fill-16.svg","octicons-bell-fill-24":"octicons/bell-fill-24.svg","octicons-bell-slash-16":"octicons/bell-slash-16.svg","octicons-bell-slash-24":"octicons/bell-slash-24.svg","octicons-blocked-16":"octicons/blocked-16.svg","octicons-blocked-24":"octicons/blocked-24.svg","octicons-bold-16":"octicons/bold-16.svg","octicons-bold-24":"octicons/bold-24.svg","octicons-book-16":"octicons/book-16.svg","octicons-book-24":"octicons/book-24.svg","octicons-bookmark-16":"octicons/bookmark-16.svg","octicons-bookmark-24":"octicons/bookmark-24.svg","octicons-bookmark-fill-24":"octicons/bookmark-fill-24.svg","octicons-bookmark-slash-16":"octicons/bookmark-slash-16.svg","octicons-bookmark-slash-24":"octicons/bookmark-slash-24.svg","octicons-bookmark-slash-fill-24":"octicons/bookmark-slash-fill-24.svg","octicons-briefcase-16":"octicons/briefcase-16.svg","octicons-briefcase-24":"octicons/briefcase-24.svg","octicons-broadcast-16":"octicons/broadcast-16.svg","octicons-broadcast-24":"octicons/broadcast-24.svg","octicons-browser-16":"octicons/browser-16.svg","octicons-browser-24":"octicons/browser-24.svg","octicons-bug-16":"octicons/bug-16.svg","octicons-bug-24":"octicons/bug-24.svg","octicons-cache-16":"octicons/cache-16.svg","octicons-calendar-16":"octicons/calendar-16.svg","octicons-calendar-24":"octicons/calendar-24.svg","octicons-check-16":"octicons/check-16.svg","octicons-check-24":"octicons/check-24.svg","octicons-check-circle-16":"octicons/check-circle-16.svg","octicons-check-circle-24":"octicons/check-circle-24.svg","octicons-check-circle-fill-12":"octicons/check-circle-fill-12.svg","octicons-check-circle-fill-16":"octicons/check-circle-fill-16.svg","octicons-check-circle-fill-24":"octicons/check-circle-fill-24.svg","octicons-checkbox-16":"octicons/checkbox-16.svg","octicons-checkbox-24":"octicons/checkbox-24.svg","octicons-checklist-16":"octicons/checklist-16.svg","octicons-checklist-24":"octicons/checklist-24.svg","octicons-chevron-down-16":"octicons/chevron-down-16.svg","octicons-chevron-down-24":"octicons/chevron-down-24.svg","octicons-chevron-left-16":"octicons/chevron-left-16.svg","octicons-chevron-left-24":"octicons/chevron-left-24.svg","octicons-chevron-right-16":"octicons/chevron-right-16.svg","octicons-chevron-right-24":"octicons/chevron-right-24.svg","octicons-chevron-up-16":"octicons/chevron-up-16.svg","octicons-chevron-up-24":"octicons/chevron-up-24.svg","octicons-circle-16":"octicons/circle-16.svg","octicons-circle-24":"octicons/circle-24.svg","octicons-circle-slash-16":"octicons/circle-slash-16.svg","octicons-circle-slash-24":"octicons/circle-slash-24.svg","octicons-clock-16":"octicons/clock-16.svg","octicons-clock-24":"octicons/clock-24.svg","octicons-cloud-16":"octicons/cloud-16.svg","octicons-cloud-24":"octicons/cloud-24.svg","octicons-cloud-offline-16":"octicons/cloud-offline-16.svg","octicons-cloud-offline-24":"octicons/cloud-offline-24.svg","octicons-code-16":"octicons/code-16.svg","octicons-code-24":"octicons/code-24.svg","octicons-code-of-conduct-16":"octicons/code-of-conduct-16.svg","octicons-code-of-conduct-24":"octicons/code-of-conduct-24.svg","octicons-code-review-16":"octicons/code-review-16.svg","octicons-code-review-24":"octicons/code-review-24.svg","octicons-code-square-16":"octicons/code-square-16.svg","octicons-code-square-24":"octicons/code-square-24.svg","octicons-codescan-16":"octicons/codescan-16.svg","octicons-codescan-24":"octicons/codescan-24.svg","octicons-codescan-checkmark-16":"octicons/codescan-checkmark-16.svg","octicons-codescan-checkmark-24":"octicons/codescan-checkmark-24.svg","octicons-codespaces-16":"octicons/codespaces-16.svg","octicons-codespaces-24":"octicons/codespaces-24.svg","octicons-columns-16":"octicons/columns-16.svg","octicons-columns-24":"octicons/columns-24.svg","octicons-command-palette-16":"octicons/command-palette-16.svg","octicons-command-palette-24":"octicons/command-palette-24.svg","octicons-comment-16":"octicons/comment-16.svg","octicons-comment-24":"octicons/comment-24.svg","octicons-comment-discussion-16":"octicons/comment-discussion-16.svg","octicons-comment-discussion-24":"octicons/comment-discussion-24.svg","octicons-commit-24":"octicons/commit-24.svg","octicons-container-16":"octicons/container-16.svg","octicons-container-24":"octicons/container-24.svg","octicons-copilot-16":"octicons/copilot-16.svg","octicons-copilot-24":"octicons/copilot-24.svg","octicons-copilot-48":"octicons/copilot-48.svg","octicons-copilot-96":"octicons/copilot-96.svg","octicons-copilot-error-16":"octicons/copilot-error-16.svg","octicons-copilot-warning-16":"octicons/copilot-warning-16.svg","octicons-copy-16":"octicons/copy-16.svg","octicons-copy-24":"octicons/copy-24.svg","octicons-cpu-16":"octicons/cpu-16.svg","octicons-cpu-24":"octicons/cpu-24.svg","octicons-credit-card-16":"octicons/credit-card-16.svg","octicons-credit-card-24":"octicons/credit-card-24.svg","octicons-cross-reference-16":"octicons/cross-reference-16.svg","octicons-cross-reference-24":"octicons/cross-reference-24.svg","octicons-dash-16":"octicons/dash-16.svg","octicons-dash-24":"octicons/dash-24.svg","octicons-database-16":"octicons/database-16.svg","octicons-database-24":"octicons/database-24.svg","octicons-dependabot-16":"octicons/dependabot-16.svg","octicons-dependabot-24":"octicons/dependabot-24.svg","octicons-desktop-download-16":"octicons/desktop-download-16.svg","octicons-desktop-download-24":"octicons/desktop-download-24.svg","octicons-device-camera-16":"octicons/device-camera-16.svg","octicons-device-camera-video-16":"octicons/device-camera-video-16.svg","octicons-device-camera-video-24":"octicons/device-camera-video-24.svg","octicons-device-desktop-16":"octicons/device-desktop-16.svg","octicons-device-desktop-24":"octicons/device-desktop-24.svg","octicons-device-mobile-16":"octicons/device-mobile-16.svg","octicons-device-mobile-24":"octicons/device-mobile-24.svg","octicons-diamond-16":"octicons/diamond-16.svg","octicons-diamond-24":"octicons/diamond-24.svg","octicons-diff-16":"octicons/diff-16.svg","octicons-diff-24":"octicons/diff-24.svg","octicons-diff-added-16":"octicons/diff-added-16.svg","octicons-diff-ignored-16":"octicons/diff-ignored-16.svg","octicons-diff-modified-16":"octicons/diff-modified-16.svg","octicons-diff-removed-16":"octicons/diff-removed-16.svg","octicons-diff-renamed-16":"octicons/diff-renamed-16.svg","octicons-dot-16":"octicons/dot-16.svg","octicons-dot-24":"octicons/dot-24.svg","octicons-dot-fill-16":"octicons/dot-fill-16.svg","octicons-dot-fill-24":"octicons/dot-fill-24.svg","octicons-download-16":"octicons/download-16.svg","octicons-download-24":"octicons/download-24.svg","octicons-duplicate-16":"octicons/duplicate-16.svg","octicons-duplicate-24":"octicons/duplicate-24.svg","octicons-ellipsis-16":"octicons/ellipsis-16.svg","octicons-eye-16":"octicons/eye-16.svg","octicons-eye-24":"octicons/eye-24.svg","octicons-eye-closed-16":"octicons/eye-closed-16.svg","octicons-eye-closed-24":"octicons/eye-closed-24.svg","octicons-feed-discussion-16":"octicons/feed-discussion-16.svg","octicons-feed-forked-16":"octicons/feed-forked-16.svg","octicons-feed-heart-16":"octicons/feed-heart-16.svg","octicons-feed-merged-16":"octicons/feed-merged-16.svg","octicons-feed-person-16":"octicons/feed-person-16.svg","octicons-feed-repo-16":"octicons/feed-repo-16.svg","octicons-feed-rocket-16":"octicons/feed-rocket-16.svg","octicons-feed-star-16":"octicons/feed-star-16.svg","octicons-feed-tag-16":"octicons/feed-tag-16.svg","octicons-feed-trophy-16":"octicons/feed-trophy-16.svg","octicons-file-16":"octicons/file-16.svg","octicons-file-24":"octicons/file-24.svg","octicons-file-added-16":"octicons/file-added-16.svg","octicons-file-badge-16":"octicons/file-badge-16.svg","octicons-file-binary-16":"octicons/file-binary-16.svg","octicons-file-binary-24":"octicons/file-binary-24.svg","octicons-file-code-16":"octicons/file-code-16.svg","octicons-file-code-24":"octicons/file-code-24.svg","octicons-file-diff-16":"octicons/file-diff-16.svg","octicons-file-diff-24":"octicons/file-diff-24.svg","octicons-file-directory-16":"octicons/file-directory-16.svg","octicons-file-directory-24":"octicons/file-directory-24.svg","octicons-file-directory-fill-16":"octicons/file-directory-fill-16.svg","octicons-file-directory-fill-24":"octicons/file-directory-fill-24.svg","octicons-file-directory-open-fill-16":"octicons/file-directory-open-fill-16.svg","octicons-file-media-24":"octicons/file-media-24.svg","octicons-file-moved-16":"octicons/file-moved-16.svg","octicons-file-removed-16":"octicons/file-removed-16.svg","octicons-file-submodule-16":"octicons/file-submodule-16.svg","octicons-file-submodule-24":"octicons/file-submodule-24.svg","octicons-file-symlink-file-16":"octicons/file-symlink-file-16.svg","octicons-file-symlink-file-24":"octicons/file-symlink-file-24.svg","octicons-file-zip-16":"octicons/file-zip-16.svg","octicons-file-zip-24":"octicons/file-zip-24.svg","octicons-filter-16":"octicons/filter-16.svg","octicons-filter-24":"octicons/filter-24.svg","octicons-flame-16":"octicons/flame-16.svg","octicons-flame-24":"octicons/flame-24.svg","octicons-fold-16":"octicons/fold-16.svg","octicons-fold-24":"octicons/fold-24.svg","octicons-fold-down-16":"octicons/fold-down-16.svg","octicons-fold-down-24":"octicons/fold-down-24.svg","octicons-fold-up-16":"octicons/fold-up-16.svg","octicons-fold-up-24":"octicons/fold-up-24.svg","octicons-gear-16":"octicons/gear-16.svg","octicons-gear-24":"octicons/gear-24.svg","octicons-gift-16":"octicons/gift-16.svg","octicons-gift-24":"octicons/gift-24.svg","octicons-git-branch-16":"octicons/git-branch-16.svg","octicons-git-branch-24":"octicons/git-branch-24.svg","octicons-git-commit-16":"octicons/git-commit-16.svg","octicons-git-commit-24":"octicons/git-commit-24.svg","octicons-git-compare-16":"octicons/git-compare-16.svg","octicons-git-compare-24":"octicons/git-compare-24.svg","octicons-git-merge-16":"octicons/git-merge-16.svg","octicons-git-merge-24":"octicons/git-merge-24.svg","octicons-git-merge-queue-16":"octicons/git-merge-queue-16.svg","octicons-git-pull-request-16":"octicons/git-pull-request-16.svg","octicons-git-pull-request-24":"octicons/git-pull-request-24.svg","octicons-git-pull-request-closed-16":"octicons/git-pull-request-closed-16.svg","octicons-git-pull-request-closed-24":"octicons/git-pull-request-closed-24.svg","octicons-git-pull-request-draft-16":"octicons/git-pull-request-draft-16.svg","octicons-git-pull-request-draft-24":"octicons/git-pull-request-draft-24.svg","octicons-globe-16":"octicons/globe-16.svg","octicons-globe-24":"octicons/globe-24.svg","octicons-grabber-16":"octicons/grabber-16.svg","octicons-grabber-24":"octicons/grabber-24.svg","octicons-graph-16":"octicons/graph-16.svg","octicons-graph-24":"octicons/graph-24.svg","octicons-hash-16":"octicons/hash-16.svg","octicons-hash-24":"octicons/hash-24.svg","octicons-heading-16":"octicons/heading-16.svg","octicons-heading-24":"octicons/heading-24.svg","octicons-heart-16":"octicons/heart-16.svg","octicons-heart-24":"octicons/heart-24.svg","octicons-heart-fill-16":"octicons/heart-fill-16.svg","octicons-heart-fill-24":"octicons/heart-fill-24.svg","octicons-history-16":"octicons/history-16.svg","octicons-history-24":"octicons/history-24.svg","octicons-home-16":"octicons/home-16.svg","octicons-home-24":"octicons/home-24.svg","octicons-home-fill-24":"octicons/home-fill-24.svg","octicons-horizontal-rule-16":"octicons/horizontal-rule-16.svg","octicons-horizontal-rule-24":"octicons/horizontal-rule-24.svg","octicons-hourglass-16":"octicons/hourglass-16.svg","octicons-hourglass-24":"octicons/hourglass-24.svg","octicons-hubot-16":"octicons/hubot-16.svg","octicons-hubot-24":"octicons/hubot-24.svg","octicons-id-badge-16":"octicons/id-badge-16.svg","octicons-image-16":"octicons/image-16.svg","octicons-image-24":"octicons/image-24.svg","octicons-inbox-16":"octicons/inbox-16.svg","octicons-inbox-24":"octicons/inbox-24.svg","octicons-infinity-16":"octicons/infinity-16.svg","octicons-infinity-24":"octicons/infinity-24.svg","octicons-info-16":"octicons/info-16.svg","octicons-info-24":"octicons/info-24.svg","octicons-issue-closed-16":"octicons/issue-closed-16.svg","octicons-issue-closed-24":"octicons/issue-closed-24.svg","octicons-issue-draft-16":"octicons/issue-draft-16.svg","octicons-issue-draft-24":"octicons/issue-draft-24.svg","octicons-issue-opened-16":"octicons/issue-opened-16.svg","octicons-issue-opened-24":"octicons/issue-opened-24.svg","octicons-issue-reopened-16":"octicons/issue-reopened-16.svg","octicons-issue-reopened-24":"octicons/issue-reopened-24.svg","octicons-italic-16":"octicons/italic-16.svg","octicons-italic-24":"octicons/italic-24.svg","octicons-iterations-16":"octicons/iterations-16.svg","octicons-iterations-24":"octicons/iterations-24.svg","octicons-kebab-horizontal-16":"octicons/kebab-horizontal-16.svg","octicons-kebab-horizontal-24":"octicons/kebab-horizontal-24.svg","octicons-key-16":"octicons/key-16.svg","octicons-key-24":"octicons/key-24.svg","octicons-key-asterisk-16":"octicons/key-asterisk-16.svg","octicons-law-16":"octicons/law-16.svg","octicons-law-24":"octicons/law-24.svg","octicons-light-bulb-16":"octicons/light-bulb-16.svg","octicons-light-bulb-24":"octicons/light-bulb-24.svg","octicons-link-16":"octicons/link-16.svg","octicons-link-24":"octicons/link-24.svg","octicons-link-external-16":"octicons/link-external-16.svg","octicons-link-external-24":"octicons/link-external-24.svg","octicons-list-ordered-16":"octicons/list-ordered-16.svg","octicons-list-ordered-24":"octicons/list-ordered-24.svg","octicons-list-unordered-16":"octicons/list-unordered-16.svg","octicons-list-unordered-24":"octicons/list-unordered-24.svg","octicons-location-16":"octicons/location-16.svg","octicons-location-24":"octicons/location-24.svg","octicons-lock-16":"octicons/lock-16.svg","octicons-lock-24":"octicons/lock-24.svg","octicons-log-16":"octicons/log-16.svg","octicons-logo-gist-16":"octicons/logo-gist-16.svg","octicons-logo-github-16":"octicons/logo-github-16.svg","octicons-mail-16":"octicons/mail-16.svg","octicons-mail-24":"octicons/mail-24.svg","octicons-mark-github-16":"octicons/mark-github-16.svg","octicons-markdown-16":"octicons/markdown-16.svg","octicons-megaphone-16":"octicons/megaphone-16.svg","octicons-megaphone-24":"octicons/megaphone-24.svg","octicons-mention-16":"octicons/mention-16.svg","octicons-mention-24":"octicons/mention-24.svg","octicons-meter-16":"octicons/meter-16.svg","octicons-milestone-16":"octicons/milestone-16.svg","octicons-milestone-24":"octicons/milestone-24.svg","octicons-mirror-16":"octicons/mirror-16.svg","octicons-mirror-24":"octicons/mirror-24.svg","octicons-moon-16":"octicons/moon-16.svg","octicons-moon-24":"octicons/moon-24.svg","octicons-mortar-board-16":"octicons/mortar-board-16.svg","octicons-mortar-board-24":"octicons/mortar-board-24.svg","octicons-multi-select-16":"octicons/multi-select-16.svg","octicons-multi-select-24":"octicons/multi-select-24.svg","octicons-mute-16":"octicons/mute-16.svg","octicons-mute-24":"octicons/mute-24.svg","octicons-no-entry-16":"octicons/no-entry-16.svg","octicons-no-entry-24":"octicons/no-entry-24.svg","octicons-no-entry-fill-12":"octicons/no-entry-fill-12.svg","octicons-north-star-16":"octicons/north-star-16.svg","octicons-north-star-24":"octicons/north-star-24.svg","octicons-note-16":"octicons/note-16.svg","octicons-note-24":"octicons/note-24.svg","octicons-number-16":"octicons/number-16.svg","octicons-number-24":"octicons/number-24.svg","octicons-organization-16":"octicons/organization-16.svg","octicons-organization-24":"octicons/organization-24.svg","octicons-package-16":"octicons/package-16.svg","octicons-package-24":"octicons/package-24.svg","octicons-package-dependencies-16":"octicons/package-dependencies-16.svg","octicons-package-dependencies-24":"octicons/package-dependencies-24.svg","octicons-package-dependents-16":"octicons/package-dependents-16.svg","octicons-package-dependents-24":"octicons/package-dependents-24.svg","octicons-paintbrush-16":"octicons/paintbrush-16.svg","octicons-paper-airplane-16":"octicons/paper-airplane-16.svg","octicons-paper-airplane-24":"octicons/paper-airplane-24.svg","octicons-paperclip-16":"octicons/paperclip-16.svg","octicons-paperclip-24":"octicons/paperclip-24.svg","octicons-paste-16":"octicons/paste-16.svg","octicons-paste-24":"octicons/paste-24.svg","octicons-pencil-16":"octicons/pencil-16.svg","octicons-pencil-24":"octicons/pencil-24.svg","octicons-people-16":"octicons/people-16.svg","octicons-people-24":"octicons/people-24.svg","octicons-person-16":"octicons/person-16.svg","octicons-person-24":"octicons/person-24.svg","octicons-person-add-16":"octicons/person-add-16.svg","octicons-person-add-24":"octicons/person-add-24.svg","octicons-person-fill-16":"octicons/person-fill-16.svg","octicons-person-fill-24":"octicons/person-fill-24.svg","octicons-pin-16":"octicons/pin-16.svg","octicons-pin-24":"octicons/pin-24.svg","octicons-play-16":"octicons/play-16.svg","octicons-play-24":"octicons/play-24.svg","octicons-plug-16":"octicons/plug-16.svg","octicons-plug-24":"octicons/plug-24.svg","octicons-plus-16":"octicons/plus-16.svg","octicons-plus-24":"octicons/plus-24.svg","octicons-plus-circle-16":"octicons/plus-circle-16.svg","octicons-plus-circle-24":"octicons/plus-circle-24.svg","octicons-project-16":"octicons/project-16.svg","octicons-project-24":"octicons/project-24.svg","octicons-pulse-16":"octicons/pulse-16.svg","octicons-pulse-24":"octicons/pulse-24.svg","octicons-question-16":"octicons/question-16.svg","octicons-question-24":"octicons/question-24.svg","octicons-quote-16":"octicons/quote-16.svg","octicons-quote-24":"octicons/quote-24.svg","octicons-reply-16":"octicons/reply-16.svg","octicons-reply-24":"octicons/reply-24.svg","octicons-repo-16":"octicons/repo-16.svg","octicons-repo-24":"octicons/repo-24.svg","octicons-repo-clone-16":"octicons/repo-clone-16.svg","octicons-repo-deleted-16":"octicons/repo-deleted-16.svg","octicons-repo-forked-16":"octicons/repo-forked-16.svg","octicons-repo-forked-24":"octicons/repo-forked-24.svg","octicons-repo-locked-16":"octicons/repo-locked-16.svg","octicons-repo-locked-24":"octicons/repo-locked-24.svg","octicons-repo-pull-16":"octicons/repo-pull-16.svg","octicons-repo-push-16":"octicons/repo-push-16.svg","octicons-repo-push-24":"octicons/repo-push-24.svg","octicons-repo-template-16":"octicons/repo-template-16.svg","octicons-repo-template-24":"octicons/repo-template-24.svg","octicons-report-16":"octicons/report-16.svg","octicons-report-24":"octicons/report-24.svg","octicons-rocket-16":"octicons/rocket-16.svg","octicons-rocket-24":"octicons/rocket-24.svg","octicons-rows-16":"octicons/rows-16.svg","octicons-rows-24":"octicons/rows-24.svg","octicons-rss-16":"octicons/rss-16.svg","octicons-rss-24":"octicons/rss-24.svg","octicons-ruby-16":"octicons/ruby-16.svg","octicons-ruby-24":"octicons/ruby-24.svg","octicons-screen-full-16":"octicons/screen-full-16.svg","octicons-screen-full-24":"octicons/screen-full-24.svg","octicons-screen-normal-16":"octicons/screen-normal-16.svg","octicons-screen-normal-24":"octicons/screen-normal-24.svg","octicons-search-16":"octicons/search-16.svg","octicons-search-24":"octicons/search-24.svg","octicons-server-16":"octicons/server-16.svg","octicons-server-24":"octicons/server-24.svg","octicons-share-16":"octicons/share-16.svg","octicons-share-24":"octicons/share-24.svg","octicons-share-android-16":"octicons/share-android-16.svg","octicons-share-android-24":"octicons/share-android-24.svg","octicons-shield-16":"octicons/shield-16.svg","octicons-shield-24":"octicons/shield-24.svg","octicons-shield-check-16":"octicons/shield-check-16.svg","octicons-shield-check-24":"octicons/shield-check-24.svg","octicons-shield-lock-16":"octicons/shield-lock-16.svg","octicons-shield-lock-24":"octicons/shield-lock-24.svg","octicons-shield-x-16":"octicons/shield-x-16.svg","octicons-shield-x-24":"octicons/shield-x-24.svg","octicons-sidebar-collapse-16":"octicons/sidebar-collapse-16.svg","octicons-sidebar-collapse-24":"octicons/sidebar-collapse-24.svg","octicons-sidebar-expand-16":"octicons/sidebar-expand-16.svg","octicons-sidebar-expand-24":"octicons/sidebar-expand-24.svg","octicons-sign-in-16":"octicons/sign-in-16.svg","octicons-sign-in-24":"octicons/sign-in-24.svg","octicons-sign-out-16":"octicons/sign-out-16.svg","octicons-sign-out-24":"octicons/sign-out-24.svg","octicons-single-select-16":"octicons/single-select-16.svg","octicons-single-select-24":"octicons/single-select-24.svg","octicons-skip-16":"octicons/skip-16.svg","octicons-skip-24":"octicons/skip-24.svg","octicons-sliders-16":"octicons/sliders-16.svg","octicons-smiley-16":"octicons/smiley-16.svg","octicons-smiley-24":"octicons/smiley-24.svg","octicons-sort-asc-16":"octicons/sort-asc-16.svg","octicons-sort-asc-24":"octicons/sort-asc-24.svg","octicons-sort-desc-16":"octicons/sort-desc-16.svg","octicons-sort-desc-24":"octicons/sort-desc-24.svg","octicons-square-16":"octicons/square-16.svg","octicons-square-24":"octicons/square-24.svg","octicons-square-fill-16":"octicons/square-fill-16.svg","octicons-square-fill-24":"octicons/square-fill-24.svg","octicons-squirrel-16":"octicons/squirrel-16.svg","octicons-squirrel-24":"octicons/squirrel-24.svg","octicons-stack-16":"octicons/stack-16.svg","octicons-stack-24":"octicons/stack-24.svg","octicons-star-16":"octicons/star-16.svg","octicons-star-24":"octicons/star-24.svg","octicons-star-fill-16":"octicons/star-fill-16.svg","octicons-star-fill-24":"octicons/star-fill-24.svg","octicons-stop-16":"octicons/stop-16.svg","octicons-stop-24":"octicons/stop-24.svg","octicons-stopwatch-16":"octicons/stopwatch-16.svg","octicons-stopwatch-24":"octicons/stopwatch-24.svg","octicons-strikethrough-16":"octicons/strikethrough-16.svg","octicons-strikethrough-24":"octicons/strikethrough-24.svg","octicons-sun-16":"octicons/sun-16.svg","octicons-sun-24":"octicons/sun-24.svg","octicons-sync-16":"octicons/sync-16.svg","octicons-sync-24":"octicons/sync-24.svg","octicons-tab-24":"octicons/tab-24.svg","octicons-tab-external-16":"octicons/tab-external-16.svg","octicons-table-16":"octicons/table-16.svg","octicons-table-24":"octicons/table-24.svg","octicons-tag-16":"octicons/tag-16.svg","octicons-tag-24":"octicons/tag-24.svg","octicons-tasklist-16":"octicons/tasklist-16.svg","octicons-tasklist-24":"octicons/tasklist-24.svg","octicons-telescope-16":"octicons/telescope-16.svg","octicons-telescope-24":"octicons/telescope-24.svg","octicons-telescope-fill-16":"octicons/telescope-fill-16.svg","octicons-telescope-fill-24":"octicons/telescope-fill-24.svg","octicons-terminal-16":"octicons/terminal-16.svg","octicons-terminal-24":"octicons/terminal-24.svg","octicons-three-bars-16":"octicons/three-bars-16.svg","octicons-thumbsdown-16":"octicons/thumbsdown-16.svg","octicons-thumbsdown-24":"octicons/thumbsdown-24.svg","octicons-thumbsup-16":"octicons/thumbsup-16.svg","octicons-thumbsup-24":"octicons/thumbsup-24.svg","octicons-tools-16":"octicons/tools-16.svg","octicons-tools-24":"octicons/tools-24.svg","octicons-trash-16":"octicons/trash-16.svg","octicons-trash-24":"octicons/trash-24.svg","octicons-triangle-down-16":"octicons/triangle-down-16.svg","octicons-triangle-down-24":"octicons/triangle-down-24.svg","octicons-triangle-left-16":"octicons/triangle-left-16.svg","octicons-triangle-left-24":"octicons/triangle-left-24.svg","octicons-triangle-right-16":"octicons/triangle-right-16.svg","octicons-triangle-right-24":"octicons/triangle-right-24.svg","octicons-triangle-up-16":"octicons/triangle-up-16.svg","octicons-triangle-up-24":"octicons/triangle-up-24.svg","octicons-trophy-16":"octicons/trophy-16.svg","octicons-trophy-24":"octicons/trophy-24.svg","octicons-typography-16":"octicons/typography-16.svg","octicons-typography-24":"octicons/typography-24.svg","octicons-unfold-16":"octicons/unfold-16.svg","octicons-unfold-24":"octicons/unfold-24.svg","octicons-unlock-16":"octicons/unlock-16.svg","octicons-unlock-24":"octicons/unlock-24.svg","octicons-unmute-16":"octicons/unmute-16.svg","octicons-unmute-24":"octicons/unmute-24.svg","octicons-unverified-16":"octicons/unverified-16.svg","octicons-unverified-24":"octicons/unverified-24.svg","octicons-upload-16":"octicons/upload-16.svg","octicons-upload-24":"octicons/upload-24.svg","octicons-verified-16":"octicons/verified-16.svg","octicons-verified-24":"octicons/verified-24.svg","octicons-versions-16":"octicons/versions-16.svg","octicons-versions-24":"octicons/versions-24.svg","octicons-video-16":"octicons/video-16.svg","octicons-video-24":"octicons/video-24.svg","octicons-webhook-16":"octicons/webhook-16.svg","octicons-workflow-16":"octicons/workflow-16.svg","octicons-workflow-24":"octicons/workflow-24.svg","octicons-x-16":"octicons/x-16.svg","octicons-x-24":"octicons/x-24.svg","octicons-x-circle-16":"octicons/x-circle-16.svg","octicons-x-circle-24":"octicons/x-circle-24.svg","octicons-x-circle-fill-12":"octicons/x-circle-fill-12.svg","octicons-x-circle-fill-16":"octicons/x-circle-fill-16.svg","octicons-x-circle-fill-24":"octicons/x-circle-fill-24.svg","octicons-zap-16":"octicons/zap-16.svg","octicons-zap-24":"octicons/zap-24.svg"}},"emojis":{"base":"https://raw.githubusercontent.com/twitter/twemoji/master/assets/svg/","data":{"100":"1f4af.svg","1234":"1f522.svg","8ball":"1f3b1.svg","a":"1f170.svg","ab":"1f18e.svg","abacus":"1f9ee.svg","abc":"1f524.svg","abcd":"1f521.svg","accept":"1f251.svg","accordion":"1fa97.svg","adhesive_bandage":"1fa79.svg","adult":"1f9d1.svg","adult_tone1":"1f9d1-1f3fb.svg","adult_tone2":"1f9d1-1f3fc.svg","adult_tone3":"1f9d1-1f3fd.svg","adult_tone4":"1f9d1-1f3fe.svg","adult_tone5":"1f9d1-1f3ff.svg","aerial_tramway":"1f6a1.svg","airplane":"2708.svg","airplane_arriving":"1f6ec.svg","airplane_departure":"1f6eb.svg","airplane_small":"1f6e9.svg","alarm_clock":"23f0.svg","alembic":"2697.svg","alien":"1f47d.svg","ambulance":"1f691.svg","amphora":"1f3fa.svg","anatomical_heart":"1fac0.svg","anchor":"2693.svg","angel":"1f47c.svg","angel_tone1":"1f47c-1f3fb.svg","angel_tone2":"1f47c-1f3fc.svg","angel_tone3":"1f47c-1f3fd.svg","angel_tone4":"1f47c-1f3fe.svg","angel_tone5":"1f47c-1f3ff.svg","anger":"1f4a2.svg","anger_right":"1f5ef.svg","angry":"1f620.svg","anguished":"1f627.svg","ant":"1f41c.svg","apple":"1f34e.svg","aquarius":"2652.svg","aries":"2648.svg","arrow_backward":"25c0.svg","arrow_double_down":"23ec.svg","arrow_double_up":"23eb.svg","arrow_down":"2b07.svg","arrow_down_small":"1f53d.svg","arrow_forward":"25b6.svg","arrow_heading_down":"2935.svg","arrow_heading_up":"2934.svg","arrow_left":"2b05.svg","arrow_lower_left":"2199.svg","arrow_lower_right":"2198.svg","arrow_right":"27a1.svg","arrow_right_hook":"21aa.svg","arrow_up":"2b06.svg","arrow_up_down":"2195.svg","arrow_up_small":"1f53c.svg","arrow_upper_left":"2196.svg","arrow_upper_right":"2197.svg","arrows_clockwise":"1f503.svg","arrows_counterclockwise":"1f504.svg","art":"1f3a8.svg","articulated_lorry":"1f69b.svg","artist":"1f9d1-200d-1f3a8.svg","artist_tone1":"1f9d1-1f3fb-200d-1f3a8.svg","artist_tone2":"1f9d1-1f3fc-200d-1f3a8.svg","artist_tone3":"1f9d1-1f3fd-200d-1f3a8.svg","artist_tone4":"1f9d1-1f3fe-200d-1f3a8.svg","artist_tone5":"1f9d1-1f3ff-200d-1f3a8.svg","asterisk":"2a-20e3.svg","astonished":"1f632.svg","astronaut":"1f9d1-200d-1f680.svg","astronaut_tone1":"1f9d1-1f3fb-200d-1f680.svg","astronaut_tone2":"1f9d1-1f3fc-200d-1f680.svg","astronaut_tone3":"1f9d1-1f3fd-200d-1f680.svg","astronaut_tone4":"1f9d1-1f3fe-200d-1f680.svg","astronaut_tone5":"1f9d1-1f3ff-200d-1f680.svg","athletic_shoe":"1f45f.svg","atm":"1f3e7.svg","atom":"269b.svg","auto_rickshaw":"1f6fa.svg","avocado":"1f951.svg","axe":"1fa93.svg","b":"1f171.svg","baby":"1f476.svg","baby_bottle":"1f37c.svg","baby_chick":"1f424.svg","baby_symbol":"1f6bc.svg","baby_tone1":"1f476-1f3fb.svg","baby_tone2":"1f476-1f3fc.svg","baby_tone3":"1f476-1f3fd.svg","baby_tone4":"1f476-1f3fe.svg","baby_tone5":"1f476-1f3ff.svg","back":"1f519.svg","bacon":"1f953.svg","badger":"1f9a1.svg","badminton":"1f3f8.svg","bagel":"1f96f.svg","baggage_claim":"1f6c4.svg","bald":"1f9b2.svg","ballet_shoes":"1fa70.svg","balloon":"1f388.svg","ballot_box":"1f5f3.svg","ballot_box_with_check":"2611.svg","bamboo":"1f38d.svg","banana":"1f34c.svg","bangbang":"203c.svg","banjo":"1fa95.svg","bank":"1f3e6.svg","bar_chart":"1f4ca.svg","barber":"1f488.svg","baseball":"26be.svg","basket":"1f9fa.svg","basketball":"1f3c0.svg","bat":"1f987.svg","bath":"1f6c0.svg","bath_tone1":"1f6c0-1f3fb.svg","bath_tone2":"1f6c0-1f3fc.svg","bath_tone3":"1f6c0-1f3fd.svg","bath_tone4":"1f6c0-1f3fe.svg","bath_tone5":"1f6c0-1f3ff.svg","bathtub":"1f6c1.svg","battery":"1f50b.svg","beach":"1f3d6.svg","beach_umbrella":"26f1.svg","bear":"1f43b.svg","bearded_person":"1f9d4.svg","bearded_person_tone1":"1f9d4-1f3fb.svg","bearded_person_tone2":"1f9d4-1f3fc.svg","bearded_person_tone3":"1f9d4-1f3fd.svg","bearded_person_tone4":"1f9d4-1f3fe.svg","bearded_person_tone5":"1f9d4-1f3ff.svg","beaver":"1f9ab.svg","bed":"1f6cf.svg","bee":"1f41d.svg","beer":"1f37a.svg","beers":"1f37b.svg","beetle":"1fab2.svg","beginner":"1f530.svg","bell":"1f514.svg","bell_pepper":"1fad1.svg","bellhop":"1f6ce.svg","bento":"1f371.svg","beverage_box":"1f9c3.svg","bike":"1f6b2.svg","bikini":"1f459.svg","billed_cap":"1f9e2.svg","biohazard":"2623.svg","bird":"1f426.svg","birthday":"1f382.svg","bison":"1f9ac.svg","black_cat":"1f408-200d-2b1b.svg","black_circle":"26ab.svg","black_heart":"1f5a4.svg","black_joker":"1f0cf.svg","black_large_square":"2b1b.svg","black_medium_small_square":"25fe.svg","black_medium_square":"25fc.svg","black_nib":"2712.svg","black_small_square":"25aa.svg","black_square_button":"1f532.svg","blond-haired_man":"1f471-200d-2642-fe0f.svg","blond-haired_man_tone1":"1f471-1f3fb-200d-2642-fe0f.svg","blond-haired_man_tone2":"1f471-1f3fc-200d-2642-fe0f.svg","blond-haired_man_tone3":"1f471-1f3fd-200d-2642-fe0f.svg","blond-haired_man_tone4":"1f471-1f3fe-200d-2642-fe0f.svg","blond-haired_man_tone5":"1f471-1f3ff-200d-2642-fe0f.svg","blond-haired_woman":"1f471-200d-2640-fe0f.svg","blond-haired_woman_tone1":"1f471-1f3fb-200d-2640-fe0f.svg","blond-haired_woman_tone2":"1f471-1f3fc-200d-2640-fe0f.svg","blond-haired_woman_tone3":"1f471-1f3fd-200d-2640-fe0f.svg","blond-haired_woman_tone4":"1f471-1f3fe-200d-2640-fe0f.svg","blond-haired_woman_tone5":"1f471-1f3ff-200d-2640-fe0f.svg","blond_haired_person":"1f471.svg","blond_haired_person_tone1":"1f471-1f3fb.svg","blond_haired_person_tone2":"1f471-1f3fc.svg","blond_haired_person_tone3":"1f471-1f3fd.svg","blond_haired_person_tone4":"1f471-1f3fe.svg","blond_haired_person_tone5":"1f471-1f3ff.svg","blossom":"1f33c.svg","blowfish":"1f421.svg","blue_book":"1f4d8.svg","blue_car":"1f699.svg","blue_circle":"1f535.svg","blue_heart":"1f499.svg","blue_square":"1f7e6.svg","blueberries":"1fad0.svg","blush":"1f60a.svg","boar":"1f417.svg","bomb":"1f4a3.svg","bone":"1f9b4.svg","book":"1f4d6.svg","bookmark":"1f516.svg","bookmark_tabs":"1f4d1.svg","books":"1f4da.svg","boom":"1f4a5.svg","boomerang":"1fa83.svg","boot":"1f462.svg","bouquet":"1f490.svg","bow_and_arrow":"1f3f9.svg","bowl_with_spoon":"1f963.svg","bowling":"1f3b3.svg","boxing_glove":"1f94a.svg","boy":"1f466.svg","boy_tone1":"1f466-1f3fb.svg","boy_tone2":"1f466-1f3fc.svg","boy_tone3":"1f466-1f3fd.svg","boy_tone4":"1f466-1f3fe.svg","boy_tone5":"1f466-1f3ff.svg","brain":"1f9e0.svg","bread":"1f35e.svg","breast_feeding":"1f931.svg","breast_feeding_tone1":"1f931-1f3fb.svg","breast_feeding_tone2":"1f931-1f3fc.svg","breast_feeding_tone3":"1f931-1f3fd.svg","breast_feeding_tone4":"1f931-1f3fe.svg","breast_feeding_tone5":"1f931-1f3ff.svg","bricks":"1f9f1.svg","bridge_at_night":"1f309.svg","briefcase":"1f4bc.svg","briefs":"1fa72.svg","broccoli":"1f966.svg","broken_heart":"1f494.svg","broom":"1f9f9.svg","brown_circle":"1f7e4.svg","brown_heart":"1f90e.svg","brown_square":"1f7eb.svg","bubble_tea":"1f9cb.svg","bucket":"1faa3.svg","bug":"1f41b.svg","bulb":"1f4a1.svg","bullettrain_front":"1f685.svg","bullettrain_side":"1f684.svg","burrito":"1f32f.svg","bus":"1f68c.svg","busstop":"1f68f.svg","bust_in_silhouette":"1f464.svg","busts_in_silhouette":"1f465.svg","butter":"1f9c8.svg","butterfly":"1f98b.svg","cactus":"1f335.svg","cake":"1f370.svg","calendar":"1f4c6.svg","calendar_spiral":"1f5d3.svg","call_me":"1f919.svg","call_me_tone1":"1f919-1f3fb.svg","call_me_tone2":"1f919-1f3fc.svg","call_me_tone3":"1f919-1f3fd.svg","call_me_tone4":"1f919-1f3fe.svg","call_me_tone5":"1f919-1f3ff.svg","calling":"1f4f2.svg","camel":"1f42b.svg","camera":"1f4f7.svg","camera_with_flash":"1f4f8.svg","camping":"1f3d5.svg","cancer":"264b.svg","candle":"1f56f.svg","candy":"1f36c.svg","canned_food":"1f96b.svg","canoe":"1f6f6.svg","capital_abcd":"1f520.svg","capricorn":"2651.svg","card_box":"1f5c3.svg","card_index":"1f4c7.svg","carousel_horse":"1f3a0.svg","carpentry_saw":"1fa9a.svg","carrot":"1f955.svg","cat2":"1f408.svg","cat":"1f431.svg","cd":"1f4bf.svg","chains":"26d3.svg","chair":"1fa91.svg","champagne":"1f37e.svg","champagne_glass":"1f942.svg","chart":"1f4b9.svg","chart_with_downwards_trend":"1f4c9.svg","chart_with_upwards_trend":"1f4c8.svg","checkered_flag":"1f3c1.svg","cheese":"1f9c0.svg","cherries":"1f352.svg","cherry_blossom":"1f338.svg","chess_pawn":"265f.svg","chestnut":"1f330.svg","chicken":"1f414.svg","child":"1f9d2.svg","child_tone1":"1f9d2-1f3fb.svg","child_tone2":"1f9d2-1f3fc.svg","child_tone3":"1f9d2-1f3fd.svg","child_tone4":"1f9d2-1f3fe.svg","child_tone5":"1f9d2-1f3ff.svg","children_crossing":"1f6b8.svg","chipmunk":"1f43f.svg","chocolate_bar":"1f36b.svg","chopsticks":"1f962.svg","christmas_tree":"1f384.svg","church":"26ea.svg","cinema":"1f3a6.svg","circus_tent":"1f3aa.svg","city_dusk":"1f306.svg","city_sunset":"1f307.svg","cityscape":"1f3d9.svg","cl":"1f191.svg","clap":"1f44f.svg","clap_tone1":"1f44f-1f3fb.svg","clap_tone2":"1f44f-1f3fc.svg","clap_tone3":"1f44f-1f3fd.svg","clap_tone4":"1f44f-1f3fe.svg","clap_tone5":"1f44f-1f3ff.svg","clapper":"1f3ac.svg","classical_building":"1f3db.svg","clipboard":"1f4cb.svg","clock1030":"1f565.svg","clock10":"1f559.svg","clock1130":"1f566.svg","clock11":"1f55a.svg","clock1230":"1f567.svg","clock12":"1f55b.svg","clock130":"1f55c.svg","clock1":"1f550.svg","clock230":"1f55d.svg","clock2":"1f551.svg","clock330":"1f55e.svg","clock3":"1f552.svg","clock430":"1f55f.svg","clock4":"1f553.svg","clock530":"1f560.svg","clock5":"1f554.svg","clock630":"1f561.svg","clock6":"1f555.svg","clock730":"1f562.svg","clock7":"1f556.svg","clock830":"1f563.svg","clock8":"1f557.svg","clock930":"1f564.svg","clock9":"1f558.svg","clock":"1f570.svg","closed_book":"1f4d5.svg","closed_lock_with_key":"1f510.svg","closed_umbrella":"1f302.svg","cloud":"2601.svg","cloud_lightning":"1f329.svg","cloud_rain":"1f327.svg","cloud_snow":"1f328.svg","cloud_tornado":"1f32a.svg","clown":"1f921.svg","clubs":"2663.svg","coat":"1f9e5.svg","cockroach":"1fab3.svg","cocktail":"1f378.svg","coconut":"1f965.svg","coffee":"2615.svg","coffin":"26b0.svg","coin":"1fa99.svg","cold_face":"1f976.svg","cold_sweat":"1f630.svg","comet":"2604.svg","compass":"1f9ed.svg","compression":"1f5dc.svg","computer":"1f4bb.svg","confetti_ball":"1f38a.svg","confounded":"1f616.svg","confused":"1f615.svg","congratulations":"3297.svg","construction":"1f6a7.svg","construction_site":"1f3d7.svg","construction_worker":"1f477.svg","construction_worker_tone1":"1f477-1f3fb.svg","construction_worker_tone2":"1f477-1f3fc.svg","construction_worker_tone3":"1f477-1f3fd.svg","construction_worker_tone4":"1f477-1f3fe.svg","construction_worker_tone5":"1f477-1f3ff.svg","control_knobs":"1f39b.svg","convenience_store":"1f3ea.svg","cook":"1f9d1-200d-1f373.svg","cook_tone1":"1f9d1-1f3fb-200d-1f373.svg","cook_tone2":"1f9d1-1f3fc-200d-1f373.svg","cook_tone3":"1f9d1-1f3fd-200d-1f373.svg","cook_tone4":"1f9d1-1f3fe-200d-1f373.svg","cook_tone5":"1f9d1-1f3ff-200d-1f373.svg","cookie":"1f36a.svg","cooking":"1f373.svg","cool":"1f192.svg","copyright":"a9.svg","corn":"1f33d.svg","couch":"1f6cb.svg","couple":"1f46b.svg","couple_mm":"1f468-200d-2764-fe0f-200d-1f468.svg","couple_with_heart":"1f491.svg","couple_with_heart_man_man_tone1":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone1_tone2":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone1_tone3":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone1_tone4":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone1_tone5":"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone2":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone2_tone1":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone2_tone3":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone2_tone4":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone2_tone5":"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone3":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone3_tone1":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone3_tone2":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone3_tone4":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone3_tone5":"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone4":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_man_man_tone4_tone1":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone4_tone2":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone4_tone3":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone4_tone5":"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone5":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_man_man_tone5_tone1":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_man_man_tone5_tone2":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_man_man_tone5_tone3":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_man_man_tone5_tone4":"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_person_person_tone1_tone2":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone1_tone3":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone1_tone4":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_person_person_tone1_tone5":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone2_tone1":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone2_tone3":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone2_tone4":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_person_person_tone2_tone5":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone3_tone1":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone3_tone2":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone3_tone4":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_person_person_tone3_tone5":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone4_tone1":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone4_tone2":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone4_tone3":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone4_tone5":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff.svg","couple_with_heart_person_person_tone5_tone1":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb.svg","couple_with_heart_person_person_tone5_tone2":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc.svg","couple_with_heart_person_person_tone5_tone3":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd.svg","couple_with_heart_person_person_tone5_tone4":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe.svg","couple_with_heart_tone1":"1f491-1f3fb.svg","couple_with_heart_tone2":"1f491-1f3fc.svg","couple_with_heart_tone3":"1f491-1f3fd.svg","couple_with_heart_tone4":"1f491-1f3fe.svg","couple_with_heart_tone5":"1f491-1f3ff.svg","couple_with_heart_woman_man":"1f469-200d-2764-fe0f-200d-1f468.svg","couple_with_heart_woman_man_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_man_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff.svg","couple_with_heart_woman_man_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb.svg","couple_with_heart_woman_man_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc.svg","couple_with_heart_woman_man_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd.svg","couple_with_heart_woman_man_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe.svg","couple_with_heart_woman_woman_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_with_heart_woman_woman_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff.svg","couple_with_heart_woman_woman_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb.svg","couple_with_heart_woman_woman_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc.svg","couple_with_heart_woman_woman_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd.svg","couple_with_heart_woman_woman_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe.svg","couple_ww":"1f469-200d-2764-fe0f-200d-1f469.svg","couplekiss":"1f48f.svg","cow2":"1f404.svg","cow":"1f42e.svg","cowboy":"1f920.svg","crab":"1f980.svg","crayon":"1f58d.svg","credit_card":"1f4b3.svg","crescent_moon":"1f319.svg","cricket":"1f997.svg","cricket_game":"1f3cf.svg","crocodile":"1f40a.svg","croissant":"1f950.svg","cross":"271d.svg","crossed_flags":"1f38c.svg","crossed_swords":"2694.svg","crown":"1f451.svg","cruise_ship":"1f6f3.svg","cry":"1f622.svg","crying_cat_face":"1f63f.svg","crystal_ball":"1f52e.svg","cucumber":"1f952.svg","cup_with_straw":"1f964.svg","cupcake":"1f9c1.svg","cupid":"1f498.svg","curling_stone":"1f94c.svg","curly_haired":"1f9b1.svg","curly_loop":"27b0.svg","currency_exchange":"1f4b1.svg","curry":"1f35b.svg","custard":"1f36e.svg","customs":"1f6c3.svg","cut_of_meat":"1f969.svg","cyclone":"1f300.svg","dagger":"1f5e1.svg","dancer":"1f483.svg","dancer_tone1":"1f483-1f3fb.svg","dancer_tone2":"1f483-1f3fc.svg","dancer_tone3":"1f483-1f3fd.svg","dancer_tone4":"1f483-1f3fe.svg","dancer_tone5":"1f483-1f3ff.svg","dango":"1f361.svg","dark_sunglasses":"1f576.svg","dart":"1f3af.svg","dash":"1f4a8.svg","date":"1f4c5.svg","deaf_man":"1f9cf-200d-2642-fe0f.svg","deaf_man_tone1":"1f9cf-1f3fb-200d-2642-fe0f.svg","deaf_man_tone2":"1f9cf-1f3fc-200d-2642-fe0f.svg","deaf_man_tone3":"1f9cf-1f3fd-200d-2642-fe0f.svg","deaf_man_tone4":"1f9cf-1f3fe-200d-2642-fe0f.svg","deaf_man_tone5":"1f9cf-1f3ff-200d-2642-fe0f.svg","deaf_person":"1f9cf.svg","deaf_person_tone1":"1f9cf-1f3fb.svg","deaf_person_tone2":"1f9cf-1f3fc.svg","deaf_person_tone3":"1f9cf-1f3fd.svg","deaf_person_tone4":"1f9cf-1f3fe.svg","deaf_person_tone5":"1f9cf-1f3ff.svg","deaf_woman":"1f9cf-200d-2640-fe0f.svg","deaf_woman_tone1":"1f9cf-1f3fb-200d-2640-fe0f.svg","deaf_woman_tone2":"1f9cf-1f3fc-200d-2640-fe0f.svg","deaf_woman_tone3":"1f9cf-1f3fd-200d-2640-fe0f.svg","deaf_woman_tone4":"1f9cf-1f3fe-200d-2640-fe0f.svg","deaf_woman_tone5":"1f9cf-1f3ff-200d-2640-fe0f.svg","deciduous_tree":"1f333.svg","deer":"1f98c.svg","department_store":"1f3ec.svg","desert":"1f3dc.svg","desktop":"1f5a5.svg","detective":"1f575.svg","detective_tone1":"1f575-1f3fb.svg","detective_tone2":"1f575-1f3fc.svg","detective_tone3":"1f575-1f3fd.svg","detective_tone4":"1f575-1f3fe.svg","detective_tone5":"1f575-1f3ff.svg","diamond_shape_with_a_dot_inside":"1f4a0.svg","diamonds":"2666.svg","disappointed":"1f61e.svg","disappointed_relieved":"1f625.svg","disguised_face":"1f978.svg","dividers":"1f5c2.svg","diving_mask":"1f93f.svg","diya_lamp":"1fa94.svg","dizzy":"1f4ab.svg","dizzy_face":"1f635.svg","dna":"1f9ec.svg","do_not_litter":"1f6af.svg","dodo":"1f9a4.svg","dog2":"1f415.svg","dog":"1f436.svg","dollar":"1f4b5.svg","dolls":"1f38e.svg","dolphin":"1f42c.svg","door":"1f6aa.svg","doughnut":"1f369.svg","dove":"1f54a.svg","dragon":"1f409.svg","dragon_face":"1f432.svg","dress":"1f457.svg","dromedary_camel":"1f42a.svg","drooling_face":"1f924.svg","drop_of_blood":"1fa78.svg","droplet":"1f4a7.svg","drum":"1f941.svg","duck":"1f986.svg","dumpling":"1f95f.svg","dvd":"1f4c0.svg","e-mail":"1f4e7.svg","eagle":"1f985.svg","ear":"1f442.svg","ear_of_rice":"1f33e.svg","ear_tone1":"1f442-1f3fb.svg","ear_tone2":"1f442-1f3fc.svg","ear_tone3":"1f442-1f3fd.svg","ear_tone4":"1f442-1f3fe.svg","ear_tone5":"1f442-1f3ff.svg","ear_with_hearing_aid":"1f9bb.svg","ear_with_hearing_aid_tone1":"1f9bb-1f3fb.svg","ear_with_hearing_aid_tone2":"1f9bb-1f3fc.svg","ear_with_hearing_aid_tone3":"1f9bb-1f3fd.svg","ear_with_hearing_aid_tone4":"1f9bb-1f3fe.svg","ear_with_hearing_aid_tone5":"1f9bb-1f3ff.svg","earth_africa":"1f30d.svg","earth_americas":"1f30e.svg","earth_asia":"1f30f.svg","egg":"1f95a.svg","eggplant":"1f346.svg","eight":"38-20e3.svg","eight_pointed_black_star":"2734.svg","eight_spoked_asterisk":"2733.svg","eject":"23cf.svg","electric_plug":"1f50c.svg","elephant":"1f418.svg","elevator":"1f6d7.svg","elf":"1f9dd.svg","elf_tone1":"1f9dd-1f3fb.svg","elf_tone2":"1f9dd-1f3fc.svg","elf_tone3":"1f9dd-1f3fd.svg","elf_tone4":"1f9dd-1f3fe.svg","elf_tone5":"1f9dd-1f3ff.svg","end":"1f51a.svg","england":"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f.svg","envelope":"2709.svg","envelope_with_arrow":"1f4e9.svg","euro":"1f4b6.svg","european_castle":"1f3f0.svg","european_post_office":"1f3e4.svg","evergreen_tree":"1f332.svg","exclamation":"2757.svg","exploding_head":"1f92f.svg","expressionless":"1f611.svg","eye":"1f441.svg","eye_in_speech_bubble":"1f441-200d-1f5e8.svg","eyeglasses":"1f453.svg","eyes":"1f440.svg","face_exhaling":"1f62e-200d-1f4a8.svg","face_in_clouds":"1f636-200d-1f32b-fe0f.svg","face_vomiting":"1f92e.svg","face_with_hand_over_mouth":"1f92d.svg","face_with_monocle":"1f9d0.svg","face_with_raised_eyebrow":"1f928.svg","face_with_spiral_eyes":"1f635-200d-1f4ab.svg","face_with_symbols_over_mouth":"1f92c.svg","factory":"1f3ed.svg","factory_worker":"1f9d1-200d-1f3ed.svg","factory_worker_tone1":"1f9d1-1f3fb-200d-1f3ed.svg","factory_worker_tone2":"1f9d1-1f3fc-200d-1f3ed.svg","factory_worker_tone3":"1f9d1-1f3fd-200d-1f3ed.svg","factory_worker_tone4":"1f9d1-1f3fe-200d-1f3ed.svg","factory_worker_tone5":"1f9d1-1f3ff-200d-1f3ed.svg","fairy":"1f9da.svg","fairy_tone1":"1f9da-1f3fb.svg","fairy_tone2":"1f9da-1f3fc.svg","fairy_tone3":"1f9da-1f3fd.svg","fairy_tone4":"1f9da-1f3fe.svg","fairy_tone5":"1f9da-1f3ff.svg","falafel":"1f9c6.svg","fallen_leaf":"1f342.svg","family":"1f46a.svg","family_man_boy":"1f468-200d-1f466.svg","family_man_boy_boy":"1f468-200d-1f466-200d-1f466.svg","family_man_girl":"1f468-200d-1f467.svg","family_man_girl_boy":"1f468-200d-1f467-200d-1f466.svg","family_man_girl_girl":"1f468-200d-1f467-200d-1f467.svg","family_man_woman_boy":"1f468-200d-1f469-200d-1f466.svg","family_mmb":"1f468-200d-1f468-200d-1f466.svg","family_mmbb":"1f468-200d-1f468-200d-1f466-200d-1f466.svg","family_mmg":"1f468-200d-1f468-200d-1f467.svg","family_mmgb":"1f468-200d-1f468-200d-1f467-200d-1f466.svg","family_mmgg":"1f468-200d-1f468-200d-1f467-200d-1f467.svg","family_mwbb":"1f468-200d-1f469-200d-1f466-200d-1f466.svg","family_mwg":"1f468-200d-1f469-200d-1f467.svg","family_mwgb":"1f468-200d-1f469-200d-1f467-200d-1f466.svg","family_mwgg":"1f468-200d-1f469-200d-1f467-200d-1f467.svg","family_woman_boy":"1f469-200d-1f466.svg","family_woman_boy_boy":"1f469-200d-1f466-200d-1f466.svg","family_woman_girl":"1f469-200d-1f467.svg","family_woman_girl_boy":"1f469-200d-1f467-200d-1f466.svg","family_woman_girl_girl":"1f469-200d-1f467-200d-1f467.svg","family_wwb":"1f469-200d-1f469-200d-1f466.svg","family_wwbb":"1f469-200d-1f469-200d-1f466-200d-1f466.svg","family_wwg":"1f469-200d-1f469-200d-1f467.svg","family_wwgb":"1f469-200d-1f469-200d-1f467-200d-1f466.svg","family_wwgg":"1f469-200d-1f469-200d-1f467-200d-1f467.svg","farmer":"1f9d1-200d-1f33e.svg","farmer_tone1":"1f9d1-1f3fb-200d-1f33e.svg","farmer_tone2":"1f9d1-1f3fc-200d-1f33e.svg","farmer_tone3":"1f9d1-1f3fd-200d-1f33e.svg","farmer_tone4":"1f9d1-1f3fe-200d-1f33e.svg","farmer_tone5":"1f9d1-1f3ff-200d-1f33e.svg","fast_forward":"23e9.svg","fax":"1f4e0.svg","fearful":"1f628.svg","feather":"1fab6.svg","feet":"1f43e.svg","female_sign":"2640.svg","ferris_wheel":"1f3a1.svg","ferry":"26f4.svg","field_hockey":"1f3d1.svg","file_cabinet":"1f5c4.svg","file_folder":"1f4c1.svg","film_frames":"1f39e.svg","fingers_crossed":"1f91e.svg","fingers_crossed_tone1":"1f91e-1f3fb.svg","fingers_crossed_tone2":"1f91e-1f3fc.svg","fingers_crossed_tone3":"1f91e-1f3fd.svg","fingers_crossed_tone4":"1f91e-1f3fe.svg","fingers_crossed_tone5":"1f91e-1f3ff.svg","fire":"1f525.svg","fire_engine":"1f692.svg","fire_extinguisher":"1f9ef.svg","firecracker":"1f9e8.svg","firefighter":"1f9d1-200d-1f692.svg","firefighter_tone1":"1f9d1-1f3fb-200d-1f692.svg","firefighter_tone2":"1f9d1-1f3fc-200d-1f692.svg","firefighter_tone3":"1f9d1-1f3fd-200d-1f692.svg","firefighter_tone4":"1f9d1-1f3fe-200d-1f692.svg","firefighter_tone5":"1f9d1-1f3ff-200d-1f692.svg","fireworks":"1f386.svg","first_place":"1f947.svg","first_quarter_moon":"1f313.svg","first_quarter_moon_with_face":"1f31b.svg","fish":"1f41f.svg","fish_cake":"1f365.svg","fishing_pole_and_fish":"1f3a3.svg","fist":"270a.svg","fist_tone1":"270a-1f3fb.svg","fist_tone2":"270a-1f3fc.svg","fist_tone3":"270a-1f3fd.svg","fist_tone4":"270a-1f3fe.svg","fist_tone5":"270a-1f3ff.svg","five":"35-20e3.svg","flag_ac":"1f1e6-1f1e8.svg","flag_ad":"1f1e6-1f1e9.svg","flag_ae":"1f1e6-1f1ea.svg","flag_af":"1f1e6-1f1eb.svg","flag_ag":"1f1e6-1f1ec.svg","flag_ai":"1f1e6-1f1ee.svg","flag_al":"1f1e6-1f1f1.svg","flag_am":"1f1e6-1f1f2.svg","flag_ao":"1f1e6-1f1f4.svg","flag_aq":"1f1e6-1f1f6.svg","flag_ar":"1f1e6-1f1f7.svg","flag_as":"1f1e6-1f1f8.svg","flag_at":"1f1e6-1f1f9.svg","flag_au":"1f1e6-1f1fa.svg","flag_aw":"1f1e6-1f1fc.svg","flag_ax":"1f1e6-1f1fd.svg","flag_az":"1f1e6-1f1ff.svg","flag_ba":"1f1e7-1f1e6.svg","flag_bb":"1f1e7-1f1e7.svg","flag_bd":"1f1e7-1f1e9.svg","flag_be":"1f1e7-1f1ea.svg","flag_bf":"1f1e7-1f1eb.svg","flag_bg":"1f1e7-1f1ec.svg","flag_bh":"1f1e7-1f1ed.svg","flag_bi":"1f1e7-1f1ee.svg","flag_bj":"1f1e7-1f1ef.svg","flag_bl":"1f1e7-1f1f1.svg","flag_black":"1f3f4.svg","flag_bm":"1f1e7-1f1f2.svg","flag_bn":"1f1e7-1f1f3.svg","flag_bo":"1f1e7-1f1f4.svg","flag_bq":"1f1e7-1f1f6.svg","flag_br":"1f1e7-1f1f7.svg","flag_bs":"1f1e7-1f1f8.svg","flag_bt":"1f1e7-1f1f9.svg","flag_bv":"1f1e7-1f1fb.svg","flag_bw":"1f1e7-1f1fc.svg","flag_by":"1f1e7-1f1fe.svg","flag_bz":"1f1e7-1f1ff.svg","flag_ca":"1f1e8-1f1e6.svg","flag_cc":"1f1e8-1f1e8.svg","flag_cd":"1f1e8-1f1e9.svg","flag_cf":"1f1e8-1f1eb.svg","flag_cg":"1f1e8-1f1ec.svg","flag_ch":"1f1e8-1f1ed.svg","flag_ci":"1f1e8-1f1ee.svg","flag_ck":"1f1e8-1f1f0.svg","flag_cl":"1f1e8-1f1f1.svg","flag_cm":"1f1e8-1f1f2.svg","flag_cn":"1f1e8-1f1f3.svg","flag_co":"1f1e8-1f1f4.svg","flag_cp":"1f1e8-1f1f5.svg","flag_cr":"1f1e8-1f1f7.svg","flag_cu":"1f1e8-1f1fa.svg","flag_cv":"1f1e8-1f1fb.svg","flag_cw":"1f1e8-1f1fc.svg","flag_cx":"1f1e8-1f1fd.svg","flag_cy":"1f1e8-1f1fe.svg","flag_cz":"1f1e8-1f1ff.svg","flag_de":"1f1e9-1f1ea.svg","flag_dg":"1f1e9-1f1ec.svg","flag_dj":"1f1e9-1f1ef.svg","flag_dk":"1f1e9-1f1f0.svg","flag_dm":"1f1e9-1f1f2.svg","flag_do":"1f1e9-1f1f4.svg","flag_dz":"1f1e9-1f1ff.svg","flag_ea":"1f1ea-1f1e6.svg","flag_ec":"1f1ea-1f1e8.svg","flag_ee":"1f1ea-1f1ea.svg","flag_eg":"1f1ea-1f1ec.svg","flag_eh":"1f1ea-1f1ed.svg","flag_er":"1f1ea-1f1f7.svg","flag_es":"1f1ea-1f1f8.svg","flag_et":"1f1ea-1f1f9.svg","flag_eu":"1f1ea-1f1fa.svg","flag_fi":"1f1eb-1f1ee.svg","flag_fj":"1f1eb-1f1ef.svg","flag_fk":"1f1eb-1f1f0.svg","flag_fm":"1f1eb-1f1f2.svg","flag_fo":"1f1eb-1f1f4.svg","flag_fr":"1f1eb-1f1f7.svg","flag_ga":"1f1ec-1f1e6.svg","flag_gb":"1f1ec-1f1e7.svg","flag_gd":"1f1ec-1f1e9.svg","flag_ge":"1f1ec-1f1ea.svg","flag_gf":"1f1ec-1f1eb.svg","flag_gg":"1f1ec-1f1ec.svg","flag_gh":"1f1ec-1f1ed.svg","flag_gi":"1f1ec-1f1ee.svg","flag_gl":"1f1ec-1f1f1.svg","flag_gm":"1f1ec-1f1f2.svg","flag_gn":"1f1ec-1f1f3.svg","flag_gp":"1f1ec-1f1f5.svg","flag_gq":"1f1ec-1f1f6.svg","flag_gr":"1f1ec-1f1f7.svg","flag_gs":"1f1ec-1f1f8.svg","flag_gt":"1f1ec-1f1f9.svg","flag_gu":"1f1ec-1f1fa.svg","flag_gw":"1f1ec-1f1fc.svg","flag_gy":"1f1ec-1f1fe.svg","flag_hk":"1f1ed-1f1f0.svg","flag_hm":"1f1ed-1f1f2.svg","flag_hn":"1f1ed-1f1f3.svg","flag_hr":"1f1ed-1f1f7.svg","flag_ht":"1f1ed-1f1f9.svg","flag_hu":"1f1ed-1f1fa.svg","flag_ic":"1f1ee-1f1e8.svg","flag_id":"1f1ee-1f1e9.svg","flag_ie":"1f1ee-1f1ea.svg","flag_il":"1f1ee-1f1f1.svg","flag_im":"1f1ee-1f1f2.svg","flag_in":"1f1ee-1f1f3.svg","flag_io":"1f1ee-1f1f4.svg","flag_iq":"1f1ee-1f1f6.svg","flag_ir":"1f1ee-1f1f7.svg","flag_is":"1f1ee-1f1f8.svg","flag_it":"1f1ee-1f1f9.svg","flag_je":"1f1ef-1f1ea.svg","flag_jm":"1f1ef-1f1f2.svg","flag_jo":"1f1ef-1f1f4.svg","flag_jp":"1f1ef-1f1f5.svg","flag_ke":"1f1f0-1f1ea.svg","flag_kg":"1f1f0-1f1ec.svg","flag_kh":"1f1f0-1f1ed.svg","flag_ki":"1f1f0-1f1ee.svg","flag_km":"1f1f0-1f1f2.svg","flag_kn":"1f1f0-1f1f3.svg","flag_kp":"1f1f0-1f1f5.svg","flag_kr":"1f1f0-1f1f7.svg","flag_kw":"1f1f0-1f1fc.svg","flag_ky":"1f1f0-1f1fe.svg","flag_kz":"1f1f0-1f1ff.svg","flag_la":"1f1f1-1f1e6.svg","flag_lb":"1f1f1-1f1e7.svg","flag_lc":"1f1f1-1f1e8.svg","flag_li":"1f1f1-1f1ee.svg","flag_lk":"1f1f1-1f1f0.svg","flag_lr":"1f1f1-1f1f7.svg","flag_ls":"1f1f1-1f1f8.svg","flag_lt":"1f1f1-1f1f9.svg","flag_lu":"1f1f1-1f1fa.svg","flag_lv":"1f1f1-1f1fb.svg","flag_ly":"1f1f1-1f1fe.svg","flag_ma":"1f1f2-1f1e6.svg","flag_mc":"1f1f2-1f1e8.svg","flag_md":"1f1f2-1f1e9.svg","flag_me":"1f1f2-1f1ea.svg","flag_mf":"1f1f2-1f1eb.svg","flag_mg":"1f1f2-1f1ec.svg","flag_mh":"1f1f2-1f1ed.svg","flag_mk":"1f1f2-1f1f0.svg","flag_ml":"1f1f2-1f1f1.svg","flag_mm":"1f1f2-1f1f2.svg","flag_mn":"1f1f2-1f1f3.svg","flag_mo":"1f1f2-1f1f4.svg","flag_mp":"1f1f2-1f1f5.svg","flag_mq":"1f1f2-1f1f6.svg","flag_mr":"1f1f2-1f1f7.svg","flag_ms":"1f1f2-1f1f8.svg","flag_mt":"1f1f2-1f1f9.svg","flag_mu":"1f1f2-1f1fa.svg","flag_mv":"1f1f2-1f1fb.svg","flag_mw":"1f1f2-1f1fc.svg","flag_mx":"1f1f2-1f1fd.svg","flag_my":"1f1f2-1f1fe.svg","flag_mz":"1f1f2-1f1ff.svg","flag_na":"1f1f3-1f1e6.svg","flag_nc":"1f1f3-1f1e8.svg","flag_ne":"1f1f3-1f1ea.svg","flag_nf":"1f1f3-1f1eb.svg","flag_ng":"1f1f3-1f1ec.svg","flag_ni":"1f1f3-1f1ee.svg","flag_nl":"1f1f3-1f1f1.svg","flag_no":"1f1f3-1f1f4.svg","flag_np":"1f1f3-1f1f5.svg","flag_nr":"1f1f3-1f1f7.svg","flag_nu":"1f1f3-1f1fa.svg","flag_nz":"1f1f3-1f1ff.svg","flag_om":"1f1f4-1f1f2.svg","flag_pa":"1f1f5-1f1e6.svg","flag_pe":"1f1f5-1f1ea.svg","flag_pf":"1f1f5-1f1eb.svg","flag_pg":"1f1f5-1f1ec.svg","flag_ph":"1f1f5-1f1ed.svg","flag_pk":"1f1f5-1f1f0.svg","flag_pl":"1f1f5-1f1f1.svg","flag_pm":"1f1f5-1f1f2.svg","flag_pn":"1f1f5-1f1f3.svg","flag_pr":"1f1f5-1f1f7.svg","flag_ps":"1f1f5-1f1f8.svg","flag_pt":"1f1f5-1f1f9.svg","flag_pw":"1f1f5-1f1fc.svg","flag_py":"1f1f5-1f1fe.svg","flag_qa":"1f1f6-1f1e6.svg","flag_re":"1f1f7-1f1ea.svg","flag_ro":"1f1f7-1f1f4.svg","flag_rs":"1f1f7-1f1f8.svg","flag_ru":"1f1f7-1f1fa.svg","flag_rw":"1f1f7-1f1fc.svg","flag_sa":"1f1f8-1f1e6.svg","flag_sb":"1f1f8-1f1e7.svg","flag_sc":"1f1f8-1f1e8.svg","flag_sd":"1f1f8-1f1e9.svg","flag_se":"1f1f8-1f1ea.svg","flag_sg":"1f1f8-1f1ec.svg","flag_sh":"1f1f8-1f1ed.svg","flag_si":"1f1f8-1f1ee.svg","flag_sj":"1f1f8-1f1ef.svg","flag_sk":"1f1f8-1f1f0.svg","flag_sl":"1f1f8-1f1f1.svg","flag_sm":"1f1f8-1f1f2.svg","flag_sn":"1f1f8-1f1f3.svg","flag_so":"1f1f8-1f1f4.svg","flag_sr":"1f1f8-1f1f7.svg","flag_ss":"1f1f8-1f1f8.svg","flag_st":"1f1f8-1f1f9.svg","flag_sv":"1f1f8-1f1fb.svg","flag_sx":"1f1f8-1f1fd.svg","flag_sy":"1f1f8-1f1fe.svg","flag_sz":"1f1f8-1f1ff.svg","flag_ta":"1f1f9-1f1e6.svg","flag_tc":"1f1f9-1f1e8.svg","flag_td":"1f1f9-1f1e9.svg","flag_tf":"1f1f9-1f1eb.svg","flag_tg":"1f1f9-1f1ec.svg","flag_th":"1f1f9-1f1ed.svg","flag_tj":"1f1f9-1f1ef.svg","flag_tk":"1f1f9-1f1f0.svg","flag_tl":"1f1f9-1f1f1.svg","flag_tm":"1f1f9-1f1f2.svg","flag_tn":"1f1f9-1f1f3.svg","flag_to":"1f1f9-1f1f4.svg","flag_tr":"1f1f9-1f1f7.svg","flag_tt":"1f1f9-1f1f9.svg","flag_tv":"1f1f9-1f1fb.svg","flag_tw":"1f1f9-1f1fc.svg","flag_tz":"1f1f9-1f1ff.svg","flag_ua":"1f1fa-1f1e6.svg","flag_ug":"1f1fa-1f1ec.svg","flag_um":"1f1fa-1f1f2.svg","flag_us":"1f1fa-1f1f8.svg","flag_uy":"1f1fa-1f1fe.svg","flag_uz":"1f1fa-1f1ff.svg","flag_va":"1f1fb-1f1e6.svg","flag_vc":"1f1fb-1f1e8.svg","flag_ve":"1f1fb-1f1ea.svg","flag_vg":"1f1fb-1f1ec.svg","flag_vi":"1f1fb-1f1ee.svg","flag_vn":"1f1fb-1f1f3.svg","flag_vu":"1f1fb-1f1fa.svg","flag_wf":"1f1fc-1f1eb.svg","flag_white":"1f3f3.svg","flag_ws":"1f1fc-1f1f8.svg","flag_xk":"1f1fd-1f1f0.svg","flag_ye":"1f1fe-1f1ea.svg","flag_yt":"1f1fe-1f1f9.svg","flag_za":"1f1ff-1f1e6.svg","flag_zm":"1f1ff-1f1f2.svg","flag_zw":"1f1ff-1f1fc.svg","flags":"1f38f.svg","flamingo":"1f9a9.svg","flashlight":"1f526.svg","flatbread":"1fad3.svg","fleur-de-lis":"269c.svg","floppy_disk":"1f4be.svg","flower_playing_cards":"1f3b4.svg","flushed":"1f633.svg","fly":"1fab0.svg","flying_disc":"1f94f.svg","flying_saucer":"1f6f8.svg","fog":"1f32b.svg","foggy":"1f301.svg","fondue":"1fad5.svg","foot":"1f9b6.svg","foot_tone1":"1f9b6-1f3fb.svg","foot_tone2":"1f9b6-1f3fc.svg","foot_tone3":"1f9b6-1f3fd.svg","foot_tone4":"1f9b6-1f3fe.svg","foot_tone5":"1f9b6-1f3ff.svg","football":"1f3c8.svg","footprints":"1f463.svg","fork_and_knife":"1f374.svg","fork_knife_plate":"1f37d.svg","fortune_cookie":"1f960.svg","fountain":"26f2.svg","four":"34-20e3.svg","four_leaf_clover":"1f340.svg","fox":"1f98a.svg","frame_photo":"1f5bc.svg","free":"1f193.svg","french_bread":"1f956.svg","fried_shrimp":"1f364.svg","fries":"1f35f.svg","frog":"1f438.svg","frowning2":"2639.svg","frowning":"1f626.svg","fuelpump":"26fd.svg","full_moon":"1f315.svg","full_moon_with_face":"1f31d.svg","game_die":"1f3b2.svg","garlic":"1f9c4.svg","gear":"2699.svg","gem":"1f48e.svg","gemini":"264a.svg","genie":"1f9de.svg","ghost":"1f47b.svg","gift":"1f381.svg","gift_heart":"1f49d.svg","giraffe":"1f992.svg","girl":"1f467.svg","girl_tone1":"1f467-1f3fb.svg","girl_tone2":"1f467-1f3fc.svg","girl_tone3":"1f467-1f3fd.svg","girl_tone4":"1f467-1f3fe.svg","girl_tone5":"1f467-1f3ff.svg","globe_with_meridians":"1f310.svg","gloves":"1f9e4.svg","goal":"1f945.svg","goat":"1f410.svg","goggles":"1f97d.svg","golf":"26f3.svg","gorilla":"1f98d.svg","grapes":"1f347.svg","green_apple":"1f34f.svg","green_book":"1f4d7.svg","green_circle":"1f7e2.svg","green_heart":"1f49a.svg","green_square":"1f7e9.svg","grey_exclamation":"2755.svg","grey_question":"2754.svg","grimacing":"1f62c.svg","grin":"1f601.svg","grinning":"1f600.svg","guard":"1f482.svg","guard_tone1":"1f482-1f3fb.svg","guard_tone2":"1f482-1f3fc.svg","guard_tone3":"1f482-1f3fd.svg","guard_tone4":"1f482-1f3fe.svg","guard_tone5":"1f482-1f3ff.svg","guide_dog":"1f9ae.svg","guitar":"1f3b8.svg","gun":"1f52b.svg","hamburger":"1f354.svg","hammer":"1f528.svg","hammer_pick":"2692.svg","hamster":"1f439.svg","hand_splayed":"1f590.svg","hand_splayed_tone1":"1f590-1f3fb.svg","hand_splayed_tone2":"1f590-1f3fc.svg","hand_splayed_tone3":"1f590-1f3fd.svg","hand_splayed_tone4":"1f590-1f3fe.svg","hand_splayed_tone5":"1f590-1f3ff.svg","handbag":"1f45c.svg","handshake":"1f91d.svg","hash":"23-20e3.svg","hatched_chick":"1f425.svg","hatching_chick":"1f423.svg","head_bandage":"1f915.svg","headphones":"1f3a7.svg","headstone":"1faa6.svg","health_worker":"1f9d1-200d-2695-fe0f.svg","health_worker_tone1":"1f9d1-1f3fb-200d-2695-fe0f.svg","health_worker_tone2":"1f9d1-1f3fc-200d-2695-fe0f.svg","health_worker_tone3":"1f9d1-1f3fd-200d-2695-fe0f.svg","health_worker_tone4":"1f9d1-1f3fe-200d-2695-fe0f.svg","health_worker_tone5":"1f9d1-1f3ff-200d-2695-fe0f.svg","hear_no_evil":"1f649.svg","heart":"2764.svg","heart_decoration":"1f49f.svg","heart_exclamation":"2763.svg","heart_eyes":"1f60d.svg","heart_eyes_cat":"1f63b.svg","heart_on_fire":"2764-fe0f-200d-1f525.svg","heartbeat":"1f493.svg","heartpulse":"1f497.svg","hearts":"2665.svg","heavy_check_mark":"2714.svg","heavy_division_sign":"2797.svg","heavy_dollar_sign":"1f4b2.svg","heavy_minus_sign":"2796.svg","heavy_multiplication_x":"2716.svg","heavy_plus_sign":"2795.svg","hedgehog":"1f994.svg","helicopter":"1f681.svg","helmet_with_cross":"26d1.svg","herb":"1f33f.svg","hibiscus":"1f33a.svg","high_brightness":"1f506.svg","high_heel":"1f460.svg","hiking_boot":"1f97e.svg","hindu_temple":"1f6d5.svg","hippopotamus":"1f99b.svg","hockey":"1f3d2.svg","hole":"1f573.svg","homes":"1f3d8.svg","honey_pot":"1f36f.svg","hook":"1fa9d.svg","horse":"1f434.svg","horse_racing":"1f3c7.svg","horse_racing_tone1":"1f3c7-1f3fb.svg","horse_racing_tone2":"1f3c7-1f3fc.svg","horse_racing_tone3":"1f3c7-1f3fd.svg","horse_racing_tone4":"1f3c7-1f3fe.svg","horse_racing_tone5":"1f3c7-1f3ff.svg","hospital":"1f3e5.svg","hot_face":"1f975.svg","hot_pepper":"1f336.svg","hotdog":"1f32d.svg","hotel":"1f3e8.svg","hotsprings":"2668.svg","hourglass":"231b.svg","hourglass_flowing_sand":"23f3.svg","house":"1f3e0.svg","house_abandoned":"1f3da.svg","house_with_garden":"1f3e1.svg","hugging":"1f917.svg","hushed":"1f62f.svg","hut":"1f6d6.svg","ice_cream":"1f368.svg","ice_cube":"1f9ca.svg","ice_skate":"26f8.svg","icecream":"1f366.svg","id":"1f194.svg","ideograph_advantage":"1f250.svg","imp":"1f47f.svg","inbox_tray":"1f4e5.svg","incoming_envelope":"1f4e8.svg","infinity":"267e.svg","information_source":"2139.svg","innocent":"1f607.svg","interrobang":"2049.svg","island":"1f3dd.svg","izakaya_lantern":"1f3ee.svg","jack_o_lantern":"1f383.svg","japan":"1f5fe.svg","japanese_castle":"1f3ef.svg","japanese_goblin":"1f47a.svg","japanese_ogre":"1f479.svg","jeans":"1f456.svg","jigsaw":"1f9e9.svg","joy":"1f602.svg","joy_cat":"1f639.svg","joystick":"1f579.svg","judge":"1f9d1-200d-2696-fe0f.svg","judge_tone1":"1f9d1-1f3fb-200d-2696-fe0f.svg","judge_tone2":"1f9d1-1f3fc-200d-2696-fe0f.svg","judge_tone3":"1f9d1-1f3fd-200d-2696-fe0f.svg","judge_tone4":"1f9d1-1f3fe-200d-2696-fe0f.svg","judge_tone5":"1f9d1-1f3ff-200d-2696-fe0f.svg","kaaba":"1f54b.svg","kangaroo":"1f998.svg","key2":"1f5dd.svg","key":"1f511.svg","keyboard":"2328.svg","keycap_ten":"1f51f.svg","kimono":"1f458.svg","kiss":"1f48b.svg","kiss_man_man_tone1":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone1_tone2":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone1_tone3":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone1_tone4":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone1_tone5":"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone2":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone2_tone1":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone2_tone3":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone2_tone4":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone2_tone5":"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone3":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone3_tone1":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone3_tone2":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone3_tone4":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone3_tone5":"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone4":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_man_man_tone4_tone1":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone4_tone2":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone4_tone3":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone4_tone5":"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone5":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_man_man_tone5_tone1":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_man_man_tone5_tone2":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_man_man_tone5_tone3":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_man_man_tone5_tone4":"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_mm":"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468.svg","kiss_person_person_tone1_tone2":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone1_tone3":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone1_tone4":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_person_person_tone1_tone5":"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone2_tone1":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone2_tone3":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone2_tone4":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_person_person_tone2_tone5":"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone3_tone1":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone3_tone2":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone3_tone4":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_person_person_tone3_tone5":"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone4_tone1":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone4_tone2":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone4_tone3":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone4_tone5":"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff.svg","kiss_person_person_tone5_tone1":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb.svg","kiss_person_person_tone5_tone2":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc.svg","kiss_person_person_tone5_tone3":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd.svg","kiss_person_person_tone5_tone4":"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe.svg","kiss_tone1":"1f48f-1f3fb.svg","kiss_tone2":"1f48f-1f3fc.svg","kiss_tone3":"1f48f-1f3fd.svg","kiss_tone4":"1f48f-1f3fe.svg","kiss_tone5":"1f48f-1f3ff.svg","kiss_woman_man":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468.svg","kiss_woman_man_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_man_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff.svg","kiss_woman_man_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb.svg","kiss_woman_man_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc.svg","kiss_woman_man_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd.svg","kiss_woman_man_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe.svg","kiss_woman_woman_tone1":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone1_tone2":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone1_tone3":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone1_tone4":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone1_tone5":"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone2":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone2_tone1":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone2_tone3":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone2_tone4":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone2_tone5":"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone3":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone3_tone1":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone3_tone2":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone3_tone4":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone3_tone5":"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone4":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_woman_woman_tone4_tone1":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone4_tone2":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone4_tone3":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone4_tone5":"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone5":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff.svg","kiss_woman_woman_tone5_tone1":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb.svg","kiss_woman_woman_tone5_tone2":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc.svg","kiss_woman_woman_tone5_tone3":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd.svg","kiss_woman_woman_tone5_tone4":"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe.svg","kiss_ww":"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469.svg","kissing":"1f617.svg","kissing_cat":"1f63d.svg","kissing_closed_eyes":"1f61a.svg","kissing_heart":"1f618.svg","kissing_smiling_eyes":"1f619.svg","kite":"1fa81.svg","kiwi":"1f95d.svg","knife":"1f52a.svg","knot":"1faa2.svg","koala":"1f428.svg","koko":"1f201.svg","lab_coat":"1f97c.svg","label":"1f3f7.svg","lacrosse":"1f94d.svg","ladder":"1fa9c.svg","lady_beetle":"1f41e.svg","large_blue_diamond":"1f537.svg","large_orange_diamond":"1f536.svg","last_quarter_moon":"1f317.svg","last_quarter_moon_with_face":"1f31c.svg","laughing":"1f606.svg","leafy_green":"1f96c.svg","leaves":"1f343.svg","ledger":"1f4d2.svg","left_facing_fist":"1f91b.svg","left_facing_fist_tone1":"1f91b-1f3fb.svg","left_facing_fist_tone2":"1f91b-1f3fc.svg","left_facing_fist_tone3":"1f91b-1f3fd.svg","left_facing_fist_tone4":"1f91b-1f3fe.svg","left_facing_fist_tone5":"1f91b-1f3ff.svg","left_luggage":"1f6c5.svg","left_right_arrow":"2194.svg","leftwards_arrow_with_hook":"21a9.svg","leg":"1f9b5.svg","leg_tone1":"1f9b5-1f3fb.svg","leg_tone2":"1f9b5-1f3fc.svg","leg_tone3":"1f9b5-1f3fd.svg","leg_tone4":"1f9b5-1f3fe.svg","leg_tone5":"1f9b5-1f3ff.svg","lemon":"1f34b.svg","leo":"264c.svg","leopard":"1f406.svg","level_slider":"1f39a.svg","levitate":"1f574.svg","levitate_tone1":"1f574-1f3fb.svg","levitate_tone2":"1f574-1f3fc.svg","levitate_tone3":"1f574-1f3fd.svg","levitate_tone4":"1f574-1f3fe.svg","levitate_tone5":"1f574-1f3ff.svg","libra":"264e.svg","light_rail":"1f688.svg","link":"1f517.svg","lion_face":"1f981.svg","lips":"1f444.svg","lipstick":"1f484.svg","lizard":"1f98e.svg","llama":"1f999.svg","lobster":"1f99e.svg","lock":"1f512.svg","lock_with_ink_pen":"1f50f.svg","lollipop":"1f36d.svg","long_drum":"1fa98.svg","loop":"27bf.svg","loud_sound":"1f50a.svg","loudspeaker":"1f4e2.svg","love_hotel":"1f3e9.svg","love_letter":"1f48c.svg","love_you_gesture":"1f91f.svg","love_you_gesture_tone1":"1f91f-1f3fb.svg","love_you_gesture_tone2":"1f91f-1f3fc.svg","love_you_gesture_tone3":"1f91f-1f3fd.svg","love_you_gesture_tone4":"1f91f-1f3fe.svg","love_you_gesture_tone5":"1f91f-1f3ff.svg","low_brightness":"1f505.svg","luggage":"1f9f3.svg","lungs":"1fac1.svg","lying_face":"1f925.svg","m":"24c2.svg","mag":"1f50d.svg","mag_right":"1f50e.svg","mage":"1f9d9.svg","mage_tone1":"1f9d9-1f3fb.svg","mage_tone2":"1f9d9-1f3fc.svg","mage_tone3":"1f9d9-1f3fd.svg","mage_tone4":"1f9d9-1f3fe.svg","mage_tone5":"1f9d9-1f3ff.svg","magic_wand":"1fa84.svg","magnet":"1f9f2.svg","mahjong":"1f004.svg","mailbox":"1f4eb.svg","mailbox_closed":"1f4ea.svg","mailbox_with_mail":"1f4ec.svg","mailbox_with_no_mail":"1f4ed.svg","male_sign":"2642.svg","mammoth":"1f9a3.svg","man":"1f468.svg","man_artist":"1f468-200d-1f3a8.svg","man_artist_tone1":"1f468-1f3fb-200d-1f3a8.svg","man_artist_tone2":"1f468-1f3fc-200d-1f3a8.svg","man_artist_tone3":"1f468-1f3fd-200d-1f3a8.svg","man_artist_tone4":"1f468-1f3fe-200d-1f3a8.svg","man_artist_tone5":"1f468-1f3ff-200d-1f3a8.svg","man_astronaut":"1f468-200d-1f680.svg","man_astronaut_tone1":"1f468-1f3fb-200d-1f680.svg","man_astronaut_tone2":"1f468-1f3fc-200d-1f680.svg","man_astronaut_tone3":"1f468-1f3fd-200d-1f680.svg","man_astronaut_tone4":"1f468-1f3fe-200d-1f680.svg","man_astronaut_tone5":"1f468-1f3ff-200d-1f680.svg","man_bald":"1f468-200d-1f9b2.svg","man_bald_tone1":"1f468-1f3fb-200d-1f9b2.svg","man_bald_tone2":"1f468-1f3fc-200d-1f9b2.svg","man_bald_tone3":"1f468-1f3fd-200d-1f9b2.svg","man_bald_tone4":"1f468-1f3fe-200d-1f9b2.svg","man_bald_tone5":"1f468-1f3ff-200d-1f9b2.svg","man_beard":"1f9d4-200d-2642-fe0f.svg","man_biking":"1f6b4-200d-2642-fe0f.svg","man_biking_tone1":"1f6b4-1f3fb-200d-2642-fe0f.svg","man_biking_tone2":"1f6b4-1f3fc-200d-2642-fe0f.svg","man_biking_tone3":"1f6b4-1f3fd-200d-2642-fe0f.svg","man_biking_tone4":"1f6b4-1f3fe-200d-2642-fe0f.svg","man_biking_tone5":"1f6b4-1f3ff-200d-2642-fe0f.svg","man_bouncing_ball":"26f9-fe0f-200d-2642-fe0f.svg","man_bouncing_ball_tone1":"26f9-1f3fb-200d-2642-fe0f.svg","man_bouncing_ball_tone2":"26f9-1f3fc-200d-2642-fe0f.svg","man_bouncing_ball_tone3":"26f9-1f3fd-200d-2642-fe0f.svg","man_bouncing_ball_tone4":"26f9-1f3fe-200d-2642-fe0f.svg","man_bouncing_ball_tone5":"26f9-1f3ff-200d-2642-fe0f.svg","man_bowing":"1f647-200d-2642-fe0f.svg","man_bowing_tone1":"1f647-1f3fb-200d-2642-fe0f.svg","man_bowing_tone2":"1f647-1f3fc-200d-2642-fe0f.svg","man_bowing_tone3":"1f647-1f3fd-200d-2642-fe0f.svg","man_bowing_tone4":"1f647-1f3fe-200d-2642-fe0f.svg","man_bowing_tone5":"1f647-1f3ff-200d-2642-fe0f.svg","man_cartwheeling":"1f938-200d-2642-fe0f.svg","man_cartwheeling_tone1":"1f938-1f3fb-200d-2642-fe0f.svg","man_cartwheeling_tone2":"1f938-1f3fc-200d-2642-fe0f.svg","man_cartwheeling_tone3":"1f938-1f3fd-200d-2642-fe0f.svg","man_cartwheeling_tone4":"1f938-1f3fe-200d-2642-fe0f.svg","man_cartwheeling_tone5":"1f938-1f3ff-200d-2642-fe0f.svg","man_climbing":"1f9d7-200d-2642-fe0f.svg","man_climbing_tone1":"1f9d7-1f3fb-200d-2642-fe0f.svg","man_climbing_tone2":"1f9d7-1f3fc-200d-2642-fe0f.svg","man_climbing_tone3":"1f9d7-1f3fd-200d-2642-fe0f.svg","man_climbing_tone4":"1f9d7-1f3fe-200d-2642-fe0f.svg","man_climbing_tone5":"1f9d7-1f3ff-200d-2642-fe0f.svg","man_construction_worker":"1f477-200d-2642-fe0f.svg","man_construction_worker_tone1":"1f477-1f3fb-200d-2642-fe0f.svg","man_construction_worker_tone2":"1f477-1f3fc-200d-2642-fe0f.svg","man_construction_worker_tone3":"1f477-1f3fd-200d-2642-fe0f.svg","man_construction_worker_tone4":"1f477-1f3fe-200d-2642-fe0f.svg","man_construction_worker_tone5":"1f477-1f3ff-200d-2642-fe0f.svg","man_cook":"1f468-200d-1f373.svg","man_cook_tone1":"1f468-1f3fb-200d-1f373.svg","man_cook_tone2":"1f468-1f3fc-200d-1f373.svg","man_cook_tone3":"1f468-1f3fd-200d-1f373.svg","man_cook_tone4":"1f468-1f3fe-200d-1f373.svg","man_cook_tone5":"1f468-1f3ff-200d-1f373.svg","man_curly_haired":"1f468-200d-1f9b1.svg","man_curly_haired_tone1":"1f468-1f3fb-200d-1f9b1.svg","man_curly_haired_tone2":"1f468-1f3fc-200d-1f9b1.svg","man_curly_haired_tone3":"1f468-1f3fd-200d-1f9b1.svg","man_curly_haired_tone4":"1f468-1f3fe-200d-1f9b1.svg","man_curly_haired_tone5":"1f468-1f3ff-200d-1f9b1.svg","man_dancing":"1f57a.svg","man_dancing_tone1":"1f57a-1f3fb.svg","man_dancing_tone2":"1f57a-1f3fc.svg","man_dancing_tone3":"1f57a-1f3fd.svg","man_dancing_tone4":"1f57a-1f3fe.svg","man_dancing_tone5":"1f57a-1f3ff.svg","man_detective":"1f575-fe0f-200d-2642-fe0f.svg","man_detective_tone1":"1f575-1f3fb-200d-2642-fe0f.svg","man_detective_tone2":"1f575-1f3fc-200d-2642-fe0f.svg","man_detective_tone3":"1f575-1f3fd-200d-2642-fe0f.svg","man_detective_tone4":"1f575-1f3fe-200d-2642-fe0f.svg","man_detective_tone5":"1f575-1f3ff-200d-2642-fe0f.svg","man_elf":"1f9dd-200d-2642-fe0f.svg","man_elf_tone1":"1f9dd-1f3fb-200d-2642-fe0f.svg","man_elf_tone2":"1f9dd-1f3fc-200d-2642-fe0f.svg","man_elf_tone3":"1f9dd-1f3fd-200d-2642-fe0f.svg","man_elf_tone4":"1f9dd-1f3fe-200d-2642-fe0f.svg","man_elf_tone5":"1f9dd-1f3ff-200d-2642-fe0f.svg","man_facepalming":"1f926-200d-2642-fe0f.svg","man_facepalming_tone1":"1f926-1f3fb-200d-2642-fe0f.svg","man_facepalming_tone2":"1f926-1f3fc-200d-2642-fe0f.svg","man_facepalming_tone3":"1f926-1f3fd-200d-2642-fe0f.svg","man_facepalming_tone4":"1f926-1f3fe-200d-2642-fe0f.svg","man_facepalming_tone5":"1f926-1f3ff-200d-2642-fe0f.svg","man_factory_worker":"1f468-200d-1f3ed.svg","man_factory_worker_tone1":"1f468-1f3fb-200d-1f3ed.svg","man_factory_worker_tone2":"1f468-1f3fc-200d-1f3ed.svg","man_factory_worker_tone3":"1f468-1f3fd-200d-1f3ed.svg","man_factory_worker_tone4":"1f468-1f3fe-200d-1f3ed.svg","man_factory_worker_tone5":"1f468-1f3ff-200d-1f3ed.svg","man_fairy":"1f9da-200d-2642-fe0f.svg","man_fairy_tone1":"1f9da-1f3fb-200d-2642-fe0f.svg","man_fairy_tone2":"1f9da-1f3fc-200d-2642-fe0f.svg","man_fairy_tone3":"1f9da-1f3fd-200d-2642-fe0f.svg","man_fairy_tone4":"1f9da-1f3fe-200d-2642-fe0f.svg","man_fairy_tone5":"1f9da-1f3ff-200d-2642-fe0f.svg","man_farmer":"1f468-200d-1f33e.svg","man_farmer_tone1":"1f468-1f3fb-200d-1f33e.svg","man_farmer_tone2":"1f468-1f3fc-200d-1f33e.svg","man_farmer_tone3":"1f468-1f3fd-200d-1f33e.svg","man_farmer_tone4":"1f468-1f3fe-200d-1f33e.svg","man_farmer_tone5":"1f468-1f3ff-200d-1f33e.svg","man_feeding_baby":"1f468-200d-1f37c.svg","man_feeding_baby_tone1":"1f468-1f3fb-200d-1f37c.svg","man_feeding_baby_tone2":"1f468-1f3fc-200d-1f37c.svg","man_feeding_baby_tone3":"1f468-1f3fd-200d-1f37c.svg","man_feeding_baby_tone4":"1f468-1f3fe-200d-1f37c.svg","man_feeding_baby_tone5":"1f468-1f3ff-200d-1f37c.svg","man_firefighter":"1f468-200d-1f692.svg","man_firefighter_tone1":"1f468-1f3fb-200d-1f692.svg","man_firefighter_tone2":"1f468-1f3fc-200d-1f692.svg","man_firefighter_tone3":"1f468-1f3fd-200d-1f692.svg","man_firefighter_tone4":"1f468-1f3fe-200d-1f692.svg","man_firefighter_tone5":"1f468-1f3ff-200d-1f692.svg","man_frowning":"1f64d-200d-2642-fe0f.svg","man_frowning_tone1":"1f64d-1f3fb-200d-2642-fe0f.svg","man_frowning_tone2":"1f64d-1f3fc-200d-2642-fe0f.svg","man_frowning_tone3":"1f64d-1f3fd-200d-2642-fe0f.svg","man_frowning_tone4":"1f64d-1f3fe-200d-2642-fe0f.svg","man_frowning_tone5":"1f64d-1f3ff-200d-2642-fe0f.svg","man_genie":"1f9de-200d-2642-fe0f.svg","man_gesturing_no":"1f645-200d-2642-fe0f.svg","man_gesturing_no_tone1":"1f645-1f3fb-200d-2642-fe0f.svg","man_gesturing_no_tone2":"1f645-1f3fc-200d-2642-fe0f.svg","man_gesturing_no_tone3":"1f645-1f3fd-200d-2642-fe0f.svg","man_gesturing_no_tone4":"1f645-1f3fe-200d-2642-fe0f.svg","man_gesturing_no_tone5":"1f645-1f3ff-200d-2642-fe0f.svg","man_gesturing_ok":"1f646-200d-2642-fe0f.svg","man_gesturing_ok_tone1":"1f646-1f3fb-200d-2642-fe0f.svg","man_gesturing_ok_tone2":"1f646-1f3fc-200d-2642-fe0f.svg","man_gesturing_ok_tone3":"1f646-1f3fd-200d-2642-fe0f.svg","man_gesturing_ok_tone4":"1f646-1f3fe-200d-2642-fe0f.svg","man_gesturing_ok_tone5":"1f646-1f3ff-200d-2642-fe0f.svg","man_getting_face_massage":"1f486-200d-2642-fe0f.svg","man_getting_face_massage_tone1":"1f486-1f3fb-200d-2642-fe0f.svg","man_getting_face_massage_tone2":"1f486-1f3fc-200d-2642-fe0f.svg","man_getting_face_massage_tone3":"1f486-1f3fd-200d-2642-fe0f.svg","man_getting_face_massage_tone4":"1f486-1f3fe-200d-2642-fe0f.svg","man_getting_face_massage_tone5":"1f486-1f3ff-200d-2642-fe0f.svg","man_getting_haircut":"1f487-200d-2642-fe0f.svg","man_getting_haircut_tone1":"1f487-1f3fb-200d-2642-fe0f.svg","man_getting_haircut_tone2":"1f487-1f3fc-200d-2642-fe0f.svg","man_getting_haircut_tone3":"1f487-1f3fd-200d-2642-fe0f.svg","man_getting_haircut_tone4":"1f487-1f3fe-200d-2642-fe0f.svg","man_getting_haircut_tone5":"1f487-1f3ff-200d-2642-fe0f.svg","man_golfing":"1f3cc-fe0f-200d-2642-fe0f.svg","man_golfing_tone1":"1f3cc-1f3fb-200d-2642-fe0f.svg","man_golfing_tone2":"1f3cc-1f3fc-200d-2642-fe0f.svg","man_golfing_tone3":"1f3cc-1f3fd-200d-2642-fe0f.svg","man_golfing_tone4":"1f3cc-1f3fe-200d-2642-fe0f.svg","man_golfing_tone5":"1f3cc-1f3ff-200d-2642-fe0f.svg","man_guard":"1f482-200d-2642-fe0f.svg","man_guard_tone1":"1f482-1f3fb-200d-2642-fe0f.svg","man_guard_tone2":"1f482-1f3fc-200d-2642-fe0f.svg","man_guard_tone3":"1f482-1f3fd-200d-2642-fe0f.svg","man_guard_tone4":"1f482-1f3fe-200d-2642-fe0f.svg","man_guard_tone5":"1f482-1f3ff-200d-2642-fe0f.svg","man_health_worker":"1f468-200d-2695-fe0f.svg","man_health_worker_tone1":"1f468-1f3fb-200d-2695-fe0f.svg","man_health_worker_tone2":"1f468-1f3fc-200d-2695-fe0f.svg","man_health_worker_tone3":"1f468-1f3fd-200d-2695-fe0f.svg","man_health_worker_tone4":"1f468-1f3fe-200d-2695-fe0f.svg","man_health_worker_tone5":"1f468-1f3ff-200d-2695-fe0f.svg","man_in_lotus_position":"1f9d8-200d-2642-fe0f.svg","man_in_lotus_position_tone1":"1f9d8-1f3fb-200d-2642-fe0f.svg","man_in_lotus_position_tone2":"1f9d8-1f3fc-200d-2642-fe0f.svg","man_in_lotus_position_tone3":"1f9d8-1f3fd-200d-2642-fe0f.svg","man_in_lotus_position_tone4":"1f9d8-1f3fe-200d-2642-fe0f.svg","man_in_lotus_position_tone5":"1f9d8-1f3ff-200d-2642-fe0f.svg","man_in_manual_wheelchair":"1f468-200d-1f9bd.svg","man_in_manual_wheelchair_tone1":"1f468-1f3fb-200d-1f9bd.svg","man_in_manual_wheelchair_tone2":"1f468-1f3fc-200d-1f9bd.svg","man_in_manual_wheelchair_tone3":"1f468-1f3fd-200d-1f9bd.svg","man_in_manual_wheelchair_tone4":"1f468-1f3fe-200d-1f9bd.svg","man_in_manual_wheelchair_tone5":"1f468-1f3ff-200d-1f9bd.svg","man_in_motorized_wheelchair":"1f468-200d-1f9bc.svg","man_in_motorized_wheelchair_tone1":"1f468-1f3fb-200d-1f9bc.svg","man_in_motorized_wheelchair_tone2":"1f468-1f3fc-200d-1f9bc.svg","man_in_motorized_wheelchair_tone3":"1f468-1f3fd-200d-1f9bc.svg","man_in_motorized_wheelchair_tone4":"1f468-1f3fe-200d-1f9bc.svg","man_in_motorized_wheelchair_tone5":"1f468-1f3ff-200d-1f9bc.svg","man_in_santa_hat":"1f468-200d-1f384.svg","man_in_santa_hat_tone1":"1f468-1f3fb-200d-1f384.svg","man_in_santa_hat_tone2":"1f468-1f3fc-200d-1f384.svg","man_in_santa_hat_tone3":"1f468-1f3fd-200d-1f384.svg","man_in_santa_hat_tone4":"1f468-1f3fe-200d-1f384.svg","man_in_santa_hat_tone5":"1f469-1f3ff-200d-1f384.svg","man_in_steamy_room":"1f9d6-200d-2642-fe0f.svg","man_in_steamy_room_tone1":"1f9d6-1f3fb-200d-2642-fe0f.svg","man_in_steamy_room_tone2":"1f9d6-1f3fc-200d-2642-fe0f.svg","man_in_steamy_room_tone3":"1f9d6-1f3fd-200d-2642-fe0f.svg","man_in_steamy_room_tone4":"1f9d6-1f3fe-200d-2642-fe0f.svg","man_in_steamy_room_tone5":"1f9d6-1f3ff-200d-2642-fe0f.svg","man_in_tuxedo":"1f935-200d-2642-fe0f.svg","man_in_tuxedo_tone1":"1f935-1f3fb-200d-2642-fe0f.svg","man_in_tuxedo_tone2":"1f935-1f3fc-200d-2642-fe0f.svg","man_in_tuxedo_tone3":"1f935-1f3fd-200d-2642-fe0f.svg","man_in_tuxedo_tone4":"1f935-1f3fe-200d-2642-fe0f.svg","man_in_tuxedo_tone5":"1f935-1f3ff-200d-2642-fe0f.svg","man_judge":"1f468-200d-2696-fe0f.svg","man_judge_tone1":"1f468-1f3fb-200d-2696-fe0f.svg","man_judge_tone2":"1f468-1f3fc-200d-2696-fe0f.svg","man_judge_tone3":"1f468-1f3fd-200d-2696-fe0f.svg","man_judge_tone4":"1f468-1f3fe-200d-2696-fe0f.svg","man_judge_tone5":"1f468-1f3ff-200d-2696-fe0f.svg","man_juggling":"1f939-200d-2642-fe0f.svg","man_juggling_tone1":"1f939-1f3fb-200d-2642-fe0f.svg","man_juggling_tone2":"1f939-1f3fc-200d-2642-fe0f.svg","man_juggling_tone3":"1f939-1f3fd-200d-2642-fe0f.svg","man_juggling_tone4":"1f939-1f3fe-200d-2642-fe0f.svg","man_juggling_tone5":"1f939-1f3ff-200d-2642-fe0f.svg","man_kneeling":"1f9ce-200d-2642-fe0f.svg","man_kneeling_tone1":"1f9ce-1f3fb-200d-2642-fe0f.svg","man_kneeling_tone2":"1f9ce-1f3fc-200d-2642-fe0f.svg","man_kneeling_tone3":"1f9ce-1f3fd-200d-2642-fe0f.svg","man_kneeling_tone4":"1f9ce-1f3fe-200d-2642-fe0f.svg","man_kneeling_tone5":"1f9ce-1f3ff-200d-2642-fe0f.svg","man_lifting_weights":"1f3cb-fe0f-200d-2642-fe0f.svg","man_lifting_weights_tone1":"1f3cb-1f3fb-200d-2642-fe0f.svg","man_lifting_weights_tone2":"1f3cb-1f3fc-200d-2642-fe0f.svg","man_lifting_weights_tone3":"1f3cb-1f3fd-200d-2642-fe0f.svg","man_lifting_weights_tone4":"1f3cb-1f3fe-200d-2642-fe0f.svg","man_lifting_weights_tone5":"1f3cb-1f3ff-200d-2642-fe0f.svg","man_mage":"1f9d9-200d-2642-fe0f.svg","man_mage_tone1":"1f9d9-1f3fb-200d-2642-fe0f.svg","man_mage_tone2":"1f9d9-1f3fc-200d-2642-fe0f.svg","man_mage_tone3":"1f9d9-1f3fd-200d-2642-fe0f.svg","man_mage_tone4":"1f9d9-1f3fe-200d-2642-fe0f.svg","man_mage_tone5":"1f9d9-1f3ff-200d-2642-fe0f.svg","man_mechanic":"1f468-200d-1f527.svg","man_mechanic_tone1":"1f468-1f3fb-200d-1f527.svg","man_mechanic_tone2":"1f468-1f3fc-200d-1f527.svg","man_mechanic_tone3":"1f468-1f3fd-200d-1f527.svg","man_mechanic_tone4":"1f468-1f3fe-200d-1f527.svg","man_mechanic_tone5":"1f468-1f3ff-200d-1f527.svg","man_mountain_biking":"1f6b5-200d-2642-fe0f.svg","man_mountain_biking_tone1":"1f6b5-1f3fb-200d-2642-fe0f.svg","man_mountain_biking_tone2":"1f6b5-1f3fc-200d-2642-fe0f.svg","man_mountain_biking_tone3":"1f6b5-1f3fd-200d-2642-fe0f.svg","man_mountain_biking_tone4":"1f6b5-1f3fe-200d-2642-fe0f.svg","man_mountain_biking_tone5":"1f6b5-1f3ff-200d-2642-fe0f.svg","man_office_worker":"1f468-200d-1f4bc.svg","man_office_worker_tone1":"1f468-1f3fb-200d-1f4bc.svg","man_office_worker_tone2":"1f468-1f3fc-200d-1f4bc.svg","man_office_worker_tone3":"1f468-1f3fd-200d-1f4bc.svg","man_office_worker_tone4":"1f468-1f3fe-200d-1f4bc.svg","man_office_worker_tone5":"1f468-1f3ff-200d-1f4bc.svg","man_pilot":"1f468-200d-2708-fe0f.svg","man_pilot_tone1":"1f468-1f3fb-200d-2708-fe0f.svg","man_pilot_tone2":"1f468-1f3fc-200d-2708-fe0f.svg","man_pilot_tone3":"1f468-1f3fd-200d-2708-fe0f.svg","man_pilot_tone4":"1f468-1f3fe-200d-2708-fe0f.svg","man_pilot_tone5":"1f468-1f3ff-200d-2708-fe0f.svg","man_playing_handball":"1f93e-200d-2642-fe0f.svg","man_playing_handball_tone1":"1f93e-1f3fb-200d-2642-fe0f.svg","man_playing_handball_tone2":"1f93e-1f3fc-200d-2642-fe0f.svg","man_playing_handball_tone3":"1f93e-1f3fd-200d-2642-fe0f.svg","man_playing_handball_tone4":"1f93e-1f3fe-200d-2642-fe0f.svg","man_playing_handball_tone5":"1f93e-1f3ff-200d-2642-fe0f.svg","man_playing_water_polo":"1f93d-200d-2642-fe0f.svg","man_playing_water_polo_tone1":"1f93d-1f3fb-200d-2642-fe0f.svg","man_playing_water_polo_tone2":"1f93d-1f3fc-200d-2642-fe0f.svg","man_playing_water_polo_tone3":"1f93d-1f3fd-200d-2642-fe0f.svg","man_playing_water_polo_tone4":"1f93d-1f3fe-200d-2642-fe0f.svg","man_playing_water_polo_tone5":"1f93d-1f3ff-200d-2642-fe0f.svg","man_police_officer":"1f46e-200d-2642-fe0f.svg","man_police_officer_tone1":"1f46e-1f3fb-200d-2642-fe0f.svg","man_police_officer_tone2":"1f46e-1f3fc-200d-2642-fe0f.svg","man_police_officer_tone3":"1f46e-1f3fd-200d-2642-fe0f.svg","man_police_officer_tone4":"1f46e-1f3fe-200d-2642-fe0f.svg","man_police_officer_tone5":"1f46e-1f3ff-200d-2642-fe0f.svg","man_pouting":"1f64e-200d-2642-fe0f.svg","man_pouting_tone1":"1f64e-1f3fb-200d-2642-fe0f.svg","man_pouting_tone2":"1f64e-1f3fc-200d-2642-fe0f.svg","man_pouting_tone3":"1f64e-1f3fd-200d-2642-fe0f.svg","man_pouting_tone4":"1f64e-1f3fe-200d-2642-fe0f.svg","man_pouting_tone5":"1f64e-1f3ff-200d-2642-fe0f.svg","man_raising_hand":"1f64b-200d-2642-fe0f.svg","man_raising_hand_tone1":"1f64b-1f3fb-200d-2642-fe0f.svg","man_raising_hand_tone2":"1f64b-1f3fc-200d-2642-fe0f.svg","man_raising_hand_tone3":"1f64b-1f3fd-200d-2642-fe0f.svg","man_raising_hand_tone4":"1f64b-1f3fe-200d-2642-fe0f.svg","man_raising_hand_tone5":"1f64b-1f3ff-200d-2642-fe0f.svg","man_red_haired":"1f468-200d-1f9b0.svg","man_red_haired_tone1":"1f468-1f3fb-200d-1f9b0.svg","man_red_haired_tone2":"1f468-1f3fc-200d-1f9b0.svg","man_red_haired_tone3":"1f468-1f3fd-200d-1f9b0.svg","man_red_haired_tone4":"1f468-1f3fe-200d-1f9b0.svg","man_red_haired_tone5":"1f468-1f3ff-200d-1f9b0.svg","man_rowing_boat":"1f6a3-200d-2642-fe0f.svg","man_rowing_boat_tone1":"1f6a3-1f3fb-200d-2642-fe0f.svg","man_rowing_boat_tone2":"1f6a3-1f3fc-200d-2642-fe0f.svg","man_rowing_boat_tone3":"1f6a3-1f3fd-200d-2642-fe0f.svg","man_rowing_boat_tone4":"1f6a3-1f3fe-200d-2642-fe0f.svg","man_rowing_boat_tone5":"1f6a3-1f3ff-200d-2642-fe0f.svg","man_running":"1f3c3-200d-2642-fe0f.svg","man_running_tone1":"1f3c3-1f3fb-200d-2642-fe0f.svg","man_running_tone2":"1f3c3-1f3fc-200d-2642-fe0f.svg","man_running_tone3":"1f3c3-1f3fd-200d-2642-fe0f.svg","man_running_tone4":"1f3c3-1f3fe-200d-2642-fe0f.svg","man_running_tone5":"1f3c3-1f3ff-200d-2642-fe0f.svg","man_scientist":"1f468-200d-1f52c.svg","man_scientist_tone1":"1f468-1f3fb-200d-1f52c.svg","man_scientist_tone2":"1f468-1f3fc-200d-1f52c.svg","man_scientist_tone3":"1f468-1f3fd-200d-1f52c.svg","man_scientist_tone4":"1f468-1f3fe-200d-1f52c.svg","man_scientist_tone5":"1f468-1f3ff-200d-1f52c.svg","man_shrugging":"1f937-200d-2642-fe0f.svg","man_shrugging_tone1":"1f937-1f3fb-200d-2642-fe0f.svg","man_shrugging_tone2":"1f937-1f3fc-200d-2642-fe0f.svg","man_shrugging_tone3":"1f937-1f3fd-200d-2642-fe0f.svg","man_shrugging_tone4":"1f937-1f3fe-200d-2642-fe0f.svg","man_shrugging_tone5":"1f937-1f3ff-200d-2642-fe0f.svg","man_singer":"1f468-200d-1f3a4.svg","man_singer_tone1":"1f468-1f3fb-200d-1f3a4.svg","man_singer_tone2":"1f468-1f3fc-200d-1f3a4.svg","man_singer_tone3":"1f468-1f3fd-200d-1f3a4.svg","man_singer_tone4":"1f468-1f3fe-200d-1f3a4.svg","man_singer_tone5":"1f468-1f3ff-200d-1f3a4.svg","man_standing":"1f9cd-200d-2642-fe0f.svg","man_standing_tone1":"1f9cd-1f3fb-200d-2642-fe0f.svg","man_standing_tone2":"1f9cd-1f3fc-200d-2642-fe0f.svg","man_standing_tone3":"1f9cd-1f3fd-200d-2642-fe0f.svg","man_standing_tone4":"1f9cd-1f3fe-200d-2642-fe0f.svg","man_standing_tone5":"1f9cd-1f3ff-200d-2642-fe0f.svg","man_student":"1f468-200d-1f393.svg","man_student_tone1":"1f468-1f3fb-200d-1f393.svg","man_student_tone2":"1f468-1f3fc-200d-1f393.svg","man_student_tone3":"1f468-1f3fd-200d-1f393.svg","man_student_tone4":"1f468-1f3fe-200d-1f393.svg","man_student_tone5":"1f468-1f3ff-200d-1f393.svg","man_superhero":"1f9b8-200d-2642-fe0f.svg","man_superhero_tone1":"1f9b8-1f3fb-200d-2642-fe0f.svg","man_superhero_tone2":"1f9b8-1f3fc-200d-2642-fe0f.svg","man_superhero_tone3":"1f9b8-1f3fd-200d-2642-fe0f.svg","man_superhero_tone4":"1f9b8-1f3fe-200d-2642-fe0f.svg","man_superhero_tone5":"1f9b8-1f3ff-200d-2642-fe0f.svg","man_supervillain":"1f9b9-200d-2642-fe0f.svg","man_supervillain_tone1":"1f9b9-1f3fb-200d-2642-fe0f.svg","man_supervillain_tone2":"1f9b9-1f3fc-200d-2642-fe0f.svg","man_supervillain_tone3":"1f9b9-1f3fd-200d-2642-fe0f.svg","man_supervillain_tone4":"1f9b9-1f3fe-200d-2642-fe0f.svg","man_supervillain_tone5":"1f9b9-1f3ff-200d-2642-fe0f.svg","man_surfing":"1f3c4-200d-2642-fe0f.svg","man_surfing_tone1":"1f3c4-1f3fb-200d-2642-fe0f.svg","man_surfing_tone2":"1f3c4-1f3fc-200d-2642-fe0f.svg","man_surfing_tone3":"1f3c4-1f3fd-200d-2642-fe0f.svg","man_surfing_tone4":"1f3c4-1f3fe-200d-2642-fe0f.svg","man_surfing_tone5":"1f3c4-1f3ff-200d-2642-fe0f.svg","man_swimming":"1f3ca-200d-2642-fe0f.svg","man_swimming_tone1":"1f3ca-1f3fb-200d-2642-fe0f.svg","man_swimming_tone2":"1f3ca-1f3fc-200d-2642-fe0f.svg","man_swimming_tone3":"1f3ca-1f3fd-200d-2642-fe0f.svg","man_swimming_tone4":"1f3ca-1f3fe-200d-2642-fe0f.svg","man_swimming_tone5":"1f3ca-1f3ff-200d-2642-fe0f.svg","man_teacher":"1f468-200d-1f3eb.svg","man_teacher_tone1":"1f468-1f3fb-200d-1f3eb.svg","man_teacher_tone2":"1f468-1f3fc-200d-1f3eb.svg","man_teacher_tone3":"1f468-1f3fd-200d-1f3eb.svg","man_teacher_tone4":"1f468-1f3fe-200d-1f3eb.svg","man_teacher_tone5":"1f468-1f3ff-200d-1f3eb.svg","man_technologist":"1f468-200d-1f4bb.svg","man_technologist_tone1":"1f468-1f3fb-200d-1f4bb.svg","man_technologist_tone2":"1f468-1f3fc-200d-1f4bb.svg","man_technologist_tone3":"1f468-1f3fd-200d-1f4bb.svg","man_technologist_tone4":"1f468-1f3fe-200d-1f4bb.svg","man_technologist_tone5":"1f468-1f3ff-200d-1f4bb.svg","man_tipping_hand":"1f481-200d-2642-fe0f.svg","man_tipping_hand_tone1":"1f481-1f3fb-200d-2642-fe0f.svg","man_tipping_hand_tone2":"1f481-1f3fc-200d-2642-fe0f.svg","man_tipping_hand_tone3":"1f481-1f3fd-200d-2642-fe0f.svg","man_tipping_hand_tone4":"1f481-1f3fe-200d-2642-fe0f.svg","man_tipping_hand_tone5":"1f481-1f3ff-200d-2642-fe0f.svg","man_tone1":"1f468-1f3fb.svg","man_tone1_beard":"1f9d4-1f3fb-200d-2642-fe0f.svg","man_tone2":"1f468-1f3fc.svg","man_tone2_beard":"1f9d4-1f3fc-200d-2642-fe0f.svg","man_tone3":"1f468-1f3fd.svg","man_tone3_beard":"1f9d4-1f3fd-200d-2642-fe0f.svg","man_tone4":"1f468-1f3fe.svg","man_tone4_beard":"1f9d4-1f3fe-200d-2642-fe0f.svg","man_tone5":"1f468-1f3ff.svg","man_tone5_beard":"1f9d4-1f3ff-200d-2642-fe0f.svg","man_vampire":"1f9db-200d-2642-fe0f.svg","man_vampire_tone1":"1f9db-1f3fb-200d-2642-fe0f.svg","man_vampire_tone2":"1f9db-1f3fc-200d-2642-fe0f.svg","man_vampire_tone3":"1f9db-1f3fd-200d-2642-fe0f.svg","man_vampire_tone4":"1f9db-1f3fe-200d-2642-fe0f.svg","man_vampire_tone5":"1f9db-1f3ff-200d-2642-fe0f.svg","man_walking":"1f6b6-200d-2642-fe0f.svg","man_walking_tone1":"1f6b6-1f3fb-200d-2642-fe0f.svg","man_walking_tone2":"1f6b6-1f3fc-200d-2642-fe0f.svg","man_walking_tone3":"1f6b6-1f3fd-200d-2642-fe0f.svg","man_walking_tone4":"1f6b6-1f3fe-200d-2642-fe0f.svg","man_walking_tone5":"1f6b6-1f3ff-200d-2642-fe0f.svg","man_wearing_turban":"1f473-200d-2642-fe0f.svg","man_wearing_turban_tone1":"1f473-1f3fb-200d-2642-fe0f.svg","man_wearing_turban_tone2":"1f473-1f3fc-200d-2642-fe0f.svg","man_wearing_turban_tone3":"1f473-1f3fd-200d-2642-fe0f.svg","man_wearing_turban_tone4":"1f473-1f3fe-200d-2642-fe0f.svg","man_wearing_turban_tone5":"1f473-1f3ff-200d-2642-fe0f.svg","man_white_haired":"1f468-200d-1f9b3.svg","man_white_haired_tone1":"1f468-1f3fb-200d-1f9b3.svg","man_white_haired_tone2":"1f468-1f3fc-200d-1f9b3.svg","man_white_haired_tone3":"1f468-1f3fd-200d-1f9b3.svg","man_white_haired_tone4":"1f468-1f3fe-200d-1f9b3.svg","man_white_haired_tone5":"1f468-1f3ff-200d-1f9b3.svg","man_with_chinese_cap":"1f472.svg","man_with_chinese_cap_tone1":"1f472-1f3fb.svg","man_with_chinese_cap_tone2":"1f472-1f3fc.svg","man_with_chinese_cap_tone3":"1f472-1f3fd.svg","man_with_chinese_cap_tone4":"1f472-1f3fe.svg","man_with_chinese_cap_tone5":"1f472-1f3ff.svg","man_with_probing_cane":"1f468-200d-1f9af.svg","man_with_probing_cane_tone1":"1f468-1f3fb-200d-1f9af.svg","man_with_probing_cane_tone2":"1f468-1f3fc-200d-1f9af.svg","man_with_probing_cane_tone3":"1f468-1f3fd-200d-1f9af.svg","man_with_probing_cane_tone4":"1f468-1f3fe-200d-1f9af.svg","man_with_probing_cane_tone5":"1f468-1f3ff-200d-1f9af.svg","man_with_veil":"1f470-200d-2642-fe0f.svg","man_with_veil_tone1":"1f470-1f3fb-200d-2642-fe0f.svg","man_with_veil_tone2":"1f470-1f3fc-200d-2642-fe0f.svg","man_with_veil_tone3":"1f470-1f3fd-200d-2642-fe0f.svg","man_with_veil_tone4":"1f470-1f3fe-200d-2642-fe0f.svg","man_with_veil_tone5":"1f470-1f3ff-200d-2642-fe0f.svg","man_zombie":"1f9df-200d-2642-fe0f.svg","mango":"1f96d.svg","mans_shoe":"1f45e.svg","manual_wheelchair":"1f9bd.svg","map":"1f5fa.svg","maple_leaf":"1f341.svg","martial_arts_uniform":"1f94b.svg","mask":"1f637.svg","mate":"1f9c9.svg","meat_on_bone":"1f356.svg","mechanic":"1f9d1-200d-1f527.svg","mechanic_tone1":"1f9d1-1f3fb-200d-1f527.svg","mechanic_tone2":"1f9d1-1f3fc-200d-1f527.svg","mechanic_tone3":"1f9d1-1f3fd-200d-1f527.svg","mechanic_tone4":"1f9d1-1f3fe-200d-1f527.svg","mechanic_tone5":"1f9d1-1f3ff-200d-1f527.svg","mechanical_arm":"1f9be.svg","mechanical_leg":"1f9bf.svg","medal":"1f3c5.svg","medical_symbol":"2695.svg","mega":"1f4e3.svg","melon":"1f348.svg","men_holding_hands_tone1":"1f46c-1f3fb.svg","men_holding_hands_tone1_tone2":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone1_tone3":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone1_tone4":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone1_tone5":"1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone2":"1f46c-1f3fc.svg","men_holding_hands_tone2_tone1":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone2_tone3":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone2_tone4":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone2_tone5":"1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone3":"1f46c-1f3fd.svg","men_holding_hands_tone3_tone1":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone3_tone2":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone3_tone4":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe.svg","men_holding_hands_tone3_tone5":"1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone4":"1f46c-1f3fe.svg","men_holding_hands_tone4_tone1":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone4_tone2":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone4_tone3":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone4_tone5":"1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff.svg","men_holding_hands_tone5":"1f46c-1f3ff.svg","men_holding_hands_tone5_tone1":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb.svg","men_holding_hands_tone5_tone2":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc.svg","men_holding_hands_tone5_tone3":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd.svg","men_holding_hands_tone5_tone4":"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe.svg","men_with_bunny_ears_partying":"1f46f-200d-2642-fe0f.svg","men_wrestling":"1f93c-200d-2642-fe0f.svg","mending_heart":"2764-fe0f-200d-1fa79.svg","menorah":"1f54e.svg","mens":"1f6b9.svg","mermaid":"1f9dc-200d-2640-fe0f.svg","mermaid_tone1":"1f9dc-1f3fb-200d-2640-fe0f.svg","mermaid_tone2":"1f9dc-1f3fc-200d-2640-fe0f.svg","mermaid_tone3":"1f9dc-1f3fd-200d-2640-fe0f.svg","mermaid_tone4":"1f9dc-1f3fe-200d-2640-fe0f.svg","mermaid_tone5":"1f9dc-1f3ff-200d-2640-fe0f.svg","merman":"1f9dc-200d-2642-fe0f.svg","merman_tone1":"1f9dc-1f3fb-200d-2642-fe0f.svg","merman_tone2":"1f9dc-1f3fc-200d-2642-fe0f.svg","merman_tone3":"1f9dc-1f3fd-200d-2642-fe0f.svg","merman_tone4":"1f9dc-1f3fe-200d-2642-fe0f.svg","merman_tone5":"1f9dc-1f3ff-200d-2642-fe0f.svg","merperson":"1f9dc.svg","merperson_tone1":"1f9dc-1f3fb.svg","merperson_tone2":"1f9dc-1f3fc.svg","merperson_tone3":"1f9dc-1f3fd.svg","merperson_tone4":"1f9dc-1f3fe.svg","merperson_tone5":"1f9dc-1f3ff.svg","metal":"1f918.svg","metal_tone1":"1f918-1f3fb.svg","metal_tone2":"1f918-1f3fc.svg","metal_tone3":"1f918-1f3fd.svg","metal_tone4":"1f918-1f3fe.svg","metal_tone5":"1f918-1f3ff.svg","metro":"1f687.svg","microbe":"1f9a0.svg","microphone2":"1f399.svg","microphone":"1f3a4.svg","microscope":"1f52c.svg","middle_finger":"1f595.svg","middle_finger_tone1":"1f595-1f3fb.svg","middle_finger_tone2":"1f595-1f3fc.svg","middle_finger_tone3":"1f595-1f3fd.svg","middle_finger_tone4":"1f595-1f3fe.svg","middle_finger_tone5":"1f595-1f3ff.svg","military_helmet":"1fa96.svg","military_medal":"1f396.svg","milk":"1f95b.svg","milky_way":"1f30c.svg","minibus":"1f690.svg","minidisc":"1f4bd.svg","mirror":"1fa9e.svg","mobile_phone":"1f4f1.svg","mobile_phone_off":"1f4f4.svg","money_mouth":"1f911.svg","money_with_wings":"1f4b8.svg","moneybag":"1f4b0.svg","monkey":"1f412.svg","monkey_face":"1f435.svg","monorail":"1f69d.svg","moon_cake":"1f96e.svg","mortar_board":"1f393.svg","mosque":"1f54c.svg","mosquito":"1f99f.svg","motor_scooter":"1f6f5.svg","motorboat":"1f6e5.svg","motorcycle":"1f3cd.svg","motorized_wheelchair":"1f9bc.svg","motorway":"1f6e3.svg","mount_fuji":"1f5fb.svg","mountain":"26f0.svg","mountain_cableway":"1f6a0.svg","mountain_railway":"1f69e.svg","mountain_snow":"1f3d4.svg","mouse2":"1f401.svg","mouse":"1f42d.svg","mouse_three_button":"1f5b1.svg","mouse_trap":"1faa4.svg","movie_camera":"1f3a5.svg","moyai":"1f5ff.svg","mrs_claus":"1f936.svg","mrs_claus_tone1":"1f936-1f3fb.svg","mrs_claus_tone2":"1f936-1f3fc.svg","mrs_claus_tone3":"1f936-1f3fd.svg","mrs_claus_tone4":"1f936-1f3fe.svg","mrs_claus_tone5":"1f936-1f3ff.svg","muscle":"1f4aa.svg","muscle_tone1":"1f4aa-1f3fb.svg","muscle_tone2":"1f4aa-1f3fc.svg","muscle_tone3":"1f4aa-1f3fd.svg","muscle_tone4":"1f4aa-1f3fe.svg","muscle_tone5":"1f4aa-1f3ff.svg","mushroom":"1f344.svg","musical_keyboard":"1f3b9.svg","musical_note":"1f3b5.svg","musical_score":"1f3bc.svg","mute":"1f507.svg","mx_claus":"1f9d1-200d-1f384.svg","mx_claus_tone1":"1f9d1-1f3fb-200d-1f384.svg","mx_claus_tone2":"1f9d1-1f3fc-200d-1f384.svg","mx_claus_tone3":"1f9d1-1f3fd-200d-1f384.svg","mx_claus_tone4":"1f9d1-1f3fe-200d-1f384.svg","mx_claus_tone5":"1f9d1-1f3ff-200d-1f384.svg","nail_care":"1f485.svg","nail_care_tone1":"1f485-1f3fb.svg","nail_care_tone2":"1f485-1f3fc.svg","nail_care_tone3":"1f485-1f3fd.svg","nail_care_tone4":"1f485-1f3fe.svg","nail_care_tone5":"1f485-1f3ff.svg","name_badge":"1f4db.svg","nauseated_face":"1f922.svg","nazar_amulet":"1f9ff.svg","necktie":"1f454.svg","negative_squared_cross_mark":"274e.svg","nerd":"1f913.svg","nesting_dolls":"1fa86.svg","neutral_face":"1f610.svg","new":"1f195.svg","new_moon":"1f311.svg","new_moon_with_face":"1f31a.svg","newspaper2":"1f5de.svg","newspaper":"1f4f0.svg","ng":"1f196.svg","night_with_stars":"1f303.svg","nine":"39-20e3.svg","ninja":"1f977.svg","ninja_tone1":"1f977-1f3fb.svg","ninja_tone2":"1f977-1f3fc.svg","ninja_tone3":"1f977-1f3fd.svg","ninja_tone4":"1f977-1f3fe.svg","ninja_tone5":"1f977-1f3ff.svg","no_bell":"1f515.svg","no_bicycles":"1f6b3.svg","no_entry":"26d4.svg","no_entry_sign":"1f6ab.svg","no_mobile_phones":"1f4f5.svg","no_mouth":"1f636.svg","no_pedestrians":"1f6b7.svg","no_smoking":"1f6ad.svg","non-potable_water":"1f6b1.svg","nose":"1f443.svg","nose_tone1":"1f443-1f3fb.svg","nose_tone2":"1f443-1f3fc.svg","nose_tone3":"1f443-1f3fd.svg","nose_tone4":"1f443-1f3fe.svg","nose_tone5":"1f443-1f3ff.svg","notebook":"1f4d3.svg","notebook_with_decorative_cover":"1f4d4.svg","notepad_spiral":"1f5d2.svg","notes":"1f3b6.svg","nut_and_bolt":"1f529.svg","o2":"1f17e.svg","o":"2b55.svg","ocean":"1f30a.svg","octagonal_sign":"1f6d1.svg","octopus":"1f419.svg","oden":"1f362.svg","office":"1f3e2.svg","office_worker":"1f9d1-200d-1f4bc.svg","office_worker_tone1":"1f9d1-1f3fb-200d-1f4bc.svg","office_worker_tone2":"1f9d1-1f3fc-200d-1f4bc.svg","office_worker_tone3":"1f9d1-1f3fd-200d-1f4bc.svg","office_worker_tone4":"1f9d1-1f3fe-200d-1f4bc.svg","office_worker_tone5":"1f9d1-1f3ff-200d-1f4bc.svg","oil":"1f6e2.svg","ok":"1f197.svg","ok_hand":"1f44c.svg","ok_hand_tone1":"1f44c-1f3fb.svg","ok_hand_tone2":"1f44c-1f3fc.svg","ok_hand_tone3":"1f44c-1f3fd.svg","ok_hand_tone4":"1f44c-1f3fe.svg","ok_hand_tone5":"1f44c-1f3ff.svg","older_adult":"1f9d3.svg","older_adult_tone1":"1f9d3-1f3fb.svg","older_adult_tone2":"1f9d3-1f3fc.svg","older_adult_tone3":"1f9d3-1f3fd.svg","older_adult_tone4":"1f9d3-1f3fe.svg","older_adult_tone5":"1f9d3-1f3ff.svg","older_man":"1f474.svg","older_man_tone1":"1f474-1f3fb.svg","older_man_tone2":"1f474-1f3fc.svg","older_man_tone3":"1f474-1f3fd.svg","older_man_tone4":"1f474-1f3fe.svg","older_man_tone5":"1f474-1f3ff.svg","older_woman":"1f475.svg","older_woman_tone1":"1f475-1f3fb.svg","older_woman_tone2":"1f475-1f3fc.svg","older_woman_tone3":"1f475-1f3fd.svg","older_woman_tone4":"1f475-1f3fe.svg","older_woman_tone5":"1f475-1f3ff.svg","olive":"1fad2.svg","om_symbol":"1f549.svg","on":"1f51b.svg","oncoming_automobile":"1f698.svg","oncoming_bus":"1f68d.svg","oncoming_police_car":"1f694.svg","oncoming_taxi":"1f696.svg","one":"31-20e3.svg","one_piece_swimsuit":"1fa71.svg","onion":"1f9c5.svg","open_file_folder":"1f4c2.svg","open_hands":"1f450.svg","open_hands_tone1":"1f450-1f3fb.svg","open_hands_tone2":"1f450-1f3fc.svg","open_hands_tone3":"1f450-1f3fd.svg","open_hands_tone4":"1f450-1f3fe.svg","open_hands_tone5":"1f450-1f3ff.svg","open_mouth":"1f62e.svg","ophiuchus":"26ce.svg","orange_book":"1f4d9.svg","orange_circle":"1f7e0.svg","orange_heart":"1f9e1.svg","orange_square":"1f7e7.svg","orangutan":"1f9a7.svg","orthodox_cross":"2626.svg","otter":"1f9a6.svg","outbox_tray":"1f4e4.svg","owl":"1f989.svg","ox":"1f402.svg","oyster":"1f9aa.svg","package":"1f4e6.svg","page_facing_up":"1f4c4.svg","page_with_curl":"1f4c3.svg","pager":"1f4df.svg","paintbrush":"1f58c.svg","palm_tree":"1f334.svg","palms_up_together":"1f932.svg","palms_up_together_tone1":"1f932-1f3fb.svg","palms_up_together_tone2":"1f932-1f3fc.svg","palms_up_together_tone3":"1f932-1f3fd.svg","palms_up_together_tone4":"1f932-1f3fe.svg","palms_up_together_tone5":"1f932-1f3ff.svg","pancakes":"1f95e.svg","panda_face":"1f43c.svg","paperclip":"1f4ce.svg","paperclips":"1f587.svg","parachute":"1fa82.svg","park":"1f3de.svg","parking":"1f17f.svg","parrot":"1f99c.svg","part_alternation_mark":"303d.svg","partly_sunny":"26c5.svg","partying_face":"1f973.svg","passport_control":"1f6c2.svg","pause_button":"23f8.svg","peace":"262e.svg","peach":"1f351.svg","peacock":"1f99a.svg","peanuts":"1f95c.svg","pear":"1f350.svg","pen_ballpoint":"1f58a.svg","pen_fountain":"1f58b.svg","pencil2":"270f.svg","pencil":"1f4dd.svg","penguin":"1f427.svg","pensive":"1f614.svg","people_holding_hands":"1f9d1-200d-1f91d-200d-1f9d1.svg","people_holding_hands_tone1":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone1_tone2":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone1_tone3":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone1_tone4":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone1_tone5":"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone2":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone2_tone1":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone2_tone3":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone2_tone4":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone2_tone5":"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone3":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone3_tone1":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone3_tone2":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone3_tone4":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone3_tone5":"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone4":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe.svg","people_holding_hands_tone4_tone1":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone4_tone2":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone4_tone3":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone4_tone5":"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone5":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff.svg","people_holding_hands_tone5_tone1":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb.svg","people_holding_hands_tone5_tone2":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc.svg","people_holding_hands_tone5_tone3":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd.svg","people_holding_hands_tone5_tone4":"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe.svg","people_hugging":"1fac2.svg","people_with_bunny_ears_partying":"1f46f.svg","people_wrestling":"1f93c.svg","performing_arts":"1f3ad.svg","persevere":"1f623.svg","person_bald":"1f9d1-200d-1f9b2.svg","person_biking":"1f6b4.svg","person_biking_tone1":"1f6b4-1f3fb.svg","person_biking_tone2":"1f6b4-1f3fc.svg","person_biking_tone3":"1f6b4-1f3fd.svg","person_biking_tone4":"1f6b4-1f3fe.svg","person_biking_tone5":"1f6b4-1f3ff.svg","person_bouncing_ball":"26f9.svg","person_bouncing_ball_tone1":"26f9-1f3fb.svg","person_bouncing_ball_tone2":"26f9-1f3fc.svg","person_bouncing_ball_tone3":"26f9-1f3fd.svg","person_bouncing_ball_tone4":"26f9-1f3fe.svg","person_bouncing_ball_tone5":"26f9-1f3ff.svg","person_bowing":"1f647.svg","person_bowing_tone1":"1f647-1f3fb.svg","person_bowing_tone2":"1f647-1f3fc.svg","person_bowing_tone3":"1f647-1f3fd.svg","person_bowing_tone4":"1f647-1f3fe.svg","person_bowing_tone5":"1f647-1f3ff.svg","person_climbing":"1f9d7.svg","person_climbing_tone1":"1f9d7-1f3fb.svg","person_climbing_tone2":"1f9d7-1f3fc.svg","person_climbing_tone3":"1f9d7-1f3fd.svg","person_climbing_tone4":"1f9d7-1f3fe.svg","person_climbing_tone5":"1f9d7-1f3ff.svg","person_curly_hair":"1f9d1-200d-1f9b1.svg","person_doing_cartwheel":"1f938.svg","person_doing_cartwheel_tone1":"1f938-1f3fb.svg","person_doing_cartwheel_tone2":"1f938-1f3fc.svg","person_doing_cartwheel_tone3":"1f938-1f3fd.svg","person_doing_cartwheel_tone4":"1f938-1f3fe.svg","person_doing_cartwheel_tone5":"1f938-1f3ff.svg","person_facepalming":"1f926.svg","person_facepalming_tone1":"1f926-1f3fb.svg","person_facepalming_tone2":"1f926-1f3fc.svg","person_facepalming_tone3":"1f926-1f3fd.svg","person_facepalming_tone4":"1f926-1f3fe.svg","person_facepalming_tone5":"1f926-1f3ff.svg","person_feeding_baby":"1f9d1-200d-1f37c.svg","person_feeding_baby_tone1":"1f9d1-1f3fb-200d-1f37c.svg","person_feeding_baby_tone2":"1f9d1-1f3fc-200d-1f37c.svg","person_feeding_baby_tone3":"1f9d1-1f3fd-200d-1f37c.svg","person_feeding_baby_tone4":"1f9d1-1f3fe-200d-1f37c.svg","person_feeding_baby_tone5":"1f9d1-1f3ff-200d-1f37c.svg","person_fencing":"1f93a.svg","person_frowning":"1f64d.svg","person_frowning_tone1":"1f64d-1f3fb.svg","person_frowning_tone2":"1f64d-1f3fc.svg","person_frowning_tone3":"1f64d-1f3fd.svg","person_frowning_tone4":"1f64d-1f3fe.svg","person_frowning_tone5":"1f64d-1f3ff.svg","person_gesturing_no":"1f645.svg","person_gesturing_no_tone1":"1f645-1f3fb.svg","person_gesturing_no_tone2":"1f645-1f3fc.svg","person_gesturing_no_tone3":"1f645-1f3fd.svg","person_gesturing_no_tone4":"1f645-1f3fe.svg","person_gesturing_no_tone5":"1f645-1f3ff.svg","person_gesturing_ok":"1f646.svg","person_gesturing_ok_tone1":"1f646-1f3fb.svg","person_gesturing_ok_tone2":"1f646-1f3fc.svg","person_gesturing_ok_tone3":"1f646-1f3fd.svg","person_gesturing_ok_tone4":"1f646-1f3fe.svg","person_gesturing_ok_tone5":"1f646-1f3ff.svg","person_getting_haircut":"1f487.svg","person_getting_haircut_tone1":"1f487-1f3fb.svg","person_getting_haircut_tone2":"1f487-1f3fc.svg","person_getting_haircut_tone3":"1f487-1f3fd.svg","person_getting_haircut_tone4":"1f487-1f3fe.svg","person_getting_haircut_tone5":"1f487-1f3ff.svg","person_getting_massage":"1f486.svg","person_getting_massage_tone1":"1f486-1f3fb.svg","person_getting_massage_tone2":"1f486-1f3fc.svg","person_getting_massage_tone3":"1f486-1f3fd.svg","person_getting_massage_tone4":"1f486-1f3fe.svg","person_getting_massage_tone5":"1f486-1f3ff.svg","person_golfing":"1f3cc.svg","person_golfing_tone1":"1f3cc-1f3fb.svg","person_golfing_tone2":"1f3cc-1f3fc.svg","person_golfing_tone3":"1f3cc-1f3fd.svg","person_golfing_tone4":"1f3cc-1f3fe.svg","person_golfing_tone5":"1f3cc-1f3ff.svg","person_in_bed_tone1":"1f6cc-1f3fb.svg","person_in_bed_tone2":"1f6cc-1f3fc.svg","person_in_bed_tone3":"1f6cc-1f3fd.svg","person_in_bed_tone4":"1f6cc-1f3fe.svg","person_in_bed_tone5":"1f6cc-1f3ff.svg","person_in_lotus_position":"1f9d8.svg","person_in_lotus_position_tone1":"1f9d8-1f3fb.svg","person_in_lotus_position_tone2":"1f9d8-1f3fc.svg","person_in_lotus_position_tone3":"1f9d8-1f3fd.svg","person_in_lotus_position_tone4":"1f9d8-1f3fe.svg","person_in_lotus_position_tone5":"1f9d8-1f3ff.svg","person_in_manual_wheelchair":"1f9d1-200d-1f9bd.svg","person_in_manual_wheelchair_tone1":"1f9d1-1f3fb-200d-1f9bd.svg","person_in_manual_wheelchair_tone2":"1f9d1-1f3fc-200d-1f9bd.svg","person_in_manual_wheelchair_tone3":"1f9d1-1f3fd-200d-1f9bd.svg","person_in_manual_wheelchair_tone4":"1f9d1-1f3fe-200d-1f9bd.svg","person_in_manual_wheelchair_tone5":"1f9d1-1f3ff-200d-1f9bd.svg","person_in_motorized_wheelchair":"1f9d1-200d-1f9bc.svg","person_in_motorized_wheelchair_tone1":"1f9d1-1f3fb-200d-1f9bc.svg","person_in_motorized_wheelchair_tone2":"1f9d1-1f3fc-200d-1f9bc.svg","person_in_motorized_wheelchair_tone3":"1f9d1-1f3fd-200d-1f9bc.svg","person_in_motorized_wheelchair_tone4":"1f9d1-1f3fe-200d-1f9bc.svg","person_in_motorized_wheelchair_tone5":"1f9d1-1f3ff-200d-1f9bc.svg","person_in_steamy_room":"1f9d6.svg","person_in_steamy_room_tone1":"1f9d6-1f3fb.svg","person_in_steamy_room_tone2":"1f9d6-1f3fc.svg","person_in_steamy_room_tone3":"1f9d6-1f3fd.svg","person_in_steamy_room_tone4":"1f9d6-1f3fe.svg","person_in_steamy_room_tone5":"1f9d6-1f3ff.svg","person_in_tuxedo":"1f935.svg","person_in_tuxedo_tone1":"1f935-1f3fb.svg","person_in_tuxedo_tone2":"1f935-1f3fc.svg","person_in_tuxedo_tone3":"1f935-1f3fd.svg","person_in_tuxedo_tone4":"1f935-1f3fe.svg","person_in_tuxedo_tone5":"1f935-1f3ff.svg","person_juggling":"1f939.svg","person_juggling_tone1":"1f939-1f3fb.svg","person_juggling_tone2":"1f939-1f3fc.svg","person_juggling_tone3":"1f939-1f3fd.svg","person_juggling_tone4":"1f939-1f3fe.svg","person_juggling_tone5":"1f939-1f3ff.svg","person_kneeling":"1f9ce.svg","person_kneeling_tone1":"1f9ce-1f3fb.svg","person_kneeling_tone2":"1f9ce-1f3fc.svg","person_kneeling_tone3":"1f9ce-1f3fd.svg","person_kneeling_tone4":"1f9ce-1f3fe.svg","person_kneeling_tone5":"1f9ce-1f3ff.svg","person_lifting_weights":"1f3cb.svg","person_lifting_weights_tone1":"1f3cb-1f3fb.svg","person_lifting_weights_tone2":"1f3cb-1f3fc.svg","person_lifting_weights_tone3":"1f3cb-1f3fd.svg","person_lifting_weights_tone4":"1f3cb-1f3fe.svg","person_lifting_weights_tone5":"1f3cb-1f3ff.svg","person_mountain_biking":"1f6b5.svg","person_mountain_biking_tone1":"1f6b5-1f3fb.svg","person_mountain_biking_tone2":"1f6b5-1f3fc.svg","person_mountain_biking_tone3":"1f6b5-1f3fd.svg","person_mountain_biking_tone4":"1f6b5-1f3fe.svg","person_mountain_biking_tone5":"1f6b5-1f3ff.svg","person_playing_handball":"1f93e.svg","person_playing_handball_tone1":"1f93e-1f3fb.svg","person_playing_handball_tone2":"1f93e-1f3fc.svg","person_playing_handball_tone3":"1f93e-1f3fd.svg","person_playing_handball_tone4":"1f93e-1f3fe.svg","person_playing_handball_tone5":"1f93e-1f3ff.svg","person_playing_water_polo":"1f93d.svg","person_playing_water_polo_tone1":"1f93d-1f3fb.svg","person_playing_water_polo_tone2":"1f93d-1f3fc.svg","person_playing_water_polo_tone3":"1f93d-1f3fd.svg","person_playing_water_polo_tone4":"1f93d-1f3fe.svg","person_playing_water_polo_tone5":"1f93d-1f3ff.svg","person_pouting":"1f64e.svg","person_pouting_tone1":"1f64e-1f3fb.svg","person_pouting_tone2":"1f64e-1f3fc.svg","person_pouting_tone3":"1f64e-1f3fd.svg","person_pouting_tone4":"1f64e-1f3fe.svg","person_pouting_tone5":"1f64e-1f3ff.svg","person_raising_hand":"1f64b.svg","person_raising_hand_tone1":"1f64b-1f3fb.svg","person_raising_hand_tone2":"1f64b-1f3fc.svg","person_raising_hand_tone3":"1f64b-1f3fd.svg","person_raising_hand_tone4":"1f64b-1f3fe.svg","person_raising_hand_tone5":"1f64b-1f3ff.svg","person_red_hair":"1f9d1-200d-1f9b0.svg","person_rowing_boat":"1f6a3.svg","person_rowing_boat_tone1":"1f6a3-1f3fb.svg","person_rowing_boat_tone2":"1f6a3-1f3fc.svg","person_rowing_boat_tone3":"1f6a3-1f3fd.svg","person_rowing_boat_tone4":"1f6a3-1f3fe.svg","person_rowing_boat_tone5":"1f6a3-1f3ff.svg","person_running":"1f3c3.svg","person_running_tone1":"1f3c3-1f3fb.svg","person_running_tone2":"1f3c3-1f3fc.svg","person_running_tone3":"1f3c3-1f3fd.svg","person_running_tone4":"1f3c3-1f3fe.svg","person_running_tone5":"1f3c3-1f3ff.svg","person_shrugging":"1f937.svg","person_shrugging_tone1":"1f937-1f3fb.svg","person_shrugging_tone2":"1f937-1f3fc.svg","person_shrugging_tone3":"1f937-1f3fd.svg","person_shrugging_tone4":"1f937-1f3fe.svg","person_shrugging_tone5":"1f937-1f3ff.svg","person_standing":"1f9cd.svg","person_standing_tone1":"1f9cd-1f3fb.svg","person_standing_tone2":"1f9cd-1f3fc.svg","person_standing_tone3":"1f9cd-1f3fd.svg","person_standing_tone4":"1f9cd-1f3fe.svg","person_standing_tone5":"1f9cd-1f3ff.svg","person_surfing":"1f3c4.svg","person_surfing_tone1":"1f3c4-1f3fb.svg","person_surfing_tone2":"1f3c4-1f3fc.svg","person_surfing_tone3":"1f3c4-1f3fd.svg","person_surfing_tone4":"1f3c4-1f3fe.svg","person_surfing_tone5":"1f3c4-1f3ff.svg","person_swimming":"1f3ca.svg","person_swimming_tone1":"1f3ca-1f3fb.svg","person_swimming_tone2":"1f3ca-1f3fc.svg","person_swimming_tone3":"1f3ca-1f3fd.svg","person_swimming_tone4":"1f3ca-1f3fe.svg","person_swimming_tone5":"1f3ca-1f3ff.svg","person_tipping_hand":"1f481.svg","person_tipping_hand_tone1":"1f481-1f3fb.svg","person_tipping_hand_tone2":"1f481-1f3fc.svg","person_tipping_hand_tone3":"1f481-1f3fd.svg","person_tipping_hand_tone4":"1f481-1f3fe.svg","person_tipping_hand_tone5":"1f481-1f3ff.svg","person_tone1_bald":"1f9d1-1f3fb-200d-1f9b2.svg","person_tone1_curly_hair":"1f9d1-1f3fb-200d-1f9b1.svg","person_tone1_red_hair":"1f9d1-1f3fb-200d-1f9b0.svg","person_tone1_white_hair":"1f9d1-1f3fb-200d-1f9b3.svg","person_tone2_bald":"1f9d1-1f3fc-200d-1f9b2.svg","person_tone2_curly_hair":"1f9d1-1f3fc-200d-1f9b1.svg","person_tone2_red_hair":"1f9d1-1f3fc-200d-1f9b0.svg","person_tone2_white_hair":"1f9d1-1f3fc-200d-1f9b3.svg","person_tone3_bald":"1f9d1-1f3fd-200d-1f9b2.svg","person_tone3_curly_hair":"1f9d1-1f3fd-200d-1f9b1.svg","person_tone3_red_hair":"1f9d1-1f3fd-200d-1f9b0.svg","person_tone3_white_hair":"1f9d1-1f3fd-200d-1f9b3.svg","person_tone4_bald":"1f9d1-1f3fe-200d-1f9b2.svg","person_tone4_curly_hair":"1f9d1-1f3fe-200d-1f9b1.svg","person_tone4_red_hair":"1f9d1-1f3fe-200d-1f9b0.svg","person_tone4_white_hair":"1f9d1-1f3fe-200d-1f9b3.svg","person_tone5_bald":"1f9d1-1f3ff-200d-1f9b2.svg","person_tone5_curly_hair":"1f9d1-1f3ff-200d-1f9b1.svg","person_tone5_red_hair":"1f9d1-1f3ff-200d-1f9b0.svg","person_tone5_white_hair":"1f9d1-1f3ff-200d-1f9b3.svg","person_walking":"1f6b6.svg","person_walking_tone1":"1f6b6-1f3fb.svg","person_walking_tone2":"1f6b6-1f3fc.svg","person_walking_tone3":"1f6b6-1f3fd.svg","person_walking_tone4":"1f6b6-1f3fe.svg","person_walking_tone5":"1f6b6-1f3ff.svg","person_wearing_turban":"1f473.svg","person_wearing_turban_tone1":"1f473-1f3fb.svg","person_wearing_turban_tone2":"1f473-1f3fc.svg","person_wearing_turban_tone3":"1f473-1f3fd.svg","person_wearing_turban_tone4":"1f473-1f3fe.svg","person_wearing_turban_tone5":"1f473-1f3ff.svg","person_white_hair":"1f9d1-200d-1f9b3.svg","person_with_probing_cane":"1f9d1-200d-1f9af.svg","person_with_probing_cane_tone1":"1f9d1-1f3fb-200d-1f9af.svg","person_with_probing_cane_tone2":"1f9d1-1f3fc-200d-1f9af.svg","person_with_probing_cane_tone3":"1f9d1-1f3fd-200d-1f9af.svg","person_with_probing_cane_tone4":"1f9d1-1f3fe-200d-1f9af.svg","person_with_probing_cane_tone5":"1f9d1-1f3ff-200d-1f9af.svg","person_with_veil":"1f470.svg","person_with_veil_tone1":"1f470-1f3fb.svg","person_with_veil_tone2":"1f470-1f3fc.svg","person_with_veil_tone3":"1f470-1f3fd.svg","person_with_veil_tone4":"1f470-1f3fe.svg","person_with_veil_tone5":"1f470-1f3ff.svg","petri_dish":"1f9eb.svg","pick":"26cf.svg","pickup_truck":"1f6fb.svg","pie":"1f967.svg","pig2":"1f416.svg","pig":"1f437.svg","pig_nose":"1f43d.svg","pill":"1f48a.svg","pilot":"1f9d1-200d-2708-fe0f.svg","pilot_tone1":"1f9d1-1f3fb-200d-2708-fe0f.svg","pilot_tone2":"1f9d1-1f3fc-200d-2708-fe0f.svg","pilot_tone3":"1f9d1-1f3fd-200d-2708-fe0f.svg","pilot_tone4":"1f9d1-1f3fe-200d-2708-fe0f.svg","pilot_tone5":"1f9d1-1f3ff-200d-2708-fe0f.svg","pinched_fingers":"1f90c.svg","pinched_fingers_tone1":"1f90c-1f3fb.svg","pinched_fingers_tone2":"1f90c-1f3fc.svg","pinched_fingers_tone3":"1f90c-1f3fd.svg","pinched_fingers_tone4":"1f90c-1f3fe.svg","pinched_fingers_tone5":"1f90c-1f3ff.svg","pinching_hand":"1f90f.svg","pinching_hand_tone1":"1f90f-1f3fb.svg","pinching_hand_tone2":"1f90f-1f3fc.svg","pinching_hand_tone3":"1f90f-1f3fd.svg","pinching_hand_tone4":"1f90f-1f3fe.svg","pinching_hand_tone5":"1f90f-1f3ff.svg","pineapple":"1f34d.svg","ping_pong":"1f3d3.svg","pirate_flag":"1f3f4-200d-2620-fe0f.svg","pisces":"2653.svg","pizza":"1f355.svg","piñata":"1fa85.svg","placard":"1faa7.svg","place_of_worship":"1f6d0.svg","play_pause":"23ef.svg","pleading_face":"1f97a.svg","plunger":"1faa0.svg","point_down":"1f447.svg","point_down_tone1":"1f447-1f3fb.svg","point_down_tone2":"1f447-1f3fc.svg","point_down_tone3":"1f447-1f3fd.svg","point_down_tone4":"1f447-1f3fe.svg","point_down_tone5":"1f447-1f3ff.svg","point_left":"1f448.svg","point_left_tone1":"1f448-1f3fb.svg","point_left_tone2":"1f448-1f3fc.svg","point_left_tone3":"1f448-1f3fd.svg","point_left_tone4":"1f448-1f3fe.svg","point_left_tone5":"1f448-1f3ff.svg","point_right":"1f449.svg","point_right_tone1":"1f449-1f3fb.svg","point_right_tone2":"1f449-1f3fc.svg","point_right_tone3":"1f449-1f3fd.svg","point_right_tone4":"1f449-1f3fe.svg","point_right_tone5":"1f449-1f3ff.svg","point_up":"261d.svg","point_up_2":"1f446.svg","point_up_2_tone1":"1f446-1f3fb.svg","point_up_2_tone2":"1f446-1f3fc.svg","point_up_2_tone3":"1f446-1f3fd.svg","point_up_2_tone4":"1f446-1f3fe.svg","point_up_2_tone5":"1f446-1f3ff.svg","point_up_tone1":"261d-1f3fb.svg","point_up_tone2":"261d-1f3fc.svg","point_up_tone3":"261d-1f3fd.svg","point_up_tone4":"261d-1f3fe.svg","point_up_tone5":"261d-1f3ff.svg","polar_bear":"1f43b-200d-2744-fe0f.svg","police_car":"1f693.svg","police_officer":"1f46e.svg","police_officer_tone1":"1f46e-1f3fb.svg","police_officer_tone2":"1f46e-1f3fc.svg","police_officer_tone3":"1f46e-1f3fd.svg","police_officer_tone4":"1f46e-1f3fe.svg","police_officer_tone5":"1f46e-1f3ff.svg","poodle":"1f429.svg","poop":"1f4a9.svg","popcorn":"1f37f.svg","post_office":"1f3e3.svg","postal_horn":"1f4ef.svg","postbox":"1f4ee.svg","potable_water":"1f6b0.svg","potato":"1f954.svg","potted_plant":"1fab4.svg","pouch":"1f45d.svg","poultry_leg":"1f357.svg","pound":"1f4b7.svg","pouting_cat":"1f63e.svg","pray":"1f64f.svg","pray_tone1":"1f64f-1f3fb.svg","pray_tone2":"1f64f-1f3fc.svg","pray_tone3":"1f64f-1f3fd.svg","pray_tone4":"1f64f-1f3fe.svg","pray_tone5":"1f64f-1f3ff.svg","prayer_beads":"1f4ff.svg","pregnant_woman":"1f930.svg","pregnant_woman_tone1":"1f930-1f3fb.svg","pregnant_woman_tone2":"1f930-1f3fc.svg","pregnant_woman_tone3":"1f930-1f3fd.svg","pregnant_woman_tone4":"1f930-1f3fe.svg","pregnant_woman_tone5":"1f930-1f3ff.svg","pretzel":"1f968.svg","prince":"1f934.svg","prince_tone1":"1f934-1f3fb.svg","prince_tone2":"1f934-1f3fc.svg","prince_tone3":"1f934-1f3fd.svg","prince_tone4":"1f934-1f3fe.svg","prince_tone5":"1f934-1f3ff.svg","princess":"1f478.svg","princess_tone1":"1f478-1f3fb.svg","princess_tone2":"1f478-1f3fc.svg","princess_tone3":"1f478-1f3fd.svg","princess_tone4":"1f478-1f3fe.svg","princess_tone5":"1f478-1f3ff.svg","printer":"1f5a8.svg","probing_cane":"1f9af.svg","projector":"1f4fd.svg","punch":"1f44a.svg","punch_tone1":"1f44a-1f3fb.svg","punch_tone2":"1f44a-1f3fc.svg","punch_tone3":"1f44a-1f3fd.svg","punch_tone4":"1f44a-1f3fe.svg","punch_tone5":"1f44a-1f3ff.svg","purple_circle":"1f7e3.svg","purple_heart":"1f49c.svg","purple_square":"1f7ea.svg","purse":"1f45b.svg","pushpin":"1f4cc.svg","put_litter_in_its_place":"1f6ae.svg","question":"2753.svg","rabbit2":"1f407.svg","rabbit":"1f430.svg","raccoon":"1f99d.svg","race_car":"1f3ce.svg","racehorse":"1f40e.svg","radio":"1f4fb.svg","radio_button":"1f518.svg","radioactive":"2622.svg","rage":"1f621.svg","railway_car":"1f683.svg","railway_track":"1f6e4.svg","rainbow":"1f308.svg","rainbow_flag":"1f3f3-fe0f-200d-1f308.svg","raised_back_of_hand":"1f91a.svg","raised_back_of_hand_tone1":"1f91a-1f3fb.svg","raised_back_of_hand_tone2":"1f91a-1f3fc.svg","raised_back_of_hand_tone3":"1f91a-1f3fd.svg","raised_back_of_hand_tone4":"1f91a-1f3fe.svg","raised_back_of_hand_tone5":"1f91a-1f3ff.svg","raised_hand":"270b.svg","raised_hand_tone1":"270b-1f3fb.svg","raised_hand_tone2":"270b-1f3fc.svg","raised_hand_tone3":"270b-1f3fd.svg","raised_hand_tone4":"270b-1f3fe.svg","raised_hand_tone5":"270b-1f3ff.svg","raised_hands":"1f64c.svg","raised_hands_tone1":"1f64c-1f3fb.svg","raised_hands_tone2":"1f64c-1f3fc.svg","raised_hands_tone3":"1f64c-1f3fd.svg","raised_hands_tone4":"1f64c-1f3fe.svg","raised_hands_tone5":"1f64c-1f3ff.svg","ram":"1f40f.svg","ramen":"1f35c.svg","rat":"1f400.svg","razor":"1fa92.svg","receipt":"1f9fe.svg","record_button":"23fa.svg","recycle":"267b.svg","red_car":"1f697.svg","red_circle":"1f534.svg","red_envelope":"1f9e7.svg","red_haired":"1f9b0.svg","red_square":"1f7e5.svg","regional_indicator_a":"1f1e6.svg","regional_indicator_b":"1f1e7.svg","regional_indicator_c":"1f1e8.svg","regional_indicator_d":"1f1e9.svg","regional_indicator_e":"1f1ea.svg","regional_indicator_f":"1f1eb.svg","regional_indicator_g":"1f1ec.svg","regional_indicator_h":"1f1ed.svg","regional_indicator_i":"1f1ee.svg","regional_indicator_j":"1f1ef.svg","regional_indicator_k":"1f1f0.svg","regional_indicator_l":"1f1f1.svg","regional_indicator_m":"1f1f2.svg","regional_indicator_n":"1f1f3.svg","regional_indicator_o":"1f1f4.svg","regional_indicator_p":"1f1f5.svg","regional_indicator_q":"1f1f6.svg","regional_indicator_r":"1f1f7.svg","regional_indicator_s":"1f1f8.svg","regional_indicator_t":"1f1f9.svg","regional_indicator_u":"1f1fa.svg","regional_indicator_v":"1f1fb.svg","regional_indicator_w":"1f1fc.svg","regional_indicator_x":"1f1fd.svg","regional_indicator_y":"1f1fe.svg","regional_indicator_z":"1f1ff.svg","registered":"ae.svg","relaxed":"263a.svg","relieved":"1f60c.svg","reminder_ribbon":"1f397.svg","repeat":"1f501.svg","repeat_one":"1f502.svg","restroom":"1f6bb.svg","revolving_hearts":"1f49e.svg","rewind":"23ea.svg","rhino":"1f98f.svg","ribbon":"1f380.svg","rice":"1f35a.svg","rice_ball":"1f359.svg","rice_cracker":"1f358.svg","rice_scene":"1f391.svg","right_facing_fist":"1f91c.svg","right_facing_fist_tone1":"1f91c-1f3fb.svg","right_facing_fist_tone2":"1f91c-1f3fc.svg","right_facing_fist_tone3":"1f91c-1f3fd.svg","right_facing_fist_tone4":"1f91c-1f3fe.svg","right_facing_fist_tone5":"1f91c-1f3ff.svg","ring":"1f48d.svg","ringed_planet":"1fa90.svg","robot":"1f916.svg","rock":"1faa8.svg","rocket":"1f680.svg","rofl":"1f923.svg","roll_of_paper":"1f9fb.svg","roller_coaster":"1f3a2.svg","roller_skate":"1f6fc.svg","rolling_eyes":"1f644.svg","rooster":"1f413.svg","rose":"1f339.svg","rosette":"1f3f5.svg","rotating_light":"1f6a8.svg","round_pushpin":"1f4cd.svg","rugby_football":"1f3c9.svg","running_shirt_with_sash":"1f3bd.svg","sa":"1f202.svg","safety_pin":"1f9f7.svg","safety_vest":"1f9ba.svg","sagittarius":"2650.svg","sailboat":"26f5.svg","sake":"1f376.svg","salad":"1f957.svg","salt":"1f9c2.svg","sandal":"1f461.svg","sandwich":"1f96a.svg","santa":"1f385.svg","santa_tone1":"1f385-1f3fb.svg","santa_tone2":"1f385-1f3fc.svg","santa_tone3":"1f385-1f3fd.svg","santa_tone4":"1f385-1f3fe.svg","santa_tone5":"1f385-1f3ff.svg","sari":"1f97b.svg","satellite":"1f4e1.svg","satellite_orbital":"1f6f0.svg","sauropod":"1f995.svg","saxophone":"1f3b7.svg","scales":"2696.svg","scarf":"1f9e3.svg","school":"1f3eb.svg","school_satchel":"1f392.svg","scientist":"1f9d1-200d-1f52c.svg","scientist_tone1":"1f9d1-1f3fb-200d-1f52c.svg","scientist_tone2":"1f9d1-1f3fc-200d-1f52c.svg","scientist_tone3":"1f9d1-1f3fd-200d-1f52c.svg","scientist_tone4":"1f9d1-1f3fe-200d-1f52c.svg","scientist_tone5":"1f9d1-1f3ff-200d-1f52c.svg","scissors":"2702.svg","scooter":"1f6f4.svg","scorpion":"1f982.svg","scorpius":"264f.svg","scotland":"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f.svg","scream":"1f631.svg","scream_cat":"1f640.svg","screwdriver":"1fa9b.svg","scroll":"1f4dc.svg","seal":"1f9ad.svg","seat":"1f4ba.svg","second_place":"1f948.svg","secret":"3299.svg","see_no_evil":"1f648.svg","seedling":"1f331.svg","selfie":"1f933.svg","selfie_tone1":"1f933-1f3fb.svg","selfie_tone2":"1f933-1f3fc.svg","selfie_tone3":"1f933-1f3fd.svg","selfie_tone4":"1f933-1f3fe.svg","selfie_tone5":"1f933-1f3ff.svg","service_dog":"1f415-200d-1f9ba.svg","seven":"37-20e3.svg","sewing_needle":"1faa1.svg","shallow_pan_of_food":"1f958.svg","shamrock":"2618.svg","shark":"1f988.svg","shaved_ice":"1f367.svg","sheep":"1f411.svg","shell":"1f41a.svg","shibuya":"e50a.svg","shield":"1f6e1.svg","shinto_shrine":"26e9.svg","ship":"1f6a2.svg","shirt":"1f455.svg","shopping_bags":"1f6cd.svg","shopping_cart":"1f6d2.svg","shorts":"1fa73.svg","shower":"1f6bf.svg","shrimp":"1f990.svg","shushing_face":"1f92b.svg","signal_strength":"1f4f6.svg","singer":"1f9d1-200d-1f3a4.svg","singer_tone1":"1f9d1-1f3fb-200d-1f3a4.svg","singer_tone2":"1f9d1-1f3fc-200d-1f3a4.svg","singer_tone3":"1f9d1-1f3fd-200d-1f3a4.svg","singer_tone4":"1f9d1-1f3fe-200d-1f3a4.svg","singer_tone5":"1f9d1-1f3ff-200d-1f3a4.svg","six":"36-20e3.svg","six_pointed_star":"1f52f.svg","skateboard":"1f6f9.svg","ski":"1f3bf.svg","skier":"26f7.svg","skier_tone1":"26f7-1f3fb.svg","skier_tone2":"26f7-1f3fc.svg","skier_tone3":"26f7-1f3fd.svg","skier_tone4":"26f7-1f3fe.svg","skier_tone5":"26f7-1f3ff.svg","skull":"1f480.svg","skull_crossbones":"2620.svg","skunk":"1f9a8.svg","sled":"1f6f7.svg","sleeping":"1f634.svg","sleeping_accommodation":"1f6cc.svg","sleepy":"1f62a.svg","slight_frown":"1f641.svg","slight_smile":"1f642.svg","slot_machine":"1f3b0.svg","sloth":"1f9a5.svg","small_blue_diamond":"1f539.svg","small_orange_diamond":"1f538.svg","small_red_triangle":"1f53a.svg","small_red_triangle_down":"1f53b.svg","smile":"1f604.svg","smile_cat":"1f638.svg","smiley":"1f603.svg","smiley_cat":"1f63a.svg","smiling_face_with_3_hearts":"1f970.svg","smiling_face_with_tear":"1f972.svg","smiling_imp":"1f608.svg","smirk":"1f60f.svg","smirk_cat":"1f63c.svg","smoking":"1f6ac.svg","snail":"1f40c.svg","snake":"1f40d.svg","sneezing_face":"1f927.svg","snowboarder":"1f3c2.svg","snowboarder_tone1":"1f3c2-1f3fb.svg","snowboarder_tone2":"1f3c2-1f3fc.svg","snowboarder_tone3":"1f3c2-1f3fd.svg","snowboarder_tone4":"1f3c2-1f3fe.svg","snowboarder_tone5":"1f3c2-1f3ff.svg","snowflake":"2744.svg","snowman2":"2603.svg","snowman":"26c4.svg","soap":"1f9fc.svg","sob":"1f62d.svg","soccer":"26bd.svg","socks":"1f9e6.svg","softball":"1f94e.svg","soon":"1f51c.svg","sos":"1f198.svg","sound":"1f509.svg","space_invader":"1f47e.svg","spades":"2660.svg","spaghetti":"1f35d.svg","sparkle":"2747.svg","sparkler":"1f387.svg","sparkles":"2728.svg","sparkling_heart":"1f496.svg","speak_no_evil":"1f64a.svg","speaker":"1f508.svg","speaking_head":"1f5e3.svg","speech_balloon":"1f4ac.svg","speech_left":"1f5e8.svg","speedboat":"1f6a4.svg","spider":"1f577.svg","spider_web":"1f578.svg","sponge":"1f9fd.svg","spoon":"1f944.svg","squeeze_bottle":"1f9f4.svg","squid":"1f991.svg","stadium":"1f3df.svg","star2":"1f31f.svg","star":"2b50.svg","star_and_crescent":"262a.svg","star_of_david":"2721.svg","star_struck":"1f929.svg","stars":"1f320.svg","station":"1f689.svg","statue_of_liberty":"1f5fd.svg","steam_locomotive":"1f682.svg","stethoscope":"1fa7a.svg","stew":"1f372.svg","stop_button":"23f9.svg","stopwatch":"23f1.svg","straight_ruler":"1f4cf.svg","strawberry":"1f353.svg","stuck_out_tongue":"1f61b.svg","stuck_out_tongue_closed_eyes":"1f61d.svg","stuck_out_tongue_winking_eye":"1f61c.svg","student":"1f9d1-200d-1f393.svg","student_tone1":"1f9d1-1f3fb-200d-1f393.svg","student_tone2":"1f9d1-1f3fc-200d-1f393.svg","student_tone3":"1f9d1-1f3fd-200d-1f393.svg","student_tone4":"1f9d1-1f3fe-200d-1f393.svg","student_tone5":"1f9d1-1f3ff-200d-1f393.svg","stuffed_flatbread":"1f959.svg","sun_with_face":"1f31e.svg","sunflower":"1f33b.svg","sunglasses":"1f60e.svg","sunny":"2600.svg","sunrise":"1f305.svg","sunrise_over_mountains":"1f304.svg","superhero":"1f9b8.svg","superhero_tone1":"1f9b8-1f3fb.svg","superhero_tone2":"1f9b8-1f3fc.svg","superhero_tone3":"1f9b8-1f3fd.svg","superhero_tone4":"1f9b8-1f3fe.svg","superhero_tone5":"1f9b8-1f3ff.svg","supervillain":"1f9b9.svg","supervillain_tone1":"1f9b9-1f3fb.svg","supervillain_tone2":"1f9b9-1f3fc.svg","supervillain_tone3":"1f9b9-1f3fd.svg","supervillain_tone4":"1f9b9-1f3fe.svg","supervillain_tone5":"1f9b9-1f3ff.svg","sushi":"1f363.svg","suspension_railway":"1f69f.svg","swan":"1f9a2.svg","sweat":"1f613.svg","sweat_drops":"1f4a6.svg","sweat_smile":"1f605.svg","sweet_potato":"1f360.svg","symbols":"1f523.svg","synagogue":"1f54d.svg","syringe":"1f489.svg","t_rex":"1f996.svg","taco":"1f32e.svg","tada":"1f389.svg","takeout_box":"1f961.svg","tamale":"1fad4.svg","tanabata_tree":"1f38b.svg","tangerine":"1f34a.svg","taurus":"2649.svg","taxi":"1f695.svg","tea":"1f375.svg","teacher":"1f9d1-200d-1f3eb.svg","teacher_tone1":"1f9d1-1f3fb-200d-1f3eb.svg","teacher_tone2":"1f9d1-1f3fc-200d-1f3eb.svg","teacher_tone3":"1f9d1-1f3fd-200d-1f3eb.svg","teacher_tone4":"1f9d1-1f3fe-200d-1f3eb.svg","teacher_tone5":"1f9d1-1f3ff-200d-1f3eb.svg","teapot":"1fad6.svg","technologist":"1f9d1-200d-1f4bb.svg","technologist_tone1":"1f9d1-1f3fb-200d-1f4bb.svg","technologist_tone2":"1f9d1-1f3fc-200d-1f4bb.svg","technologist_tone3":"1f9d1-1f3fd-200d-1f4bb.svg","technologist_tone4":"1f9d1-1f3fe-200d-1f4bb.svg","technologist_tone5":"1f9d1-1f3ff-200d-1f4bb.svg","teddy_bear":"1f9f8.svg","telephone":"260e.svg","telephone_receiver":"1f4de.svg","telescope":"1f52d.svg","tennis":"1f3be.svg","tent":"26fa.svg","test_tube":"1f9ea.svg","thermometer":"1f321.svg","thermometer_face":"1f912.svg","thinking":"1f914.svg","third_place":"1f949.svg","thong_sandal":"1fa74.svg","thought_balloon":"1f4ad.svg","thread":"1f9f5.svg","three":"33-20e3.svg","thumbsdown":"1f44e.svg","thumbsdown_tone1":"1f44e-1f3fb.svg","thumbsdown_tone2":"1f44e-1f3fc.svg","thumbsdown_tone3":"1f44e-1f3fd.svg","thumbsdown_tone4":"1f44e-1f3fe.svg","thumbsdown_tone5":"1f44e-1f3ff.svg","thumbsup":"1f44d.svg","thumbsup_tone1":"1f44d-1f3fb.svg","thumbsup_tone2":"1f44d-1f3fc.svg","thumbsup_tone3":"1f44d-1f3fd.svg","thumbsup_tone4":"1f44d-1f3fe.svg","thumbsup_tone5":"1f44d-1f3ff.svg","thunder_cloud_rain":"26c8.svg","ticket":"1f3ab.svg","tickets":"1f39f.svg","tiger2":"1f405.svg","tiger":"1f42f.svg","timer":"23f2.svg","tired_face":"1f62b.svg","tm":"2122.svg","toilet":"1f6bd.svg","tokyo_tower":"1f5fc.svg","tomato":"1f345.svg","tone1":"1f3fb.svg","tone2":"1f3fc.svg","tone3":"1f3fd.svg","tone4":"1f3fe.svg","tone5":"1f3ff.svg","tongue":"1f445.svg","toolbox":"1f9f0.svg","tools":"1f6e0.svg","tooth":"1f9b7.svg","toothbrush":"1faa5.svg","top":"1f51d.svg","tophat":"1f3a9.svg","track_next":"23ed.svg","track_previous":"23ee.svg","trackball":"1f5b2.svg","tractor":"1f69c.svg","traffic_light":"1f6a5.svg","train2":"1f686.svg","train":"1f68b.svg","tram":"1f68a.svg","transgender_flag":"1f3f3-fe0f-200d-26a7-fe0f.svg","transgender_symbol":"26a7.svg","triangular_flag_on_post":"1f6a9.svg","triangular_ruler":"1f4d0.svg","trident":"1f531.svg","triumph":"1f624.svg","trolleybus":"1f68e.svg","trophy":"1f3c6.svg","tropical_drink":"1f379.svg","tropical_fish":"1f420.svg","truck":"1f69a.svg","trumpet":"1f3ba.svg","tulip":"1f337.svg","tumbler_glass":"1f943.svg","turkey":"1f983.svg","turtle":"1f422.svg","tv":"1f4fa.svg","twisted_rightwards_arrows":"1f500.svg","two":"32-20e3.svg","two_hearts":"1f495.svg","two_men_holding_hands":"1f46c.svg","two_women_holding_hands":"1f46d.svg","u5272":"1f239.svg","u5408":"1f234.svg","u55b6":"1f23a.svg","u6307":"1f22f.svg","u6708":"1f237.svg","u6709":"1f236.svg","u6e80":"1f235.svg","u7121":"1f21a.svg","u7533":"1f238.svg","u7981":"1f232.svg","u7a7a":"1f233.svg","umbrella2":"2602.svg","umbrella":"2614.svg","unamused":"1f612.svg","underage":"1f51e.svg","unicorn":"1f984.svg","united_nations":"1f1fa-1f1f3.svg","unlock":"1f513.svg","up":"1f199.svg","upside_down":"1f643.svg","urn":"26b1.svg","v":"270c.svg","v_tone1":"270c-1f3fb.svg","v_tone2":"270c-1f3fc.svg","v_tone3":"270c-1f3fd.svg","v_tone4":"270c-1f3fe.svg","v_tone5":"270c-1f3ff.svg","vampire":"1f9db.svg","vampire_tone1":"1f9db-1f3fb.svg","vampire_tone2":"1f9db-1f3fc.svg","vampire_tone3":"1f9db-1f3fd.svg","vampire_tone4":"1f9db-1f3fe.svg","vampire_tone5":"1f9db-1f3ff.svg","vertical_traffic_light":"1f6a6.svg","vhs":"1f4fc.svg","vibration_mode":"1f4f3.svg","video_camera":"1f4f9.svg","video_game":"1f3ae.svg","violin":"1f3bb.svg","virgo":"264d.svg","volcano":"1f30b.svg","volleyball":"1f3d0.svg","vs":"1f19a.svg","vulcan":"1f596.svg","vulcan_tone1":"1f596-1f3fb.svg","vulcan_tone2":"1f596-1f3fc.svg","vulcan_tone3":"1f596-1f3fd.svg","vulcan_tone4":"1f596-1f3fe.svg","vulcan_tone5":"1f596-1f3ff.svg","waffle":"1f9c7.svg","wales":"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f.svg","waning_crescent_moon":"1f318.svg","waning_gibbous_moon":"1f316.svg","warning":"26a0.svg","wastebasket":"1f5d1.svg","watch":"231a.svg","water_buffalo":"1f403.svg","watermelon":"1f349.svg","wave":"1f44b.svg","wave_tone1":"1f44b-1f3fb.svg","wave_tone2":"1f44b-1f3fc.svg","wave_tone3":"1f44b-1f3fd.svg","wave_tone4":"1f44b-1f3fe.svg","wave_tone5":"1f44b-1f3ff.svg","wavy_dash":"3030.svg","waxing_crescent_moon":"1f312.svg","waxing_gibbous_moon":"1f314.svg","wc":"1f6be.svg","weary":"1f629.svg","wedding":"1f492.svg","whale2":"1f40b.svg","whale":"1f433.svg","wheel_of_dharma":"2638.svg","wheelchair":"267f.svg","white_check_mark":"2705.svg","white_circle":"26aa.svg","white_flower":"1f4ae.svg","white_haired":"1f9b3.svg","white_heart":"1f90d.svg","white_large_square":"2b1c.svg","white_medium_small_square":"25fd.svg","white_medium_square":"25fb.svg","white_small_square":"25ab.svg","white_square_button":"1f533.svg","white_sun_cloud":"1f325.svg","white_sun_rain_cloud":"1f326.svg","white_sun_small_cloud":"1f324.svg","wilted_rose":"1f940.svg","wind_blowing_face":"1f32c.svg","wind_chime":"1f390.svg","window":"1fa9f.svg","wine_glass":"1f377.svg","wink":"1f609.svg","wolf":"1f43a.svg","woman":"1f469.svg","woman_and_man_holding_hands_tone1":"1f46b-1f3fb.svg","woman_and_man_holding_hands_tone1_tone2":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone1_tone3":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone1_tone4":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone1_tone5":"1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone2":"1f46b-1f3fc.svg","woman_and_man_holding_hands_tone2_tone1":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone2_tone3":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone2_tone4":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone2_tone5":"1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone3":"1f46b-1f3fd.svg","woman_and_man_holding_hands_tone3_tone1":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone3_tone2":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone3_tone4":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe.svg","woman_and_man_holding_hands_tone3_tone5":"1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone4":"1f46b-1f3fe.svg","woman_and_man_holding_hands_tone4_tone1":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone4_tone2":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone4_tone3":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone4_tone5":"1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff.svg","woman_and_man_holding_hands_tone5":"1f46b-1f3ff.svg","woman_and_man_holding_hands_tone5_tone1":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb.svg","woman_and_man_holding_hands_tone5_tone2":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc.svg","woman_and_man_holding_hands_tone5_tone3":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd.svg","woman_and_man_holding_hands_tone5_tone4":"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe.svg","woman_artist":"1f469-200d-1f3a8.svg","woman_artist_tone1":"1f469-1f3fb-200d-1f3a8.svg","woman_artist_tone2":"1f469-1f3fc-200d-1f3a8.svg","woman_artist_tone3":"1f469-1f3fd-200d-1f3a8.svg","woman_artist_tone4":"1f469-1f3fe-200d-1f3a8.svg","woman_artist_tone5":"1f469-1f3ff-200d-1f3a8.svg","woman_astronaut":"1f469-200d-1f680.svg","woman_astronaut_tone1":"1f469-1f3fb-200d-1f680.svg","woman_astronaut_tone2":"1f469-1f3fc-200d-1f680.svg","woman_astronaut_tone3":"1f469-1f3fd-200d-1f680.svg","woman_astronaut_tone4":"1f469-1f3fe-200d-1f680.svg","woman_astronaut_tone5":"1f469-1f3ff-200d-1f680.svg","woman_bald":"1f469-200d-1f9b2.svg","woman_bald_tone1":"1f469-1f3fb-200d-1f9b2.svg","woman_bald_tone2":"1f469-1f3fc-200d-1f9b2.svg","woman_bald_tone3":"1f469-1f3fd-200d-1f9b2.svg","woman_bald_tone4":"1f469-1f3fe-200d-1f9b2.svg","woman_bald_tone5":"1f469-1f3ff-200d-1f9b2.svg","woman_beard":"1f9d4-200d-2640-fe0f.svg","woman_biking":"1f6b4-200d-2640-fe0f.svg","woman_biking_tone1":"1f6b4-1f3fb-200d-2640-fe0f.svg","woman_biking_tone2":"1f6b4-1f3fc-200d-2640-fe0f.svg","woman_biking_tone3":"1f6b4-1f3fd-200d-2640-fe0f.svg","woman_biking_tone4":"1f6b4-1f3fe-200d-2640-fe0f.svg","woman_biking_tone5":"1f6b4-1f3ff-200d-2640-fe0f.svg","woman_bouncing_ball":"26f9-fe0f-200d-2640-fe0f.svg","woman_bouncing_ball_tone1":"26f9-1f3fb-200d-2640-fe0f.svg","woman_bouncing_ball_tone2":"26f9-1f3fc-200d-2640-fe0f.svg","woman_bouncing_ball_tone3":"26f9-1f3fd-200d-2640-fe0f.svg","woman_bouncing_ball_tone4":"26f9-1f3fe-200d-2640-fe0f.svg","woman_bouncing_ball_tone5":"26f9-1f3ff-200d-2640-fe0f.svg","woman_bowing":"1f647-200d-2640-fe0f.svg","woman_bowing_tone1":"1f647-1f3fb-200d-2640-fe0f.svg","woman_bowing_tone2":"1f647-1f3fc-200d-2640-fe0f.svg","woman_bowing_tone3":"1f647-1f3fd-200d-2640-fe0f.svg","woman_bowing_tone4":"1f647-1f3fe-200d-2640-fe0f.svg","woman_bowing_tone5":"1f647-1f3ff-200d-2640-fe0f.svg","woman_cartwheeling":"1f938-200d-2640-fe0f.svg","woman_cartwheeling_tone1":"1f938-1f3fb-200d-2640-fe0f.svg","woman_cartwheeling_tone2":"1f938-1f3fc-200d-2640-fe0f.svg","woman_cartwheeling_tone3":"1f938-1f3fd-200d-2640-fe0f.svg","woman_cartwheeling_tone4":"1f938-1f3fe-200d-2640-fe0f.svg","woman_cartwheeling_tone5":"1f938-1f3ff-200d-2640-fe0f.svg","woman_climbing":"1f9d7-200d-2640-fe0f.svg","woman_climbing_tone1":"1f9d7-1f3fb-200d-2640-fe0f.svg","woman_climbing_tone2":"1f9d7-1f3fc-200d-2640-fe0f.svg","woman_climbing_tone3":"1f9d7-1f3fd-200d-2640-fe0f.svg","woman_climbing_tone4":"1f9d7-1f3fe-200d-2640-fe0f.svg","woman_climbing_tone5":"1f9d7-1f3ff-200d-2640-fe0f.svg","woman_construction_worker":"1f477-200d-2640-fe0f.svg","woman_construction_worker_tone1":"1f477-1f3fb-200d-2640-fe0f.svg","woman_construction_worker_tone2":"1f477-1f3fc-200d-2640-fe0f.svg","woman_construction_worker_tone3":"1f477-1f3fd-200d-2640-fe0f.svg","woman_construction_worker_tone4":"1f477-1f3fe-200d-2640-fe0f.svg","woman_construction_worker_tone5":"1f477-1f3ff-200d-2640-fe0f.svg","woman_cook":"1f469-200d-1f373.svg","woman_cook_tone1":"1f469-1f3fb-200d-1f373.svg","woman_cook_tone2":"1f469-1f3fc-200d-1f373.svg","woman_cook_tone3":"1f469-1f3fd-200d-1f373.svg","woman_cook_tone4":"1f469-1f3fe-200d-1f373.svg","woman_cook_tone5":"1f469-1f3ff-200d-1f373.svg","woman_curly_haired":"1f469-200d-1f9b1.svg","woman_curly_haired_tone1":"1f469-1f3fb-200d-1f9b1.svg","woman_curly_haired_tone2":"1f469-1f3fc-200d-1f9b1.svg","woman_curly_haired_tone3":"1f469-1f3fd-200d-1f9b1.svg","woman_curly_haired_tone4":"1f469-1f3fe-200d-1f9b1.svg","woman_curly_haired_tone5":"1f469-1f3ff-200d-1f9b1.svg","woman_detective":"1f575-fe0f-200d-2640-fe0f.svg","woman_detective_tone1":"1f575-1f3fb-200d-2640-fe0f.svg","woman_detective_tone2":"1f575-1f3fc-200d-2640-fe0f.svg","woman_detective_tone3":"1f575-1f3fd-200d-2640-fe0f.svg","woman_detective_tone4":"1f575-1f3fe-200d-2640-fe0f.svg","woman_detective_tone5":"1f575-1f3ff-200d-2640-fe0f.svg","woman_elf":"1f9dd-200d-2640-fe0f.svg","woman_elf_tone1":"1f9dd-1f3fb-200d-2640-fe0f.svg","woman_elf_tone2":"1f9dd-1f3fc-200d-2640-fe0f.svg","woman_elf_tone3":"1f9dd-1f3fd-200d-2640-fe0f.svg","woman_elf_tone4":"1f9dd-1f3fe-200d-2640-fe0f.svg","woman_elf_tone5":"1f9dd-1f3ff-200d-2640-fe0f.svg","woman_facepalming":"1f926-200d-2640-fe0f.svg","woman_facepalming_tone1":"1f926-1f3fb-200d-2640-fe0f.svg","woman_facepalming_tone2":"1f926-1f3fc-200d-2640-fe0f.svg","woman_facepalming_tone3":"1f926-1f3fd-200d-2640-fe0f.svg","woman_facepalming_tone4":"1f926-1f3fe-200d-2640-fe0f.svg","woman_facepalming_tone5":"1f926-1f3ff-200d-2640-fe0f.svg","woman_factory_worker":"1f469-200d-1f3ed.svg","woman_factory_worker_tone1":"1f469-1f3fb-200d-1f3ed.svg","woman_factory_worker_tone2":"1f469-1f3fc-200d-1f3ed.svg","woman_factory_worker_tone3":"1f469-1f3fd-200d-1f3ed.svg","woman_factory_worker_tone4":"1f469-1f3fe-200d-1f3ed.svg","woman_factory_worker_tone5":"1f469-1f3ff-200d-1f3ed.svg","woman_fairy":"1f9da-200d-2640-fe0f.svg","woman_fairy_tone1":"1f9da-1f3fb-200d-2640-fe0f.svg","woman_fairy_tone2":"1f9da-1f3fc-200d-2640-fe0f.svg","woman_fairy_tone3":"1f9da-1f3fd-200d-2640-fe0f.svg","woman_fairy_tone4":"1f9da-1f3fe-200d-2640-fe0f.svg","woman_fairy_tone5":"1f9da-1f3ff-200d-2640-fe0f.svg","woman_farmer":"1f469-200d-1f33e.svg","woman_farmer_tone1":"1f469-1f3fb-200d-1f33e.svg","woman_farmer_tone2":"1f469-1f3fc-200d-1f33e.svg","woman_farmer_tone3":"1f469-1f3fd-200d-1f33e.svg","woman_farmer_tone4":"1f469-1f3fe-200d-1f33e.svg","woman_farmer_tone5":"1f469-1f3ff-200d-1f33e.svg","woman_feeding_baby":"1f469-200d-1f37c.svg","woman_feeding_baby_tone1":"1f469-1f3fb-200d-1f37c.svg","woman_feeding_baby_tone2":"1f469-1f3fc-200d-1f37c.svg","woman_feeding_baby_tone3":"1f469-1f3fd-200d-1f37c.svg","woman_feeding_baby_tone4":"1f469-1f3fe-200d-1f37c.svg","woman_feeding_baby_tone5":"1f469-1f3ff-200d-1f37c.svg","woman_firefighter":"1f469-200d-1f692.svg","woman_firefighter_tone1":"1f469-1f3fb-200d-1f692.svg","woman_firefighter_tone2":"1f469-1f3fc-200d-1f692.svg","woman_firefighter_tone3":"1f469-1f3fd-200d-1f692.svg","woman_firefighter_tone4":"1f469-1f3fe-200d-1f692.svg","woman_firefighter_tone5":"1f469-1f3ff-200d-1f692.svg","woman_frowning":"1f64d-200d-2640-fe0f.svg","woman_frowning_tone1":"1f64d-1f3fb-200d-2640-fe0f.svg","woman_frowning_tone2":"1f64d-1f3fc-200d-2640-fe0f.svg","woman_frowning_tone3":"1f64d-1f3fd-200d-2640-fe0f.svg","woman_frowning_tone4":"1f64d-1f3fe-200d-2640-fe0f.svg","woman_frowning_tone5":"1f64d-1f3ff-200d-2640-fe0f.svg","woman_genie":"1f9de-200d-2640-fe0f.svg","woman_gesturing_no":"1f645-200d-2640-fe0f.svg","woman_gesturing_no_tone1":"1f645-1f3fb-200d-2640-fe0f.svg","woman_gesturing_no_tone2":"1f645-1f3fc-200d-2640-fe0f.svg","woman_gesturing_no_tone3":"1f645-1f3fd-200d-2640-fe0f.svg","woman_gesturing_no_tone4":"1f645-1f3fe-200d-2640-fe0f.svg","woman_gesturing_no_tone5":"1f645-1f3ff-200d-2640-fe0f.svg","woman_gesturing_ok":"1f646-200d-2640-fe0f.svg","woman_gesturing_ok_tone1":"1f646-1f3fb-200d-2640-fe0f.svg","woman_gesturing_ok_tone2":"1f646-1f3fc-200d-2640-fe0f.svg","woman_gesturing_ok_tone3":"1f646-1f3fd-200d-2640-fe0f.svg","woman_gesturing_ok_tone4":"1f646-1f3fe-200d-2640-fe0f.svg","woman_gesturing_ok_tone5":"1f646-1f3ff-200d-2640-fe0f.svg","woman_getting_face_massage":"1f486-200d-2640-fe0f.svg","woman_getting_face_massage_tone1":"1f486-1f3fb-200d-2640-fe0f.svg","woman_getting_face_massage_tone2":"1f486-1f3fc-200d-2640-fe0f.svg","woman_getting_face_massage_tone3":"1f486-1f3fd-200d-2640-fe0f.svg","woman_getting_face_massage_tone4":"1f486-1f3fe-200d-2640-fe0f.svg","woman_getting_face_massage_tone5":"1f486-1f3ff-200d-2640-fe0f.svg","woman_getting_haircut":"1f487-200d-2640-fe0f.svg","woman_getting_haircut_tone1":"1f487-1f3fb-200d-2640-fe0f.svg","woman_getting_haircut_tone2":"1f487-1f3fc-200d-2640-fe0f.svg","woman_getting_haircut_tone3":"1f487-1f3fd-200d-2640-fe0f.svg","woman_getting_haircut_tone4":"1f487-1f3fe-200d-2640-fe0f.svg","woman_getting_haircut_tone5":"1f487-1f3ff-200d-2640-fe0f.svg","woman_golfing":"1f3cc-fe0f-200d-2640-fe0f.svg","woman_golfing_tone1":"1f3cc-1f3fb-200d-2640-fe0f.svg","woman_golfing_tone2":"1f3cc-1f3fc-200d-2640-fe0f.svg","woman_golfing_tone3":"1f3cc-1f3fd-200d-2640-fe0f.svg","woman_golfing_tone4":"1f3cc-1f3fe-200d-2640-fe0f.svg","woman_golfing_tone5":"1f3cc-1f3ff-200d-2640-fe0f.svg","woman_guard":"1f482-200d-2640-fe0f.svg","woman_guard_tone1":"1f482-1f3fb-200d-2640-fe0f.svg","woman_guard_tone2":"1f482-1f3fc-200d-2640-fe0f.svg","woman_guard_tone3":"1f482-1f3fd-200d-2640-fe0f.svg","woman_guard_tone4":"1f482-1f3fe-200d-2640-fe0f.svg","woman_guard_tone5":"1f482-1f3ff-200d-2640-fe0f.svg","woman_health_worker":"1f469-200d-2695-fe0f.svg","woman_health_worker_tone1":"1f469-1f3fb-200d-2695-fe0f.svg","woman_health_worker_tone2":"1f469-1f3fc-200d-2695-fe0f.svg","woman_health_worker_tone3":"1f469-1f3fd-200d-2695-fe0f.svg","woman_health_worker_tone4":"1f469-1f3fe-200d-2695-fe0f.svg","woman_health_worker_tone5":"1f469-1f3ff-200d-2695-fe0f.svg","woman_in_lotus_position":"1f9d8-200d-2640-fe0f.svg","woman_in_lotus_position_tone1":"1f9d8-1f3fb-200d-2640-fe0f.svg","woman_in_lotus_position_tone2":"1f9d8-1f3fc-200d-2640-fe0f.svg","woman_in_lotus_position_tone3":"1f9d8-1f3fd-200d-2640-fe0f.svg","woman_in_lotus_position_tone4":"1f9d8-1f3fe-200d-2640-fe0f.svg","woman_in_lotus_position_tone5":"1f9d8-1f3ff-200d-2640-fe0f.svg","woman_in_manual_wheelchair":"1f469-200d-1f9bd.svg","woman_in_manual_wheelchair_tone1":"1f469-1f3fb-200d-1f9bd.svg","woman_in_manual_wheelchair_tone2":"1f469-1f3fc-200d-1f9bd.svg","woman_in_manual_wheelchair_tone3":"1f469-1f3fd-200d-1f9bd.svg","woman_in_manual_wheelchair_tone4":"1f469-1f3fe-200d-1f9bd.svg","woman_in_manual_wheelchair_tone5":"1f469-1f3ff-200d-1f9bd.svg","woman_in_motorized_wheelchair":"1f469-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone1":"1f469-1f3fb-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone2":"1f469-1f3fc-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone3":"1f469-1f3fd-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone4":"1f469-1f3fe-200d-1f9bc.svg","woman_in_motorized_wheelchair_tone5":"1f469-1f3ff-200d-1f9bc.svg","woman_in_santa_hat":"1f469-200d-1f384.svg","woman_in_santa_hat_tone1":"1f469-1f3fb-200d-1f384.svg","woman_in_santa_hat_tone2":"1f468-1f3ff-200d-1f384.svg","woman_in_santa_hat_tone3":"1f469-1f3fe-200d-1f384.svg","woman_in_santa_hat_tone4":"1f469-1f3fd-200d-1f384.svg","woman_in_santa_hat_tone5":"1f469-1f3fc-200d-1f384.svg","woman_in_steamy_room":"1f9d6-200d-2640-fe0f.svg","woman_in_steamy_room_tone1":"1f9d6-1f3fb-200d-2640-fe0f.svg","woman_in_steamy_room_tone2":"1f9d6-1f3fc-200d-2640-fe0f.svg","woman_in_steamy_room_tone3":"1f9d6-1f3fd-200d-2640-fe0f.svg","woman_in_steamy_room_tone4":"1f9d6-1f3fe-200d-2640-fe0f.svg","woman_in_steamy_room_tone5":"1f9d6-1f3ff-200d-2640-fe0f.svg","woman_in_tuxedo":"1f935-200d-2640-fe0f.svg","woman_in_tuxedo_tone1":"1f935-1f3fb-200d-2640-fe0f.svg","woman_in_tuxedo_tone2":"1f935-1f3fc-200d-2640-fe0f.svg","woman_in_tuxedo_tone3":"1f935-1f3fd-200d-2640-fe0f.svg","woman_in_tuxedo_tone4":"1f935-1f3fe-200d-2640-fe0f.svg","woman_in_tuxedo_tone5":"1f935-1f3ff-200d-2640-fe0f.svg","woman_judge":"1f469-200d-2696-fe0f.svg","woman_judge_tone1":"1f469-1f3fb-200d-2696-fe0f.svg","woman_judge_tone2":"1f469-1f3fc-200d-2696-fe0f.svg","woman_judge_tone3":"1f469-1f3fd-200d-2696-fe0f.svg","woman_judge_tone4":"1f469-1f3fe-200d-2696-fe0f.svg","woman_judge_tone5":"1f469-1f3ff-200d-2696-fe0f.svg","woman_juggling":"1f939-200d-2640-fe0f.svg","woman_juggling_tone1":"1f939-1f3fb-200d-2640-fe0f.svg","woman_juggling_tone2":"1f939-1f3fc-200d-2640-fe0f.svg","woman_juggling_tone3":"1f939-1f3fd-200d-2640-fe0f.svg","woman_juggling_tone4":"1f939-1f3fe-200d-2640-fe0f.svg","woman_juggling_tone5":"1f939-1f3ff-200d-2640-fe0f.svg","woman_kneeling":"1f9ce-200d-2640-fe0f.svg","woman_kneeling_tone1":"1f9ce-1f3fb-200d-2640-fe0f.svg","woman_kneeling_tone2":"1f9ce-1f3fc-200d-2640-fe0f.svg","woman_kneeling_tone3":"1f9ce-1f3fd-200d-2640-fe0f.svg","woman_kneeling_tone4":"1f9ce-1f3fe-200d-2640-fe0f.svg","woman_kneeling_tone5":"1f9ce-1f3ff-200d-2640-fe0f.svg","woman_leviate_tone2":"1f574-1f3fc-200d-2640-fe0f.svg","woman_leviate_tone3":"1f574-1f3fd-200d-2640-fe0f.svg","woman_leviate_tone4":"1f574-1f3fe-200d-2640-fe0f.svg","woman_leviate_tone5":"1f574-1f3ff-200d-2640-fe0f.svg","woman_levitate":"1f574-fe0f-200d-2640-fe0f.svg","woman_levitate_tone1":"1f574-1f3fb-200d-2640-fe0f.svg","woman_lifting_weights":"1f3cb-fe0f-200d-2640-fe0f.svg","woman_lifting_weights_tone1":"1f3cb-1f3fb-200d-2640-fe0f.svg","woman_lifting_weights_tone2":"1f3cb-1f3fc-200d-2640-fe0f.svg","woman_lifting_weights_tone3":"1f3cb-1f3fd-200d-2640-fe0f.svg","woman_lifting_weights_tone4":"1f3cb-1f3fe-200d-2640-fe0f.svg","woman_lifting_weights_tone5":"1f3cb-1f3ff-200d-2640-fe0f.svg","woman_mage":"1f9d9-200d-2640-fe0f.svg","woman_mage_tone1":"1f9d9-1f3fb-200d-2640-fe0f.svg","woman_mage_tone2":"1f9d9-1f3fc-200d-2640-fe0f.svg","woman_mage_tone3":"1f9d9-1f3fd-200d-2640-fe0f.svg","woman_mage_tone4":"1f9d9-1f3fe-200d-2640-fe0f.svg","woman_mage_tone5":"1f9d9-1f3ff-200d-2640-fe0f.svg","woman_mechanic":"1f469-200d-1f527.svg","woman_mechanic_tone1":"1f469-1f3fb-200d-1f527.svg","woman_mechanic_tone2":"1f469-1f3fc-200d-1f527.svg","woman_mechanic_tone3":"1f469-1f3fd-200d-1f527.svg","woman_mechanic_tone4":"1f469-1f3fe-200d-1f527.svg","woman_mechanic_tone5":"1f469-1f3ff-200d-1f527.svg","woman_mountain_biking":"1f6b5-200d-2640-fe0f.svg","woman_mountain_biking_tone1":"1f6b5-1f3fb-200d-2640-fe0f.svg","woman_mountain_biking_tone2":"1f6b5-1f3fc-200d-2640-fe0f.svg","woman_mountain_biking_tone3":"1f6b5-1f3fd-200d-2640-fe0f.svg","woman_mountain_biking_tone4":"1f6b5-1f3fe-200d-2640-fe0f.svg","woman_mountain_biking_tone5":"1f6b5-1f3ff-200d-2640-fe0f.svg","woman_office_worker":"1f469-200d-1f4bc.svg","woman_office_worker_tone1":"1f469-1f3fb-200d-1f4bc.svg","woman_office_worker_tone2":"1f469-1f3fc-200d-1f4bc.svg","woman_office_worker_tone3":"1f469-1f3fd-200d-1f4bc.svg","woman_office_worker_tone4":"1f469-1f3fe-200d-1f4bc.svg","woman_office_worker_tone5":"1f469-1f3ff-200d-1f4bc.svg","woman_pilot":"1f469-200d-2708-fe0f.svg","woman_pilot_tone1":"1f469-1f3fb-200d-2708-fe0f.svg","woman_pilot_tone2":"1f469-1f3fc-200d-2708-fe0f.svg","woman_pilot_tone3":"1f469-1f3fd-200d-2708-fe0f.svg","woman_pilot_tone4":"1f469-1f3fe-200d-2708-fe0f.svg","woman_pilot_tone5":"1f469-1f3ff-200d-2708-fe0f.svg","woman_playing_handball":"1f93e-200d-2640-fe0f.svg","woman_playing_handball_tone1":"1f93e-1f3fb-200d-2640-fe0f.svg","woman_playing_handball_tone2":"1f93e-1f3fc-200d-2640-fe0f.svg","woman_playing_handball_tone3":"1f93e-1f3fd-200d-2640-fe0f.svg","woman_playing_handball_tone4":"1f93e-1f3fe-200d-2640-fe0f.svg","woman_playing_handball_tone5":"1f93e-1f3ff-200d-2640-fe0f.svg","woman_playing_water_polo":"1f93d-200d-2640-fe0f.svg","woman_playing_water_polo_tone1":"1f93d-1f3fb-200d-2640-fe0f.svg","woman_playing_water_polo_tone2":"1f93d-1f3fc-200d-2640-fe0f.svg","woman_playing_water_polo_tone3":"1f93d-1f3fd-200d-2640-fe0f.svg","woman_playing_water_polo_tone4":"1f93d-1f3fe-200d-2640-fe0f.svg","woman_playing_water_polo_tone5":"1f93d-1f3ff-200d-2640-fe0f.svg","woman_police_officer":"1f46e-200d-2640-fe0f.svg","woman_police_officer_tone1":"1f46e-1f3fb-200d-2640-fe0f.svg","woman_police_officer_tone2":"1f46e-1f3fc-200d-2640-fe0f.svg","woman_police_officer_tone3":"1f46e-1f3fd-200d-2640-fe0f.svg","woman_police_officer_tone4":"1f46e-1f3fe-200d-2640-fe0f.svg","woman_police_officer_tone5":"1f46e-1f3ff-200d-2640-fe0f.svg","woman_pouting":"1f64e-200d-2640-fe0f.svg","woman_pouting_tone1":"1f64e-1f3fb-200d-2640-fe0f.svg","woman_pouting_tone2":"1f64e-1f3fc-200d-2640-fe0f.svg","woman_pouting_tone3":"1f64e-1f3fd-200d-2640-fe0f.svg","woman_pouting_tone4":"1f64e-1f3fe-200d-2640-fe0f.svg","woman_pouting_tone5":"1f64e-1f3ff-200d-2640-fe0f.svg","woman_raising_hand":"1f64b-200d-2640-fe0f.svg","woman_raising_hand_tone1":"1f64b-1f3fb-200d-2640-fe0f.svg","woman_raising_hand_tone2":"1f64b-1f3fc-200d-2640-fe0f.svg","woman_raising_hand_tone3":"1f64b-1f3fd-200d-2640-fe0f.svg","woman_raising_hand_tone4":"1f64b-1f3fe-200d-2640-fe0f.svg","woman_raising_hand_tone5":"1f64b-1f3ff-200d-2640-fe0f.svg","woman_red_haired":"1f469-200d-1f9b0.svg","woman_red_haired_tone1":"1f469-1f3fb-200d-1f9b0.svg","woman_red_haired_tone2":"1f469-1f3fc-200d-1f9b0.svg","woman_red_haired_tone3":"1f469-1f3fd-200d-1f9b0.svg","woman_red_haired_tone4":"1f469-1f3fe-200d-1f9b0.svg","woman_red_haired_tone5":"1f469-1f3ff-200d-1f9b0.svg","woman_rowing_boat":"1f6a3-200d-2640-fe0f.svg","woman_rowing_boat_tone1":"1f6a3-1f3fb-200d-2640-fe0f.svg","woman_rowing_boat_tone2":"1f6a3-1f3fc-200d-2640-fe0f.svg","woman_rowing_boat_tone3":"1f6a3-1f3fd-200d-2640-fe0f.svg","woman_rowing_boat_tone4":"1f6a3-1f3fe-200d-2640-fe0f.svg","woman_rowing_boat_tone5":"1f6a3-1f3ff-200d-2640-fe0f.svg","woman_running":"1f3c3-200d-2640-fe0f.svg","woman_running_tone1":"1f3c3-1f3fb-200d-2640-fe0f.svg","woman_running_tone2":"1f3c3-1f3fc-200d-2640-fe0f.svg","woman_running_tone3":"1f3c3-1f3fd-200d-2640-fe0f.svg","woman_running_tone4":"1f3c3-1f3fe-200d-2640-fe0f.svg","woman_running_tone5":"1f3c3-1f3ff-200d-2640-fe0f.svg","woman_scientist":"1f469-200d-1f52c.svg","woman_scientist_tone1":"1f469-1f3fb-200d-1f52c.svg","woman_scientist_tone2":"1f469-1f3fc-200d-1f52c.svg","woman_scientist_tone3":"1f469-1f3fd-200d-1f52c.svg","woman_scientist_tone4":"1f469-1f3fe-200d-1f52c.svg","woman_scientist_tone5":"1f469-1f3ff-200d-1f52c.svg","woman_shrugging":"1f937-200d-2640-fe0f.svg","woman_shrugging_tone1":"1f937-1f3fb-200d-2640-fe0f.svg","woman_shrugging_tone2":"1f937-1f3fc-200d-2640-fe0f.svg","woman_shrugging_tone3":"1f937-1f3fd-200d-2640-fe0f.svg","woman_shrugging_tone4":"1f937-1f3fe-200d-2640-fe0f.svg","woman_shrugging_tone5":"1f937-1f3ff-200d-2640-fe0f.svg","woman_singer":"1f469-200d-1f3a4.svg","woman_singer_tone1":"1f469-1f3fb-200d-1f3a4.svg","woman_singer_tone2":"1f469-1f3fc-200d-1f3a4.svg","woman_singer_tone3":"1f469-1f3fd-200d-1f3a4.svg","woman_singer_tone4":"1f469-1f3fe-200d-1f3a4.svg","woman_singer_tone5":"1f469-1f3ff-200d-1f3a4.svg","woman_standing":"1f9cd-200d-2640-fe0f.svg","woman_standing_tone1":"1f9cd-1f3fb-200d-2640-fe0f.svg","woman_standing_tone2":"1f9cd-1f3fc-200d-2640-fe0f.svg","woman_standing_tone3":"1f9cd-1f3fd-200d-2640-fe0f.svg","woman_standing_tone4":"1f9cd-1f3fe-200d-2640-fe0f.svg","woman_standing_tone5":"1f9cd-1f3ff-200d-2640-fe0f.svg","woman_student":"1f469-200d-1f393.svg","woman_student_tone1":"1f469-1f3fb-200d-1f393.svg","woman_student_tone2":"1f469-1f3fc-200d-1f393.svg","woman_student_tone3":"1f469-1f3fd-200d-1f393.svg","woman_student_tone4":"1f469-1f3fe-200d-1f393.svg","woman_student_tone5":"1f469-1f3ff-200d-1f393.svg","woman_superhero":"1f9b8-200d-2640-fe0f.svg","woman_superhero_tone1":"1f9b8-1f3fb-200d-2640-fe0f.svg","woman_superhero_tone2":"1f9b8-1f3fc-200d-2640-fe0f.svg","woman_superhero_tone3":"1f9b8-1f3fd-200d-2640-fe0f.svg","woman_superhero_tone4":"1f9b8-1f3fe-200d-2640-fe0f.svg","woman_superhero_tone5":"1f9b8-1f3ff-200d-2640-fe0f.svg","woman_supervillain":"1f9b9-200d-2640-fe0f.svg","woman_supervillain_tone1":"1f9b9-1f3fb-200d-2640-fe0f.svg","woman_supervillain_tone2":"1f9b9-1f3fc-200d-2640-fe0f.svg","woman_supervillain_tone3":"1f9b9-1f3fd-200d-2640-fe0f.svg","woman_supervillain_tone4":"1f9b9-1f3fe-200d-2640-fe0f.svg","woman_supervillain_tone5":"1f9b9-1f3ff-200d-2640-fe0f.svg","woman_surfing":"1f3c4-200d-2640-fe0f.svg","woman_surfing_tone1":"1f3c4-1f3fb-200d-2640-fe0f.svg","woman_surfing_tone2":"1f3c4-1f3fc-200d-2640-fe0f.svg","woman_surfing_tone3":"1f3c4-1f3fd-200d-2640-fe0f.svg","woman_surfing_tone4":"1f3c4-1f3fe-200d-2640-fe0f.svg","woman_surfing_tone5":"1f3c4-1f3ff-200d-2640-fe0f.svg","woman_swimming":"1f3ca-200d-2640-fe0f.svg","woman_swimming_tone1":"1f3ca-1f3fb-200d-2640-fe0f.svg","woman_swimming_tone2":"1f3ca-1f3fc-200d-2640-fe0f.svg","woman_swimming_tone3":"1f3ca-1f3fd-200d-2640-fe0f.svg","woman_swimming_tone4":"1f3ca-1f3fe-200d-2640-fe0f.svg","woman_swimming_tone5":"1f3ca-1f3ff-200d-2640-fe0f.svg","woman_teacher":"1f469-200d-1f3eb.svg","woman_teacher_tone1":"1f469-1f3fb-200d-1f3eb.svg","woman_teacher_tone2":"1f469-1f3fc-200d-1f3eb.svg","woman_teacher_tone3":"1f469-1f3fd-200d-1f3eb.svg","woman_teacher_tone4":"1f469-1f3fe-200d-1f3eb.svg","woman_teacher_tone5":"1f469-1f3ff-200d-1f3eb.svg","woman_technologist":"1f469-200d-1f4bb.svg","woman_technologist_tone1":"1f469-1f3fb-200d-1f4bb.svg","woman_technologist_tone2":"1f469-1f3fc-200d-1f4bb.svg","woman_technologist_tone3":"1f469-1f3fd-200d-1f4bb.svg","woman_technologist_tone4":"1f469-1f3fe-200d-1f4bb.svg","woman_technologist_tone5":"1f469-1f3ff-200d-1f4bb.svg","woman_tipping_hand":"1f481-200d-2640-fe0f.svg","woman_tipping_hand_tone1":"1f481-1f3fb-200d-2640-fe0f.svg","woman_tipping_hand_tone2":"1f481-1f3fc-200d-2640-fe0f.svg","woman_tipping_hand_tone3":"1f481-1f3fd-200d-2640-fe0f.svg","woman_tipping_hand_tone4":"1f481-1f3fe-200d-2640-fe0f.svg","woman_tipping_hand_tone5":"1f481-1f3ff-200d-2640-fe0f.svg","woman_tone1":"1f469-1f3fb.svg","woman_tone1_beard":"1f9d4-1f3fb-200d-2640-fe0f.svg","woman_tone2":"1f469-1f3fc.svg","woman_tone2_beard":"1f9d4-1f3fc-200d-2640-fe0f.svg","woman_tone3":"1f469-1f3fd.svg","woman_tone3_beard":"1f9d4-1f3fd-200d-2640-fe0f.svg","woman_tone4":"1f469-1f3fe.svg","woman_tone4_beard":"1f9d4-1f3fe-200d-2640-fe0f.svg","woman_tone5":"1f469-1f3ff.svg","woman_tone5_beard":"1f9d4-1f3ff-200d-2640-fe0f.svg","woman_vampire":"1f9db-200d-2640-fe0f.svg","woman_vampire_tone1":"1f9db-1f3fb-200d-2640-fe0f.svg","woman_vampire_tone2":"1f9db-1f3fc-200d-2640-fe0f.svg","woman_vampire_tone3":"1f9db-1f3fd-200d-2640-fe0f.svg","woman_vampire_tone4":"1f9db-1f3fe-200d-2640-fe0f.svg","woman_vampire_tone5":"1f9db-1f3ff-200d-2640-fe0f.svg","woman_walking":"1f6b6-200d-2640-fe0f.svg","woman_walking_tone1":"1f6b6-1f3fb-200d-2640-fe0f.svg","woman_walking_tone2":"1f6b6-1f3fc-200d-2640-fe0f.svg","woman_walking_tone3":"1f6b6-1f3fd-200d-2640-fe0f.svg","woman_walking_tone4":"1f6b6-1f3fe-200d-2640-fe0f.svg","woman_walking_tone5":"1f6b6-1f3ff-200d-2640-fe0f.svg","woman_wearing_turban":"1f473-200d-2640-fe0f.svg","woman_wearing_turban_tone1":"1f473-1f3fb-200d-2640-fe0f.svg","woman_wearing_turban_tone2":"1f473-1f3fc-200d-2640-fe0f.svg","woman_wearing_turban_tone3":"1f473-1f3fd-200d-2640-fe0f.svg","woman_wearing_turban_tone4":"1f473-1f3fe-200d-2640-fe0f.svg","woman_wearing_turban_tone5":"1f473-1f3ff-200d-2640-fe0f.svg","woman_white_haired":"1f469-200d-1f9b3.svg","woman_white_haired_tone1":"1f469-1f3fb-200d-1f9b3.svg","woman_white_haired_tone2":"1f469-1f3fc-200d-1f9b3.svg","woman_white_haired_tone3":"1f469-1f3fd-200d-1f9b3.svg","woman_white_haired_tone4":"1f469-1f3fe-200d-1f9b3.svg","woman_white_haired_tone5":"1f469-1f3ff-200d-1f9b3.svg","woman_with_headscarf":"1f9d5.svg","woman_with_headscarf_tone1":"1f9d5-1f3fb.svg","woman_with_headscarf_tone2":"1f9d5-1f3fc.svg","woman_with_headscarf_tone3":"1f9d5-1f3fd.svg","woman_with_headscarf_tone4":"1f9d5-1f3fe.svg","woman_with_headscarf_tone5":"1f9d5-1f3ff.svg","woman_with_probing_cane":"1f469-200d-1f9af.svg","woman_with_probing_cane_tone1":"1f469-1f3fb-200d-1f9af.svg","woman_with_probing_cane_tone2":"1f469-1f3fc-200d-1f9af.svg","woman_with_probing_cane_tone3":"1f469-1f3fd-200d-1f9af.svg","woman_with_probing_cane_tone4":"1f469-1f3fe-200d-1f9af.svg","woman_with_probing_cane_tone5":"1f469-1f3ff-200d-1f9af.svg","woman_with_veil":"1f470-200d-2640-fe0f.svg","woman_with_veil_tone1":"1f470-1f3fb-200d-2640-fe0f.svg","woman_with_veil_tone2":"1f470-1f3fc-200d-2640-fe0f.svg","woman_with_veil_tone3":"1f470-1f3fd-200d-2640-fe0f.svg","woman_with_veil_tone4":"1f470-1f3fe-200d-2640-fe0f.svg","woman_with_veil_tone5":"1f470-1f3ff-200d-2640-fe0f.svg","woman_zombie":"1f9df-200d-2640-fe0f.svg","womans_clothes":"1f45a.svg","womans_flat_shoe":"1f97f.svg","womans_hat":"1f452.svg","women_holding_hands_tone1":"1f46d-1f3fb.svg","women_holding_hands_tone1_tone2":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone1_tone3":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone1_tone4":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone1_tone5":"1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone2":"1f46d-1f3fc.svg","women_holding_hands_tone2_tone1":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone2_tone3":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone2_tone4":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone2_tone5":"1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone3":"1f46d-1f3fd.svg","women_holding_hands_tone3_tone1":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone3_tone2":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone3_tone4":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe.svg","women_holding_hands_tone3_tone5":"1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone4":"1f46d-1f3fe.svg","women_holding_hands_tone4_tone1":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone4_tone2":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone4_tone3":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone4_tone5":"1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff.svg","women_holding_hands_tone5":"1f46d-1f3ff.svg","women_holding_hands_tone5_tone1":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb.svg","women_holding_hands_tone5_tone2":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc.svg","women_holding_hands_tone5_tone3":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd.svg","women_holding_hands_tone5_tone4":"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe.svg","women_with_bunny_ears_partying":"1f46f-200d-2640-fe0f.svg","women_wrestling":"1f93c-200d-2640-fe0f.svg","womens":"1f6ba.svg","wood":"1fab5.svg","woozy_face":"1f974.svg","worm":"1fab1.svg","worried":"1f61f.svg","wrench":"1f527.svg","writing_hand":"270d.svg","writing_hand_tone1":"270d-1f3fb.svg","writing_hand_tone2":"270d-1f3fc.svg","writing_hand_tone3":"270d-1f3fd.svg","writing_hand_tone4":"270d-1f3fe.svg","writing_hand_tone5":"270d-1f3ff.svg","x":"274c.svg","yarn":"1f9f6.svg","yawning_face":"1f971.svg","yellow_circle":"1f7e1.svg","yellow_heart":"1f49b.svg","yellow_square":"1f7e8.svg","yen":"1f4b4.svg","yin_yang":"262f.svg","yo_yo":"1fa80.svg","yum":"1f60b.svg","zany_face":"1f92a.svg","zap":"26a1.svg","zebra":"1f993.svg","zero":"30-20e3.svg","zipper_mouth":"1f910.svg","zombie":"1f9df.svg","zzz":"1f4a4.svg"}}} \ No newline at end of file diff --git a/docs/zh/theme/overrides/assets/stylesheets/home.def3a648.min.css b/docs/zh/theme/overrides/assets/stylesheets/home.def3a648.min.css new file mode 100644 index 0000000..a047783 --- /dev/null +++ b/docs/zh/theme/overrides/assets/stylesheets/home.def3a648.min.css @@ -0,0 +1 @@ +.md-typeset{color:var(--md-typeset-color)}.md-typeset h2{font-weight:700;margin-top:.175em}.md-typeset h2+h3{font-size:1em;margin-top:-.8em}.md-typeset :target{--md-scroll-margin:5.2rem}.md-main__inner{margin:0}.md-main__inner>.md-content,.md-main__inner>.md-sidebar--secondary{display:none}.md-content__inner{margin-bottom:0;padding:5.2rem 0}.md-content__inner:before{display:none}.md-content header{display:block;transition:opacity .75s}.js .md-content header[hidden]{opacity:0}.md-typeset .md-button{background-color:#dd2e57;border-width:0;color:var(--md-primary-bg-color);margin-right:.5rem;margin-top:.5rem}.md-typeset .md-button--secondary{background-color:initial}.md-header:not(.md-header--shadow){background-color:initial;transition:background-color 125ms,transform 125ms cubic-bezier(.1,.7,.1,1),box-shadow 0ms}.md-header--shadow{transition:background-color .25s,transform .25s cubic-bezier(.1,.7,.1,1),box-shadow .25s}:root{--md-parallax-perspective:2.5rem}.mdx-parallax{height:100vh;margin-top:-2.4rem;overflow-x:hidden;overflow-y:auto;overscroll-behavior-y:none;perspective:var(--md-parallax-perspective);scroll-behavior:smooth;width:100vw}.mdx-parallax__group{background-color:var(--md-default-bg-color);color:var(--md-typeset-color);display:block;position:relative;transform-style:preserve-3d}.mdx-parallax__group:first-child{background-color:initial;contain:strict;height:140vh}.safari .mdx-parallax__group:first-child{contain:none}@media (min-width:125vh){.mdx-parallax__group:first-child{height:120vw}}@media (min-width:137.5vh){.mdx-parallax__group:first-child{height:125vw}}@media (min-width:150vh){.mdx-parallax__group:first-child{height:130vw}}@media (min-width:162.5vh){.mdx-parallax__group:first-child{height:135vw}}@media (min-width:175vh){.mdx-parallax__group:first-child{height:140vw}}@media (min-width:187.5vh){.mdx-parallax__group:first-child{height:145vw}}@media (min-width:200vh){.mdx-parallax__group:first-child{height:150vw}}.mdx-parallax__group:last-child{background-color:var(--md-default-bg-color)}.mdx-parallax__layer{height:max(120vh,100vw);pointer-events:none;position:absolute;top:0;transform:translateZ(calc(var(--md-parallax-perspective)*var(--md-parallax-depth)*-1)) scale(calc(var(--md-parallax-depth) + 1));transform-origin:50vw 50vh;width:100vw;z-index:calc(10 - var(--md-parallax-depth, 0))}.mdx-parallax__image{display:block;height:100%;object-fit:cover;object-position:var(--md-image-position,50%);position:absolute;width:100%;z-index:-1}.mdx-parallax__blend{background-image:linear-gradient(to bottom,transparent,var(--md-default-bg-color));bottom:0;height:min(100vh,100vw);top:auto}.mdx-content__column:last-child{margin-top:2.4rem}.mdx-content__column p:last-child{margin-bottom:0}@media screen and (min-width:60em){.mdx-content__inner{display:flex;flex-wrap:nowrap;gap:6.4rem}.mdx-content__column{margin-top:0}.mdx-content__column:first-child{flex:2 0}.mdx-content__column:last-child{flex:1 0;margin-top:0}}.mdx-connect{display:block;transition:transform .75s cubic-bezier(.075,.85,.175,1) 125ms,opacity .75s 125ms}.js .mdx-connect[hidden]{opacity:0;transform:translateY(1.6rem)}.mdx-connect .mdx-connect__link{color:var(--md-default-fg-color);display:block}.mdx-connect .mdx-connect__link span{margin-right:.2rem}.mdx-expect{margin:2.4rem 0}.mdx-expect__list{display:flex;flex-flow:row wrap;gap:1.6rem;padding:0}.mdx-expect__item{display:flex;flex:1 0 48%;gap:.6rem;margin:0;transition:transform .75s cubic-bezier(.075,.85,.175,1),opacity .75s}.mdx-expect__item:first-child{transition-delay:.2s}.mdx-expect__item:nth-child(2){transition-delay:275ms}.mdx-expect__item:nth-child(3){transition-delay:.35s}.mdx-expect__item:nth-child(4){transition-delay:425ms}.mdx-expect__item:nth-child(5){transition-delay:.5s}.mdx-expect__item:nth-child(6){transition-delay:575ms}.js .mdx-expect__item[hidden]{opacity:0;transform:translate(-.8rem,.4rem)}.js .mdx-expect__item[hidden]:nth-child(2n){transform:translate(.8rem,.4rem)}.mdx-expect__icon{fill:currentcolor;background-color:var(--md-default-fg-color--lightest);border-radius:100%;flex-shrink:0;height:2.2rem;padding:.4rem;width:2.2rem}.mdx-expect__description>:last-child{margin-bottom:0}@media screen and (max-width:76.1875em){.mdx-expect__description>:last-child{margin-left:-2.8rem}}.mdx-hero{display:block;height:inherit}.js .mdx-hero[hidden]>*{opacity:0;transform:translateY(16px);transition:transform 0ms .1s,opacity .1s}.mdx-hero__scrollwrap{height:100vh;margin-bottom:-100vh;position:-webkit-sticky;position:sticky;top:0;z-index:9}.mdx-hero__inner{bottom:3.2rem;display:block;position:absolute;transition:transform .4s cubic-bezier(.1,.7,.1,1),opacity .25s;width:100%}@media screen and (max-width:44.9375em){.mdx-hero__inner{bottom:6.4rem}}.mdx-hero__teaser{-webkit-backface-visibility:hidden;backface-visibility:hidden;color:var(--md-primary-bg-color);margin:0 .8rem;max-width:24rem}.mdx-hero__teaser h1{color:inherit;font-weight:700;margin-bottom:0}.mdx-hero__teaser :not(.md-button){text-shadow:0 0 .2rem rgba(33,29,45,.8)}.mdx-hero .mdx-hero__attribution{background-color:var(--md-default-bg-color--light);border-radius:.1rem;bottom:-2.4rem;color:var(--md-default-fg-color);font-size:.5rem;padding:.1rem .4rem;position:absolute;right:.8rem;transition:color 125ms,background-color 125ms}.mdx-hero .mdx-hero__attribution:focus,.mdx-hero .mdx-hero__attribution:hover{background-color:var(--md-accent-fg-color);color:var(--md-accent-bg-color)}.mdx-hero__more{bottom:-2.4rem;display:block;left:50%;margin-left:-.6rem;pointer-events:none;position:absolute;text-align:center}.mdx-hero__more svg{fill:#fff;height:1.2rem;width:1.2rem}.mdx-spotlight{margin:2em 0}.mdx-spotlight__feature{display:flex;flex:1 0 48%;flex-flow:row nowrap;gap:3.2rem;margin:0 0 3.2rem}@media screen and (max-width:59.9375em){.mdx-spotlight__feature{flex-direction:column;gap:0}}@media screen and (min-width:60em){.mdx-spotlight__feature:nth-child(odd){flex-direction:row-reverse}}.mdx-spotlight__feature:last-child{margin-bottom:1em}.mdx-spotlight__feature>a{display:block;flex-shrink:0;transition:transform .5s cubic-bezier(.075,.85,.175,1)}@media screen and (max-width:59.9375em){.mdx-spotlight__feature>a{margin-left:auto;margin-right:auto}}.mdx-spotlight__feature>a:hover{transform:scale(1.025)}.mdx-spotlight__feature a>img{border-radius:.2rem;box-shadow:var(--md-shadow-z2);display:block;height:auto;max-width:100%;width:25rem}.mdx-spotlight__feature a>img,.mdx-spotlight__feature figcaption{transition:transform .75s cubic-bezier(.075,.85,.175,1) 125ms,opacity .75s 125ms}.mdx-spotlight__feature figcaption{margin-top:.8rem}.js .mdx-spotlight__feature[hidden]>a>img{opacity:0;transform:translateY(1.6rem)}.js .mdx-spotlight__feature[hidden]>figcaption{opacity:0;transform:translateX(1.6rem)}.js .mdx-spotlight__feature[hidden]:nth-child(2n)>figcaption{transform:translateX(-1.6rem)}.mdx-trust{display:block;max-width:40rem;transition:transform .75s cubic-bezier(.075,.85,.175,1) 125ms,opacity .75s 125ms}.js .mdx-trust[hidden]{opacity:0;transform:translateY(1.6rem)}.mdx-users{display:flex;gap:3.2rem;margin:2.4rem 0}@media screen and (max-width:59.9375em){.mdx-users{flex-direction:column}}.mdx-users__testimonial{display:flex;flex:1;flex-direction:column;gap:1.2rem;margin:0;text-align:center}.mdx-users__testimonial:first-child{transition-delay:.2s}.mdx-users__testimonial:nth-child(2){transition-delay:275ms}.mdx-users__testimonial:nth-child(3){transition-delay:.35s}.mdx-users__testimonial img{border-radius:5rem;height:auto;margin-left:auto;margin-right:auto;width:10rem}.mdx-users__testimonial figcaption,.mdx-users__testimonial img{transition:transform .75s cubic-bezier(.075,.85,.175,1),opacity .75s;transition-delay:inherit}.mdx-users__testimonial figcaption{display:block}.mdx-users__testimonial hr{margin-left:auto;margin-right:auto;width:5rem}.mdx-users__testimonial cite{display:block;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;text-align:justify}.js .mdx-users__testimonial[hidden] img{opacity:0;transform:scale(.75)}.js .mdx-users__testimonial[hidden] figcaption{opacity:0;transform:translateY(1.6rem)}@media screen and (min-width:60em){.md-sidebar--secondary{display:none}}@media screen and (min-width:76.25em){.md-sidebar--primary{display:none}}.md-tabs{background-color:initial;position:absolute;top:2.4rem} \ No newline at end of file diff --git a/docs/zh/theme/overrides/assets/stylesheets/main.e13ced4c.min.css b/docs/zh/theme/overrides/assets/stylesheets/main.e13ced4c.min.css new file mode 100644 index 0000000..671294a --- /dev/null +++ b/docs/zh/theme/overrides/assets/stylesheets/main.e13ced4c.min.css @@ -0,0 +1 @@ +@-webkit-keyframes heart{0%,40%,80%,to{transform:scale(1)}20%,60%{transform:scale(1.15)}}@keyframes heart{0%,40%,80%,to{transform:scale(1)}20%,60%{transform:scale(1.15)}}@-webkit-keyframes new{0%,to{transform:scale(1) rotate(0deg)}50%{transform:scale(1.15) rotate(10deg)}}@keyframes new{0%,to{transform:scale(1) rotate(0deg)}50%{transform:scale(1.15) rotate(10deg)}}.md-typeset .twitter{color:#00acee}.md-typeset .mdx-video{width:auto}.md-typeset .mdx-video__inner{height:0;padding-bottom:56.138%;position:relative;width:100%}.md-typeset .mdx-video iframe{border:none;height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}.md-typeset .mdx-heart{-webkit-animation:heart 1s infinite;animation:heart 1s infinite}.md-typeset .mdx-pulse{-webkit-animation:new 2s infinite;animation:new 2s infinite}.md-typeset .mdx-pulse svg{fill:var(--md-accent-fg-color)}.md-typeset .mdx-insiders{color:#e91e63}.md-typeset .mdx-switch button{cursor:pointer;transition:opacity .25s}.md-typeset .mdx-switch button:focus,.md-typeset .mdx-switch button:hover{opacity:.75}.md-typeset .mdx-switch button>code{background-color:var(--md-primary-fg-color);color:var(--md-primary-bg-color);display:block}.md-typeset .mdx-deprecated{opacity:.5;transition:opacity .25s}.md-typeset .mdx-deprecated:focus-within,.md-typeset .mdx-deprecated:hover{opacity:1}.md-typeset .mdx-columns ol,.md-typeset .mdx-columns ul{column-count:2}@media screen and (max-width:29.9375em){.md-typeset .mdx-columns ol,.md-typeset .mdx-columns ul{columns:initial}}.md-typeset .mdx-columns li{break-inside:avoid}.md-typeset .mdx-author{display:flex;font-size:.68rem}.md-typeset .mdx-author img{border-radius:100%;height:2rem}.md-typeset .mdx-author p:first-child{flex-shrink:0;margin-right:.8rem}.md-typeset .mdx-author p>span{display:block}.md-banner a,.md-banner a:focus,.md-banner a:hover{color:currentcolor}.md-banner strong{white-space:nowrap}[dir=ltr] .md-banner .twitter{margin-left:.2em}[dir=rtl] .md-banner .twitter{margin-right:.2em}.md-typeset .mdx-iconsearch{background-color:var(--md-default-bg-color);border-radius:.1rem;box-shadow:var(--md-shadow-z1);position:relative;transition:box-shadow 125ms}.md-typeset .mdx-iconsearch:focus-within,.md-typeset .mdx-iconsearch:hover{box-shadow:var(--md-shadow-z2)}.md-typeset .mdx-iconsearch .md-input{background:var(--md-default-bg-color);box-shadow:none}[data-md-color-scheme=slate] .md-typeset .mdx-iconsearch .md-input{background:var(--md-code-bg-color)}.md-typeset .mdx-iconsearch-result{-webkit-backface-visibility:hidden;backface-visibility:hidden;max-height:50vh;overflow-y:auto;scrollbar-color:var(--md-default-fg-color--lighter) transparent;scrollbar-width:thin;touch-action:pan-y}.md-tooltip .md-typeset .mdx-iconsearch-result{max-height:10.25rem}.md-typeset .mdx-iconsearch-result::-webkit-scrollbar{height:.2rem;width:.2rem}.md-typeset .mdx-iconsearch-result::-webkit-scrollbar-thumb{background-color:var(--md-default-fg-color--lighter)}.md-typeset .mdx-iconsearch-result::-webkit-scrollbar-thumb:hover{background-color:var(--md-accent-fg-color)}.md-typeset .mdx-iconsearch-result__meta{color:var(--md-default-fg-color--lighter);font-size:.64rem;position:absolute;right:.6rem;top:.4rem}[dir=ltr] .md-typeset .mdx-iconsearch-result__list{margin-left:0}[dir=rtl] .md-typeset .mdx-iconsearch-result__list{margin-right:0}.md-typeset .mdx-iconsearch-result__list{list-style:none;margin:0;padding:0}[dir=ltr] .md-typeset .mdx-iconsearch-result__item{margin-left:0}[dir=rtl] .md-typeset .mdx-iconsearch-result__item{margin-right:0}.md-typeset .mdx-iconsearch-result__item{border-bottom:.05rem solid var(--md-default-fg-color--lightest);margin:0;padding:.2rem .6rem}.md-typeset .mdx-iconsearch-result__item:last-child{border-bottom:none}.md-typeset .mdx-iconsearch-result__item>*{margin-right:.6rem}.md-typeset .mdx-iconsearch-result__item img{height:.9rem;width:.9rem}[data-md-color-scheme=slate] .md-typeset .mdx-iconsearch-result__item img[src*=squidfunk]{filter:invert(1)}.md-typeset .mdx-premium p{margin:2em 0;text-align:center}.md-typeset .mdx-premium img{height:3.25rem}.md-typeset .mdx-premium p:last-child{display:flex;flex-wrap:wrap;justify-content:center}.md-typeset .mdx-premium p:last-child>a{display:block;flex-shrink:0}.md-typeset .mdx-sponsorship__list{margin:2em 0}.md-typeset .mdx-sponsorship__list:after{clear:both;content:"";display:block}.md-typeset .mdx-sponsorship__item{border-radius:100%;display:block;float:left;height:1.6rem;margin:.2rem;overflow:hidden;transform:scale(1);transition:color 125ms,transform 125ms;width:1.6rem}.md-typeset .mdx-sponsorship__item:focus,.md-typeset .mdx-sponsorship__item:hover{transform:scale(1.1)}.md-typeset .mdx-sponsorship__item:focus img,.md-typeset .mdx-sponsorship__item:hover img{filter:grayscale(0)}.md-typeset .mdx-sponsorship__item--private{background:var(--md-default-fg-color--lightest);color:var(--md-default-fg-color--lighter);font-size:.6rem;font-weight:700;line-height:1.6rem;text-align:center}.md-typeset .mdx-sponsorship__item img{display:block;filter:grayscale(100%) opacity(75%);height:auto;transition:filter 125ms;width:100%}.md-typeset .mdx-sponsorship-button{font-weight:400}.md-typeset .mdx-sponsorship-count,.md-typeset .mdx-sponsorship-total{font-weight:700} \ No newline at end of file diff --git a/docs/zh/theme/overrides/home.html b/docs/zh/theme/overrides/home.html new file mode 100644 index 0000000..0645d63 --- /dev/null +++ b/docs/zh/theme/overrides/home.html @@ -0,0 +1,26 @@ +{#- + This file was automatically generated - do not edit +-#} +{% extends "overrides/main.html" %} + +{% block htmltitle %} + {{ config.site_name }} +{% endblock %} +{% block styles %} + {{ super() }} + + +{% endblock %} +{% block announce %}{% endblock %} +{% block hero %} + {% include "overrides/partials/parallax.html" %} +{% endblock %} + +{% block tabs %}{% endblock %} + +{#- +{% block content %}{% endblock %} + +{% block footer %}{% endblock %} + +-#} diff --git a/docs/zh/theme/overrides/main.html b/docs/zh/theme/overrides/main.html new file mode 100644 index 0000000..4fd82ac --- /dev/null +++ b/docs/zh/theme/overrides/main.html @@ -0,0 +1,22 @@ +{#- + This file was automatically generated - do not edit +-#} +{% extends "base.html" %} +{% block styles %} + {{ super() }} + +{% endblock %} +{% block announce %} + + 算丰二号全新上线咯!点击链接,免费体验! + + +{% endblock %} +{% block content %} + {% include "overrides/partials/content.html" %} +{% endblock %} + +{% block scripts %} + {{ super() }} + +{% endblock %} \ No newline at end of file diff --git a/docs/zh/theme/overrides/partials/comments.html b/docs/zh/theme/overrides/partials/comments.html new file mode 100644 index 0000000..94efcd8 --- /dev/null +++ b/docs/zh/theme/overrides/partials/comments.html @@ -0,0 +1,49 @@ + +

{{ lang.t("meta.comments") }}

+ + + + + diff --git a/docs/zh/theme/overrides/partials/content.html b/docs/zh/theme/overrides/partials/content.html new file mode 100644 index 0000000..a2be7bd --- /dev/null +++ b/docs/zh/theme/overrides/partials/content.html @@ -0,0 +1,28 @@ +{#- + This file was automatically generated - do not edit +-#} +{% if page.edit_url %} + {% set hisrtory = "https://github.com/DaoCloud/DaoCloud-docs/commits/" %} + {% set edit = "https://github.com/DaoCloud/DaoCloud-docs/edit/" %} + {% set view = "https://raw.githubusercontent.com/DaoCloud/DaoCloud-docs/" %} + + {% include ".icons/material/history.svg" %} + + + {% include ".icons/material/file-edit-outline.svg" %} + + + {% include ".icons/material/file-eye-outline.svg" %} + +{% endif %} +{% if "tags" in config.plugins %} + {% include "partials/tags.html" %} +{% endif %} +{% if not "\x3ch1" in page.content %} +

{{ page.title | d(config.site_name, true)}}

+{% endif %} +{{ page.content }} + +{% block comments %} + {% include "overrides/partials/comments.html" %} +{% endblock %} \ No newline at end of file diff --git a/docs/zh/theme/overrides/partials/parallax.html b/docs/zh/theme/overrides/partials/parallax.html new file mode 100644 index 0000000..4e160f8 --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax.html @@ -0,0 +1,15 @@ +{#- + This file was automatically generated - do not edit +-#} +
+ {% include "overrides/partials/parallax/hero.html" %} + {% include "overrides/partials/parallax/expect.html" %} + {% include "overrides/partials/parallax/spotlight.html" %} + {% include "overrides/partials/parallax/trust.html" %} + {% include "overrides/partials/parallax/users.html" %} + {% include "overrides/partials/parallax/connect.html" %} +
+ {% include "partials/footer.html" %} +
+
+ diff --git a/docs/zh/theme/overrides/partials/parallax/connect.html b/docs/zh/theme/overrides/partials/parallax/connect.html new file mode 100644 index 0000000..f26582d --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax/connect.html @@ -0,0 +1,83 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+
+ + +
+ +
+
diff --git a/docs/zh/theme/overrides/partials/parallax/expect.html b/docs/zh/theme/overrides/partials/parallax/expect.html new file mode 100644 index 0000000..72331c5 --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax/expect.html @@ -0,0 +1,87 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+ +
+
    + + + + + + +
+
+
+
+
diff --git a/docs/zh/theme/overrides/partials/parallax/hero.html b/docs/zh/theme/overrides/partials/parallax/hero.html new file mode 100644 index 0000000..fdf21de --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax/hero.html @@ -0,0 +1,49 @@ +{#- + This file was automatically generated - do not edit +-#} +
+ {% for layer in [ + { "depth": 8, "position": "70%", "image": "1-landscape" }, + { "depth": 5, "position": "25%", "image": "2-plateau" }, + { "depth": 4, "position": "20%", "image": "3-astronaut-1" }, + { "depth": 3, "position": "30%", "image": "4-astronaut-2" }, + { "depth": 2, "position": "40%", "image": "5-plants-1" }, + { "depth": 1, "position": "50%", "image": "6-plants-2" }, + ] %} + {% set image = "overrides/assets/images/layers/" ~ layer["image"] %} + {% set style = "style=\"" ~ [ + "--md-parallax-depth: " ~ layer["depth"], + "--md-image-position: " ~ layer["position"] + ] | join(";") ~ "\"" %} + + {% for type in ["avif", "webp"] %} + + {% endfor %} + + + {% endfor %} +
+
+
+ {% include "partials/tabs.html" %} +
+
+

驾驭数字方程式

+

{{ config.site_description }}

+ + 快速入门 + + + 了解更多 + + + © DaoCloud + +
+
+ {% include ".icons/material/arrow-down.svg" %} +
+
+
+
+
diff --git a/docs/zh/theme/overrides/partials/parallax/spotlight.html b/docs/zh/theme/overrides/partials/parallax/spotlight.html new file mode 100644 index 0000000..ca0d27a --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax/spotlight.html @@ -0,0 +1,106 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+ +
+ + + + +
+
+
+
diff --git a/docs/zh/theme/overrides/partials/parallax/trust.html b/docs/zh/theme/overrides/partials/parallax/trust.html new file mode 100644 index 0000000..7aec8a7 --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax/trust.html @@ -0,0 +1,28 @@ +{#- + This file was automatically generated - do not edit +-#} +
+ Trusted in the industry +
+
+ + +
+
+
diff --git a/docs/zh/theme/overrides/partials/parallax/users.html b/docs/zh/theme/overrides/partials/parallax/users.html new file mode 100644 index 0000000..bb62fd2 --- /dev/null +++ b/docs/zh/theme/overrides/partials/parallax/users.html @@ -0,0 +1,61 @@ +{#- + This file was automatically generated - do not edit +-#} +
+
+
+ +
+ + + +
+
+
+
diff --git a/makefile b/makefile new file mode 100644 index 0000000..3a5a02e --- /dev/null +++ b/makefile @@ -0,0 +1,34 @@ +# support mkdocs-material-insider +IMAGE_HUB ?= release.daocloud.io/ +BASE_IMAGE ?= ${IMAGE_HUB}daocloud/ndx-mkdocs-material +BASE_IMAGE_VERSION ?= v1.2.3 + +INS_IMAGE_HUB ?= release-ci.daocloud.io/ +INS_IMAGE ?= ${INS_IMAGE_HUB}product/ndx-mkdocs-material-insider +INS_IMAGE_VERSION ?= v1.1.1 + +help: + @echo + @echo "使用:" + @echo ' make [指令]' + @echo + @echo "指令:" + @echo ' serve 使用 docker 启动服务,默认端口8000' + @echo ' in-serve 内部使用,使用 docker 启动服务,默认端口8000' + @echo ' clean 清理静态文件' + @echo ' help 显示帮助信息' + @echo + @echo "版本: DaoCloud-docs 1.0.0 20220921" + @echo + +serve: + docker run --rm -it -e ENABLED_GIT_REVISION_DATE="false" -p 8000:8000 -v ${PWD}/docs/zh:/docs ${BASE_IMAGE}:${BASE_IMAGE_VERSION} + +in-serve: + docker run --rm -it -e ENABLED_GIT_REVISION_DATE="false" -p 8000:8000 -v ${PWD}:/docs ${INS_IMAGE}:${INS_IMAGE_VERSION} + +clean: + rm -rf public site + + +.PHONY: clean serve in-serve help diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..70e2de4 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,2678 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "anybadge" +version = "1.14.0" +description = "Simple, flexible badge generator for project badges." +optional = false +python-versions = ">=3.7" +files = [ + {file = "anybadge-1.14.0-py3-none-any.whl", hash = "sha256:8711a7f7f45317c62a460f14084f005ba665cbebdf2a94e7df53bc3ab35df4c9"}, + {file = "anybadge-1.14.0.tar.gz", hash = "sha256:47f06e0a6320d3e5eac55c712dc0bab71b9ed85353c591d448653c5a0740783f"}, +] + +[package.dependencies] +packaging = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "asyncio" +version = "3.4.3" +description = "reference implementation of PEP 3156" +optional = false +python-versions = "*" +files = [ + {file = "asyncio-3.4.3-cp33-none-win32.whl", hash = "sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de"}, + {file = "asyncio-3.4.3-cp33-none-win_amd64.whl", hash = "sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c"}, + {file = "asyncio-3.4.3-py3-none-any.whl", hash = "sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d"}, + {file = "asyncio-3.4.3.tar.gz", hash = "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "babel" +version = "2.12.1" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, + {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "beautifulsoup4" +version = "4.11.2" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, + {file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "bracex" +version = "2.3.post1" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.7" +files = [ + {file = "bracex-2.3.post1-py3-none-any.whl", hash = "sha256:351b7f20d56fb9ea91f9b9e9e7664db466eb234188c175fd943f8f755c807e73"}, + {file = "bracex-2.3.post1.tar.gz", hash = "sha256:e7b23fc8b2cd06d3dec0692baabecb249dda94e06a617901ff03a6c56fd71693"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "brotli" +version = "1.0.9" +description = "Python bindings for the Brotli compression library" +optional = false +python-versions = "*" +files = [ + {file = "Brotli-1.0.9-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:268fe94547ba25b58ebc724680609c8ee3e5a843202e9a381f6f9c5e8bdb5c70"}, + {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b"}, + {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5913a1177fc36e30fcf6dc868ce23b0453952c78c04c266d3149b3d39e1410d6"}, + {file = "Brotli-1.0.9-cp27-cp27m-win32.whl", hash = "sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa"}, + {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452"}, + {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7"}, + {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9744a863b489c79a73aba014df554b0e7a0fc44ef3f8a0ef2a52919c7d155031"}, + {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43"}, + {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c"}, + {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c"}, + {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0"}, + {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91"}, + {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa"}, + {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb"}, + {file = "Brotli-1.0.9-cp310-cp310-win32.whl", hash = "sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181"}, + {file = "Brotli-1.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:622a231b08899c864eb87e85f81c75e7b9ce05b001e59bbfbf43d4a71f5f32b2"}, + {file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cc0283a406774f465fb45ec7efb66857c09ffefbe49ec20b7882eff6d3c86d3a"}, + {file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:11d3283d89af7033236fa4e73ec2cbe743d4f6a81d41bd234f24bf63dde979df"}, + {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c1306004d49b84bd0c4f90457c6f57ad109f5cc6067a9664e12b7b79a9948ad"}, + {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1375b5d17d6145c798661b67e4ae9d5496920d9265e2f00f1c2c0b5ae91fbde"}, + {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cab1b5964b39607a66adbba01f1c12df2e55ac36c81ec6ed44f2fca44178bf1a"}, + {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ed6a5b3d23ecc00ea02e1ed8e0ff9a08f4fc87a1f58a2530e71c0f48adf882f"}, + {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cb02ed34557afde2d2da68194d12f5719ee96cfb2eacc886352cb73e3808fc5d"}, + {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b3523f51818e8f16599613edddb1ff924eeb4b53ab7e7197f85cbc321cdca32f"}, + {file = "Brotli-1.0.9-cp311-cp311-win32.whl", hash = "sha256:ba72d37e2a924717990f4d7482e8ac88e2ef43fb95491eb6e0d124d77d2a150d"}, + {file = "Brotli-1.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:3ffaadcaeafe9d30a7e4e1e97ad727e4f5610b9fa2f7551998471e3736738679"}, + {file = "Brotli-1.0.9-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4"}, + {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296"}, + {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430"}, + {file = "Brotli-1.0.9-cp35-cp35m-win32.whl", hash = "sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1"}, + {file = "Brotli-1.0.9-cp35-cp35m-win_amd64.whl", hash = "sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea"}, + {file = "Brotli-1.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f"}, + {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4"}, + {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:93130612b837103e15ac3f9cbacb4613f9e348b58b3aad53721d92e57f96d46a"}, + {file = "Brotli-1.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b"}, + {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f"}, + {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6"}, + {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b"}, + {file = "Brotli-1.0.9-cp36-cp36m-win32.whl", hash = "sha256:61a7ee1f13ab913897dac7da44a73c6d44d48a4adff42a5701e3239791c96e14"}, + {file = "Brotli-1.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:1c48472a6ba3b113452355b9af0a60da5c2ae60477f8feda8346f8fd48e3e87c"}, + {file = "Brotli-1.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126"}, + {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d"}, + {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12"}, + {file = "Brotli-1.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130"}, + {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a"}, + {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3"}, + {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d"}, + {file = "Brotli-1.0.9-cp37-cp37m-win32.whl", hash = "sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"}, + {file = "Brotli-1.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5"}, + {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb"}, + {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8"}, + {file = "Brotli-1.0.9-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb"}, + {file = "Brotli-1.0.9-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b6ef7d9f9c38292df3690fe3e302b5b530999fa90014853dcd0d6902fb59f26"}, + {file = "Brotli-1.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c"}, + {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b"}, + {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17"}, + {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649"}, + {file = "Brotli-1.0.9-cp38-cp38-win32.whl", hash = "sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429"}, + {file = "Brotli-1.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:269a5743a393c65db46a7bb982644c67ecba4b8d91b392403ad8a861ba6f495f"}, + {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19"}, + {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5cb1e18167792d7d21e21365d7650b72d5081ed476123ff7b8cac7f45189c0c7"}, + {file = "Brotli-1.0.9-cp39-cp39-manylinux1_i686.whl", hash = "sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b"}, + {file = "Brotli-1.0.9-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389"}, + {file = "Brotli-1.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7"}, + {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806"}, + {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1"}, + {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c"}, + {file = "Brotli-1.0.9-cp39-cp39-win32.whl", hash = "sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3"}, + {file = "Brotli-1.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9749a124280a0ada4187a6cfd1ffd35c350fb3af79c706589d98e088c5044267"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:73fd30d4ce0ea48010564ccee1a26bfe39323fde05cb34b5863455629db61dc7"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02177603aaca36e1fd21b091cb742bb3b305a569e2402f1ca38af471777fb019"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b43775532a5904bc938f9c15b77c613cb6ad6fb30990f3b0afaea82797a402d8"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5bf37a08493232fbb0f8229f1824b366c2fc1d02d64e7e918af40acd15f3e337"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:330e3f10cd01da535c70d09c4283ba2df5fb78e915bea0a28becad6e2ac010be"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e1abbeef02962596548382e393f56e4c94acd286bd0c5afba756cffc33670e8a"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3148362937217b7072cf80a2dcc007f09bb5ecb96dae4617316638194113d5be"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336b40348269f9b91268378de5ff44dc6fbaa2268194f85177b53463d313842a"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b09a16a1950b9ef495a0f8b9d0a87599a9d1f179e2d4ac014b2ec831f87e7"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c8e521a0ce7cf690ca84b8cc2272ddaf9d8a50294fd086da67e517439614c755"}, + {file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "brotlicffi" +version = "1.0.9.2" +description = "Python CFFI bindings to the Brotli library" +optional = false +python-versions = "*" +files = [ + {file = "brotlicffi-1.0.9.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:408ec4359f9763280d5c4e0ad29c51d1240b25fdd18719067e972163b4125b98"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2e4629f7690ded66c8818715c6d4dd6a7ff6a4f10fad6186fe99850f781ce210"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:137c4635edcdf593de5ce9d0daa596bf499591b16b8fca5fd72a490deb54b2ee"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:af8a1b7bcfccf9c41a3c8654994d6a81821fdfe4caddcfe5045bfda936546ca3"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9078432af4785f35ab3840587eed7fb131e3fc77eb2a739282b649b343c584dd"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7bb913d5bf3b4ce2ec59872711dc9faaff5f320c3c3827cada2d8a7b793a7753"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:16a0c9392a1059e2e62839fbd037d2e7e03c8ae5da65e9746f582464f7fab1bb"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:94d2810efc5723f1447b332223b197466190518a3eeca93b9f357efb5b22c6dc"}, + {file = "brotlicffi-1.0.9.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:9e70f3e20f317d70912b10dbec48b29114d3dbd0e9d88475cb328e6c086f0546"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:586f0ea3c2eed455d5f2330b9ab4a591514c8de0ee53d445645efcfbf053c69f"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-manylinux1_i686.whl", hash = "sha256:4454c3baedc277fd6e65f983e3eb8e77f4bc15060f69370a0201746e2edeca81"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:52c1c12dad6eb1d44213a0a76acf5f18f64653bd801300bef5e2f983405bdde5"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:21cd400d24b344c218d8e32b394849e31b7c15784667575dbda9f65c46a64b0a"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:71061f8bc86335b652e442260c4367b782a92c6e295cf5a10eff84c7d19d8cf5"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:15e0db52c56056be6310fc116b3d7c6f34185594e261f23790b2fb6489998363"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-win32.whl", hash = "sha256:551305703d12a2dd1ae43d3dde35dee20b1cb49b5796279d4d34e2c6aec6be4d"}, + {file = "brotlicffi-1.0.9.2-cp35-abi3-win_amd64.whl", hash = "sha256:2be4fb8a7cb482f226af686cd06d2a2cab164ccdf99e460f8e3a5ec9a5337da2"}, + {file = "brotlicffi-1.0.9.2-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:8e7221d8a084d32d15c7b58e0ce0573972375c5038423dbe83f217cfe512e680"}, + {file = "brotlicffi-1.0.9.2-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:75a46bc5ed2753e1648cc211dcb2c1ac66116038766822dc104023f67ff4dfd8"}, + {file = "brotlicffi-1.0.9.2-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:1e27c43ef72a278f9739b12b2df80ee72048cd4cbe498f8bbe08aaaa67a5d5c8"}, + {file = "brotlicffi-1.0.9.2-pp27-pypy_73-win32.whl", hash = "sha256:feb942814285bdc5e97efc77a04e48283c17dfab9ea082d79c0a7b9e53ef1eab"}, + {file = "brotlicffi-1.0.9.2-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a6208d82c3172eeeb3be83ed4efd5831552c7cd47576468e50fcf0fb23fcf97f"}, + {file = "brotlicffi-1.0.9.2-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:408c810c599786fb806556ff17e844a903884e6370ca400bcec7fa286149f39c"}, + {file = "brotlicffi-1.0.9.2-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:a73099858ee343e8801710a08be8d194f47715ff21e98d92a19ac461058f52d1"}, + {file = "brotlicffi-1.0.9.2-pp36-pypy36_pp73-win32.whl", hash = "sha256:916b790f967a18a595e61f218c252f83718ac91f24157d622cf0fa710cd26ab7"}, + {file = "brotlicffi-1.0.9.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ba4a00263af40e875ec3d6c7f623cbf8c795b55705da18c64ec36b6bf0848bc5"}, + {file = "brotlicffi-1.0.9.2-pp37-pypy37_pp73-manylinux1_x86_64.whl", hash = "sha256:df78aa47741122b0d5463f1208b7bb18bc9706dee5152d9f56e0ead4865015cd"}, + {file = "brotlicffi-1.0.9.2-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:9030cd5099252d16bfa4e22659c84a89c102e94f8e81d30764788b72e2d7cfb7"}, + {file = "brotlicffi-1.0.9.2-pp37-pypy37_pp73-win32.whl", hash = "sha256:7e72978f4090a161885b114f87b784f538dcb77dafc6602592c1cf39ae8d243d"}, + {file = "brotlicffi-1.0.9.2.tar.gz", hash = "sha256:0c248a68129d8fc6a217767406c731e498c3e19a7be05ea0a90c3c86637b7d96"}, +] + +[package.dependencies] +cffi = ">=1.0.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "certifi" +version = "2024.7.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "chardet" +version = "3.0.4" +description = "Universal encoding detector for Python 2 and 3" +optional = false +python-versions = "*" +files = [ + {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, + {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "charset-normalizer" +version = "3.1.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "csscompressor" +version = "0.9.5" +description = "A python port of YUI CSS Compressor" +optional = false +python-versions = "*" +files = [ + {file = "csscompressor-0.9.5.tar.gz", hash = "sha256:afa22badbcf3120a4f392e4d22f9fff485c044a1feda4a950ecc5eba9dd31a05"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "cssselect2" +version = "0.7.0" +description = "CSS selectors for Python ElementTree" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cssselect2-0.7.0-py3-none-any.whl", hash = "sha256:fd23a65bfd444595913f02fc71f6b286c29261e354c41d722ca7a261a49b5969"}, + {file = "cssselect2-0.7.0.tar.gz", hash = "sha256:1ccd984dab89fc68955043aca4e1b03e0cf29cad9880f6e28e3ba7a74b14aa5a"}, +] + +[package.dependencies] +tinycss2 = "*" +webencodings = "*" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "docxcompose" +version = "1.4.0" +description = "Compose .docx documents" +optional = false +python-versions = "*" +files = [ + {file = "docxcompose-1.4.0.tar.gz", hash = "sha256:bcf2799a0b63c29eb77a3d799a2f28443ae0f69f8691ff3d753f706be515c3e9"}, +] + +[package.dependencies] +babel = "*" +lxml = "*" +python-docx = ">=0.8.8" +setuptools = "*" +six = "*" + +[package.extras] +test = ["pytest"] +tests = ["pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "editorconfig" +version = "0.12.3" +description = "EditorConfig File Locator and Interpreter for Python" +optional = false +python-versions = "*" +files = [ + {file = "EditorConfig-0.12.3-py3-none-any.whl", hash = "sha256:6b0851425aa875b08b16789ee0eeadbd4ab59666e9ebe728e526314c4a2e52c1"}, + {file = "EditorConfig-0.12.3.tar.gz", hash = "sha256:57f8ce78afcba15c8b18d46b5170848c88d56fd38f05c2ec60dbbfcb8996e89e"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "fonttools" +version = "4.39.2" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.39.2-py3-none-any.whl", hash = "sha256:85245aa2fd4cf502a643c9a9a2b5a393703e150a6eaacc3e0e84bb448053f061"}, + {file = "fonttools-4.39.2.zip", hash = "sha256:e2d9f10337c9e3b17f9bce17a60a16a885a7d23b59b7f45ce07ea643e5580439"}, +] + +[package.dependencies] +brotli = {version = ">=1.0.1", optional = true, markers = "platform_python_implementation == \"CPython\" and extra == \"woff\""} +brotlicffi = {version = ">=0.8.0", optional = true, markers = "platform_python_implementation != \"CPython\" and extra == \"woff\""} +zopfli = {version = ">=0.1.4", optional = true, markers = "extra == \"woff\""} + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "scipy"] +lxml = ["lxml (>=4.0,<5)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.0.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "gitdb" +version = "4.0.10" +description = "Git Object Database" +optional = false +python-versions = ">=3.7" +files = [ + {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, + {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, +] + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "gitpython" +version = "3.1.31" +description = "GitPython is a Python library used to interact with Git repositories" +optional = false +python-versions = ">=3.7" +files = [ + {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, + {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, +] + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "googletrans" +version = "3.1.0a0" +description = "Free Google Translate API for Python. Translates totally free of charge." +optional = false +python-versions = ">=3.6" +files = [ + {file = "googletrans-3.1.0a0.tar.gz", hash = "sha256:d20373a7975791318a7e5d6c6e3205012d7a990b8fabbfc6b0c16017a6dfae04"}, +] + +[package.dependencies] +httpx = "0.13.3" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "h11" +version = "0.9.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = "*" +files = [ + {file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"}, + {file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "h2" +version = "3.2.0" +description = "HTTP/2 State-Machine based protocol implementation" +optional = false +python-versions = "*" +files = [ + {file = "h2-3.2.0-py2.py3-none-any.whl", hash = "sha256:61e0f6601fa709f35cdb730863b4e5ec7ad449792add80d1410d4174ed139af5"}, + {file = "h2-3.2.0.tar.gz", hash = "sha256:875f41ebd6f2c44781259005b157faed1a5031df3ae5aa7bcb4628a6c0782f14"}, +] + +[package.dependencies] +hpack = ">=3.0,<4" +hyperframe = ">=5.2.0,<6" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "hpack" +version = "3.0.0" +description = "Pure-Python HPACK header compression" +optional = false +python-versions = "*" +files = [ + {file = "hpack-3.0.0-py2.py3-none-any.whl", hash = "sha256:0edd79eda27a53ba5be2dfabf3b15780928a0dff6eb0c60a3d6767720e970c89"}, + {file = "hpack-3.0.0.tar.gz", hash = "sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "hstspreload" +version = "2023.1.1" +description = "Chromium HSTS Preload list as a Python package" +optional = false +python-versions = ">=3.6" +files = [ + {file = "hstspreload-2023.1.1-py3-none-any.whl", hash = "sha256:ac8a56dd603b4bf55292fc7a157e0deea18ee5e2e5c114d131da8949cc7a54bb"}, + {file = "hstspreload-2023.1.1.tar.gz", hash = "sha256:b2330a88b3fe3344c9eb431257e1ff3ae06c3bc2ff87ca686a5f253e2881a6c1"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "html5lib" +version = "1.1" +description = "HTML parser based on the WHATWG HTML specification" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, + {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, +] + +[package.dependencies] +six = ">=1.9" +webencodings = "*" + +[package.extras] +all = ["chardet (>=2.2)", "genshi", "lxml"] +chardet = ["chardet (>=2.2)"] +genshi = ["genshi"] +lxml = ["lxml"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "htmlmin" +version = "0.1.12" +description = "An HTML Minifier" +optional = false +python-versions = "*" +files = [ + {file = "htmlmin-0.1.12.tar.gz", hash = "sha256:50c1ef4630374a5d723900096a961cff426dff46b48f34d194a81bbe14eca178"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "httpcore" +version = "0.9.1" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.6" +files = [ + {file = "httpcore-0.9.1-py3-none-any.whl", hash = "sha256:9850fe97a166a794d7e920590d5ec49a05488884c9fc8b5dba8561effab0c2a0"}, + {file = "httpcore-0.9.1.tar.gz", hash = "sha256:ecc5949310d9dae4de64648a4ce529f86df1f232ce23dcfefe737c24d21dfbe9"}, +] + +[package.dependencies] +h11 = ">=0.8,<0.10" +h2 = "==3.*" +sniffio = "==1.*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "httpx" +version = "0.13.3" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.6" +files = [ + {file = "httpx-0.13.3-py3-none-any.whl", hash = "sha256:32d930858eab677bc29a742aaa4f096de259f1c78c68a90ad11f5c3c04f08335"}, + {file = "httpx-0.13.3.tar.gz", hash = "sha256:3642bd13e90b80ba8a243a730275eb10a4c26ec96f5fc16b87e458d4ab21efae"}, +] + +[package.dependencies] +certifi = "*" +chardet = "==3.*" +hstspreload = "*" +httpcore = "==0.9.*" +idna = "==2.*" +rfc3986 = ">=1.3,<2" +sniffio = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "hyperframe" +version = "5.2.0" +description = "HTTP/2 framing layer for Python" +optional = false +python-versions = "*" +files = [ + {file = "hyperframe-5.2.0-py2.py3-none-any.whl", hash = "sha256:5187962cb16dcc078f23cb5a4b110098d546c3f41ff2d4038a9896893bbd0b40"}, + {file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "importlib-metadata" +version = "6.1.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "importlib_metadata-6.1.0-py3-none-any.whl", hash = "sha256:ff80f3b5394912eb1b108fcfd444dc78b7f1f3e16b16188054bd01cb9cb86f09"}, + {file = "importlib_metadata-6.1.0.tar.gz", hash = "sha256:43ce9281e097583d758c2c708c4376371261a02c34682491a8e98352365aad20"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "jieba" +version = "0.42.1" +description = "Chinese Words Segmentation Utilities" +optional = false +python-versions = "*" +files = [ + {file = "jieba-0.42.1.tar.gz", hash = "sha256:055ca12f62674fafed09427f176506079bc135638a14e23e25be909131928db2"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "jsbeautifier" +version = "1.14.7" +description = "JavaScript unobfuscator and beautifier." +optional = false +python-versions = "*" +files = [ + {file = "jsbeautifier-1.14.7.tar.gz", hash = "sha256:77993254db1ff6f84eb6e1d75e3b6b72cba2ef20813a585b2d81e8e5e3c713c6"}, +] + +[package.dependencies] +editorconfig = ">=0.12.2" +six = ">=1.13.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "jsmin" +version = "3.0.1" +description = "JavaScript minifier." +optional = false +python-versions = "*" +files = [ + {file = "jsmin-3.0.1.tar.gz", hash = "sha256:c0959a121ef94542e807a674142606f7e90214a2b3d1eb17300244bbb5cc2bfc"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "libsass" +version = "0.22.0" +description = "Sass for Python: A straightforward binding of libsass for Python." +optional = false +python-versions = ">=3.6" +files = [ + {file = "libsass-0.22.0-cp36-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f1efc1b612299c88aec9e39d6ca0c266d360daa5b19d9430bdeaffffa86993f9"}, + {file = "libsass-0.22.0-cp37-abi3-macosx_10_15_x86_64.whl", hash = "sha256:081e256ab3c5f3f09c7b8dea3bf3bf5e64a97c6995fd9eea880639b3f93a9f9a"}, + {file = "libsass-0.22.0-cp37-abi3-win32.whl", hash = "sha256:89c5ce497fcf3aba1dd1b19aae93b99f68257e5f2026b731b00a872f13324c7f"}, + {file = "libsass-0.22.0-cp37-abi3-win_amd64.whl", hash = "sha256:65455a2728b696b62100eb5932604aa13a29f4ac9a305d95773c14aaa7200aaf"}, + {file = "libsass-0.22.0-cp38-abi3-macosx_14_0_arm64.whl", hash = "sha256:5fb2297a4754a6c8e25cfe5c015a3b51a2b6b9021b333f989bb8ce9d60eb5828"}, + {file = "libsass-0.22.0.tar.gz", hash = "sha256:3ab5ad18e47db560f4f0c09e3d28cf3bb1a44711257488ac2adad69f4f7f8425"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "lxml" +version = "4.9.3" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, + {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, + {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, + {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, + {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, + {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, + {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, + {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, + {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, + {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, + {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, + {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, + {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, + {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, + {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, + {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, + {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, + {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, + {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, + {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, + {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, + {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, + {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, + {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, + {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=0.29.35)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "markdown" +version = "3.3.7" +description = "Python implementation of Markdown." +optional = false +python-versions = ">=3.6" +files = [ + {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"}, + {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +testing = ["coverage", "pyyaml"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "markupsafe" +version = "2.1.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs" +version = "1.4.2" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.4.2-py3-none-any.whl", hash = "sha256:c8856a832c1e56702577023cd64cc5f84948280c1c0fcc6af4cd39006ea6aa8c"}, + {file = "mkdocs-1.4.2.tar.gz", hash = "sha256:8947af423a6d0facf41ea1195b8e1e8c85ad94ac95ae307fe11232e0424b11c5"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.2.1,<3.4" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-awesome-pages-plugin" +version = "2.8.0" +description = "An MkDocs plugin that simplifies configuring page titles and their order" +optional = false +python-versions = ">=3.6.2" +files = [ + {file = "mkdocs-awesome-pages-plugin-2.8.0.tar.gz", hash = "sha256:af7e327e14b2eea3b2735c37428e33a528ecd2d9ae2296dc0f1632f0f3bc28f7"}, + {file = "mkdocs_awesome_pages_plugin-2.8.0-py3-none-any.whl", hash = "sha256:6b21ad4f41aecbe89e3a9a51f8837892cc7ce8ca0f9f4e0a355d56159ace3d68"}, +] + +[package.dependencies] +mkdocs = ">=1" +natsort = ">=8.1.0" +wcmatch = ">=7" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-embed-external-markdown" +version = "2.3.0" +description = "Mkdocs plugin that allow to inject external markdown or markdown section from given url" +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ + {file = "mkdocs-embed-external-markdown-2.3.0.tar.gz", hash = "sha256:543ecbaf1d1b62bb6b557714d20ac76b7c24b2b76adc5243a406e636964a8d45"}, + {file = "mkdocs_embed_external_markdown-2.3.0-py3-none-any.whl", hash = "sha256:a14918a2beacf50ba215670e802fee75de3013bb9db8d8e8d23dd6978004b5bc"}, +] + +[package.dependencies] +Jinja2 = ">=3.0.3,<4.0.0" +requests = ">=2.27.1,<3.0.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-git-authors-plugin" +version = "0.6.5" +description = "Mkdocs plugin to display git authors of a page" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-git-authors-plugin-0.6.5.tar.gz", hash = "sha256:5e10d1685745e128b0bc88e229c13cf62bab2b5a1b716b68301216b94e206bd4"}, + {file = "mkdocs_git_authors_plugin-0.6.5-py3-none-any.whl", hash = "sha256:b82aad1a476a673d0746e8ce5ccccbd39822fc730ef0a6a113ec8517d30016fc"}, +] + +[package.dependencies] +mkdocs = ">=1.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-git-committers-plugin-2" +version = "1.1.1" +description = "An MkDocs plugin to create a list of contributors on the page" +optional = false +python-versions = ">=2.7" +files = [ + {file = "mkdocs_git_committers_plugin_2-1.1.1-py3-none-any.whl", hash = "sha256:14d4a89bf8965ab62ca9b8b0cd90f6c9b421bb89bfedca0d91c5119f18791360"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +gitpython = "*" +mkdocs = ">=1.0.3" +requests = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-git-revision-date-localized-plugin" +version = "1.2.0" +description = "Mkdocs plugin that enables displaying the localized date of the last git modification of a markdown file." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-git-revision-date-localized-plugin-1.2.0.tar.gz", hash = "sha256:7752edd7c4dcaa9383e9a5b6a4f729831a62d604b0c43b319331127720c6a2bf"}, + {file = "mkdocs_git_revision_date_localized_plugin-1.2.0-py3-none-any.whl", hash = "sha256:540b9c930d8d48630c090b72ac2c3900ac2ed0799b23738a33b88e31f5198fe7"}, +] + +[package.dependencies] +babel = ">=2.7.0" +GitPython = "*" +mkdocs = ">=1.0" +pytz = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-git-revision-date-plugin" +version = "0.3.2" +description = "MkDocs plugin for setting revision date from git per markdown file." +optional = false +python-versions = ">=3.4" +files = [ + {file = "mkdocs_git_revision_date_plugin-0.3.2-py3-none-any.whl", hash = "sha256:2e67956cb01823dd2418e2833f3623dee8604cdf223bddd005fe36226a56f6ef"}, +] + +[package.dependencies] +GitPython = "*" +jinja2 = "*" +mkdocs = ">=0.17" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-macros-plugin" +version = "0.7.0" +description = "Unleash the power of MkDocs with macros and variables" +optional = false +python-versions = ">=3.5" +files = [ + {file = "mkdocs-macros-plugin-0.7.0.tar.gz", hash = "sha256:9e64e1cabcf6925359de29fe54f62d5847fb455c2528c440b87f8f1240650608"}, + {file = "mkdocs_macros_plugin-0.7.0-py3-none-any.whl", hash = "sha256:96bdabeb98b96139544f0048ea2f5cb80c7befde6b21e94c6d4596c22774cbcf"}, +] + +[package.dependencies] +jinja2 = "*" +mkdocs = ">=0.17" +python-dateutil = "*" +pyyaml = "*" +termcolor = "*" + +[package.extras] +test = ["mkdocs-include-markdown-plugin", "mkdocs-macros-test", "mkdocs-material (>=6.2)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-material" +version = "9.1.3" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs_material-9.1.3-py3-none-any.whl", hash = "sha256:a8d14d03569008afb0f5a5785c253249b5ff038e3a5509f96a393b8596bf5062"}, + {file = "mkdocs_material-9.1.3.tar.gz", hash = "sha256:0be1b5d76c00efc9b2ecbd2d71014be950351e710f5947f276264878afc82ca0"}, +] + +[package.dependencies] +colorama = ">=0.4" +jinja2 = ">=3.0" +markdown = ">=3.2" +mkdocs = ">=1.4.2" +mkdocs-material-extensions = ">=1.1" +pygments = ">=2.14" +pymdown-extensions = ">=9.9.1" +regex = ">=2022.4.24" +requests = ">=2.26" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-material-extensions" +version = "1.1.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, + {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-mermaid2-plugin" +version = "0.6.0" +description = "A MkDocs plugin for including mermaid graphs in markdown sources" +optional = false +python-versions = ">=3.5" +files = [ + {file = "mkdocs-mermaid2-plugin-0.6.0.tar.gz", hash = "sha256:99cca6db7c6b4a954a701dcb6b507191bc32a7b0b47eacf2885c1bacf77d1af1"}, + {file = "mkdocs_mermaid2_plugin-0.6.0-py3-none-any.whl", hash = "sha256:ffbe8a7daa7ed718cb800c44c5ce4c0ff413caebf7b8b63d9c4a998dfd78a64d"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.6.3" +jsbeautifier = "*" +mkdocs = ">=1.0.4" +mkdocs-material = "*" +pymdown-extensions = ">=8.0" +pyyaml = "*" +requests = "*" +setuptools = ">=18.5" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-minify-plugin" +version = "0.5.0" +description = "An MkDocs plugin to minify HTML, JS or CSS files prior to being written to disk" +optional = false +python-versions = ">=3.0" +files = [ + {file = "mkdocs-minify-plugin-0.5.0.tar.gz", hash = "sha256:32d9e8fbd89327a0f4f648f517297aad344c1bad64cfde110d059bd2f2780a6d"}, + {file = "mkdocs_minify_plugin-0.5.0-py2-none-any.whl", hash = "sha256:487c31ae6b8b3230f56910ce6bcf5c7e6ad9a8c4f51c720a4b989f30c2b0233f"}, +] + +[package.dependencies] +csscompressor = ">=0.9.5" +htmlmin = ">=0.1.4" +jsmin = ">=3.0.0" +mkdocs = ">=1.0.4" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-multirepo-plugin" +version = "0.4.12" +description = "Build documentation in multiple repos into one site." +optional = false +python-versions = "*" +files = [ + {file = "mkdocs_multirepo_plugin-0.4.12-py2.py3-none-any.whl", hash = "sha256:842d5bc7be45b7b7e63e0c4f85fe0d482116d5211ef4516747a9f6b5595da58c"}, + {file = "mkdocs_multirepo_plugin-0.4.12.tar.gz", hash = "sha256:cd6ec718df6cc4b997d165c9fb2243846d754ea640382d260245c672e9ddf1db"}, +] + +[package.dependencies] +asyncio = "*" +mkdocs = {version = ">=1.0.4", markers = "python_version >= \"3.6\""} +python-slugify = {version = "*", markers = "python_version >= \"2.7\" and python_version < \"2.8\" or python_full_version >= \"3.6.0\""} + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-print-site-plugin" +version = "2.3.4" +description = "MkDocs plugin that combines all pages into one, allowing for easy export to PDF and standalone HTML." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-print-site-plugin-2.3.4.tar.gz", hash = "sha256:40c8c918a58f66c1f44b97512433fefd28a7ae74f8aa6c1633ddf14a6c04aa7f"}, + {file = "mkdocs_print_site_plugin-2.3.4-py3-none-any.whl", hash = "sha256:a74540cc3098695ae4623effc2c0be1631d0d1061344dcce283e775044cca0b4"}, +] + +[package.dependencies] +mkdocs-material = ">=7.3.0" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-redirects" +version = "1.2.0" +description = "A MkDocs plugin for dynamic page redirects to prevent broken links." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-redirects-1.2.0.tar.gz", hash = "sha256:ddd38267d49fdfa19fb2f25b4aed2fb53f0496c818bf3018009c8eaf6676a327"}, +] + +[package.dependencies] +mkdocs = ">=1.1.1" + +[package.extras] +dev = ["autoflake", "black", "isort", "pytest", "twine (>=1.13.0)"] +release = ["twine (>=1.13.0)"] +test = ["autoflake", "black", "isort", "pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-rss-plugin" +version = "1.6.0" +description = "MkDocs plugin which generates a static RSS feed using git log and page.meta." +optional = false +python-versions = ">=3.8, <4" +files = [ + {file = "mkdocs-rss-plugin-1.6.0.tar.gz", hash = "sha256:7e7f08e7ea947d98042b9c05885d93c0f26b236865fc5b36a2261bb112a5d766"}, + {file = "mkdocs_rss_plugin-1.6.0-py2.py3-none-any.whl", hash = "sha256:93644af3b9800842a5849ed5481e225f443bf0cda74843c9e81f6a62f6d14113"}, +] + +[package.dependencies] +GitPython = ">=3.1,<3.2" +mkdocs = ">=1.1,<2" +tzdata = {version = "==2022.*", markers = "python_version >= \"3.9\" and sys_platform == \"win32\""} + +[package.extras] +dev = ["black", "feedparser (>=6.0,<6.1)", "flake8 (>=4,<6.1)", "pre-commit (>=2.10,<3.1)", "pytest-cov (==4.0.*)", "validator-collection (>=1.5,<1.6)"] +doc = ["mkdocs-bootswatch (>=1,<2)", "mkdocs-minify-plugin (==0.5.*)", "pygments (>=2.5,<3)", "pymdown-extensions (>=7,<10)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-swagger-ui-tag" +version = "0.6.1" +description = "A MkDocs plugin supports for add Swagger UI in page." +optional = false +python-versions = "*" +files = [ + {file = "mkdocs-swagger-ui-tag-0.6.1.tar.gz", hash = "sha256:141ac067d3213c63f0261557b25bb99af54827b80f0e208aff712e3c0aba44dc"}, + {file = "mkdocs_swagger_ui_tag-0.6.1-py3-none-any.whl", hash = "sha256:07584dfb09d0784edf6442bd151857803ebee86c5b84821f4a8f4a583905b964"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.11.1" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "mkdocs-with-pdf" +version = "0.9.3" +description = "Generate a single PDF file from MkDocs repository" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mkdocs-with-pdf-0.9.3.tar.gz", hash = "sha256:bda3375d7040d1b8871da17c6d71ea736bdca6c669608f28ed62771031d2e0c6"}, + {file = "mkdocs_with_pdf-0.9.3-py3-none-any.whl", hash = "sha256:002d76417b5cc584effdfdb6ec8d073266a308a85680c430562e97f00b886e49"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.6.3" +libsass = ">=0.15" +mkdocs = ">=1.1" +weasyprint = ">=0.44" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "natsort" +version = "8.3.1" +description = "Simple yet flexible natural sorting in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "natsort-8.3.1-py3-none-any.whl", hash = "sha256:d583bc9050dd10538de36297c960b93f873f0cd01671a3c50df5bd86dd391dcb"}, + {file = "natsort-8.3.1.tar.gz", hash = "sha256:517595492dde570a4fd6b6a76f644440c1ba51e2338c8a671d7f0475fda8f9fd"}, +] + +[package.extras] +fast = ["fastnumbers (>=2.0.0)"] +icu = ["PyICU (>=1.0.0)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "packaging" +version = "23.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, + {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pandoc" +version = "2.3" +description = "Pandoc Documents for Python" +optional = false +python-versions = "*" +files = [ + {file = "pandoc-2.3.tar.gz", hash = "sha256:e772c2c6d871146894579828dbaf1efd538eb64fc7e71d4a6b3a11a18baef90d"}, +] + +[package.dependencies] +plumbum = "*" +ply = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pillow" +version = "9.4.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pillow-9.4.0-1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b4b4e9dda4f4e4c4e6896f93e84a8f0bcca3b059de9ddf67dac3c334b1195e1"}, + {file = "Pillow-9.4.0-1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fb5c1ad6bad98c57482236a21bf985ab0ef42bd51f7ad4e4538e89a997624e12"}, + {file = "Pillow-9.4.0-1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:f0caf4a5dcf610d96c3bd32932bfac8aee61c96e60481c2a0ea58da435e25acd"}, + {file = "Pillow-9.4.0-1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:3f4cc516e0b264c8d4ccd6b6cbc69a07c6d582d8337df79be1e15a5056b258c9"}, + {file = "Pillow-9.4.0-1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858"}, + {file = "Pillow-9.4.0-1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab"}, + {file = "Pillow-9.4.0-1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9"}, + {file = "Pillow-9.4.0-2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0"}, + {file = "Pillow-9.4.0-2-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f"}, + {file = "Pillow-9.4.0-2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c"}, + {file = "Pillow-9.4.0-2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848"}, + {file = "Pillow-9.4.0-2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1"}, + {file = "Pillow-9.4.0-2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33"}, + {file = "Pillow-9.4.0-2-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9"}, + {file = "Pillow-9.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157"}, + {file = "Pillow-9.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47"}, + {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343"}, + {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a3049a10261d7f2b6514d35bbb7a4dfc3ece4c4de14ef5876c4b7a23a0e566d"}, + {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16a8df99701f9095bea8a6c4b3197da105df6f74e6176c5b410bc2df2fd29a57"}, + {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:94cdff45173b1919350601f82d61365e792895e3c3a3443cf99819e6fbf717a5"}, + {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ed3e4b4e1e6de75fdc16d3259098de7c6571b1a6cc863b1a49e7d3d53e036070"}, + {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5b2f8a31bd43e0f18172d8ac82347c8f37ef3e0b414431157718aa234991b28"}, + {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:09b89ddc95c248ee788328528e6a2996e09eaccddeeb82a5356e92645733be35"}, + {file = "Pillow-9.4.0-cp310-cp310-win32.whl", hash = "sha256:f09598b416ba39a8f489c124447b007fe865f786a89dbfa48bb5cf395693132a"}, + {file = "Pillow-9.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6e78171be3fb7941f9910ea15b4b14ec27725865a73c15277bc39f5ca4f8391"}, + {file = "Pillow-9.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:3fa1284762aacca6dc97474ee9c16f83990b8eeb6697f2ba17140d54b453e133"}, + {file = "Pillow-9.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eaef5d2de3c7e9b21f1e762f289d17b726c2239a42b11e25446abf82b26ac132"}, + {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4dfdae195335abb4e89cc9762b2edc524f3c6e80d647a9a81bf81e17e3fb6f0"}, + {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6abfb51a82e919e3933eb137e17c4ae9c0475a25508ea88993bb59faf82f3b35"}, + {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451f10ef963918e65b8869e17d67db5e2f4ab40e716ee6ce7129b0cde2876eab"}, + {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:6663977496d616b618b6cfa43ec86e479ee62b942e1da76a2c3daa1c75933ef4"}, + {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:60e7da3a3ad1812c128750fc1bc14a7ceeb8d29f77e0a2356a8fb2aa8925287d"}, + {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:19005a8e58b7c1796bc0167862b1f54a64d3b44ee5d48152b06bb861458bc0f8"}, + {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f715c32e774a60a337b2bb8ad9839b4abf75b267a0f18806f6f4f5f1688c4b5a"}, + {file = "Pillow-9.4.0-cp311-cp311-win32.whl", hash = "sha256:b222090c455d6d1a64e6b7bb5f4035c4dff479e22455c9eaa1bdd4c75b52c80c"}, + {file = "Pillow-9.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:ba6612b6548220ff5e9df85261bddc811a057b0b465a1226b39bfb8550616aee"}, + {file = "Pillow-9.4.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5f532a2ad4d174eb73494e7397988e22bf427f91acc8e6ebf5bb10597b49c493"}, + {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dd5a9c3091a0f414a963d427f920368e2b6a4c2f7527fdd82cde8ef0bc7a327"}, + {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef21af928e807f10bf4141cad4746eee692a0dd3ff56cfb25fce076ec3cc8abe"}, + {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:847b114580c5cc9ebaf216dd8c8dbc6b00a3b7ab0131e173d7120e6deade1f57"}, + {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:653d7fb2df65efefbcbf81ef5fe5e5be931f1ee4332c2893ca638c9b11a409c4"}, + {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:46f39cab8bbf4a384ba7cb0bc8bae7b7062b6a11cfac1ca4bc144dea90d4a9f5"}, + {file = "Pillow-9.4.0-cp37-cp37m-win32.whl", hash = "sha256:7ac7594397698f77bce84382929747130765f66406dc2cd8b4ab4da68ade4c6e"}, + {file = "Pillow-9.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:46c259e87199041583658457372a183636ae8cd56dbf3f0755e0f376a7f9d0e6"}, + {file = "Pillow-9.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:0e51f608da093e5d9038c592b5b575cadc12fd748af1479b5e858045fff955a9"}, + {file = "Pillow-9.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:765cb54c0b8724a7c12c55146ae4647e0274a839fb6de7bcba841e04298e1011"}, + {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:519e14e2c49fcf7616d6d2cfc5c70adae95682ae20f0395e9280db85e8d6c4df"}, + {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d197df5489004db87d90b918033edbeee0bd6df3848a204bca3ff0a903bef837"}, + {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0845adc64fe9886db00f5ab68c4a8cd933ab749a87747555cec1c95acea64b0b"}, + {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:e1339790c083c5a4de48f688b4841f18df839eb3c9584a770cbd818b33e26d5d"}, + {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:a96e6e23f2b79433390273eaf8cc94fec9c6370842e577ab10dabdcc7ea0a66b"}, + {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7cfc287da09f9d2a7ec146ee4d72d6ea1342e770d975e49a8621bf54eaa8f30f"}, + {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d7081c084ceb58278dd3cf81f836bc818978c0ccc770cbbb202125ddabec6628"}, + {file = "Pillow-9.4.0-cp38-cp38-win32.whl", hash = "sha256:df41112ccce5d47770a0c13651479fbcd8793f34232a2dd9faeccb75eb5d0d0d"}, + {file = "Pillow-9.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7a21222644ab69ddd9967cfe6f2bb420b460dae4289c9d40ff9a4896e7c35c9a"}, + {file = "Pillow-9.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0f3269304c1a7ce82f1759c12ce731ef9b6e95b6df829dccd9fe42912cc48569"}, + {file = "Pillow-9.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb362e3b0976dc994857391b776ddaa8c13c28a16f80ac6522c23d5257156bed"}, + {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e0f87144fcbbe54297cae708c5e7f9da21a4646523456b00cc956bd4c65815"}, + {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28676836c7796805914b76b1837a40f76827ee0d5398f72f7dcc634bae7c6264"}, + {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0884ba7b515163a1a05440a138adeb722b8a6ae2c2b33aea93ea3118dd3a899e"}, + {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:53dcb50fbdc3fb2c55431a9b30caeb2f7027fcd2aeb501459464f0214200a503"}, + {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:e8c5cf126889a4de385c02a2c3d3aba4b00f70234bfddae82a5eaa3ee6d5e3e6"}, + {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c6b1389ed66cdd174d040105123a5a1bc91d0aa7059c7261d20e583b6d8cbd2"}, + {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0dd4c681b82214b36273c18ca7ee87065a50e013112eea7d78c7a1b89a739153"}, + {file = "Pillow-9.4.0-cp39-cp39-win32.whl", hash = "sha256:6d9dfb9959a3b0039ee06c1a1a90dc23bac3b430842dcb97908ddde05870601c"}, + {file = "Pillow-9.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:54614444887e0d3043557d9dbc697dbb16cfb5a35d672b7a0fcc1ed0cf1c600b"}, + {file = "Pillow-9.4.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b9b752ab91e78234941e44abdecc07f1f0d8f51fb62941d32995b8161f68cfe5"}, + {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3b56206244dc8711f7e8b7d6cad4663917cd5b2d950799425076681e8766286"}, + {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aabdab8ec1e7ca7f1434d042bf8b1e92056245fb179790dc97ed040361f16bfd"}, + {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db74f5562c09953b2c5f8ec4b7dfd3f5421f31811e97d1dbc0a7c93d6e3a24df"}, + {file = "Pillow-9.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e9d7747847c53a16a729b6ee5e737cf170f7a16611c143d95aa60a109a59c336"}, + {file = "Pillow-9.4.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b52ff4f4e002f828ea6483faf4c4e8deea8d743cf801b74910243c58acc6eda3"}, + {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:575d8912dca808edd9acd6f7795199332696d3469665ef26163cd090fa1f8bfa"}, + {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c4ed2ff6760e98d262e0cc9c9a7f7b8a9f61aa4d47c58835cdaf7b0b8811bb"}, + {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e621b0246192d3b9cb1dc62c78cfa4c6f6d2ddc0ec207d43c0dedecb914f152a"}, + {file = "Pillow-9.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8f127e7b028900421cad64f51f75c051b628db17fb00e099eb148761eed598c9"}, + {file = "Pillow-9.4.0.tar.gz", hash = "sha256:a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "plumbum" +version = "1.8.1" +description = "Plumbum: shell combinators library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "plumbum-1.8.1-py3-none-any.whl", hash = "sha256:07cf5f50bf739e91fb83ce304fc66b41dbd12db4d4546ff5266087dd9d148314"}, + {file = "plumbum-1.8.1.tar.gz", hash = "sha256:88a40fc69247d0cd585e21ca169b3820f46c484535102e16455d2202727bb37b"}, +] + +[package.dependencies] +pywin32 = {version = "*", markers = "platform_system == \"Windows\" and platform_python_implementation != \"PyPy\""} + +[package.extras] +dev = ["paramiko", "psutil", "pytest (>=6.0)", "pytest-cov", "pytest-mock", "pytest-timeout"] +docs = ["sphinx (>=4.0.0)", "sphinx-rtd-theme (>=1.0.0)"] +ssh = ["paramiko"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +optional = false +python-versions = "*" +files = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pydantic" +version = "1.10.6" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9289065611c48147c1dd1fd344e9d57ab45f1d99b0fb26c51f1cf72cd9bcd31"}, + {file = "pydantic-1.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c32b6bba301490d9bb2bf5f631907803135e8085b6aa3e5fe5a770d46dd0160"}, + {file = "pydantic-1.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd9b9e98068fa1068edfc9eabde70a7132017bdd4f362f8b4fd0abed79c33083"}, + {file = "pydantic-1.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c84583b9df62522829cbc46e2b22e0ec11445625b5acd70c5681ce09c9b11c4"}, + {file = "pydantic-1.10.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b41822064585fea56d0116aa431fbd5137ce69dfe837b599e310034171996084"}, + {file = "pydantic-1.10.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:61f1f08adfaa9cc02e0cbc94f478140385cbd52d5b3c5a657c2fceb15de8d1fb"}, + {file = "pydantic-1.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:32937835e525d92c98a1512218db4eed9ddc8f4ee2a78382d77f54341972c0e7"}, + {file = "pydantic-1.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbd5c531b22928e63d0cb1868dee76123456e1de2f1cb45879e9e7a3f3f1779b"}, + {file = "pydantic-1.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e277bd18339177daa62a294256869bbe84df1fb592be2716ec62627bb8d7c81d"}, + {file = "pydantic-1.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f15277d720aa57e173954d237628a8d304896364b9de745dcb722f584812c7"}, + {file = "pydantic-1.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b243b564cea2576725e77aeeda54e3e0229a168bc587d536cd69941e6797543d"}, + {file = "pydantic-1.10.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3ce13a558b484c9ae48a6a7c184b1ba0e5588c5525482681db418268e5f86186"}, + {file = "pydantic-1.10.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3ac1cd4deed871dfe0c5f63721e29debf03e2deefa41b3ed5eb5f5df287c7b70"}, + {file = "pydantic-1.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:b1eb6610330a1dfba9ce142ada792f26bbef1255b75f538196a39e9e90388bf4"}, + {file = "pydantic-1.10.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4ca83739c1263a044ec8b79df4eefc34bbac87191f0a513d00dd47d46e307a65"}, + {file = "pydantic-1.10.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea4e2a7cb409951988e79a469f609bba998a576e6d7b9791ae5d1e0619e1c0f2"}, + {file = "pydantic-1.10.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53de12b4608290992a943801d7756f18a37b7aee284b9ffa794ee8ea8153f8e2"}, + {file = "pydantic-1.10.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:60184e80aac3b56933c71c48d6181e630b0fbc61ae455a63322a66a23c14731a"}, + {file = "pydantic-1.10.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:415a3f719ce518e95a92effc7ee30118a25c3d032455d13e121e3840985f2efd"}, + {file = "pydantic-1.10.6-cp37-cp37m-win_amd64.whl", hash = "sha256:72cb30894a34d3a7ab6d959b45a70abac8a2a93b6480fc5a7bfbd9c935bdc4fb"}, + {file = "pydantic-1.10.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3091d2eaeda25391405e36c2fc2ed102b48bac4b384d42b2267310abae350ca6"}, + {file = "pydantic-1.10.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:751f008cd2afe812a781fd6aa2fb66c620ca2e1a13b6a2152b1ad51553cb4b77"}, + {file = "pydantic-1.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12e837fd320dd30bd625be1b101e3b62edc096a49835392dcf418f1a5ac2b832"}, + {file = "pydantic-1.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d92831d0115874d766b1f5fddcdde0c5b6c60f8c6111a394078ec227fca6d"}, + {file = "pydantic-1.10.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:476f6674303ae7965730a382a8e8d7fae18b8004b7b69a56c3d8fa93968aa21c"}, + {file = "pydantic-1.10.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3a2be0a0f32c83265fd71a45027201e1278beaa82ea88ea5b345eea6afa9ac7f"}, + {file = "pydantic-1.10.6-cp38-cp38-win_amd64.whl", hash = "sha256:0abd9c60eee6201b853b6c4be104edfba4f8f6c5f3623f8e1dba90634d63eb35"}, + {file = "pydantic-1.10.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6195ca908045054dd2d57eb9c39a5fe86409968b8040de8c2240186da0769da7"}, + {file = "pydantic-1.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43cdeca8d30de9a897440e3fb8866f827c4c31f6c73838e3a01a14b03b067b1d"}, + {file = "pydantic-1.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c19eb5163167489cb1e0161ae9220dadd4fc609a42649e7e84a8fa8fff7a80f"}, + {file = "pydantic-1.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:012c99a9c0d18cfde7469aa1ebff922e24b0c706d03ead96940f5465f2c9cf62"}, + {file = "pydantic-1.10.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:528dcf7ec49fb5a84bf6fe346c1cc3c55b0e7603c2123881996ca3ad79db5bfc"}, + {file = "pydantic-1.10.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:163e79386c3547c49366e959d01e37fc30252285a70619ffc1b10ede4758250a"}, + {file = "pydantic-1.10.6-cp39-cp39-win_amd64.whl", hash = "sha256:189318051c3d57821f7233ecc94708767dd67687a614a4e8f92b4a020d4ffd06"}, + {file = "pydantic-1.10.6-py3-none-any.whl", hash = "sha256:acc6783751ac9c9bc4680379edd6d286468a1dc8d7d9906cd6f1186ed682b2b0"}, + {file = "pydantic-1.10.6.tar.gz", hash = "sha256:cf95adb0d1671fc38d8c43dd921ad5814a735e7d9b4d9e437c088002863854fd"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pydyf" +version = "0.5.0" +description = "A low-level PDF generator." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydyf-0.5.0-py3-none-any.whl", hash = "sha256:116bc4b057822dc72d6afc826cad33444f7dcde8059aa85534380fb63e3e306f"}, + {file = "pydyf-0.5.0.tar.gz", hash = "sha256:51e751ae1504037c1fc1f4815119137b011802cd5f6c3539db066c455b14a7e1"}, +] + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pillow", "pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pygments" +version = "2.14.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.6" +files = [ + {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, + {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pymdown-extensions" +version = "9.10" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pymdown_extensions-9.10-py3-none-any.whl", hash = "sha256:31eaa76ce6f96aabfcea98787c2fff2c5c0611b20a53a94213970cfbf05f02b8"}, + {file = "pymdown_extensions-9.10.tar.gz", hash = "sha256:562c38eee4ce3f101ce631b804bfc2177a8a76c7e4dc908871fb6741a90257a7"}, +] + +[package.dependencies] +markdown = ">=3.2" +pyyaml = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pyphen" +version = "0.14.0" +description = "Pure Python module to hyphenate text" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyphen-0.14.0-py3-none-any.whl", hash = "sha256:414c9355958ca3c6a3ff233f65678c245b8ecb56418fb291e2b93499d61cd510"}, + {file = "pyphen-0.14.0.tar.gz", hash = "sha256:596c8b3be1c1a70411ba5f6517d9ccfe3083c758ae2b94a45f2707346d8e66fa"}, +] + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "python-docx" +version = "0.8.11" +description = "Create and update Microsoft Word .docx files." +optional = false +python-versions = "*" +files = [ + {file = "python-docx-0.8.11.tar.gz", hash = "sha256:1105d233a0956dd8dd1e710d20b159e2d72ac3c301041b95f4d4ceb3e0ebebc4"}, +] + +[package.dependencies] +lxml = ">=2.3.2" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "python-slugify" +version = "8.0.1" +description = "A Python slugify application that also handles Unicode" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"}, + {file = "python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pytz" +version = "2022.7.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, + {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pywin32" +version = "305" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-305-cp310-cp310-win32.whl", hash = "sha256:421f6cd86e84bbb696d54563c48014b12a23ef95a14e0bdba526be756d89f116"}, + {file = "pywin32-305-cp310-cp310-win_amd64.whl", hash = "sha256:73e819c6bed89f44ff1d690498c0a811948f73777e5f97c494c152b850fad478"}, + {file = "pywin32-305-cp310-cp310-win_arm64.whl", hash = "sha256:742eb905ce2187133a29365b428e6c3b9001d79accdc30aa8969afba1d8470f4"}, + {file = "pywin32-305-cp311-cp311-win32.whl", hash = "sha256:19ca459cd2e66c0e2cc9a09d589f71d827f26d47fe4a9d09175f6aa0256b51c2"}, + {file = "pywin32-305-cp311-cp311-win_amd64.whl", hash = "sha256:326f42ab4cfff56e77e3e595aeaf6c216712bbdd91e464d167c6434b28d65990"}, + {file = "pywin32-305-cp311-cp311-win_arm64.whl", hash = "sha256:4ecd404b2c6eceaca52f8b2e3e91b2187850a1ad3f8b746d0796a98b4cea04db"}, + {file = "pywin32-305-cp36-cp36m-win32.whl", hash = "sha256:48d8b1659284f3c17b68587af047d110d8c44837736b8932c034091683e05863"}, + {file = "pywin32-305-cp36-cp36m-win_amd64.whl", hash = "sha256:13362cc5aa93c2beaf489c9c9017c793722aeb56d3e5166dadd5ef82da021fe1"}, + {file = "pywin32-305-cp37-cp37m-win32.whl", hash = "sha256:a55db448124d1c1484df22fa8bbcbc45c64da5e6eae74ab095b9ea62e6d00496"}, + {file = "pywin32-305-cp37-cp37m-win_amd64.whl", hash = "sha256:109f98980bfb27e78f4df8a51a8198e10b0f347257d1e265bb1a32993d0c973d"}, + {file = "pywin32-305-cp38-cp38-win32.whl", hash = "sha256:9dd98384da775afa009bc04863426cb30596fd78c6f8e4e2e5bbf4edf8029504"}, + {file = "pywin32-305-cp38-cp38-win_amd64.whl", hash = "sha256:56d7a9c6e1a6835f521788f53b5af7912090674bb84ef5611663ee1595860fc7"}, + {file = "pywin32-305-cp39-cp39-win32.whl", hash = "sha256:9d968c677ac4d5cbdaa62fd3014ab241718e619d8e36ef8e11fb930515a1e918"}, + {file = "pywin32-305-cp39-cp39-win_amd64.whl", hash = "sha256:50768c6b7c3f0b38b7fb14dd4104da93ebced5f1a50dc0e834594bff6fbe1271"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "regex" +version = "2022.10.31" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.6" +files = [ + {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, + {file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, + {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, + {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, + {file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, + {file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, + {file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, + {file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, + {file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, + {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, + {file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, + {file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, + {file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, + {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, + {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, + {file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, + {file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, + {file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, + {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, + {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, + {file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, + {file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, + {file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, + {file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, + {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, + {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, + {file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, + {file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, + {file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, + {file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, + {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, + {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, + {file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, + {file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, + {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "requests" +version = "2.28.2" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7, <4" +files = [ + {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, + {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "rfc3986" +version = "1.5.0" +description = "Validating URI References per RFC 3986" +optional = false +python-versions = "*" +files = [ + {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, + {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, +] + +[package.extras] +idna2008 = ["idna"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "setuptools" +version = "70.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, + {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "smmap" +version = "5.0.0" +description = "A pure Python implementation of a sliding window memory map manager" +optional = false +python-versions = ">=3.6" +files = [ + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "soupsieve" +version = "2.4" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"}, + {file = "soupsieve-2.4.tar.gz", hash = "sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "termcolor" +version = "2.2.0" +description = "ANSI color formatting for output in terminal" +optional = false +python-versions = ">=3.7" +files = [ + {file = "termcolor-2.2.0-py3-none-any.whl", hash = "sha256:91ddd848e7251200eac969846cbae2dacd7d71c2871e92733289e7e3666f48e7"}, + {file = "termcolor-2.2.0.tar.gz", hash = "sha256:dfc8ac3f350788f23b2947b3e6cfa5a53b630b612e6cd8965a015a776020b99a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "tinycss2" +version = "1.2.1" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, + {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "typing-extensions" +version = "4.5.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +optional = false +python-versions = ">=3.7" +files = [ + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "tzdata" +version = "2022.7" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, + {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "ufile" +version = "3.2.7" +description = "UCloud UFile Python SDK" +optional = false +python-versions = "*" +files = [ + {file = "ufile-3.2.7-py3-none-any.whl", hash = "sha256:75fbf3d612d910dd296c98a53708a93a9d8b68eadbc26a6b53a5b4229cd7b37e"}, + {file = "ufile-3.2.7.tar.gz", hash = "sha256:9f1c77abaa65f2b5061348175da5cab746cdd066bc774be504265d5b2e48f141"}, +] + +[package.dependencies] +requests = "*" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "urllib3" +version = "1.26.15" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "watchdog" +version = "2.3.1" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.6" +files = [ + {file = "watchdog-2.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1f1200d4ec53b88bf04ab636f9133cb703eb19768a39351cee649de21a33697"}, + {file = "watchdog-2.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:564e7739abd4bd348aeafbf71cc006b6c0ccda3160c7053c4a53b67d14091d42"}, + {file = "watchdog-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:95ad708a9454050a46f741ba5e2f3468655ea22da1114e4c40b8cbdaca572565"}, + {file = "watchdog-2.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a073c91a6ef0dda488087669586768195c3080c66866144880f03445ca23ef16"}, + {file = "watchdog-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa8b028750b43e80eea9946d01925168eeadb488dfdef1d82be4b1e28067f375"}, + {file = "watchdog-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:964fd236cd443933268ae49b59706569c8b741073dbfd7ca705492bae9d39aab"}, + {file = "watchdog-2.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:91fd146d723392b3e6eb1ac21f122fcce149a194a2ba0a82c5e4d0ee29cd954c"}, + {file = "watchdog-2.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efe3252137392a471a2174d721e1037a0e6a5da7beb72a021e662b7000a9903f"}, + {file = "watchdog-2.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85bf2263290591b7c5fa01140601b64c831be88084de41efbcba6ea289874f44"}, + {file = "watchdog-2.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f2df370cd8e4e18499dd0bfdef476431bcc396108b97195d9448d90924e3131"}, + {file = "watchdog-2.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ea5d86d1bcf4a9d24610aa2f6f25492f441960cf04aed2bd9a97db439b643a7b"}, + {file = "watchdog-2.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6f5d0f7eac86807275eba40b577c671b306f6f335ba63a5c5a348da151aba0fc"}, + {file = "watchdog-2.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b848c71ef2b15d0ef02f69da8cc120d335cec0ed82a3fa7779e27a5a8527225"}, + {file = "watchdog-2.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0d9878be36d2b9271e3abaa6f4f051b363ff54dbbe7e7df1af3c920e4311ee43"}, + {file = "watchdog-2.3.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cd61f98cb37143206818cb1786d2438626aa78d682a8f2ecee239055a9771d5"}, + {file = "watchdog-2.3.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3d2dbcf1acd96e7a9c9aefed201c47c8e311075105d94ce5e899f118155709fd"}, + {file = "watchdog-2.3.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03f342a9432fe08107defbe8e405a2cb922c5d00c4c6c168c68b633c64ce6190"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7a596f9415a378d0339681efc08d2249e48975daae391d58f2e22a3673b977cf"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:0e1dd6d449267cc7d6935d7fe27ee0426af6ee16578eed93bacb1be9ff824d2d"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_i686.whl", hash = "sha256:7a1876f660e32027a1a46f8a0fa5747ad4fcf86cb451860eae61a26e102c8c79"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:2caf77ae137935c1466f8cefd4a3aec7017b6969f425d086e6a528241cba7256"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:53f3e95081280898d9e4fc51c5c69017715929e4eea1ab45801d5e903dd518ad"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:9da7acb9af7e4a272089bd2af0171d23e0d6271385c51d4d9bde91fe918c53ed"}, + {file = "watchdog-2.3.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:8a4d484e846dcd75e96b96d80d80445302621be40e293bfdf34a631cab3b33dc"}, + {file = "watchdog-2.3.1-py3-none-win32.whl", hash = "sha256:a74155398434937ac2780fd257c045954de5b11b5c52fc844e2199ce3eecf4cf"}, + {file = "watchdog-2.3.1-py3-none-win_amd64.whl", hash = "sha256:5defe4f0918a2a1a4afbe4dbb967f743ac3a93d546ea4674567806375b024adb"}, + {file = "watchdog-2.3.1-py3-none-win_ia64.whl", hash = "sha256:4109cccf214b7e3462e8403ab1e5b17b302ecce6c103eb2fc3afa534a7f27b96"}, + {file = "watchdog-2.3.1.tar.gz", hash = "sha256:d9f9ed26ed22a9d331820a8432c3680707ea8b54121ddcc9dc7d9f2ceeb36906"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "wcmatch" +version = "8.4.1" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.7" +files = [ + {file = "wcmatch-8.4.1-py3-none-any.whl", hash = "sha256:3476cd107aba7b25ba1d59406938a47dc7eec6cfd0ad09ff77193f21a964dee7"}, + {file = "wcmatch-8.4.1.tar.gz", hash = "sha256:b1f042a899ea4c458b7321da1b5e3331e3e0ec781583434de1301946ceadb943"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "weasyprint" +version = "58.1" +description = "The Awesome Document Factory" +optional = false +python-versions = ">=3.7" +files = [ + {file = "weasyprint-58.1-py3-none-any.whl", hash = "sha256:bd05088342a068b388052cb72f1b2431e1a0dc9d43b4db8ac92429a7a2e6b822"}, + {file = "weasyprint-58.1.tar.gz", hash = "sha256:6173009e313be65807fefbf78a8051ceb7a93776efda7ebbb88c13f5769794f3"}, +] + +[package.dependencies] +cffi = ">=0.6" +cssselect2 = ">=0.1" +fonttools = {version = ">=4.0.0", extras = ["woff"]} +html5lib = ">=1.1" +Pillow = ">=9.1.0" +pydyf = ">=0.5.0" +Pyphen = ">=0.9.1" +tinycss2 = ">=1.0.0" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "zipp" +version = "3.19.1" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.19.1-py3-none-any.whl", hash = "sha256:2828e64edb5386ea6a52e7ba7cdb17bb30a73a858f5eb6eb93d8d36f5ea26091"}, + {file = "zipp-3.19.1.tar.gz", hash = "sha256:35427f6d5594f4acf82d25541438348c26736fa9b3afa2754bcd63cdb99d8e8f"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[[package]] +name = "zopfli" +version = "0.2.2" +description = "Zopfli module for python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "zopfli-0.2.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e340851bbdea91408e6713748b4082c2e464a80eef9f9a69ff5a20e5e008cace"}, + {file = "zopfli-0.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:093a58fdf1e592f01233fc16900ceb69f27f19b347deb49544df96d912664f6d"}, + {file = "zopfli-0.2.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bd7b174fef2366723f57d16f3e8d157f9cbb53b1c555e2a1f99b6290de94ca28"}, + {file = "zopfli-0.2.2-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a712fdc3dab61037fab549ff72539b7968ffda567e5460aa2518e40a13b4dd38"}, + {file = "zopfli-0.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02a0c37826c0b28454865fdf664d54627fe8d90fac6f7325b5215719e8be09ca"}, + {file = "zopfli-0.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20b02b5c9f1cfbcfc154e54981d1b9f9581ca1f54ece39c6aed52f7166a6f081"}, + {file = "zopfli-0.2.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:01e82e6e31cfcb2eb7e3d6d72d0a498d150e3c3112cae3b5ab88ca3efedbc162"}, + {file = "zopfli-0.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c2e6d0618e1ffc27a1eaf66662f96e0bc8a4c1926fc139a0f544b93a1e1b451"}, + {file = "zopfli-0.2.2-cp310-cp310-win32.whl", hash = "sha256:e0014bd1b9703c9cdfa7f88bc793600aee5f858dd2f18105b49a70e66b9f1b1d"}, + {file = "zopfli-0.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:13487519e6ee8ed36c4a197d146d8ae60d418172d85342d3cdd28f38f905a705"}, + {file = "zopfli-0.2.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fa589e4d2b54d95447cb79a6053050fc7218f61594085ca54672cb045ba0f7f8"}, + {file = "zopfli-0.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd661f0894a4e4d78ce4c07e2625b0fd17ae172040ce57c5e1c32316a16727c9"}, + {file = "zopfli-0.2.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2137d64470469c825713aac486aacc9e2c46e300b92cb39ae47f4024b86b2e"}, + {file = "zopfli-0.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69411d85ed25ea25f480410048b397abc4c98562ce3533ecc3ce65358acc52dd"}, + {file = "zopfli-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed09efbcdc8bce5b5ff052ffd1edabdabd7a43e340ee63f8d5e81644dc50110f"}, + {file = "zopfli-0.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9de02f057ed153c9f523e72a366b8f48e2634c9f867e7109232415efe11d36c2"}, + {file = "zopfli-0.2.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2bafc105065fae35bd96100a5901a7d816f1904eb732d94b6d46cf480ead581b"}, + {file = "zopfli-0.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:898daa330577101aab03806231e9b29990ebaa34f275d9df2045d0551edd1e87"}, + {file = "zopfli-0.2.2-cp311-cp311-win32.whl", hash = "sha256:b5b2e2ac397a71772fbbdc5b31fa8257e46f2a1e718e5c17c08db3dac7c739e4"}, + {file = "zopfli-0.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:259f15d65e554b16a6086bfe96dd7bd175467eb3d024b9dbce41323b5861a285"}, + {file = "zopfli-0.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f6f62330a3999522282d0cc6370682d86985ac66edc2799f5934e309d8d615f1"}, + {file = "zopfli-0.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e05a2506e8a8d44835a11d5f1c296035d65d0f7053f77730ce99066acaf09af"}, + {file = "zopfli-0.2.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:573ae7e1cb4f0c9a248c203440950b24b213c13b5169e169a884c777ad9054e4"}, + {file = "zopfli-0.2.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:47d9ec1ca32240fae8b9b41e90d6483f4d0f2946de4785f54f4f57afe83040be"}, + {file = "zopfli-0.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:da3d682956e447f61ad23f66f49f20f189d12b15857a2e524497793ae54027c4"}, + {file = "zopfli-0.2.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:58ddab571a77988bc585e1a6fa46f9848b45880fa74bc832b135cbc22d22a619"}, + {file = "zopfli-0.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:00a66579f2e663cd7eabad71f5b114abf442f4816fdaf251b4b495aa9d016a67"}, + {file = "zopfli-0.2.2-cp37-cp37m-win32.whl", hash = "sha256:c49e29739508a7142fa1437256a7bf631926e70e68ca50a6bd62ee4e80050acc"}, + {file = "zopfli-0.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8d6d02e1a962995c380411cc4ec81d1f4fc60c293764f8acd859eb12bfdf7190"}, + {file = "zopfli-0.2.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a568f09aa932a04073a4147e2db5db2adfccd864326477d58d4ffc80550531c7"}, + {file = "zopfli-0.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c27af5f9a6538891af7257e104a37affbe26383fc0bd57b52c05fe2f45292dc9"}, + {file = "zopfli-0.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aea70d124ff9c0a33078f1451dfa2dd29eba53ea0627acb88783a19f0692044"}, + {file = "zopfli-0.2.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3b58455a9d23f6d45f2686891d7bec916132aed335052459bbed36a2b9437c1d"}, + {file = "zopfli-0.2.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7146c58c5ff604e7798d4c015c0ca8da53128ca29d0f1bccb48c785953451cd4"}, + {file = "zopfli-0.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81c2c1216814a4f2f9abcd49fd4b70f05266d3621ef3b21e4b1b7bf535876fc1"}, + {file = "zopfli-0.2.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:468c4317aca9411b576a27f6f26217bdd30e04fdfc420d3d7e8b6f1fef4e9886"}, + {file = "zopfli-0.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:691d4e0fd04e85ee5f59e019ed0da16d8f544904d3879a34986722d87a90c536"}, + {file = "zopfli-0.2.2-cp38-cp38-win32.whl", hash = "sha256:2b4b5ae717dc2c164d9fae6134eac285915aaef77723f8cf9765555ac926f6d0"}, + {file = "zopfli-0.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:c9d444b26317f3c40909d555f9c611ef8bcac6edf016af7709a32ad5848b481d"}, + {file = "zopfli-0.2.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:db004eb8ee7aab9c86647b92e1e570edb6fec9bd384a7a4f24e1f6529db34ac3"}, + {file = "zopfli-0.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a989893b20381be266a2385f4a1b77316e0df4258ee048bb190c2e426e39cbc8"}, + {file = "zopfli-0.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1689ced6f6ebf674281d85c143529232aa039c4e8d814bf3b425f1793bfdeb4"}, + {file = "zopfli-0.2.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fcc34fd420ec5750f9981db43ee9a4f2e2bfabdc52128b243fca1fd9b99e13d"}, + {file = "zopfli-0.2.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:33c876d311c5edc700ccf75a22d03dcda1efa85b43f733913a99b5f3d1eb4ea7"}, + {file = "zopfli-0.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3df7ae869dcb8e0bb3292e6ab041d16323af37d87c8dca1dde7b2fe5cb6b7cf7"}, + {file = "zopfli-0.2.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4cbc6192bf24425c757281c7c864012e51d29095771f805ea3040702c10c3d7a"}, + {file = "zopfli-0.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8563e639534201a14c109c54965f8a71574d8cf525a0a521d310e044d81fece9"}, + {file = "zopfli-0.2.2-cp39-cp39-win32.whl", hash = "sha256:4b471e3f58bd7b77cfc7a29b28a10c094ea4cd9ee14c54fbc4f1150680aac68c"}, + {file = "zopfli-0.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:1e3aefca003cbb41a6dcdd61f920c807eea99d0196aff488f02275c3b3c400a9"}, + {file = "zopfli-0.2.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:17694cfda43fb2af18b571bfc60426fb67d7701d75cc1f0e634ad0a19ffaebdd"}, + {file = "zopfli-0.2.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:71eafbe6ce975f77a5247bf44fdfdb78e846a76a3391de4d75cc68ea74542048"}, + {file = "zopfli-0.2.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a85d500cfa06f127e441e90804556a3872ea329e065d2f0ee97922d03afc9885"}, + {file = "zopfli-0.2.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:4205bb3aea31f22cd52bd1a9c298944591bfd9b6f92ede0af99127750b27eb3b"}, + {file = "zopfli-0.2.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ec845584fcdc10763d869b40b742fe0e2684adf3ca275ec997b9447ef5fe3ad9"}, + {file = "zopfli-0.2.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1360df0d423c897164a3344ed6635f7fd098cb4ce59c6d45b4275b93727d57f6"}, + {file = "zopfli-0.2.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:537da300842f06470c036d6d7e7fc9e63713735ee0b96ee97a750d1ec0399639"}, + {file = "zopfli-0.2.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2e5b7874dfe228715569940561cdc0485ed8cbfd2c76eebc4e54719e0c9cc494"}, + {file = "zopfli-0.2.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8c1b316a5eed59a9a49a886aeeaf3b7233627a1013b10f230817870278e15789"}, + {file = "zopfli-0.2.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ce7cbe8f6fff013aa695d5d92ac2b1fd46fd012858109fdde9824759b566685"}, + {file = "zopfli-0.2.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5e81fed8ac2d71832177ab06385f032cc3a37eec76537d105b1018b7fef0ff"}, + {file = "zopfli-0.2.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ea855a740ee766c872cbf84abdcc1b6a51b5dbdeb6ace995f36c934b3846467"}, + {file = "zopfli-0.2.2.zip", hash = "sha256:2d49db7540d9991976af464ebc1b9ed12988c04d90691bcb51dc4a373a9e2afc"}, +] + +[package.extras] +test = ["pytest"] + +[package.source] +type = "legacy" +url = "https://pypi.tuna.tsinghua.edu.cn/simple" +reference = "tsinghua" + +[metadata] +lock-version = "2.0" +python-versions = "^3.9" +content-hash = "0281feb00be5f2f90fd91fc0a1dd68554e02bf3efda353ca3dcf486ab5c14aeb" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9193dc6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,60 @@ +Babel==2.15.0 +beautifulsoup4==4.12.3 +bracex==2.4 +CacheControl==0.14.0 +certifi==2024.7.4 +charset-normalizer==3.3.2 +click==8.1.7 +colorama==0.4.6 +csscompressor==0.9.5 +EditorConfig==0.12.4 +filelock==3.15.4 +ghp-import==2.1.0 +gitdb==4.0.11 +GitPython==3.1.43 +htmlmin2==0.1.13 +idna==3.7 +Jinja2==3.1.4 +jsbeautifier==1.15.1 +jsmin==3.0.1 +Markdown==3.6 +MarkupSafe==2.1.5 +mergedeep==1.3.4 +mkdocs==1.6.0 +mkdocs-awesome-pages-plugin==2.9.3 +mkdocs-get-deps==0.2.0 +mkdocs-git-revision-date-localized-plugin==1.2.6 +mkdocs-git-revision-date-plugin==0.3.2 +mkdocs-macros-plugin==1.0.5 +mkdocs-material==9.5.30 +mkdocs-material-extensions==1.3.1 +mkdocs-mermaid2-plugin==1.1.1 +mkdocs-minify-plugin==0.8.0 +mkdocs-print-site-plugin==2.5.0 +mkdocs-redirects==1.2.1 +mkdocs-rss-plugin==1.15.0 +mkdocs-swagger-ui-tag==0.6.10 +msgpack==1.0.8 +natsort==8.4.0 +packaging==24.1 +paginate==0.5.6 +pathspec==0.12.1 +pip==24.0 +platformdirs==4.2.2 +Pygments==2.18.0 +pymdown-extensions==10.9 +python-dateutil==2.9.0.post0 +pytz==2024.1 +PyYAML==6.0.1 +pyyaml_env_tag==0.1 +regex==2024.7.24 +requests==2.32.3 +setuptools==69.5.1 +six==1.16.0 +smmap==5.0.1 +soupsieve==2.5 +termcolor==2.4.0 +urllib3==2.2.2 +watchdog==4.0.1 +wcmatch==8.5.2 +wheel==0.43.0 \ No newline at end of file diff --git a/resources/k8s/calico.yaml b/resources/k8s/calico.yaml new file mode 100644 index 0000000..f1fa631 --- /dev/null +++ b/resources/k8s/calico.yaml @@ -0,0 +1,1207 @@ +# Source: calico/templates/calico-config.yaml +# This ConfigMap is used to configure a self-hosted Calico installation. +kind: ConfigMap +apiVersion: v1 +metadata: + name: calico-config + namespace: kube-system +data: + # Typha is disabled. + typha_service_name: "none" + # Configure the backend to use. + calico_backend: "bird" + + # Configure the MTU to use for workload interfaces and tunnels. + # By default, MTU is auto-detected, and explicitly setting this field should not be required. + # You can override auto-detection by providing a non-zero value. + veth_mtu: "0" + + # The CNI network configuration to install on each node. The special + # values in this config will be automatically populated. + cni_network_config: |- + { + "name": "k8s-pod-network", + "cniVersion": "0.3.1", + "plugins": [ + { + "type": "calico", + "log_level": "info", + "log_file_path": "/var/log/calico/cni/cni.log", + "datastore_type": "kubernetes", + "nodename": "__KUBERNETES_NODE_NAME__", + "mtu": __CNI_MTU__, + "ipam": { + "type": "calico-ipam" + }, + "policy": { + "type": "k8s" + }, + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__" + } + }, + { + "type": "portmap", + "snat": true, + "capabilities": {"portMappings": true} + }, + { + "type": "bandwidth", + "capabilities": {"bandwidth": true} + } + ] + } + +--- +# Source: calico/templates/kdd-crds.yaml + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: bgpconfigurations.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: BGPConfiguration + listKind: BGPConfigurationList + plural: bgpconfigurations + singular: bgpconfiguration + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: BGPConfiguration contains the configuration for any BGP routing. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BGPConfigurationSpec contains the values of the BGP configuration. + properties: + asNumber: + description: 'ASNumber is the default AS number used by a node. [Default: + 64512]' + format: int32 + type: integer + communities: + description: Communities is a list of BGP community values and their + arbitrary names for tagging routes. + items: + description: Community contains standard or large community value + and its name. + properties: + name: + description: Name given to community value. + type: string + value: + description: Value must be of format `aa:nn` or `aa:nn:mm`. + For standard community use `aa:nn` format, where `aa` and + `nn` are 16 bit number. For large community use `aa:nn:mm` + format, where `aa`, `nn` and `mm` are 32 bit number. Where, + `aa` is an AS Number, `nn` and `mm` are per-AS identifier. + pattern: ^(\d+):(\d+)$|^(\d+):(\d+):(\d+)$ + type: string + type: object + type: array + listenPort: + description: ListenPort is the port where BGP protocol should listen. + Defaults to 179 + maximum: 65535 + minimum: 1 + type: integer + logSeverityScreen: + description: 'LogSeverityScreen is the log severity above which logs + are sent to the stdout. [Default: INFO]' + type: string + nodeToNodeMeshEnabled: + description: 'NodeToNodeMeshEnabled sets whether full node to node + BGP mesh is enabled. [Default: true]' + type: boolean + prefixAdvertisements: + description: PrefixAdvertisements contains per-prefix advertisement + configuration. + items: + description: PrefixAdvertisement configures advertisement properties + for the specified CIDR. + properties: + cidr: + description: CIDR for which properties should be advertised. + type: string + communities: + description: Communities can be list of either community names + already defined in `Specs.Communities` or community value + of format `aa:nn` or `aa:nn:mm`. For standard community use + `aa:nn` format, where `aa` and `nn` are 16 bit number. For + large community use `aa:nn:mm` format, where `aa`, `nn` and + `mm` are 32 bit number. Where,`aa` is an AS Number, `nn` and + `mm` are per-AS identifier. + items: + type: string + type: array + type: object + type: array + serviceClusterIPs: + description: ServiceClusterIPs are the CIDR blocks from which service + cluster IPs are allocated. If specified, Calico will advertise these + blocks, as well as any cluster IPs within them. + items: + description: ServiceClusterIPBlock represents a single allowed ClusterIP + CIDR block. + properties: + cidr: + type: string + type: object + type: array + serviceExternalIPs: + description: ServiceExternalIPs are the CIDR blocks for Kubernetes + Service External IPs. Kubernetes Service ExternalIPs will only be + advertised if they are within one of these blocks. + items: + description: ServiceExternalIPBlock represents a single allowed + External IP CIDR block. + properties: + cidr: + type: string + type: object + type: array + serviceLoadBalancerIPs: + description: ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes + Service LoadBalancer IPs. Kubernetes Service status.LoadBalancer.Ingress + IPs will only be advertised if they are within one of these blocks. + items: + description: ServiceLoadBalancerIPBlock represents a single allowed + LoadBalancer IP CIDR block. + properties: + cidr: + type: string + type: object + type: array + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: bgppeers.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: BGPPeer + listKind: BGPPeerList + plural: bgppeers + singular: bgppeer + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BGPPeerSpec contains the specification for a BGPPeer resource. + properties: + asNumber: + description: The AS Number of the peer. + format: int32 + type: integer + keepOriginalNextHop: + description: Option to keep the original nexthop field when routes + are sent to a BGP Peer. Setting "true" configures the selected BGP + Peers node to use the "next hop keep;" instead of "next hop self;"(default) + in the specific branch of the Node on "bird.cfg". + type: boolean + node: + description: The node name identifying the Calico node instance that + is targeted by this peer. If this is not set, and no nodeSelector + is specified, then this BGP peer selects all nodes in the cluster. + type: string + nodeSelector: + description: Selector for the nodes that should have this peering. When + this is set, the Node field must be empty. + type: string + password: + description: Optional BGP password for the peerings generated by this + BGPPeer resource. + properties: + secretKeyRef: + description: Selects a key of a secret in the node pod's namespace. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + type: object + peerIP: + description: The IP address of the peer followed by an optional port + number to peer with. If port number is given, format should be `[]:port` + or `:` for IPv4. If optional port number is not set, + and this peer IP and ASNumber belongs to a calico/node with ListenPort + set in BGPConfiguration, then we use that port to peer. + type: string + peerSelector: + description: Selector for the remote nodes to peer with. When this + is set, the PeerIP and ASNumber fields must be empty. For each + peering between the local node and selected remote nodes, we configure + an IPv4 peering if both ends have NodeBGPSpec.IPv4Address specified, + and an IPv6 peering if both ends have NodeBGPSpec.IPv6Address specified. The + remote AS number comes from the remote node's NodeBGPSpec.ASNumber, + or the global default if that is not set. + type: string + sourceAddress: + description: Specifies whether and how to configure a source address + for the peerings generated by this BGPPeer resource. Default value + "UseNodeIP" means to configure the node IP as the source address. "None" + means not to configure a source address. + type: string + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: blockaffinities.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: BlockAffinity + listKind: BlockAffinityList + plural: blockaffinities + singular: blockaffinity + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BlockAffinitySpec contains the specification for a BlockAffinity + resource. + properties: + cidr: + type: string + deleted: + description: Deleted indicates that this block affinity is being deleted. + This field is a string for compatibility with older releases that + mistakenly treat this field as a string. + type: string + node: + type: string + state: + type: string + required: + - cidr + - deleted + - node + - state + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusterinformations.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: ClusterInformation + listKind: ClusterInformationList + plural: clusterinformations + singular: clusterinformation + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ClusterInformation contains the cluster specific information. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ClusterInformationSpec contains the values of describing + the cluster. + properties: + calicoVersion: + description: CalicoVersion is the version of Calico that the cluster + is running + type: string + clusterGUID: + description: ClusterGUID is the GUID of the cluster + type: string + clusterType: + description: ClusterType describes the type of the cluster + type: string + datastoreReady: + description: DatastoreReady is used during significant datastore migrations + to signal to components such as Felix that it should wait before + accessing the datastore. + type: boolean + variant: + description: Variant declares which variant of Calico should be active. + type: string + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: felixconfigurations.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: FelixConfiguration + listKind: FelixConfigurationList + plural: felixconfigurations + singular: felixconfiguration + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Felix Configuration contains the configuration for Felix. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: FelixConfigurationSpec contains the values of the Felix configuration. + properties: + allowIPIPPacketsFromWorkloads: + description: 'AllowIPIPPacketsFromWorkloads controls whether Felix + will add a rule to drop IPIP encapsulated traffic from workloads + [Default: false]' + type: boolean + allowVXLANPacketsFromWorkloads: + description: 'AllowVXLANPacketsFromWorkloads controls whether Felix + will add a rule to drop VXLAN encapsulated traffic from workloads + [Default: false]' + type: boolean + awsSrcDstCheck: + description: 'Set source-destination-check on AWS EC2 instances. Accepted + value must be one of "DoNothing", "Enabled" or "Disabled". [Default: + DoNothing]' + enum: + - DoNothing + - Enable + - Disable + type: string + bpfConnectTimeLoadBalancingEnabled: + description: 'BPFConnectTimeLoadBalancingEnabled when in BPF mode, + controls whether Felix installs the connection-time load balancer. The + connect-time load balancer is required for the host to be able to + reach Kubernetes services and it improves the performance of pod-to-service + connections. The only reason to disable it is for debugging purposes. [Default: + true]' + type: boolean + bpfDataIfacePattern: + description: BPFDataIfacePattern is a regular expression that controls + which interfaces Felix should attach BPF programs to in order to + catch traffic to/from the network. This needs to match the interfaces + that Calico workload traffic flows over as well as any interfaces + that handle incoming traffic to nodeports and services from outside + the cluster. It should not match the workload interfaces (usually + named cali...). + type: string + bpfDisableUnprivileged: + description: 'BPFDisableUnprivileged, if enabled, Felix sets the kernel.unprivileged_bpf_disabled + sysctl to disable unprivileged use of BPF. This ensures that unprivileged + users cannot access Calico''s BPF maps and cannot insert their own + BPF programs to interfere with Calico''s. [Default: true]' + type: boolean + bpfEnabled: + description: 'BPFEnabled, if enabled Felix will use the BPF dataplane. + [Default: false]' + type: boolean + bpfExtToServiceConnmark: + description: 'BPFExtToServiceConnmark in BPF mode, control a 32bit + mark that is set on connections from an external client to a local + service. This mark allows us to control how packets of that connection + are routed within the host and how is routing intepreted by RPF + check. [Default: 0]' + type: integer + bpfExternalServiceMode: + description: 'BPFExternalServiceMode in BPF mode, controls how connections + from outside the cluster to services (node ports and cluster IPs) + are forwarded to remote workloads. If set to "Tunnel" then both + request and response traffic is tunneled to the remote node. If + set to "DSR", the request traffic is tunneled but the response traffic + is sent directly from the remote node. In "DSR" mode, the remote + node appears to use the IP of the ingress node; this requires a + permissive L2 network. [Default: Tunnel]' + type: string + bpfKubeProxyEndpointSlicesEnabled: + description: BPFKubeProxyEndpointSlicesEnabled in BPF mode, controls + whether Felix's embedded kube-proxy accepts EndpointSlices or not. + type: boolean + bpfKubeProxyIptablesCleanupEnabled: + description: 'BPFKubeProxyIptablesCleanupEnabled, if enabled in BPF + mode, Felix will proactively clean up the upstream Kubernetes kube-proxy''s + iptables chains. Should only be enabled if kube-proxy is not running. [Default: + true]' + type: boolean + bpfKubeProxyMinSyncPeriod: + description: 'BPFKubeProxyMinSyncPeriod, in BPF mode, controls the + minimum time between updates to the dataplane for Felix''s embedded + kube-proxy. Lower values give reduced set-up latency. Higher values + reduce Felix CPU usage by batching up more work. [Default: 1s]' + type: string + bpfLogLevel: + description: 'BPFLogLevel controls the log level of the BPF programs + when in BPF dataplane mode. One of "Off", "Info", or "Debug". The + logs are emitted to the BPF trace pipe, accessible with the command + `tc exec bpf debug`. [Default: Off].' + type: string + chainInsertMode: + description: 'ChainInsertMode controls whether Felix hooks the kernel''s + top-level iptables chains by inserting a rule at the top of the + chain or by appending a rule at the bottom. insert is the safe default + since it prevents Calico''s rules from being bypassed. If you switch + to append mode, be sure that the other rules in the chains signal + acceptance by falling through to the Calico rules, otherwise the + Calico policy will be bypassed. [Default: insert]' + type: string + dataplaneDriver: + type: string + debugDisableLogDropping: + type: boolean + debugMemoryProfilePath: + type: string + debugSimulateCalcGraphHangAfter: + type: string + debugSimulateDataplaneHangAfter: + type: string + defaultEndpointToHostAction: + description: 'DefaultEndpointToHostAction controls what happens to + traffic that goes from a workload endpoint to the host itself (after + the traffic hits the endpoint egress policy). By default Calico + blocks traffic from workload endpoints to the host itself with an + iptables "DROP" action. If you want to allow some or all traffic + from endpoint to host, set this parameter to RETURN or ACCEPT. Use + RETURN if you have your own rules in the iptables "INPUT" chain; + Calico will insert its rules at the top of that chain, then "RETURN" + packets to the "INPUT" chain once it has completed processing workload + endpoint egress policy. Use ACCEPT to unconditionally accept packets + from workloads after processing workload endpoint egress policy. + [Default: Drop]' + type: string + deviceRouteProtocol: + description: This defines the route protocol added to programmed device + routes, by default this will be RTPROT_BOOT when left blank. + type: integer + deviceRouteSourceAddress: + description: This is the source address to use on programmed device + routes. By default the source address is left blank, leaving the + kernel to choose the source address used. + type: string + disableConntrackInvalidCheck: + type: boolean + endpointReportingDelay: + type: string + endpointReportingEnabled: + type: boolean + externalNodesList: + description: ExternalNodesCIDRList is a list of CIDR's of external-non-calico-nodes + which may source tunnel traffic and have the tunneled traffic be + accepted at calico nodes. + items: + type: string + type: array + failsafeInboundHostPorts: + description: 'FailsafeInboundHostPorts is a list of UDP/TCP ports + and CIDRs that Felix will allow incoming traffic to host endpoints + on irrespective of the security policy. This is useful to avoid + accidentally cutting off a host with incorrect configuration. For + back-compatibility, if the protocol is not specified, it defaults + to "tcp". If a CIDR is not specified, it will allow traffic from + all addresses. To disable all inbound host ports, use the value + none. The default value allows ssh access and DHCP. [Default: tcp:22, + udp:68, tcp:179, tcp:2379, tcp:2380, tcp:6443, tcp:6666, tcp:6667]' + items: + description: ProtoPort is combination of protocol, port, and CIDR. + Protocol and port must be specified. + properties: + net: + type: string + port: + type: integer + protocol: + type: string + required: + - port + - protocol + type: object + type: array + failsafeOutboundHostPorts: + description: 'FailsafeOutboundHostPorts is a list of UDP/TCP ports + and CIDRs that Felix will allow outgoing traffic from host endpoints + to irrespective of the security policy. This is useful to avoid + accidentally cutting off a host with incorrect configuration. For + back-compatibility, if the protocol is not specified, it defaults + to "tcp". If a CIDR is not specified, it will allow traffic from + all addresses. To disable all outbound host ports, use the value + none. The default value opens etcd''s standard ports to ensure that + Felix does not get cut off from etcd as well as allowing DHCP and + DNS. [Default: tcp:179, tcp:2379, tcp:2380, tcp:6443, tcp:6666, + tcp:6667, udp:53, udp:67]' + items: + description: ProtoPort is combination of protocol, port, and CIDR. + Protocol and port must be specified. + properties: + net: + type: string + port: + type: integer + protocol: + type: string + required: + - port + - protocol + type: object + type: array + featureDetectOverride: + description: FeatureDetectOverride is used to override the feature + detection. Values are specified in a comma separated list with no + spaces, example; "SNATFullyRandom=true,MASQFullyRandom=false,RestoreSupportsLock=". + "true" or "false" will force the feature, empty or omitted values + are auto-detected. + type: string + genericXDPEnabled: + description: 'GenericXDPEnabled enables Generic XDP so network cards + that don''t support XDP offload or driver modes can use XDP. This + is not recommended since it doesn''t provide better performance + than iptables. [Default: false]' + type: boolean + healthEnabled: + type: boolean + healthHost: + type: string + healthPort: + type: integer + interfaceExclude: + description: 'InterfaceExclude is a comma-separated list of interfaces + that Felix should exclude when monitoring for host endpoints. The + default value ensures that Felix ignores Kubernetes'' IPVS dummy + interface, which is used internally by kube-proxy. If you want to + exclude multiple interface names using a single value, the list + supports regular expressions. For regular expressions you must wrap + the value with ''/''. For example having values ''/^kube/,veth1'' + will exclude all interfaces that begin with ''kube'' and also the + interface ''veth1''. [Default: kube-ipvs0]' + type: string + interfacePrefix: + description: 'InterfacePrefix is the interface name prefix that identifies + workload endpoints and so distinguishes them from host endpoint + interfaces. Note: in environments other than bare metal, the orchestrators + configure this appropriately. For example our Kubernetes and Docker + integrations set the ''cali'' value, and our OpenStack integration + sets the ''tap'' value. [Default: cali]' + type: string + interfaceRefreshInterval: + description: InterfaceRefreshInterval is the period at which Felix + rescans local interfaces to verify their state. The rescan can be + disabled by setting the interval to 0. + type: string + ipipEnabled: + type: boolean + ipipMTU: + description: 'IPIPMTU is the MTU to set on the tunnel device. See + Configuring MTU [Default: 1440]' + type: integer + ipsetsRefreshInterval: + description: 'IpsetsRefreshInterval is the period at which Felix re-checks + all iptables state to ensure that no other process has accidentally + broken Calico''s rules. Set to 0 to disable iptables refresh. [Default: + 90s]' + type: string + iptablesBackend: + description: IptablesBackend specifies which backend of iptables will + be used. The default is legacy. + type: string + iptablesFilterAllowAction: + type: string + iptablesLockFilePath: + description: 'IptablesLockFilePath is the location of the iptables + lock file. You may need to change this if the lock file is not in + its standard location (for example if you have mapped it into Felix''s + container at a different path). [Default: /run/xtables.lock]' + type: string + iptablesLockProbeInterval: + description: 'IptablesLockProbeInterval is the time that Felix will + wait between attempts to acquire the iptables lock if it is not + available. Lower values make Felix more responsive when the lock + is contended, but use more CPU. [Default: 50ms]' + type: string + iptablesLockTimeout: + description: 'IptablesLockTimeout is the time that Felix will wait + for the iptables lock, or 0, to disable. To use this feature, Felix + must share the iptables lock file with all other processes that + also take the lock. When running Felix inside a container, this + requires the /run directory of the host to be mounted into the calico/node + or calico/felix container. [Default: 0s disabled]' + type: string + iptablesMangleAllowAction: + type: string + iptablesMarkMask: + description: 'IptablesMarkMask is the mask that Felix selects its + IPTables Mark bits from. Should be a 32 bit hexadecimal number with + at least 8 bits set, none of which clash with any other mark bits + in use on the system. [Default: 0xff000000]' + format: int32 + type: integer + iptablesNATOutgoingInterfaceFilter: + type: string + iptablesPostWriteCheckInterval: + description: 'IptablesPostWriteCheckInterval is the period after Felix + has done a write to the dataplane that it schedules an extra read + back in order to check the write was not clobbered by another process. + This should only occur if another application on the system doesn''t + respect the iptables lock. [Default: 1s]' + type: string + iptablesRefreshInterval: + description: 'IptablesRefreshInterval is the period at which Felix + re-checks the IP sets in the dataplane to ensure that no other process + has accidentally broken Calico''s rules. Set to 0 to disable IP + sets refresh. Note: the default for this value is lower than the + other refresh intervals as a workaround for a Linux kernel bug that + was fixed in kernel version 4.11. If you are using v4.11 or greater + you may want to set this to, a higher value to reduce Felix CPU + usage. [Default: 10s]' + type: string + ipv6Support: + type: boolean + kubeNodePortRanges: + description: 'KubeNodePortRanges holds list of port ranges used for + service node ports. Only used if felix detects kube-proxy running + in ipvs mode. Felix uses these ranges to separate host and workload + traffic. [Default: 30000:32767].' + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + logFilePath: + description: 'LogFilePath is the full path to the Felix log. Set to + none to disable file logging. [Default: /var/log/calico/felix.log]' + type: string + logPrefix: + description: 'LogPrefix is the log prefix that Felix uses when rendering + LOG rules. [Default: calico-packet]' + type: string + logSeverityFile: + description: 'LogSeverityFile is the log severity above which logs + are sent to the log file. [Default: Info]' + type: string + logSeverityScreen: + description: 'LogSeverityScreen is the log severity above which logs + are sent to the stdout. [Default: Info]' + type: string + logSeveritySys: + description: 'LogSeveritySys is the log severity above which logs + are sent to the syslog. Set to None for no logging to syslog. [Default: + Info]' + type: string + maxIpsetSize: + type: integer + metadataAddr: + description: 'MetadataAddr is the IP address or domain name of the + server that can answer VM queries for cloud-init metadata. In OpenStack, + this corresponds to the machine running nova-api (or in Ubuntu, + nova-api-metadata). A value of none (case insensitive) means that + Felix should not set up any NAT rule for the metadata path. [Default: + 127.0.0.1]' + type: string + metadataPort: + description: 'MetadataPort is the port of the metadata server. This, + combined with global.MetadataAddr (if not ''None''), is used to + set up a NAT rule, from 169.254.169.254:80 to MetadataAddr:MetadataPort. + In most cases this should not need to be changed [Default: 8775].' + type: integer + mtuIfacePattern: + description: MTUIfacePattern is a regular expression that controls + which interfaces Felix should scan in order to calculate the host's + MTU. This should not match workload interfaces (usually named cali...). + type: string + natOutgoingAddress: + description: NATOutgoingAddress specifies an address to use when performing + source NAT for traffic in a natOutgoing pool that is leaving the + network. By default the address used is an address on the interface + the traffic is leaving on (ie it uses the iptables MASQUERADE target) + type: string + natPortRange: + anyOf: + - type: integer + - type: string + description: NATPortRange specifies the range of ports that is used + for port mapping when doing outgoing NAT. When unset the default + behavior of the network stack is used. + pattern: ^.* + x-kubernetes-int-or-string: true + netlinkTimeout: + type: string + openstackRegion: + description: 'OpenstackRegion is the name of the region that a particular + Felix belongs to. In a multi-region Calico/OpenStack deployment, + this must be configured somehow for each Felix (here in the datamodel, + or in felix.cfg or the environment on each compute node), and must + match the [calico] openstack_region value configured in neutron.conf + on each node. [Default: Empty]' + type: string + policySyncPathPrefix: + description: 'PolicySyncPathPrefix is used to by Felix to communicate + policy changes to external services, like Application layer policy. + [Default: Empty]' + type: string + prometheusGoMetricsEnabled: + description: 'PrometheusGoMetricsEnabled disables Go runtime metrics + collection, which the Prometheus client does by default, when set + to false. This reduces the number of metrics reported, reducing + Prometheus load. [Default: true]' + type: boolean + prometheusMetricsEnabled: + description: 'PrometheusMetricsEnabled enables the Prometheus metrics + server in Felix if set to true. [Default: false]' + type: boolean + prometheusMetricsHost: + description: 'PrometheusMetricsHost is the host that the Prometheus + metrics server should bind to. [Default: empty]' + type: string + prometheusMetricsPort: + description: 'PrometheusMetricsPort is the TCP port that the Prometheus + metrics server should bind to. [Default: 9091]' + type: integer + prometheusProcessMetricsEnabled: + description: 'PrometheusProcessMetricsEnabled disables process metrics + collection, which the Prometheus client does by default, when set + to false. This reduces the number of metrics reported, reducing + Prometheus load. [Default: true]' + type: boolean + removeExternalRoutes: + description: Whether or not to remove device routes that have not + been programmed by Felix. Disabling this will allow external applications + to also add device routes. This is enabled by default which means + we will remove externally added routes. + type: boolean + reportingInterval: + description: 'ReportingInterval is the interval at which Felix reports + its status into the datastore or 0 to disable. Must be non-zero + in OpenStack deployments. [Default: 30s]' + type: string + reportingTTL: + description: 'ReportingTTL is the time-to-live setting for process-wide + status reports. [Default: 90s]' + type: string + routeRefreshInterval: + description: 'RouteRefreshInterval is the period at which Felix re-checks + the routes in the dataplane to ensure that no other process has + accidentally broken Calico''s rules. Set to 0 to disable route refresh. + [Default: 90s]' + type: string + routeSource: + description: 'RouteSource configures where Felix gets its routing + information. - WorkloadIPs: use workload endpoints to construct + routes. - CalicoIPAM: the default - use IPAM data to construct routes.' + type: string + routeTableRange: + description: Calico programs additional Linux route tables for various + purposes. RouteTableRange specifies the indices of the route tables + that Calico should use. + properties: + max: + type: integer + min: + type: integer + required: + - max + - min + type: object + serviceLoopPrevention: + description: 'When service IP advertisement is enabled, prevent routing + loops to service IPs that are not in use, by dropping or rejecting + packets that do not get DNAT''d by kube-proxy. Unless set to "Disabled", + in which case such routing loops continue to be allowed. [Default: + Drop]' + type: string + sidecarAccelerationEnabled: + description: 'SidecarAccelerationEnabled enables experimental sidecar + acceleration [Default: false]' + type: boolean + usageReportingEnabled: + description: 'UsageReportingEnabled reports anonymous Calico version + number and cluster size to projectcalico.org. Logs warnings returned + by the usage server. For example, if a significant security vulnerability + has been discovered in the version of Calico being used. [Default: + true]' + type: boolean + usageReportingInitialDelay: + description: 'UsageReportingInitialDelay controls the minimum delay + before Felix makes a report. [Default: 300s]' + type: string + usageReportingInterval: + description: 'UsageReportingInterval controls the interval at which + Felix makes reports. [Default: 86400s]' + type: string + useInternalDataplaneDriver: + type: boolean + vxlanEnabled: + type: boolean + vxlanMTU: + description: 'VXLANMTU is the MTU to set on the tunnel device. See + Configuring MTU [Default: 1440]' + type: integer + vxlanPort: + type: integer + vxlanVNI: + type: integer + wireguardEnabled: + description: 'WireguardEnabled controls whether Wireguard is enabled. + [Default: false]' + type: boolean + wireguardInterfaceName: + description: 'WireguardInterfaceName specifies the name to use for + the Wireguard interface. [Default: wg.calico]' + type: string + wireguardListeningPort: + description: 'WireguardListeningPort controls the listening port used + by Wireguard. [Default: 51820]' + type: integer + wireguardMTU: + description: 'WireguardMTU controls the MTU on the Wireguard interface. + See Configuring MTU [Default: 1420]' + type: integer + wireguardRoutingRulePriority: + description: 'WireguardRoutingRulePriority controls the priority value + to use for the Wireguard routing rule. [Default: 99]' + type: integer + xdpEnabled: + description: 'XDPEnabled enables XDP acceleration for suitable untracked + incoming deny rules. [Default: true]' + type: boolean + xdpRefreshInterval: + description: 'XDPRefreshInterval is the period at which Felix re-checks + all XDP state to ensure that no other process has accidentally broken + Calico''s BPF maps or attached programs. Set to 0 to disable XDP + refresh. [Default: 90s]' + type: string + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: globalnetworkpolicies.crd.projectcalico.org +spec: + group: crd.projectcalico.org + names: + kind: GlobalNetworkPolicy + listKind: GlobalNetworkPolicyList + plural: globalnetworkpolicies + singular: globalnetworkpolicy + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + applyOnForward: + description: ApplyOnForward indicates to apply the rules in this policy + on forward traffic. + type: boolean + doNotTrack: + description: DoNotTrack indicates whether packets matched by the rules + in this policy should go through the data plane's connection tracking, + such as Linux conntrack. If True, the rules in this policy are + applied before any data plane connection tracking, and packets allowed + by this policy are marked as not to be tracked. + type: boolean + egress: + description: The ordered set of egress rules. Each rule contains + a set of packet match criteria and a corresponding action to apply. + items: + description: "A Rule encapsulates a set of match criteria and an + action. Both selector-based security Policy and security Profiles + reference rules - separated out as a list of rules for both ingress + and egress packet matching. \n Each positive match criteria has + a negated version, prefixed with \"Not\". All the match criteria + within a rule must be satisfied for a packet to match. A single + rule can contain the positive and negative version of a match + and both must be satisfied for the rule to match." + properties: + action: + type: string + destination: + description: Destination contains the match criteria that apply + to destination entity. + properties: + namespaceSelector: + description: "NamespaceSelector is an optional field that + contains a selector expression. Only traffic that originates + from (or terminates at) endpoints within the selected + namespaces will be matched. When both NamespaceSelector + and Selector are defined on the same rule, then only workload + endpoints that are matched by both selectors will be selected + by the rule. \n For NetworkPolicy, an empty NamespaceSelector + implies that the Selector is limited to selecting only + workload endpoints in the same namespace as the NetworkPolicy. + \n For NetworkPolicy, `global()` NamespaceSelector implies + that the Selector is limited to selecting only GlobalNetworkSet + or HostEndpoint. \n For GlobalNetworkPolicy, an empty + NamespaceSelector implies the Selector applies to workload + endpoints across all namespaces." + type: string + nets: + description: Nets is an optional field that restricts the + rule to only apply to traffic that originates from (or + terminates at) IP addresses in any of the given subnets. + items: + type: string + type: array + notNets: + description: NotNets is the negated version of the Nets + field. + items: + type: string + type: array + notPorts: + description: NotPorts is the negated version of the Ports + field. Since only some protocols have ports, if any ports + are specified it requires the Protocol match in the Rule + to be set to "TCP" or "UDP". + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + notSelector: + description: NotSelector is the negated version of the Selector + field. See Selector field for subtleties with negated + selectors. + type: string + ports: + description: "Ports is an optional field that restricts + the rule to only apply to traffic that has a source (destination) + port that matches one of these ranges/values. This value + is a list of integers or strings that represent ranges + of ports. \n Since only some protocols have ports, if + any ports are specified it requires the Protocol match + in the Rule to be set to \"TCP\" or \"UDP\"." + items: + anyOf: + - type: integer + - type: string + pattern: ^.* + x-kubernetes-int-or-string: true + type: array + selector: + description: "Selector is an optional field that contains + a selector expression (see Policy for sample syntax). + \ Only traffic that originates from (terminates at) endpoints + matching the selector will be matched. \n Note that: in + addition to the negated version of the Selector (see NotSelector + below), the selector expression syntax itself supports + negation. The two types of negation are subtly different. + One negates the set of matched endpoints, the other negates + the whole match: \n \tSelector = \"!has(my_label)\" matches + packets that are from other Calico-controlled \tendpoints + that do not have the label \"my_label\". \n \tNotSelector + = \"has(my_label)\" matches packets that are not from + Calico-controlled \tendpoints that do have the label \"my_label\". + \n The effect is that the latter will accept packets from + non-Calico sources whereas the former is limited to packets + from Calico-controlled endpoints." + type: string + serviceAccounts: + description: ServiceAccounts is an optional field that restricts + the rule to only apply to traffic that originates from + (or terminates at) a pod running as a matching service + account. + properties: + names: + description: Names is an optional field that restricts + the rule to only apply to traffic that originates + from (or terminates at) a pod running as a service + account whose name is in the list. + items: + type: string + type: array + selector: + description: Selector is an optional field that restricts + the rule to only apply to traffic that originates + from (or terminates at) a pod running as a service + account that matches the given label selector. If + both Names and Selector are specified then they are + AND'ed. + type: string + type: object + type: object + http: + description: HTTP contains match criteria that apply to HTTP + requests. + properties: + methods: + description: Methods is an optional field that restricts + the rule to apply only to HTTP requests that use one of + the listed HTTP Methods (e.g. GET, PUT, etc.) Multiple + methods are OR'd together. + items: + type: string + type: array + paths: + description: 'Paths is an optional field that restricts + the rule to apply to HTTP requests that use one of the + listed HTTP Paths. Multiple paths are OR''d together. + e.g: - exact: /foo - prefix: /bar NOTE: Each entry may + ONLY specify either a `exact` or a `prefix` match. The + validator will check for it.' + items: + description: 'HTTPPath specifies an HTTP path to match. + It may be either of the form: exact: : which matches + the path exactly or prefix: : which matches + the path prefix' + properties: + exact: + type: string + prefix: + type: string + type: object + type: array + type: object + icmp: + description: ICMP is an optional field that restricts the rule + to apply to a specific type and code of ICMP traffic. This + should only be specified if the Protocol field is set to "ICMP" + or "ICMPv6". + properties: + code: + description: Match on a specific ICMP code. If specified, + the Type value must also be specified. This is a technical + limitation imposed by the kernel's iptables firewall, + which Calico uses to enforce the rule. + type: integer + type: + description: Match on a specific ICMP type. For example + a value of 8``` diff --git a/resources/k8s/metrics-server.yaml b/resources/k8s/metrics-server.yaml new file mode 100644 index 0000000..55db4d1 --- /dev/null +++ b/resources/k8s/metrics-server.yaml @@ -0,0 +1,197 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: system:aggregated-metrics-reader +rules: +- apiGroups: + - metrics.k8s.io + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +rules: +- apiGroups: + - "" + resources: + - nodes/metrics + verbs: + - get +- apiGroups: + - "" + resources: + - pods + - nodes + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: metrics-server:system:auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + k8s-app: metrics-server + name: system:metrics-server +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:metrics-server +subjects: +- kind: ServiceAccount + name: metrics-server + namespace: kube-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: https + selector: + k8s-app: metrics-server +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + k8s-app: metrics-server + name: metrics-server + namespace: kube-system +spec: + selector: + matchLabels: + k8s-app: metrics-server + strategy: + rollingUpdate: + maxUnavailable: 0 + template: + metadata: + labels: + k8s-app: metrics-server + spec: + containers: + - args: + - --cert-dir=/tmp + - --secure-port=4443 + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --kubelet-insecure-tls + image: registry.cn-hangzhou.aliyuncs.com/chenby/metrics-server:v0.6.2 + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + path: /livez + port: https + scheme: HTTPS + periodSeconds: 10 + name: metrics-server + ports: + - containerPort: 4443 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: https + scheme: HTTPS + initialDelaySeconds: 20 + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + volumeMounts: + - mountPath: /tmp + name: tmp-dir + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + serviceAccountName: metrics-server + volumes: + - emptyDir: {} + name: tmp-dir +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + labels: + k8s-app: metrics-server + name: v1beta1.metrics.k8s.io +spec: + group: metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: metrics-server + namespace: kube-system + version: v1beta1 + versionPriority: 100 diff --git a/resources/openapi/ai-isuanova-openapi.md b/resources/openapi/ai-isuanova-openapi.md new file mode 100644 index 0000000..64f53d2 --- /dev/null +++ b/resources/openapi/ai-isuanova-openapi.md @@ -0,0 +1,45953 @@ +--- +title: suanfeng +language_tabs: + - shell: Shell + - http: HTTP + - javascript: JavaScript + - ruby: Ruby + - python: Python + - php: PHP + - java: Java + - go: Go +toc_footers: [] +includes: [] +search: true +code_clipboard: true +highlight_theme: darkula +headingLevel: 2 +generator: "@tarslib/widdershins v4.0.23" + +--- + +# OpenAPI User Manual + +# OpenAPI Authentication + +Access Key can be used to access the open API and continuous publishing. Users can obtain the key and access the API by following the steps in their personal center. + +## Get the key + +Log in to the AI computing power platform, find the __Personal Center__ in the dropdown menu in the upper right corner, and you can manage the account's access keys on the __Access Keys__ page. + +![image](https://sophongo.github.io/sophdoc/images/platform02_1.png) + +![image](https://sophongo.github.io/sophdoc/images/platform03_1.png) + + +## Accessing the API with Keys + +When accessing the Suifeng AI computing power platform openAPI, add the request header `Authorization:Bearer ${token}` to identify the visitor's identity, + +where `${token}` is the key obtained in the previous step. + +**Request Example** + +```bash +curl -X GET -H 'Authorization:Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkRKVjlBTHRBLXZ4MmtQUC1TQnVGS0dCSWc1cnBfdkxiQVVqM2U3RVByWnMiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjE0MTU5NjksImlhdCI6MTY2MDgxMTE2OSwiaXNzIjoiZ2hpcHBvLmlvIiwic3ViIjoiZjdjOGIxZjUtMTc2MS00NjYwLTg2MWQtOWI3MmI0MzJmNGViIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4iLCJncm91cHMiOltdfQ.RsUcrAYkQQ7C6BxMOrdD3qbBRUt0VVxynIGeq4wyIgye6R8Ma4cjxG5CbU1WyiHKpvIKJDJbeFQHro2euQyVde3ygA672ozkwLTnx3Tu-_mB1BubvWCBsDdUjIhCQfT39rk6EQozMjb-1X1sbLwzkfzKMls-oxkjagI_RFrYlTVPwT3Oaw-qOyulRSw7Dxd7jb0vINPq84vmlQIsI3UuTZSNO5BCgHpubcWwBss-Aon_DmYA-Et_-QtmPBA3k8E2hzDSzc7eqK0I68P25r9rwQ3DeKwD1dbRyndqWORRnz8TLEXSiCFXdZT2oiMrcJtO188Ph4eLGut1-4PzKhwgrQ' https://demo-dev.daocloud.io/apis/ghippo.io/v1alpha1/users?page=1&pageSize=10 -k +``` + +**Request Result** + +```json +{ + "items": [ + { + "id": "a7cfd010-ebbe-4601-987f-d098d9ef766e", + "name": "a", + "email": "", + "description": "", + "firstname": "", + "lastname": "", + "source": "locale", + "enabled": true, + "createdAt": "1660632794800", + "updatedAt": "0", + "lastLoginAt": "" + } + ], + "pagination": { + "page": 1, + "pageSize": 10, + "total": 1 + } +} +``` + +--- + +# OpenAPI Document Details + +Base URLs: + +# Authentication + +# Insight/Insight + + + +## POST Insight_GetHelmInstallConfig + +POST /apis/insight.io/v1alpha1/agentinstallparam + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Insight_GetGlobalConfig + +GET /apis/insight.io/v1alpha1/config + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Insight_GetUserinfo + +GET /apis/insight.io/v1alpha1/userinfo + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Insight_GetVersion + +GET /apis/insight.io/v1alpha1/version + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Alert + + + +## GET Alert_CountAlert + +GET /apis/insight.io/v1alpha1/alert/alertcount + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|resolved|query|boolean| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| +|targetType|query|string| no |none| +|target|query|string| no |none| +|severity|query|string| no |none| +|start|query|string(int64)| no |start == 0 means from 1970.01.01| +|end|query|string(int64)| no |none| +|step|query|string(int64)| no |step unit is minute| +|groupByType|query|boolean| no |none| + +#### Description + +**step**: step unit is minute +step == 0 means return total alert count num + +#### Enum + +|Name|Value| +|---|---| +|targetType|TARGET_TYPE_UNSPECIFIED| +|targetType|GLOBAL| +|targetType|CLUSTER| +|targetType|NAMESPACE| +|targetType|NODE| +|targetType|DEPLOYMENT| +|targetType|STATEFULSET| +|targetType|DAEMONSET| +|targetType|POD| +|severity|SEVERITY_UNSPECIFIED| +|severity|CRITICAL| +|severity|WARNING| +|severity|INFO| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListAlerts + +GET /apis/insight.io/v1alpha1/alert/alerts + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|resolved|query|boolean| no |set resolved to True shows alert histories| +|groupName|query|string| no |filter alerts by group name fuzzily| +|groupId|query|string| no |filter alerts by group id| +|ruleName|query|string| no |filter alerts by rule name fuzzily| +|ruleId|query|string| no |filter alerts by rule id| +|clusterName|query|string| no |filter alerts by cluster name| +|namespace|query|string| no |filter alerts by namespace| +|severity|query|string| no |filter alerts by severity| +|targetType|query|string| no |filter alerts by target_type| +|target|query|string| no |filter alerts by target| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- start_at,desc or start_at +- start_at,asc +- severity,desc or severity +- severity,asc +- rule_name,desc or rule_name +- rule_name,asc + +the default sort is start_at,desc + +#### Enum + +|Name|Value| +|---|---| +|severity|SEVERITY_UNSPECIFIED| +|severity|CRITICAL| +|severity|WARNING| +|severity|INFO| +|targetType|TARGET_TYPE_UNSPECIFIED| +|targetType|GLOBAL| +|targetType|CLUSTER| +|targetType|NAMESPACE| +|targetType|NODE| +|targetType|DEPLOYMENT| +|targetType|STATEFULSET| +|targetType|DAEMONSET| +|targetType|POD| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetAlert + +GET /apis/insight.io/v1alpha1/alert/alerts/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string(int64)| yes |none| +|resolved|query|boolean| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListGroups + +GET /apis/insight.io/v1alpha1/alert/groups + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|builtin|query|boolean| no |none| +|name|query|string| no |filter group by name| +|clusterName|query|string| no |filter alerts by cluster name| +|namespace|query|string| no |filter alerts by namespace| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- name,desc or name +- name,asc +- create_at,desc or create_at +- create_at,asc + +the default sort is name,asc + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateGroup + +POST /apis/insight.io/v1alpha1/alert/groups + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_ValidateGroup + +POST /apis/insight.io/v1alpha1/alert/groups/validate + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetGroup + +GET /apis/insight.io/v1alpha1/alert/groups/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateGroup only can update group description and notify + +PUT /apis/insight.io/v1alpha1/alert/groups/{id} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteGroup + +DELETE /apis/insight.io/v1alpha1/alert/groups/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListGroupRules + +GET /apis/insight.io/v1alpha1/alert/groups/{id}/rules + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| +|name|query|string| no |filter rule by name| +|severity|query|string| no |filter rules by severity| +|status|query|string| no |filter rules by status| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- name,desc or name +- rule_name,asc +- severity,desc or severity +- severity,asc +- status,desc or status +- status,asc +- source,desc or source +- source,asc +- create_at,desc or create_at +- create_at,asc + +the default sort is name,asc + +#### Enum + +|Name|Value| +|---|---| +|severity|SEVERITY_UNSPECIFIED| +|severity|CRITICAL| +|severity|WARNING| +|severity|INFO| +|status|UNSPECIFIED| +|status|FIRING| +|status|ENABLED| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_AddGroupRule + +POST /apis/insight.io/v1alpha1/alert/groups/{id}/rules + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |required;| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetGroupRule + +GET /apis/insight.io/v1alpha1/alert/groups/{id}/rules/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |required; id is group id| +|name|path|string| yes |required; name is rule name| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateGroupRule + +PUT /apis/insight.io/v1alpha1/alert/groups/{id}/rules/{name} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |required; id is group id| +|name|path|string| yes |required;| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteGroupRule + +DELETE /apis/insight.io/v1alpha1/alert/groups/{id}/rules/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |required; id is group id| +|name|path|string| yes |required; name is rule name| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_CleanAlertHistory + +PUT /apis/insight.io/v1alpha1/alert/history/clean + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetAlertHistoryRetentionPeriod + +GET /apis/insight.io/v1alpha1/alert/history/retentionperiod + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateAlertHistoryRetentionPeriod + +PUT /apis/insight.io/v1alpha1/alert/history/retentionperiod + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_AlertHook + +POST /apis/insight.io/v1alpha1/alert/hook + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Inhibition + +GET /apis/insight.io/v1alpha1/alert/inhibitions + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- name,desc or name +- name,asc +- create_at,desc or create_at +- create_at,asc + +the default sort is name,asc + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateInhibition + +POST /apis/insight.io/v1alpha1/alert/inhibitions + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetInhibition + +GET /apis/insight.io/v1alpha1/alert/inhibitions/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateInhibition + +PUT /apis/insight.io/v1alpha1/alert/inhibitions/{id} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteInhibition + +DELETE /apis/insight.io/v1alpha1/alert/inhibitions/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListProviders + +GET /apis/insight.io/v1alpha1/alert/providers + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|query|string| no |filter template by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| +|exactSearch|query|boolean| no |exact search by name| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- update_at,desc or update_at +- update_at,asc + +the default sort is update_at,desc + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateProvider + +POST /apis/insight.io/v1alpha1/alert/providers + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetProvider + +GET /apis/insight.io/v1alpha1/alert/providers/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |ProviderType type = 2 [ (validate.rules).enum.defined_only = true ];| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateProvider + +PUT /apis/insight.io/v1alpha1/alert/providers/{name} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteProvider + +DELETE /apis/insight.io/v1alpha1/alert/providers/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |ProviderType type = 2 [ (validate.rules).enum.defined_only = true ];| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListReceivers + +GET /apis/insight.io/v1alpha1/alert/receivers + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|query|string| no |none| +|type|query|string| no |filter receivers by type| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| +|exactSearch|query|boolean| no |exact search by name| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- create_at,desc or create_at +- create_at,asc + +the default sort is create_at,desc + +#### Enum + +|Name|Value| +|---|---| +|type|RECEIVER_TYPE_UNSPECIFIED| +|type|webhook| +|type|email| +|type|dingtalk| +|type|wecom| +|type|sms| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateReceiver + +POST /apis/insight.io/v1alpha1/alert/receivers + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_TestReceiver + +POST /apis/insight.io/v1alpha1/alert/receivers/test + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetReceiver + +GET /apis/insight.io/v1alpha1/alert/receivers/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| +|type|query|string| no |none| + +#### Enum + +|Name|Value| +|---|---| +|type|RECEIVER_TYPE_UNSPECIFIED| +|type|webhook| +|type|email| +|type|dingtalk| +|type|wecom| +|type|sms| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateReceiver + +PUT /apis/insight.io/v1alpha1/alert/receivers/{name} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteReceiver + +DELETE /apis/insight.io/v1alpha1/alert/receivers/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET RuleTemplate + +GET /apis/insight.io/v1alpha1/alert/rule-template-summary + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|targetType|query|string| no |filter by target type| + +#### Enum + +|Name|Value| +|---|---| +|targetType|TARGET_TYPE_UNSPECIFIED| +|targetType|GLOBAL| +|targetType|CLUSTER| +|targetType|NAMESPACE| +|targetType|NODE| +|targetType|DEPLOYMENT| +|targetType|STATEFULSET| +|targetType|DAEMONSET| +|targetType|POD| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListRuleTemplates + +GET /apis/insight.io/v1alpha1/alert/rule-templates + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|builtin|query|boolean| no |none| +|name|query|string| no |filter group by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| +|targetType|query|string| no |filter by target type| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- name,desc or name +- name,asc +- create_at,desc or create_at +- create_at,asc +- update_at,desc or update_at +- update_at,asc + +the default sort is name,asc + +#### Enum + +|Name|Value| +|---|---| +|targetType|TARGET_TYPE_UNSPECIFIED| +|targetType|GLOBAL| +|targetType|CLUSTER| +|targetType|NAMESPACE| +|targetType|NODE| +|targetType|DEPLOYMENT| +|targetType|STATEFULSET| +|targetType|DAEMONSET| +|targetType|POD| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateRuleTemplate + +POST /apis/insight.io/v1alpha1/alert/rule-templates + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetRuleTemplate + +GET /apis/insight.io/v1alpha1/alert/rule-templates/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateRuleTemplate + +PUT /apis/insight.io/v1alpha1/alert/rule-templates/{id} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteRuleTemplate + +DELETE /apis/insight.io/v1alpha1/alert/rule-templates/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_PreviewRule + +POST /apis/insight.io/v1alpha1/alert/rules/preview + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListSilences + +GET /apis/insight.io/v1alpha1/alert/silences + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|expired|query|boolean| no |set "expired" to false show silences that vaild for now, otherwise show| +|name|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| + +#### Description + +**expired**: set "expired" to false show silences that vaild for now, otherwise show +expired silences + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateSilence + +POST /apis/insight.io/v1alpha1/alert/silences + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_PreviewSilence + +POST /apis/insight.io/v1alpha1/alert/silences/preview + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetSilence + +GET /apis/insight.io/v1alpha1/alert/silences/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateSilence + +PUT /apis/insight.io/v1alpha1/alert/silences/{id} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteSilence + +DELETE /apis/insight.io/v1alpha1/alert/silences/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetSMTPStatus + +GET /apis/insight.io/v1alpha1/alert/smtp + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_ListTemplates + +GET /apis/insight.io/v1alpha1/alert/templates + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|query|string| no |filter template by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|array[string]| no |sorts determines the data list order, support multiple sort option.| +|exactSearch|query|boolean| no |exact search by name| + +#### Description + +**sorts**: sorts determines the data list order, support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- update_at,desc or update_at +- update_at,asc + +the default sort is update_at,desc + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Alert_CreateTemplate + +POST /apis/insight.io/v1alpha1/alert/templates + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Alert_GetTemplate + +GET /apis/insight.io/v1alpha1/alert/templates/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT Alert_UpdateTemplate + +PUT /apis/insight.io/v1alpha1/alert/templates/{name} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Alert_DeleteTemplate + +DELETE /apis/insight.io/v1alpha1/alert/templates/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Resource + + + +## GET Resource_ListClusters + +GET /apis/insight.io/v1alpha1/clusters + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|showAllCluster|query|boolean| no |show_all_cluster default is false, will only return cluster with| + +#### Description + +**showAllCluster**: show_all_cluster default is false, will only return cluster with +insight-agent installed; if set to true, will return all cluster. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetAgentSummary + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/agent + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |use cluster_name| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListCronjobs + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/cronjobs + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter jobs by cluster| +|namespace|query|string| no |filter jobs by namespace| +|phase|query|string| no |filter jobs by phase| +|name|query|string| no |filter jobs by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Description + +**phase**: filter jobs by phase + + - JOB_STATE_UNSPECIFIED: Job is unspecified. + - JOB_STATE_WAITING: Waiting for job ready. + - JOB_STATE_RUNNING: Job is working. + - JOB_STATE_COMPLETED: Jobs has completed. + - JOB_STATE_DELETING: Jobs is being deleted. + - JOB_STATE_FAILED: Jobs is not ready to work . + +#### Enum + +|Name|Value| +|---|---| +|phase|JOB_STATE_UNSPECIFIED| +|phase|JOB_STATE_WAITING| +|phase|JOB_STATE_RUNNING| +|phase|JOB_STATE_COMPLETED| +|phase|JOB_STATE_DELETING| +|phase|JOB_STATE_FAILED| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListDaemonsets + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/daemonsets + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter workloads by cluster| +|namespace|query|string| no |filter workloads by namespace| +|name|query|string| no |filter workloads by name| +|phase|query|string| no |filter workloads by phase| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNKNOWN| +|phase|WORKLOAD_STATE_RUNNING| +|phase|WORKLOAD_STATE_DELETING| +|phase|WORKLOAD_STATE_NOT_READY| +|phase|WORKLOAD_STATE_STOPPED| +|phase|WORKLOAD_STATE_WAITING| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListDeployments + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/deployments + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter workloads by cluster| +|namespace|query|string| no |filter workloads by namespace| +|name|query|string| no |filter workloads by name| +|phase|query|string| no |filter workloads by phase| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNKNOWN| +|phase|WORKLOAD_STATE_RUNNING| +|phase|WORKLOAD_STATE_DELETING| +|phase|WORKLOAD_STATE_NOT_READY| +|phase|WORKLOAD_STATE_STOPPED| +|phase|WORKLOAD_STATE_WAITING| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListJobs + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/jobs + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter jobs by cluster| +|namespace|query|string| no |filter jobs by namespace| +|phase|query|string| no |filter jobs by phase| +|name|query|string| no |filter jobs by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Description + +**phase**: filter jobs by phase + + - JOB_STATE_UNSPECIFIED: Job is unspecified. + - JOB_STATE_WAITING: Waiting for job ready. + - JOB_STATE_RUNNING: Job is working. + - JOB_STATE_COMPLETED: Jobs has completed. + - JOB_STATE_DELETING: Jobs is being deleted. + - JOB_STATE_FAILED: Jobs is not ready to work . + +#### Enum + +|Name|Value| +|---|---| +|phase|JOB_STATE_UNSPECIFIED| +|phase|JOB_STATE_WAITING| +|phase|JOB_STATE_RUNNING| +|phase|JOB_STATE_COMPLETED| +|phase|JOB_STATE_DELETING| +|phase|JOB_STATE_FAILED| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListNamespaces + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetCronjob + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetCronjobPods + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}/pods + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetDaemonset + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetDaemonsetPods + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}/pods + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetDeployment + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetDeploymentPods + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}/pods + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetJob + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetJobPods + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name}/pods + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetPod + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListPodContainers + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}/containers + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter nodes by cluster| +|namespace|path|string| yes |filter nodes by namespace| +|name|path|string| yes |filter containers by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetService + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetStatefulset + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetStatefulsetPods + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}/pods + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|namespace|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetNamespace + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/namespaces/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListNodes + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/nodes + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter nodes by cluster| +|phase|query|string| no |filter nodes by phase| +|name|query|string| no |filter nodes by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Description + +**phase**: filter nodes by phase + + - NODE_PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - NODE_PHASE_READY: The node is ready to work. + - NODE_PHASE_NOT_READY: The node is not ready. + - NODE_PHASE_UNKNOWN: The node state is unknown. + +#### Enum + +|Name|Value| +|---|---| +|phase|NODE_PHASE_UNSPECIFIED| +|phase|NODE_PHASE_READY| +|phase|NODE_PHASE_NOT_READY| +|phase|NODE_PHASE_UNKNOWN| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetNode + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/nodes/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetNodeGPUDashboard + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/nodes/{name}/gpu + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |none| +|name|path|string| yes |none| +|gpuVendors|query|array[string]| no |none| +|start|query|string(int64)| no |start unix timestamp with seconds unit| +|end|query|string(int64)| no |end unix timestamp with seconds unit| + +#### Description + +**start**: start unix timestamp with seconds unit +default now - 1h + +**end**: end unix timestamp with seconds unit +default now + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListPods + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/pods + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter nodes by cluster| +|namespace|query|string| no |filter nodes by namespaces| +|phase|query|string| no |filter nodes by status| +|name|query|string| no |filter pods by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Description + +**phase**: filter nodes by status + + - POD_PHASE_UNKNOWN: PodUnknown means that for some reason the state of the pod could not be +obtained, typically due to an error in communicating with the host of the +pod. + - POD_PHASE_PENDING: PodPending means the pod has been accepted by the system, but one or more +of the containers has not been started. This includes time before being +bound to a node, as well as time spent pulling images onto the host. + - POD_PHASE_RUNNING: PodRunning means the pod has been bound to a node and all of the containers +have been started. At least one container is still running or is in the +process of being restarted. PodSucceeded means that all containers in the +pod have voluntarily terminated with a container exit code of 0, and the +system is not going to restart any of these containers. + - POD_PHASE_SUCCEED: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + - POD_PHASE_FAILED: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + +#### Enum + +|Name|Value| +|---|---| +|phase|POD_PHASE_UNSPECIFIED| +|phase|POD_PHASE_UNKNOWN| +|phase|POD_PHASE_PENDING| +|phase|POD_PHASE_RUNNING| +|phase|POD_PHASE_SUCCEED| +|phase|POD_PHASE_FAILED| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListServices + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/services + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter services by cluster| +|namespace|query|string| no |filter services by namespaces| +|name|query|string| no |filter services by name| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListStatefulsets + +GET /apis/insight.io/v1alpha1/clusters/{cluster}/statefulsets + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|path|string| yes |filter workloads by cluster| +|namespace|query|string| no |filter workloads by namespace| +|name|query|string| no |filter workloads by name| +|phase|query|string| no |filter workloads by phase| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNKNOWN| +|phase|WORKLOAD_STATE_RUNNING| +|phase|WORKLOAD_STATE_DELETING| +|phase|WORKLOAD_STATE_NOT_READY| +|phase|WORKLOAD_STATE_STOPPED| +|phase|WORKLOAD_STATE_WAITING| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetCluster + +GET /apis/insight.io/v1alpha1/clusters/{name} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_ListClusterSummary + +GET /apis/insight.io/v1alpha1/clustersummary + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|query|string| no |filter cluster by name| +|version|query|string| no |filter cluster by k8s version| +|phase|query|string| no |filter cluster by phase| +|showAllCluster|query|boolean| no |show_all_cluster default is false, will only return cluster with| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Description + +**phase**: filter cluster by phase + + - CLUSTER_PHASE_UNSPECIFIED: The cluster state is unspecified. + - UNKNOWN: The cluster state is unknown. + - CREATING: The cluster is being created. + - RUNNING: The cluster is running. + - UPDATING: The cluster is updating. + - DELETING: The cluster is being deleted. + - FAILED: The cluster operations failed. + +**showAllCluster**: show_all_cluster default is false, will only return cluster with +insight-agent installed; if set to true, will return all cluster. + +#### Enum + +|Name|Value| +|---|---| +|phase|CLUSTER_PHASE_UNSPECIFIED| +|phase|UNKNOWN| +|phase|CREATING| +|phase|RUNNING| +|phase|UPDATING| +|phase|DELETING| +|phase|FAILED| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetPodGPUDashboard + +GET /apis/insight.io/v1alpha1/pods/{name}/gpu + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| +|start|query|string(int64)| no |start unix timestamp with seconds unit| +|end|query|string(int64)| no |end unix timestamp with seconds unit| + +#### Description + +**start**: start unix timestamp with seconds unit +default now - 1h + +**end**: end unix timestamp with seconds unit +default now + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Resource_GetPodJVMInfo + +POST /apis/insight.io/v1alpha1/pods/{name}/jvm + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|name|path|string| yes |required;| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Resource_GetServerComponentSummary + +GET /apis/insight.io/v1alpha1/server/component + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Probe + + + +## GET get the list of probes of cluster and namespace scope + +GET /apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| +|namespace|path|string| yes |none| +|fuzzyName|query|string| no |FuzzyName is used to fuzzy search by multiple parameters including name.| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sorts|query|string| no |sorts determines the data list order, do not support multiple sort option.| + +#### Description + +**sorts**: sorts determines the data list order, do not support multiple sort option. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- job_name,desc or job_name +- job_name,asc +- create_at,desc or create_at +- create_at,asc + +the default sort is create_at,desc + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST create one probe of cluster and namespace scope + +POST /apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| +|namespace|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET get one probe by probe name of cluster and namespace scope + +GET /apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes/{jobName} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| +|namespace|path|string| yes |none| +|jobName|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT update probe content of cluster and namespace scope + +PUT /apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes/{jobName} + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| +|namespace|path|string| yes |none| +|jobName|path|string| yes |none| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE delete one probe by probe name of cluster and namespace scope + +DELETE /apis/insight.io/v1alpha1/clusters/{clusterName}/namespaces/{namespace}/probes/{jobName} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| +|namespace|path|string| yes |none| +|jobName|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET get the list of prober(blackbox-exporter) of cluster scope + +GET /apis/insight.io/v1alpha1/clusters/{clusterName}/probers + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Event + + + +## GET Event_QueryEvents + +GET /apis/insight.io/v1alpha1/event/cluster/{clusterName}/events + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |Required.| +|startTime|query|string| no |startTime e.g. 2006-01-02T15:04:05.999999999Z07:00| +|endTime|query|string| no |endTime e.g. 2006-01-02T15:04:05.999999999Z07:00| +|namespace|query|string| no |Optional.| +|filter.type|query|string| no | - Normal: use lowercase to keep the same as the original Kubernetes event data| +|filter.involveObjectKind|query|string| no |none| +|filter.reason|query|string| no |none| +|filter.involveObjectName|query|string| no |fuzzy search| +|filter.message|query|string| no |fuzzy search| +|sort|query|string| no |sort determines the data list order.| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| + +#### Description + +**startTime**: startTime e.g. 2006-01-02T15:04:05.999999999Z07:00 +Optional. +Default = now-24 hour. + +**endTime**: endTime e.g. 2006-01-02T15:04:05.999999999Z07:00 +Optional. +Default = now. + +**sort**: sort determines the data list order. +parameter and sort direction divided by comma. +support sorts: +- timestamp,desc +- timestamp,asc +- type,desc +- type,asc + +Optional. +Default = timestamp,desc + +**page**: Page is current page. +Optional. +Default = 1. + +**pageSize**: Size is the data number shown per page. +Optional. +Default = 10. + +#### Enum + +|Name|Value| +|---|---| +|filter.type|TYPE_UNSPECIFIED| +|filter.type|Normal| +|filter.type|Warning| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Event_QueryEventContext + +GET /apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/context + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |Required.| +|timestamp|query|string| no |timestamp e.g. 2023-06-20T16:05:16.887681657Z| +|namespace|query|string| no |Optional.| +|filter.type|query|string| no | - Normal: use lowercase to keep the same as the original Kubernetes event data| +|filter.involveObjectKind|query|string| no |none| +|filter.reason|query|string| no |none| +|filter.involveObjectName|query|string| no |fuzzy search| +|filter.message|query|string| no |fuzzy search| +|before|query|integer(int32)| no |Optional.| +|after|query|integer(int32)| no |Optional.| + +#### Description + +**timestamp**: timestamp e.g. 2023-06-20T16:05:16.887681657Z +Required. + +**before**: Optional. +default = 50 + +**after**: Optional. +default = 50 + +#### Enum + +|Name|Value| +|---|---| +|filter.type|TYPE_UNSPECIFIED| +|filter.type|Normal| +|filter.type|Warning| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Event_QueryEventCount + +POST /apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/count + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |Required.| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Event_QueryEventFilterOptions + +GET /apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/filter-options + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |Required.| +|startTime|query|string| no |startTime e.g. 2006-01-02T15:04:05.999999999Z07:00| +|endTime|query|string| no |endTime e.g. 2006-01-02T15:04:05.999999999Z07:00| +|namespace|query|string| no |Optional.| + +#### Description + +**startTime**: startTime e.g. 2006-01-02T15:04:05.999999999Z07:00 +Optional. +Default = now-24 hour. + +**endTime**: endTime e.g. 2006-01-02T15:04:05.999999999Z07:00 +Optional. +Default = now. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Event_QueryEventHistogram + +GET /apis/insight.io/v1alpha1/event/cluster/{clusterName}/events/histogram + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |Required.| +|startTime|query|string| no |startTime e.g. 2006-01-02T15:04:05.999999999Z07:00| +|endTime|query|string| no |endTime e.g. 2006-01-02T15:04:05.999999999Z07:00| +|interval|query|string| no |interval e.g 1440s| +|namespace|query|string| no |Optional.| + +#### Description + +**startTime**: startTime e.g. 2006-01-02T15:04:05.999999999Z07:00 +Optional. +Default = now-24 hour. + +**endTime**: endTime e.g. 2006-01-02T15:04:05.999999999Z07:00 +Optional. +Default = now. + +**interval**: interval e.g 1440s +Required. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Event_GetReasons + +GET /apis/insight.io/v1alpha1/event/reasons + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/FeatureGate + + + +## GET FeatureGate_GetFeatureGates + +GET /apis/insight.io/v1alpha1/feature-gates + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET FeatureGate_GetFeatureGateByID + +GET /apis/insight.io/v1alpha1/feature-gates/{id} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|id|path|string| yes |none| + +#### Enum + +|Name|Value| +|---|---| +|id|METRICS| +|id|LOGGING| +|id|TRACING| +|id|GRAPH_VIRTUAL_NODE| +|id|LOG_ALERT| +|id|NET_FLOW| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Tracing + + + +## GET Tracing_FindJaegerTraces + +GET /apis/insight.io/v1alpha1/jaeger/v2/traces + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|serviceName|query|string| no |none| +|operationName|query|string| no |none| +|tags|query|string| no |e.g. tags[host.name]=localhost&tags[url]=http://test/test| +|start|query|string| no |e.g. 2022-06-24T08:00:47.850Z| +|end|query|string| no |e.g. 2022-06-24T08:00:47.850Z| +|durationMin|query|string| no |Span min duration. such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".| +|durationMax|query|string| no |Span min duration. such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".| +|limit|query|integer(int32)| no |none| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |only for auth| + +#### Description + +**tags**: e.g. tags[host.name]=localhost&tags[url]=http://test/test + +This is a request variable of the map type. The query format is "map_name[key]=value", e.g. If the map name is Age, the key type is string, and the value type is integer, the query parameter is expressed as Age["bob"]=18 + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_FindJaegerTrace + +GET /apis/insight.io/v1alpha1/jaeger/v2/traces/{traceId} + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|traceId|path|string| yes |none| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |only for auth| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_GetServiceApdex + +GET /apis/insight.io/v1alpha1/traces/apdex + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |Namespace| +|name|query|string| no |none| +|apdexThreshold|query|string(int64)| no |Unit is milseconds.| +|startTime|query|string(int64)| no |none| +|endTime|query|string(int64)| no |none| +|extensionFilters|query|string| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_QueryOperations + +GET /apis/insight.io/v1alpha1/traces/clusters/{clusterName}/operations + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|path|string| yes |none| +|namespace|query|string| no |none| +|serviceName|query|string| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_GetOperationDetail + +GET /apis/insight.io/v1alpha1/traces/operation-detail + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|clusterName|query|string| no |Required.| +|namespace|query|string| no |Required. namespace| +|serviceName|query|string| no |Required. At least one service name must be provided.| +|sort|query|string| no |Optional.| +|page|query|integer(int32)| no |Optional. page is current page.| +|pageSize|query|integer(int32)| no |Optional. size is the data number shown per page.| +|extensionFilters|query|string| no |Optional. support extension labels search| +|endTime|query|string(int64)| no |end_time is the ending time of the time series query range.| +|lookback|query|string(int64)| no |lookback is the duration from the end_time to look back on for metrics data points.| +|step|query|string(int64)| no |step size is the duration between data points of the query results.| +|ratePer|query|string(int64)| no |ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric.| +|spanKinds|query|array[string]| no |spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.| + +#### Description + +**sort**: Optional. +sort determines the data list order. +parameter and sort direction divided by comma. +support sorts: +- reqRate,desc +- reqRate,asc +- errRate,desc +- errRate,asc +- p50Latency,desc +- p50Latency,asc +- p95Latency,desc +- p95Latency,asc +- p99Latency,desc +- p99Latency,asc + +the default sort is P95_latency,desc + +**page**: Optional. page is current page. +Default = 1. + +**pageSize**: Optional. size is the data number shown per page. +Default = 10. + +**extensionFilters**: Optional. support extension labels search +support multiple labels, split by comma +eg. span_name=HTTP + +**endTime**: end_time is the ending time of the time series query range. +Optional. Default = now. + +**lookback**: lookback is the duration from the end_time to look back on for metrics data points. +For example, if set to 1h, the query would span from end_time-1h to end_time. +Optional. Default = 1h. + +**step**: step size is the duration between data points of the query results. +For example, if set to 5s, the results would produce a data point every 5 seconds +from the start_time to end_time. +Optional. Default = 1m. + +**ratePer**: ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric. +Optional. Default = 1m. + +**spanKinds**: spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation. +Optional. Default = [SPAN_KIND_SERVER, SPAN_KIND_CLIENT]. + + - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default. +Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application, +as opposed to an operation happening at the boundaries. Default value. + - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other +remote network request. + - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service. + - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker. +Unlike CLIENT and SERVER, there is often no direct critical path latency relationship +between producer and consumer spans. A PRODUCER span ends when the message was accepted +by the broker while the logical processing of the message might span a much longer time. + - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker. +Like the PRODUCER kind, there is often no direct critical path latency relationship +between producer and consumer spans. + +#### Enum + +|Name|Value| +|---|---| +|spanKinds|SPAN_KIND_UNSPECIFIED| +|spanKinds|SPAN_KIND_INTERNAL| +|spanKinds|SPAN_KIND_SERVER| +|spanKinds|SPAN_KIND_CLIENT| +|spanKinds|SPAN_KIND_PRODUCER| +|spanKinds|SPAN_KIND_CONSUMER| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_GetServiceDetail + +GET /apis/insight.io/v1alpha1/traces/service-detail + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |Optional. namespace| +|instanceName|query|string| no |Optional. instance name(k8s.pod.name)| +|extensionFilters|query|string| no |Optional. support extension search| +|serviceNames|query|array[string]| no |service_names are the service names to fetch metrics from.| +|groupByOperation|query|boolean| no |groupByOperation determines if the metrics returned should be grouped by operation.| +|endTime|query|string(int64)| no |end_time is the ending time of the time series query range.| +|lookback|query|string(int64)| no |lookback is the duration from the end_time to look back on for metrics data points.| +|step|query|string(int64)| no |step size is the duration between data points of the query results.| +|ratePer|query|string(int64)| no |ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric.| +|spanKinds|query|array[string]| no |spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.| + +#### Description + +**extensionFilters**: Optional. support extension search +eg.service_name=my-otel-demo-adservice + +**serviceNames**: service_names are the service names to fetch metrics from. +The results will be grouped by service_name. +Required. At least one service name must be provided. + +**groupByOperation**: groupByOperation determines if the metrics returned should be grouped by operation. +Optional. Default = false. + +**endTime**: end_time is the ending time of the time series query range. +Optional. Default = now. + +**lookback**: lookback is the duration from the end_time to look back on for metrics data points. +For example, if set to 1h, the query would span from end_time-1h to end_time. +Optional. Default = 1h. + +**step**: step size is the duration between data points of the query results. +For example, if set to 5s, the results would produce a data point every 5 seconds +from the start_time to end_time. +Optional. Default = 5s. + +**ratePer**: ratePer is the duration in which the per-second rate of change is calculated for a cumulative counter metric. +Optional. Default = 10m. + +**spanKinds**: spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation. +Optional. Default = [SPAN_KIND_SERVER]. + + - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default. +Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application, +as opposed to an operation happening at the boundaries. Default value. + - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other +remote network request. + - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service. + - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker. +Unlike CLIENT and SERVER, there is often no direct critical path latency relationship +between producer and consumer spans. A PRODUCER span ends when the message was accepted +by the broker while the logical processing of the message might span a much longer time. + - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker. +Like the PRODUCER kind, there is often no direct critical path latency relationship +between producer and consumer spans. + +#### Enum + +|Name|Value| +|---|---| +|spanKinds|SPAN_KIND_UNSPECIFIED| +|spanKinds|SPAN_KIND_INTERNAL| +|spanKinds|SPAN_KIND_SERVER| +|spanKinds|SPAN_KIND_CLIENT| +|spanKinds|SPAN_KIND_PRODUCER| +|spanKinds|SPAN_KIND_CONSUMER| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_ListServiceNames + +GET /apis/insight.io/v1alpha1/traces/service-names + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Tracing_GetServices + +GET /apis/insight.io/v1alpha1/traces/services + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|namespace|query|string| no |Optional. namespace| +|extensionFilters|query|string| no |Optional. support extension search| +|endTime|query|string(int64)| no |end_time is the ending time of the time series query range.| +|lookback|query|string(int64)| no |lookback is the duration from the end_time to look back on for metrics data points.| +|spanKinds|query|array[string]| no |spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|sort|query|string| no |sorts determines the data list order.| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| + +#### Description + +**extensionFilters**: Optional. support extension search +eg.service_name=my-otel-demo-adservice + +**endTime**: end_time is the ending time of the time series query range. +Optional. Default = now. + +**lookback**: lookback is the duration from the end_time to look back on for metrics data points. +For example, if set to 1h, the query would span from end_time-1h to end_time. +Optional. Default = 1h. + +**spanKinds**: spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation. +Optional. Default = [SPAN_KIND_SERVER, SPAN_KIND_CLIENT]. + + - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default. +Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application, +as opposed to an operation happening at the boundaries. Default value. + - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other +remote network request. + - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service. + - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker. +Unlike CLIENT and SERVER, there is often no direct critical path latency relationship +between producer and consumer spans. A PRODUCER span ends when the message was accepted +by the broker while the logical processing of the message might span a much longer time. + - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker. +Like the PRODUCER kind, there is often no direct critical path latency relationship +between producer and consumer spans. + +**sort**: sorts determines the data list order. +parameter and sort direction divided by comma. +you can also only give the parameter,the desc sort will apply it by default +support sorts: +- service_name,desc or service_name +- service_name,asc +- req_rate,desc or req_rate +- req_rate,asc +- rep_latency,desc or rep_latency +- rep_latency,asc +- error_rate,desc or error_rate +- error_rate,asc + +the default sort is service_name,asc + +#### Enum + +|Name|Value| +|---|---| +|spanKinds|SPAN_KIND_UNSPECIFIED| +|spanKinds|SPAN_KIND_INTERNAL| +|spanKinds|SPAN_KIND_SERVER| +|spanKinds|SPAN_KIND_CLIENT| +|spanKinds|SPAN_KIND_PRODUCER| +|spanKinds|SPAN_KIND_CONSUMER| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Log + + + +## POST Log_QueryLogContext + +POST /apis/insight.io/v1alpha1/log/context + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Log_DownloadLog + +POST /apis/insight.io/v1alpha1/log/export + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Log_ListLogFilePaths + +GET /apis/insight.io/v1alpha1/log/filepaths + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|node|query|string| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Log_QueryLogHistogram + +POST /apis/insight.io/v1alpha1/log/histogram + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Log_QueryLog + +POST /apis/insight.io/v1alpha1/log/query + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Log_SearchLog + +GET /apis/insight.io/v1alpha1/log/search + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|index|query|string| no |none| +|query|query|string| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Metric + + + +## GET Metric_QueryMetric + +GET /apis/insight.io/v1alpha1/metric/query + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| +|query|query|string| no |none| +|time|query|string(int64)| no |Optional, current server time is used if the time parameter is omitted.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Metric_BatchQueryMetric + +POST /apis/insight.io/v1alpha1/metric/query + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Metric_QueryRangeMetric + +GET /apis/insight.io/v1alpha1/metric/queryrange + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |none| +|clusterName|query|string| no |none| +|namespace|query|string| no |none| +|query|query|string| no |none| +|start|query|string(int64)| no |none| +|end|query|string(int64)| no |none| +|step|query|number(double)| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Metric_BatchQueryRangeMetric + +POST /apis/insight.io/v1alpha1/metric/queryrange + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/NetFlow + + + +## GET NetFlow_GetNetFlow + +GET /apis/insight.io/v1alpha1/net_flow/config + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/Overview + + + +## GET Overview_GetResourcesCount + +GET /apis/insight.io/v1alpha1/overview/resources/count + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|time|query|string(int64)| no |time unix timestamp .e.g. 1697597347| +|filters|query|array[string]| no |default [CLUSTER_NORMAL_TOTAL, CLUSTER_TOTAL, NODE_NORMAL_TOTAL, NODE_TOTAL, DEPLOYMENT_NORMAL_TOTAL, DEPLOYMENT_TOTAL| + +#### Description + +**time**: time unix timestamp .e.g. 1697597347 +default now + +**filters**: default [CLUSTER_NORMAL_TOTAL, CLUSTER_TOTAL, NODE_NORMAL_TOTAL, NODE_TOTAL, DEPLOYMENT_NORMAL_TOTAL, DEPLOYMENT_TOTAL +STATEFULSET_NORMAL_TOTAL, STATEFULSET_TOTAL, DAEMONSET_NORMAL_TOTAL, DAEMONSET_TOTAL, JOB_NORMAL_TOTAL, JOB_TOTAL +POD_NORMAL_TOTAL, POD_TOTAL, LOG_TOTAL, TRACE_TOTAL] + +#### Enum + +|Name|Value| +|---|---| +|filters|RESOURCE_TYPE_UNSPECIFIED| +|filters|CLUSTER_NORMAL_TOTAL| +|filters|CLUSTER_TOTAL| +|filters|NODE_NORMAL_TOTAL| +|filters|NODE_TOTAL| +|filters|DEPLOYMENT_NORMAL_TOTAL| +|filters|DEPLOYMENT_TOTAL| +|filters|STATEFULSET_NORMAL_TOTAL| +|filters|STATEFULSET_TOTAL| +|filters|DAEMONSET_NORMAL_TOTAL| +|filters|DAEMONSET_TOTAL| +|filters|JOB_NORMAL_TOTAL| +|filters|JOB_TOTAL| +|filters|POD_NORMAL_TOTAL| +|filters|POD_TOTAL| +|filters|LOG_TOTAL| +|filters|TRACE_TOTAL| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Overview_GetResourcesRange + +GET /apis/insight.io/v1alpha1/overview/resources/range + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|filters|query|array[string]| no |default [NODE_TOTAL, POD_NORMAL_TOTAL, POD_ABNORMAL_TOTAL]| +|start|query|string(int64)| no |start unix timestamp .e.g. 1697597347| +|end|query|string(int64)| no |end unix timestamp .e.g. 1697597347| +|step|query|number(double)| no |step time step in second, default 60| + +#### Description + +**start**: start unix timestamp .e.g. 1697597347 +default end - 1hour + +**end**: end unix timestamp .e.g. 1697597347 +default now + +#### Enum + +|Name|Value| +|---|---| +|filters|RESOURCE_TYPE_UNSPECIFIED| +|filters|NODE_TOTAL| +|filters|POD_TOTAL| +|filters|POD_ABNORMAL_TOTAL| +|filters|POD_NORMAL_TOTAL| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Overview_GetResourcesUsage + +GET /apis/insight.io/v1alpha1/overview/resources/usage + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|filters|query|array[string]| no |default [CLUSTER_CPU_USAGE, NODE_CPU_USAGE]| +|limit|query|integer(int64)| no |limit The max element of result in desc order| +|start|query|string(int64)| no |start unix timestamp .e.g. 1697597347| +|end|query|string(int64)| no |end unix timestamp .e.g. 1697597347| +|step|query|number(double)| no |step time step in second, default 60| + +#### Description + +**limit**: limit The max element of result in desc order +default 5 + +**start**: start unix timestamp .e.g. 1697597347 +default end - 1hour + +**end**: end unix timestamp .e.g. 1697597347 +default now + +#### Enum + +|Name|Value| +|---|---| +|filters|RESOURCE_TYPE_UNSPECIFIED| +|filters|CLUSTER_CPU_USAGE| +|filters|CLUSTER_MEM_USAGE| +|filters|CLUSTER_DISK_USAGE| +|filters|NODE_CPU_USAGE| +|filters|NODE_MEM_USAGE| +|filters|NODE_DISK_USAGE| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Overview_GetServicesMonitor + +GET /apis/insight.io/v1alpha1/overview/services/monitor + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|filters|query|array[string]| no |filter| +|limit|query|integer(int64)| no |limit The max element of result in desc order| +|time|query|string(int64)| no |timestamp unix timestamp .e.g. 1697597347| +|spanKinds|query|array[string]| no |spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation.| + +#### Description + +**filters**: filter +default [AVG_LATENCY, ERR_RATE] +if It's AVG_LATENCY the result value uses ms as unit otherwise uses percentage as unit + +**limit**: limit The max element of result in desc order +default 5 + +**time**: timestamp unix timestamp .e.g. 1697597347 +default now + +**spanKinds**: spanKinds is the list of span kinds to include (logical OR) in the resulting metrics aggregation. +Optional. Default = [SPAN_KIND_SERVER, SPAN_KIND_CLIENT]. + + - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default. +Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application, +as opposed to an operation happening at the boundaries. Default value. + - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other +remote network request. + - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service. + - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker. +Unlike CLIENT and SERVER, there is often no direct critical path latency relationship +between producer and consumer spans. A PRODUCER span ends when the message was accepted +by the broker while the logical processing of the message might span a much longer time. + - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker. +Like the PRODUCER kind, there is often no direct critical path latency relationship +between producer and consumer spans. + +#### Enum + +|Name|Value| +|---|---| +|filters|MONITOR_TYPE_UNSPECIFIED| +|filters|AVG_LATENCY| +|filters|ERR_RATE| +|spanKinds|SPAN_KIND_UNSPECIFIED| +|spanKinds|SPAN_KIND_INTERNAL| +|spanKinds|SPAN_KIND_SERVER| +|spanKinds|SPAN_KIND_CLIENT| +|spanKinds|SPAN_KIND_PRODUCER| +|spanKinds|SPAN_KIND_CONSUMER| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# Insight/ServiceGraph + + + +## POST ServiceGraph_GetGraph + +POST /apis/insight.io/v1alpha1/service-graph/graph + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|body|body|object| no |none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ServiceGraph_GetNodeMetrics + +GET /apis/insight.io/v1alpha1/service-graph/node-metrics + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|string| no |Required. e.g. cluster = 7760a3f4-bfca-4c1e-8731-aea80838525f| +|namespace|query|string| no |none| +|service|query|string| no |none| +|extensionFilters|query|string| no |extension_filters eg. skoala_registry=ire-111,instance=xxx| +|endTime|query|string(int64)| no |end_time End time unix timestamp, unit ms| +|lookback|query|string(int64)| no |lookback Rollback time unix timestamp, unit ms| +|step|query|string(int64)| no |step Time step unix timestamp, unit ms| +|ratePer|query|string(int64)| no |ratePer Rate of change calculation step unix timestamp, unit ms| +|clusterName|query|string| no |Required. e.g. clusterName=kpanda-global-cluster must give one of| +|spanKinds|query|array[string]| no |spanKinds is the list of span kinds to include (logical OR) in the| + +#### Description + +**clusterName**: Required. e.g. clusterName=kpanda-global-cluster must give one of +cluster,clusterName in a query + +**spanKinds**: spanKinds is the list of span kinds to include (logical OR) in the +resulting metrics aggregation. Optional. Default = [SPAN_KIND_SERVER]. + + - SPAN_KIND_UNSPECIFIED: Unspecified. Do NOT use as default. +Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + - SPAN_KIND_INTERNAL: Indicates that the span represents an internal operation within an application, +as opposed to an operation happening at the boundaries. Default value. + - SPAN_KIND_SERVER: Indicates that the span covers server-side handling of an RPC or other +remote network request. + - SPAN_KIND_CLIENT: Indicates that the span describes a request to some remote service. + - SPAN_KIND_PRODUCER: Indicates that the span describes a producer sending a message to a broker. +Unlike CLIENT and SERVER, there is often no direct critical path latency relationship +between producer and consumer spans. A PRODUCER span ends when the message was accepted +by the broker while the logical processing of the message might span a much longer time. + - SPAN_KIND_CONSUMER: Indicates that the span describes consumer receiving a message from a broker. +Like the PRODUCER kind, there is often no direct critical path latency relationship +between producer and consumer spans. + +#### Enum + +|Name|Value| +|---|---| +|spanKinds|SPAN_KIND_UNSPECIFIED| +|spanKinds|SPAN_KIND_INTERNAL| +|spanKinds|SPAN_KIND_SERVER| +|spanKinds|SPAN_KIND_CLIENT| +|spanKinds|SPAN_KIND_PRODUCER| +|spanKinds|SPAN_KIND_CONSUMER| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/RBAC + + + +## GET ListAdminClusterSummary List cluster summary by adminCluster + +GET /apis/kpanda.io/v1alpha1/admincluster + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|user|query|string| no |user is the cluster's user| +|userGroup|query|array[string]| no |userGroup is the cluster user's belong group| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterRoleBindings lists a cluster RoleBinding + +GET /apis/kpanda.io/v1alpha1/asl/clusterrolebindings + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|array[string]| no |Cluster represents which cluster the roleBinding belongs to.| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|name|query|string| no |Name represents the name of the user| +|roleRef|query|string| no |RoleRef is the role of the user, it should be the same as when it is created.| +|sortBy|query|string| no |SortBy determines the data list order reference.| +|sortDir|query|string| no |OrderBy determines the data list order.| +|labelSelector|query|string| no |LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no |FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no |FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**roleRef**: RoleRef is the role of the user, it should be the same as when it is created. +Such as: cluster-admin, ns-admin, ns-view, ns-edit, ns-admin + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListGroups lists the groups in the system. + +GET /apis/kpanda.io/v1alpha1/asl/groups + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|name|query|string| no |Name is used for fuzzy search.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListRoleBindings lists the rolebidings created by frontend. + +GET /apis/kpanda.io/v1alpha1/asl/rolebindings + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|cluster|query|array[string]| no |Cluster represents which cluster the roleBinding belongs to.| +|namespace|query|array[string]| no |Namespace represents which namespace the roleBinding belongs to.| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|name|query|string| no |Name represents the name of the user| +|roleRef|query|string| no |RoleRef is the role of the user, it should be the same as when it is created.| +|sortBy|query|string| no |SortBy determines the data list order reference.| +|sortDir|query|string| no |OrderBy determines the data list order.| +|labelSelector|query|string| no |LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no |FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no |FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**roleRef**: RoleRef is the role of the user, it should be the same as when it is created. +Such as: cluster-admin, ns-admin, ns-view, ns-edit, ns-admin + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListUsers lists the users in the system. + +GET /apis/kpanda.io/v1alpha1/asl/users + +### Params + +|Name|Location|Type|Required|Description| +|---|---|---|---|---| +|page|query|integer(int32)| no |Page is current page.| +|pageSize|query|integer(int32)| no |Size is the data number shown per page.| +|name|query|string| no |Name is used for fuzzy search.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateClusterRoleBinding creates a cluster roleBinding batch + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterrolebindings + +> Body Parameters + +```json +{ + "subject": {}, + "roleRef": {}, + "name": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "ownerReferences": [ + {} + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the clusterRoleBinding belongs to.| +|body|body|object| no ||none| +|» subject|body|object| no ||none| +|» roleRef|body|object| no ||none| +|» name|body|string| no | the name of ClusterRole|none| +|» labels|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» ownerReferences|body|[object]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteClusterRoleBinding deletes a cluster RoleBinding + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterrolebindings/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the roleBinding belongs to.| +|name|path|string| yes ||Name represents the name of the clusterrolebinding to delete.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterRoles lists the clusterroles + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the role belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of the user| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetClusterRole gets a ClusterRole + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the clusterrole belongs to.| +|name|path|string| yes ||Name represents the name of the clusterrole to delete.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateClusterRole updates a ClusterRole + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the clusterrole belongs to.| +|name|path|string| yes ||Name represents the name of the clusterrole to delete.| +|body|body|object| no | UpdateClusterRoleRequest the request of update clusterrole|none| +|» data|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateClusterRole creates a ClusterRole + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the clusterrole belongs to.| +|name|path|string| yes ||the name of role.| +|body|body|object| no ||none| +|» data|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteClusterRole deletes a ClusterRole + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterroles/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the clusterrole belongs to.| +|name|path|string| yes ||Name represents the name of the clusterrole to delete.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateRoleBinding creates a RoleBinding + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/rolebindings + +> Body Parameters + +```json +{ + "subject": {}, + "roleRef": {}, + "name": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "ownerReferences": [ + {} + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the roleBinding belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the roleBinding belongs to.| +|body|body|object| no ||none| +|» subject|body|object| no ||none| +|» roleRef|body|object| no ||none| +|» name|body|string| no ||the name of RoleBinding.| +|» labels|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» ownerReferences|body|[object]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE ListRoleBindings lists the clusterrolebidings created by the frontend. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/rolebindings/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the roleBinding belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the roleBinding belongs to.| +|name|path|string| yes ||Name represents the name of the rolebinding to delete.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListRoles lists the roles created by frontend. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the role belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the role belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of the user| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateRole creates a Role + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles + +> Body Parameters + +```json +{ + "data": "string", + "name": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the role belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the role belongs to.| +|body|body|object| no ||none| +|» data|body|string| no ||none| +|» name|body|string| no ||the name of role.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetRole gets a Role + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the role belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the role belongs to.| +|name|path|string| yes ||Name represents the name of the role to delete.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateRole updates a Role + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the role belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the role belongs to.| +|name|path|string| yes ||Name represents the name of the role to delete.| +|body|body|object| no | UpdateRoleRequest the request of update role|none| +|» data|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateRoleResponse](#schemav1alpha1updateroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteRole deletes the roles created by the frontend. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/roles/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the role belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the role belongs to.| +|name|path|string| yes ||Name represents the name of the role to delete.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListAllUserRoleSummary lists user role summary + +GET /apis/kpanda.io/v1alpha1/rolesummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster represents which cluster the roleBinding belongs to.| +|namespace|query|string| no ||Namespace represents which namespace the roleBinding belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Batch + + + +## GET ListAllCronJobs lists all clusters cronjob + +GET /apis/kpanda.io/v1alpha1/asl/cronjobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|clusters|query|array[string]| no ||Cluster the specified job belongs to.| +|namespace|query|string| no ||Namespace the specified service belongs to.| +|phase|query|string| no ||Current status of a cron job.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||Name of the job.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.| + +#### Description + +**phase**: Current status of a cron job. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status ++optional +todo: split list all jobs and list all cron jobs. + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListAllJobs lists all cluster jobs + +GET /apis/kpanda.io/v1alpha1/asl/jobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|clusters|query|array[string]| no ||Cluster the specified job belongs to.| +|namespace|query|string| no ||Namespace the specified service belongs to.| +|phase|query|string| no ||Current status of a cron job.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||Name of the job.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.| + +#### Description + +**phase**: Current status of a cron job. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status ++optional +todo: split list all jobs and list all cron jobs. + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListCronJobs Lists cronJobs in a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/cronjobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of Workload to belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search.| +|phase|query|string| no ||Phase represents the phase of workloads to search.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search. + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListJobs lists jobs in a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/jobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of Workload to belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search.| +|phase|query|string| no ||Phase represents the phase of workloads to search.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search. + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterCronJobs lists cluster cronJobs under the namespaces of a +specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified job belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|phase|query|string| no ||Status represents the current state of a job.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||Name of the job.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListJobsByCronJobsName lists Jobs By CronJobs's Name under the namespaces +of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{cronjob}/jobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the cronjob belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the cronjob belongs to.| +|cronjob|path|string| yes ||Cronjob name.| +|phase|query|string| no ||Represents the current state of a cron job.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the job list order reference.| +|sortDir|query|string| no ||OrderBy determines the job list order.| +|name|query|string| no ||Cronjob name.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the job list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the job list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCronJob gets a cronJob under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the cronjob belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the cronjob belongs to.| +|name|path|string| yes ||Cronjob name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteCronJob deletes a cronJob under the namespaces of a specific cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the cronjob belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the cronjob belongs to.| +|name|path|string| yes ||Cronjob name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST PauseCronJob pauses a cronjob under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}:pause + +> Body Parameters + +```json +{ + "paused": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the cronjob belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the cronjob belongs to.| +|name|path|string| yes ||Name represents the name of cronjob| +|body|body|object| no | PauseCronJobRequest the request of pause cronjob|none| +|» paused|body|boolean| no ||Paused indicates that the cronjob is paused.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ResumeCronJob resumes a cronjob under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronjobs/{name}:resume + +> Body Parameters + +```json +{ + "paused": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the cronjob belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the cronjob belongs to.| +|name|path|string| yes ||Name represents the name of cronjob| +|body|body|object| no | ResumeCronJobRequest the request of resume CronJob|none| +|» paused|body|boolean| no ||Paused indicates that the cronjob is paused.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterJobs list cluster jobs under the namespaces of a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified job belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|phase|query|string| no ||Status represents the current state of a job.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||Name of the job.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetJob gets a job under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified job belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|name|path|string| yes ||Name of the job.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteJob deletes a job under the namespaces of a specific cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified job belongs to.| +|namespace|path|string| yes ||Namespace the specified job belongs to.| +|name|path|string| yes ||Name of the job.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RestartJob restarts a job under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/jobs/{name}:restart + +> Body Parameters + +```json +{ + "resourceVersion": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified job belongs to.| +|namespace|path|string| yes ||Namespace the specified job belongs to.| +|name|path|string| yes ||Name of the job.| +|body|body|object| no ||none| +|» resourceVersion|body|string| no ||ResourceVersion of the job.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Apps + + + +## GET ListAllDaemonSets lists all daemonSet in all clusters + +GET /apis/kpanda.io/v1alpha1/asl/daemonsets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|array[string]| no ||Cluster represents which cluster the workloads belongs to.| +|namespace|query|string| no ||Cluster represents which namespace the workloads belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListAllDeployments lists all deployment in all clusters + +GET /apis/kpanda.io/v1alpha1/asl/deployments + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|array[string]| no ||Cluster represents which cluster the workloads belongs to.| +|namespace|query|string| no ||Cluster represents which namespace the workloads belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListAllStatefulSets lists all statefulSet in all clusters + +GET /apis/kpanda.io/v1alpha1/asl/statefulsets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|array[string]| no ||Cluster represents which cluster the workloads belongs to.| +|namespace|query|string| no ||Cluster represents which namespace the workloads belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterDaemonSets lists DaemonSet in one cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/daemonsets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of Workload to belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterDeployments lists one cluster all namespace's deployments + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/deployments + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of Workload to belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListConfigMapsRelatedWorkloads list all workloads associated with this cm + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{configmap}/related + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|configmap|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET query like controllerrevisions?kind=STATEFULSET +orcontrollerrevisions?kind=STATEFULSET + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/controllerrevisions + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified controllerrevision belongs to.| +|namespace|path|string| yes ||Namespace the specified controllerrevision belongs to.| +|kind|query|string| no ||Kind stands for what type of revisions are needed.| +|kindName|query|string| no ||The name of involvedObject.| +|name|query|string| no ||Name stands for controllerrevision name, used for fuzzy search.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||SortDir determines the data list order.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| + +#### Description + +**kindName**: The name of involvedObject. +If the kind is StatefulSet, +this presents the name of statefulset. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: SortDir determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|StatefulSet| +|kind|DaemonSet| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListDaemonSets lists daemonSet by JSON under the namespaces of a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetDaemonSet gets a daemonSets under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which namespace the workload belongs to.| +|namespace|path|string| yes ||Cluster represents which namespace the workload belongs to.| +|name|path|string| yes ||Name represents the name of workload to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteDaemonSet deletes a daemonSets under the namespaces of a specific +cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which namespace the daemonSet belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the daemonSet belongs to.| +|name|path|string| yes ||Name represents the name of daemonSet| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchDaemonSet gets a daemonset under the namespaces of a specific cluster + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster which the deployment belongs to.| +|namespace|path|string| yes ||The namespace which the deployment belongs to.| +|name|path|string| yes ||The name of the deployment.| +|body|body|object| no ||none| +|» data|body|string| no ||The json data of patch.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RestartDaemonSet restarts a daemonSets under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}:restart + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified daemonset belongs to.| +|namespace|path|string| yes ||Namespace the specified daemonset belongs to.| +|name|path|string| yes ||Daemonset name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RollbackDaemonSet rollbacks a daemonSets under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/daemonsets/{name}:rollback + +> Body Parameters + +```json +{ + "revision": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified daemonset belongs to.| +|namespace|path|string| yes ||Namespace the specified daemonset belongs to.| +|name|path|string| yes ||Daemonset name.| +|body|body|object| no ||none| +|» revision|body|string(int64)| no ||The version of Daemonset.| + +#### Description + +**» revision**: The version of Daemonset. +Revision indicates the revision of the state represented by Data. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListDeployments lists deployment by JSON under the namespaces of a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetDeployment gets a deployment under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which namespace the workload belongs to.| +|namespace|path|string| yes ||Cluster represents which namespace the workload belongs to.| +|name|path|string| yes ||Name represents the name of workload to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteDeployment deletes a deployment under the namespaces of a specific +cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchDeployment patches a deployment under the namespaces of a +specific cluster + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster which the deployment belongs to.| +|namespace|path|string| yes ||The namespace which the deployment belongs to.| +|name|path|string| yes ||The name of the deployment.| +|body|body|object| no ||none| +|» data|body|string| no ||The json data of patch.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST PauseDeployment pauses a deployment under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:pause + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RestartDeployment restarts a deployment under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:restart + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ResumeDeployment resumes a deployment under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:resume + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RollbackDeployment rollbacks a deployment under the namespaces of a +specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:rollback + +> Body Parameters + +```json +{ + "revision": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment| +|body|body|object| no | RollbackDeploymentRequest the request of Rollback Deployment|none| +|» revision|body|string(int64)| no | The revision to rollback to. If set to 0, rollback to the last revision. ++optional|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST StartDeployment starts a deployment under the namespace of a specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:start + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST StopDeployment starts a deployment under the namespace of a specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/deployments/{name}:stop + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListReplicaSets lists replicasets in specified namespace of a cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of replicaset belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the replicaset belongs to.| +|kind|query|string| no ||Kind stands for what type of replicasets are needed.| +|kindName|query|string| no ||The name of involvedObject.| +|name|query|string| no ||Name stands for replicaset name, used for fuzzy search.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||SortDir determines the data list order.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||PageSize is size of every page.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**kindName**: The name of involvedObject. +If the kind is Deployment, +this presents the name of deployments. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: SortDir determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetReplicaSet gets replicaset detail in specified namespace of a cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified replicaSet belongs to.| +|namespace|path|string| yes ||Namespace the specified replicaSet belongs to.| +|name|path|string| yes ||Name of the specified replicaSet.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateReplicaSet updates a replicaset in specified namespace of a cluster + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified replicaSet belongs to.| +|namespace|path|string| yes ||Namespace the specified replicaSet belongs to.| +|name|path|string| yes ||Name of the specified replicaSet.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the replicaSet YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateReplicaSetResponse](#schemav1alpha1updatereplicasetresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteReplicaSet deletes a replicaset in specified namespace of a cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the ReplicaSet belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ReplicaSet.| +|name|path|string| yes ||Name represents for the ReplicaSet name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetReplicaSetJSON gets replicaset yaml in specified namespace of a cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/replicasets/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified replicaSet belongs to.| +|namespace|path|string| yes ||Namespace the specified replicaSet belongs to.| +|name|path|string| yes ||Name represents for the replicaSet name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListSecretsRelatedWorkloads list all workloads associated with this secret + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{secret}/related + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|secret|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Apps_ListStatefulSets + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetStatefulSet gets a statefulSets under the namespaces of a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which namespace the workload belongs to.| +|namespace|path|string| yes ||Cluster represents which namespace the workload belongs to.| +|name|path|string| yes ||Name represents the name of workload to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteStatefulSet deletes a statefulSet under the namespaces of a specific +cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|name|path|string| yes ||Name represents the name of deployment| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchStatefulSet update a statefulSet under the namespaces of a specific +cluster + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster which the deployment belongs to.| +|namespace|path|string| yes ||The namespace which the deployment belongs to.| +|name|path|string| yes ||The name of the deployment.| +|body|body|object| no ||none| +|» data|body|string| no ||The json data of patch.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RestartStatefulSet restarts a statefulSet under the namespaces of a +specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:restart + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified statefulset belongs to.| +|namespace|path|string| yes ||Namespace the specified statefulset belongs to.| +|name|path|string| yes ||StatefulSet name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RollbackStatefulSet rollbacks a statefulSet under the namespaces of a +specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:rollback + +> Body Parameters + +```json +{ + "revision": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified statefulset belongs to.| +|namespace|path|string| yes ||Namespace the specified statefulset belongs to.| +|name|path|string| yes ||StatefulSet name.| +|body|body|object| no ||none| +|» revision|body|string(int64)| no ||Revision indicates the revision of the state represented by Data.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST StartStatefulSet starts a statefulset under the namespace of a specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:start + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the statefulset belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the statefulset belongs to.| +|name|path|string| yes ||Name represents the name of statefulset.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST StopStatefulSet starts a statefulset under the namespace of a specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/statefulsets/{name}:stop + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the statefulset belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the statefulset belongs to.| +|name|path|string| yes ||Name represents the name of statefulset.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateWorkloadByJSON creates workload by JSON under the namespaces of a +specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/{kind}/json + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the Workload belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the Workload belongs to.| +|kind|path|string| yes ||WorkloadKind the workload of kind| +|body|body|object| no | CreateWorkloadByJSONRequest the request of create workload by JSON request|none| +|» data|body|string| no | data The data field is the Workload YAML details|none| + +#### Enum + +|Name|Value| +|---|---| +|kind|deployments| +|kind|statefulsets| +|kind|daemonsets| +|kind|jobs| +|kind|cronjobs| +|kind|pods| +|kind|replicasets| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1WorkloadJSON](#schemav1alpha1workloadjson)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GetWorkloadJSON gets workload by JSON under the namespaces of a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/{kind}/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the Workload belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the Workload belongs to.| +|kind|path|string| yes ||WorkloadKind the workload of kind| +|name|path|string| yes ||Name represents the name of Workload| +|stable|query|boolean| no ||If stable is true, the v1 version under the corresponding package will be returned.| + +#### Enum + +|Name|Value| +|---|---| +|kind|deployments| +|kind|statefulsets| +|kind|daemonsets| +|kind|jobs| +|kind|cronjobs| +|kind|pods| +|kind|replicasets| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1WorkloadJSON](#schemav1alpha1workloadjson)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT UpdateWorkloadByJSON updates workload by JSON under the namespaces of a +specific cluster + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/{kind}/{name}/json + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the Workload belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the Workload belongs to.| +|kind|path|string| yes ||WorkloadKind the workload of kind| +|name|path|string| yes ||Name represents the name of Workload| +|body|body|object| no | UpdateWorkloadByJSONRequest request of update workload by JSON request|none| +|» data|body|string| no | data The data field is the Workload YAML details|none| + +#### Enum + +|Name|Value| +|---|---| +|kind|deployments| +|kind|statefulsets| +|kind|daemonsets| +|kind|jobs| +|kind|cronjobs| +|kind|pods| +|kind|replicasets| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1WorkloadJSON](#schemav1alpha1workloadjson)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET ListClusterReplicaSets lists replicasets of a cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/replicasets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified replicaset belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||PageSize is the data number per page.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||Name is used for query.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterStatefulSets lists one cluster all namespace's statefulsets + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/statefulsets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of Workload to belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name represents the name of workloads to search| +|phase|query|string| no ||Phase represents the phase of workloads to search| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase represents the phase of workloads to search + + - WORKLOAD_STATE_UNSPECIFIED: Unspecified is only a meaningless placeholder, to avoid zero not return. + - Running: Running shows the referent is available. + - Deleting: Deleting is when the referent will be deleted. + - Not_Ready: NotReady shows the referent is unavailable. + - Stopped: Stopped indicates that the referent has 0 ready pods. + - Waiting: Waiting indicates that the referent is paused. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|WORKLOAD_STATE_UNSPECIFIED| +|phase|Running| +|phase|Deleting| +|phase|Not_Ready| +|phase|Stopped| +|phase|Waiting| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Core + + + +## GET ListNamespaces gets all the namespaces across clusters + +GET /apis/kpanda.io/v1alpha1/asl/namespaces + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|array[string]| no ||Clusters is to filter namespaces by cluster names| +|workspaceId|query|integer(int32)| no ||workspace_id the specified namespace belongs to.| +|workspaceAlias|query|string| no ||workspace_alias the specified namespace belongs to.| +|name|query|string| no ||Name is to filter namespaces by namespace name| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the job list order reference.| +|sortDir|query|string| no ||OrderBy determines the job list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|onlyUnassign|query|boolean| no ||Only_unassign is used to distinguish workspaces that are not assigned.| +|excludeSystem|query|boolean| no ||ExcludeSystem determines to exclude system namespaces, defaults to False.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether to return data that belongs to a virtual cluster. Default false.| +|includeResourceQuota|query|boolean| no ||IncludeQuota used to control whether return namespace resource quota, default false.| + +#### Description + +**sortBy**: SortBy determines the job list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the job list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListAllPods will list all pod by given cluster and namespace, +if you want list pods regardless of namespace, please given specify +namespace as "" and it supports across cluster. + +GET /apis/kpanda.io/v1alpha1/asl/pods + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|array[string]| no ||Cluster represents the pods belongs to, it is a array| +|namespace|query|string| no ||Namespace is the metadata.namespace of the referenced pod.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|phase|query|string| no ||Phases is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|gpuType|query|string| no ||gpu_type is filter with pods resources, when value is * search all| + +#### Description + +**cluster**: Cluster represents the pods belongs to, it is a array +if you want to query cluster more than one, please use query +like '?cluster=cluster1&cluster=cluster2'. + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +**phase**: Phases is used for filter. + + - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Unknown: PodUnknown means that for some reason the state of the pod could not be +obtained, typically due to an error in communicating with the host of the +pod. + - Pending: PodPending means the pod has been accepted by the system, but one or more +of the containers has not been started. This includes time before being +bound to a node, as well as time spent pulling images onto the host. + - Running: PodRunning means the pod has been bound to a node and all of the +containers have been started. At least one container is still running or +is in the process of being restarted. PodSucceeded means that all +containers in the pod have voluntarily terminated with a container exit +code of 0, and the system is not going to restart any of these +containers. + - Succeeded: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + - Failed: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|PHASE_UNSPECIFIED| +|phase|Unknown| +|phase|Pending| +|phase|Running| +|phase|Succeeded| +|phase|Failed| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterConfigMaps lists all configmaps in the specified cluster, +regardless of namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/configmaps + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified configmap belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the event list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||name is used for query.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|onlyMetadata|query|boolean| no ||OnlyMetadata lists only metadata of configmaps, default false.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the event list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**name**: name is used for query. ++optional + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterEvents lists all events in the specified cluster, +regardless of namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/events + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the events belongs to.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|type|query|array[string]| no ||Type is used for query, showing events of specified type.| +|kind|query|string| no ||Kind is used for query, showing events of specified involvedObject kind,| +|name|query|string| no ||Name is used for query, showing events of specified involvedObject name,| + +#### Description + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**type**: Type is used for query, showing events of specified type. +Use example: type=WARNING&type=NORMAL. + + - EVENT_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Normal: Normal is a normal event type. + - Warning: Warning is a warning event type. + +**kind**: Kind is used for query, showing events of specified involvedObject kind, +e.g. Node. ++optional + +**name**: Name is used for query, showing events of specified involvedObject name, +e.g. node‘s name when kind is Node. ++optional + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|type|EVENT_TYPE_UNSPECIFIED| +|type|Normal| +|type|Warning| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterEventKinds lists all involvedObject's kinds of events in the +specified cluster, regardless of namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/events/kinds + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the events belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterGPUSummary lists gpu summary of all nodes of the specified cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gpusummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster defines the cluster name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterLimitRanges lists all limitranges in the specified cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/limitranges + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified LimitRange belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the LimitRange list order reference.| +|sortDir|query|string| no ||OrderBy determines the LimitRange list order.| +|name|query|string| no ||Name is used for fuzzy search.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter.| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| + +#### Description + +**sortBy**: SortBy determines the LimitRange list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the LimitRange list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterNamespaces gets all the namespaces of given cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the namespace list belong to.| +|workspaceId|query|integer(int32)| no ||workspace_id the specified namespace belongs to.| +|workspaceAlias|query|string| no ||workspace_alias the specified namespace belongs to.| +|name|query|string| no ||Name is to filter namespaces by namespace name| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the job list order reference.| +|sortDir|query|string| no ||OrderBy determines the job list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| +|phase|query|string| no ||Phases is used for filter.| +|excludeSystem|query|boolean| no ||ExcludeSystem determines to exclude system namespaces, defaults to False.| + +#### Description + +**sortBy**: SortBy determines the job list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the job list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**phase**: Phases is used for filter. + + - NAMESPACE_PHASE_UNSPECIFIED: The namespace state is unspecified. + - Active: NamespaceActive means the namespace is available for use in the system + - Terminating: NamespaceTerminating means the namespace is undergoing graceful termination + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|phase|NAMESPACE_PHASE_UNSPECIFIED| +|phase|Active| +|phase|Terminating| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateNamespace creates a namespace from the system by given namespace name + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces + +> Body Parameters + +```json +{ + "workspaceId": 0, + "workspaceAlias": "string", + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster the specified namespace belongs to.| +|body|body|object| no ||none| +|» workspaceId|body|integer(int32)| no ||workspace_id the specified namespace belongs to.| +|» workspaceAlias|body|string| no ||workspace_alias the specified namespace belongs to.| +|» data|body|string| no ||The data is the service YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListConfigMaps lists configmaps in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the configmap belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||name is used for query.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|onlyMetadata|query|boolean| no ||OnlyMetadata lists only metadata of configmaps, default false.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**name**: name is used for query. ++optional + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateConfigMap creates a configMap under the namespaces of a specific +cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified configmap belongs to.| +|namespace|path|string| yes ||When the current namespace is named, the priority is higher than that in yaml| +|body|body|object| no ||none| +|» data|body|string| no | The data field is the ConfigMap YAML details|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetConfigMap gets a configMap under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the configmap belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|path|string| yes ||name represents for the resource name| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateConfigMap updates a configMap under the namespaces of a specific +cluster + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified configmap belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|path|string| yes ||name represents for the resource name| +|body|body|object| no ||none| +|» data|body|string| no | data The data field is the ConfigMap YAML details|none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteConfigMap deletes a configMap under the namespaces of a specific +cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the configmap belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|path|string| yes ||Name is the metadata.name of the referenced ConfigMap.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +**name**: Name is the metadata.name of the referenced ConfigMap. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetConfigMapJSON gets a configMap json under the namespaces of a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the configmap belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|path|string| yes ||name represents for the resource name| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchConfigMap patchs a configMap under the namespaces of a specific +cluster + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/configmaps/{name}/json + +> Body Parameters + +```json +{ + "data": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the configmap belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|path|string| yes ||The name represents for the resource name| +|body|body|object| no ||none| +|» data|body|object| no | The data is the YAML details|none| +|»» **additionalProperties**|body|string| no ||none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListEvents lists events under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/events + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of deployment belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the deployment belongs to.| +|kind|query|string| no ||Kind represents what type of event is needed.| +|kindName|query|string| no ||The name of involvedObject.| +|name|query|string| no ||Name stands for event name, used for fuzzy search.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the event list order reference.| +|sortDir|query|string| no ||OrderBy determines the event list order.| +|type|query|array[string]| no ||Type is used for query, showing events of specified type.| +|group|query|string| no ||resource group,used when the kind type is GroupVersionResource.| +|version|query|string| no ||resource version,used when the kind type is GroupVersionResource.| +|resource|query|string| no ||resource name,used when the kind type is GroupVersionResource.| + +#### Description + +**kind**: Kind represents what type of event is needed. + + - KIND_UNSPECIFIED: KIND_UNSPECIFIED is only a meaningless placeholder, to avoid zero not +return. + - Deployment: ListEvents by deployment. + - StatefulSet: ListEvents by statefulSet. + - DaemonSet: ListEvents by daemonSet. + - Pod: ListEvents by pod. + - Service: ListEvents by service. + - Ingress: ListEvents by ingress. + - Job: ListEvents by job. + - CronJob: ListEvents by cronJob. + - HorizontalPodAutoscaler: ListEvents by HorizontalPodAutoscaler. + - ReplicaSet: ListEvents by replicaset. + - CronHPA: ListEvents by CronHPA. + - PersistentVolumeClaim: ListEvents by PersistentVolumeClaim. + - GroupVersionResource: ListEvents by GroupVersionResource. If kind is set to GroupVersionResource, +you must specify the value of group version resource. + +**kindName**: The name of involvedObject. +If the kind is DEPLOYMENT, +this presents the name of deployments. + +**sortBy**: SortBy determines the event list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the event list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**type**: Type is used for query, showing events of specified type. +Use example: type=WARNING&type=NORMAL. + + - EVENT_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Normal: Normal is a normal event type. + - Warning: Warning is a warning event type. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|kind|StatefulSet| +|kind|DaemonSet| +|kind|Pod| +|kind|Service| +|kind|Ingress| +|kind|Job| +|kind|CronJob| +|kind|HorizontalPodAutoscaler| +|kind|ReplicaSet| +|kind|CronHPA| +|kind|PersistentVolumeClaim| +|kind|GroupVersionResource| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|type|EVENT_TYPE_UNSPECIFIED| +|type|Normal| +|type|Warning| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListLimitRanges lists all limitranges in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the LimitRanges belongs to.| +|namespace|path|string| yes ||Namespace the LimitRanges belongs to.| +|name|query|string| no ||Name stands for LimitRange name, used for fuzzy search.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the LimitRange list order reference.| +|sortDir|query|string| no ||OrderBy determines the LimitRange list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter.| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| + +#### Description + +**sortBy**: SortBy determines the LimitRange list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the LimitRange list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateLimitRange creates a limitrange in the specified cluster and namespace. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified limitRange belongs to.| +|namespace|path|string| yes ||Namespace the specified limitRange belongs to.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the limitRange YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetLimitRange gets the limitrange by namespace and name. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified limitRange belongs to.| +|namespace|path|string| yes ||Namespace the specified limitRange belongs to.| +|name|path|string| yes ||Name of the specified limitRange.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateLimitRange updates the specified limitrange, the body must be a JSON +string. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified limitRange belongs to.| +|namespace|path|string| yes ||Namespace the specified limitRange belongs to.| +|name|path|string| yes ||Name of the specified limitRange.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the limitRange YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateLimitRangeResponse](#schemav1alpha1updatelimitrangeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteLimitRange deletes the limitrange by name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the LimitRange belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced LimitRange.| +|name|path|string| yes ||Name represents for the LimitRange name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetLimitRangeJSON gets the limitrange by namespace and name, returns a string in JSON format. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified limitRange belongs to.| +|namespace|path|string| yes ||Namespace the specified limitRange belongs to.| +|name|path|string| yes ||Name represents for the limitRange name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ComputeLimitRange returns the final effective quota detail of multi limit range in specified namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/limitranges:compute + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified LimitRange belongs to.| +|namespace|path|string| yes ||Namespace the specified LimitRange belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListPersistentVolumeClaims gets the pvcs from the system + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the PVC belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for fuzzy search by name.| +|phase|query|string| no ||Phases is used for fuzzy search by phase.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|accessMode|query|string| no || - PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**accessMode**: - PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - ReadWriteOnce: ReadWriteOnce can be mounted in read/write mode to exactly 1 host. + - ReadOnlyMany: ReadOnlyMany can be mounted in read-only mode to many hosts. + - ReadWriteMany: ReadWriteMany can be mounted in read/write mode to many hosts. + - ReadWriteOncePod: ReadWriteOncePod can be mounted in read/write mode to exactly 1 pod. +ReadWriteOncePod cannot be used in combination with other access modes. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|accessMode|PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED| +|accessMode|ReadWriteOnce| +|accessMode|ReadOnlyMany| +|accessMode|ReadWriteMany| +|accessMode|ReadWriteOncePod| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreatePersistentVolumeClaim create persistent volume claim + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of PVC to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of PVC to belongs to.| +|body|body|object| no ||none| +|» data|body|string| no | The data is the pvc YAML details|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetPersistentVolumeClaim gets a pvc from the system by given pvc-name; + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the PVC belongs to.| +|name|path|string| yes ||Name represents the name of PVC to search| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdatePersistentVolumeClaim update the persistent volume claim + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of PVC to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of PVC to belongs to.| +|name|path|string| yes ||name represents the name of PVC to belongs to.| +|body|body|object| no ||none| +|» data|body|string| no | data represents the data of PVC JSON|none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdatePersistentVolumeClaimResponse](#schemav1alpha1updatepersistentvolumeclaimresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeletePersistentVolumeClaim delete the specified pvc + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of PVC to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of PVC to belongs to.| +|name|path|string| yes ||name represents the name of PVC to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdatePersistentVolumeClaimAnnotations puts the specified pvc's annotations + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}/annotations + +> Body Parameters + +```json +{ + "annotations": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of PVC to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of PVC to belongs to.| +|name|path|string| yes ||name represents the name of PVC to belongs to.| +|body|body|object| no | UpdatePersistentVolumeClaimAnnotationsRequest represents the request of put pvc's AnnotationsRequest|none| +|» annotations|body|object| no | labels represents the labels of pvc|none| +|»» **additionalProperties**|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "annotations": { + "property1": "string", + "property2": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdatePersistentVolumeClaimAnnotationsResponse](#schemav1alpha1updatepersistentvolumeclaimannotationsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GetPersistentVolumeClaimJSON get the specified pvc's JSON + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the PVC belongs to.| +|name|path|string| yes ||Name represents the name of PVC to search| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdatePersistentVolumeClaimLabels puts the specified pvc's labels + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}/labels + +> Body Parameters + +```json +{ + "labels": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the PVC belongs to.| +|name|path|string| yes ||Name represents the name of PVC to search| +|body|body|object| no | UpdatePersistentVolumeClaimLabelsRequest represents the request of put pvc's labels|none| +|» labels|body|object| no | labels represents the labels of pvc|none| +|»» **additionalProperties**|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "labels": { + "property1": "string", + "property2": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdatePersistentVolumeClaimLabelsResponse](#schemav1alpha1updatepersistentvolumeclaimlabelsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST ScalePersistentVolumeClaim post scale the persistent volume claim capacity + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/persistentvolumeclaims/{name}:scale + +> Body Parameters + +```json +{ + "capacity": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of PVC belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of PVC belongs to.| +|name|path|string| yes ||name represents the name of PVC belongs to.| +|body|body|object| no | UpdateScalePersistentVolumeClaimRequest represents the request of scale Pvc|none| +|» capacity|body|string| no | capacity represents the capacity of PVC|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListPods will list all pod by given cluster and namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the pod belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced pod.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|kind|query|string| no ||The kind of pod.| +|kindName|query|string| no ||Name of kind.| +|name|query|string| no ||Name stands for pod name, used for fuzzy search.| +|phase|query|string| no ||Phases is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|status|query|string| no ||status is filter with pod status ,the status is composite state| +|gpuType|query|string| no ||gpu_type is filter with pods resources, when value is * search all| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +**kind**: The kind of pod. + + - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Deployment: A Deployment provides declarative updates for Pods and ReplicaSets. + - StatefulSet: StatefulSet is the workload API object used to manage stateful +applications. + - DaemonSet: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. + - Service: Service to expose an application running on a set of Pods. + - Job: Job is used to express a one-time task. + - CronJob: CronJob runs repeatedly according to its time schedule. + - ReplicaSet: ReplicaSet is the workload API object used to manage pods + - NetworkPolicy: NetworkPolicy uses podSelector to select pods. + +**kindName**: Name of kind. +If the kind is Deployment, +this presents the name of the deployment. + +**phase**: Phases is used for filter. + + - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Unknown: PodUnknown means that for some reason the state of the pod could not be +obtained, typically due to an error in communicating with the host of the +pod. + - Pending: PodPending means the pod has been accepted by the system, but one or more +of the containers has not been started. This includes time before being +bound to a node, as well as time spent pulling images onto the host. + - Running: PodRunning means the pod has been bound to a node and all of the +containers have been started. At least one container is still running or +is in the process of being restarted. PodSucceeded means that all +containers in the pod have voluntarily terminated with a container exit +code of 0, and the system is not going to restart any of these +containers. + - Succeeded: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + - Failed: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|kind|StatefulSet| +|kind|DaemonSet| +|kind|Service| +|kind|Job| +|kind|CronJob| +|kind|ReplicaSet| +|kind|NetworkPolicy| +|phase|PHASE_UNSPECIFIED| +|phase|Unknown| +|phase|Pending| +|phase|Running| +|phase|Succeeded| +|phase|Failed| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|status|FILTER_POD_STATUS_UNSPECIFIED| +|status|FILTER_POD_STATUS_RUNNING| +|status|FILTER_POD_STATUS_ERROR| +|status|FILTER_POD_STATUS_COMPLETED| +|status|FILTER_POD_STATUS_WAITING| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetPods will get a pod under the namespaces of a specific cluster by pods + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the pod belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced pod.| +|name|path|string| yes ||Pod name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeletePod deletes a pod under the namespaces of a specific cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the pod belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced pod.| +|name|path|string| yes ||Pod name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListContainersByPod lists containers under the namespaces of a specific +cluster by pods + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}/containers + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of pod belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the pod belongs to.| +|name|path|string| yes ||Name represents the name of pod to search| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| + +#### Description + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListResourceQuotas lists quotas in specified namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the ResourceQuotas belongs to.| +|namespace|path|string| yes ||Namespace the ResourceQuotas belongs to.| +|name|query|string| no ||Name stands for ResourceQuota name, used for name fuzzy search.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the ResourceQuota list order reference.| +|sortDir|query|string| no ||OrderBy determines the ResourceQuota list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter.| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| + +#### Description + +**sortBy**: SortBy determines the ResourceQuota list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the ResourceQuota list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateResourceQuota creates a resourceQuota to the system by given resourceQuota data + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified resourceQuota belongs to.| +|namespace|path|string| yes ||Namespace the specified resourceQuota belongs to.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the resourceQuota YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetResourceQuota gets a resourceQuota from the system by given resourceQuota name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified resourceQuota belongs to.| +|namespace|path|string| yes ||Namespace the specified resourceQuota belongs to.| +|name|path|string| yes ||Name of the specified resourceQuota.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateResourceQuota updates a resourceQuota from the system by given resourceQuota name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified resourceQuota belongs to.| +|namespace|path|string| yes ||Namespace the specified resourceQuota belongs to.| +|name|path|string| yes ||Name of the specified resourceQuota.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the resourceQuota YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateResourceQuotaResponse](#schemav1alpha1updateresourcequotaresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GetResourceQuotaJSON gets a resourceQuota json from the system by given resourceQuota name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified resourceQuota belongs to.| +|namespace|path|string| yes ||Namespace the specified resourceQuota belongs to.| +|name|path|string| yes ||Name represents for the resourceQuota name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ComputeResourceQuota returns the final effective quota detail of multi quotas in specified namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resourcequotas:compute + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified resourceQuotas belongs to.| +|namespace|path|string| yes ||Namespace the specified resourceQuotas belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListSecrets lists a secret under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced secret.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||The name use to search specific secret| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|type|query|string| no ||Type is used to filter secrets by type.| +|onlyMetadata|query|boolean| no ||OnlyMetadata lists only metadata of secrets, default false.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced secret. +This field is required in all cases. + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateSecret creates a secret under the namespaces of a specific cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||When the current namespace is named, the priority is higher than that in yaml| +|body|body|object| no ||none| +|» data|body|string| no | The data is the Secret YAML details|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetClusterSecret gets a secret under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced secret.| +|name|path|string| yes ||Secret name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced secret. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateSecret updates secret under the namespaces of a specific cluster + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced secret.| +|name|path|string| yes ||Secret name.| +|body|body|object| no ||none| +|» data|body|string| no | The data field is the Secret YAML details|none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced secret. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateSecretResponse](#schemav1alpha1updatesecretresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteSecret deletes a secret under the namespaces of a specific cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced secret.| +|name|path|string| yes ||Secret name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced secret. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetSecretJSON gets a secret json under the namespaces of a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced secret.| +|name|path|string| yes ||Secret name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced secret. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchSecret patchs a Secret under the namespaces of a specific cluster + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name}/json + +> Body Parameters + +```json +{ + "data": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced secret.| +|name|path|string| yes ||The name represents for the resource name| +|body|body|object| no ||none| +|» data|body|object| no ||The data is the secret YAML details.| +|»» **additionalProperties**|body|string| no ||none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced secret. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateServiceAccount creates a sa from the system by given sa name + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/serviceaccounts + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents the cluster of ServiceAccount to belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced pod.| +|body|body|object| no ||none| +|» data|body|string| no | The data is the ServiceAccount YAML details|none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetServiceAccount gets a sa from the system by given sa +name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/serviceaccounts/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ServiceAccount.| +|name|path|string| yes ||name represents the name of ServiceAccount to belongs to.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ServiceAccount. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteServiceAccount deletes a sa from the system by given sa name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/serviceaccounts/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the ServiceAccount belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced pod.| +|name|path|string| yes ||Name represents the name of StorageClass| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListServices lists services in the specified cluster and namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|kind|query|string| no ||The kind of service.| +|kindName|query|string| no ||Name of kind.| +|name|query|string| no ||Name stands for service name, used for fuzzy search.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the service list order reference.| +|sortDir|query|string| no ||OrderBy determines the service list order.| +|type|query|array[string]| no ||Type is a array used for frontend filter.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|ports|query|array[integer]| no ||Ports is used to filter by port.| + +#### Description + +**kind**: The kind of service. +If the kind is Deployment, +this presents the name of the deployment. + + - Deployment: A Deployment provides declarative updates for Pods and ReplicaSets. + - StatefulSet: StatefulSet is the workload API object used to manage stateful +applications. + - DaemonSet: A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. + +**sortBy**: SortBy determines the service list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the service list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**type**: Type is a array used for frontend filter. +Use examples: type=CLUSTER_IP&type=NODE_PORT. + + - SERVICE_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - ClusterIP: ClusterIP means a service will only be accessible inside the cluster, via +the cluster IP. + - NodePort: NodePort means a service will be exposed on one port of every node, in +addition to 'ClusterIP' type. + - LoadBalancer: LoadBalancer means a service will be exposed via an external load balancer +(if the cloud provider supports it), in addition to 'NodePort' type. + - ExternalName: ExternalName means a service consists of only a reference to an external +name that kubedns or equivalent will return as a CNAME record, with no +exposing or proxying of any pods involved. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|kind|StatefulSet| +|kind|DaemonSet| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|type|SERVICE_TYPE_UNSPECIFIED| +|type|ClusterIP| +|type|NodePort| +|type|LoadBalancer| +|type|ExternalName| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateService creates a service to the system by given service data + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|namespace|path|string| yes ||When the current namespace is named, the priority is higher than that in| +|body|body|object| no ||none| +|» data|body|string| no | Data is the Service YAML details|none| + +#### Description + +**namespace**: When the current namespace is named, the priority is higher than that in +yaml + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetService gets a service from the system by given service name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|name|path|string| yes ||Name represents for the service name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateService updates a service from the system by given service name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|name|path|string| yes ||Name represents for the service name| +|body|body|object| no ||none| +|» data|body|string| no | Data is the Service YAML details|none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateServiceResponse](#schemav1alpha1updateserviceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteService deletes a service from the system by given service name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the service belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced service.| +|name|path|string| yes ||Name represents for the service name| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced service. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchService patches a service from the system by given service name + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|body|body|object| no ||none| +|» data|body|string| no ||The json data of patch.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetServiceJSON gets a service json from the system by given service name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/services/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|namespace|path|string| yes ||Namespace the specified service belongs to.| +|name|path|string| yes ||Name represents for the service name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetNamespace gets a namespace from the system by given namespace +name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the namespace belongs to.| +|name|path|string| yes ||Node name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateNamespace updates a namespace from the system by given namespace name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified namespace belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|body|body|object| no ||none| +|» data|body|string| no ||The data is the namespace YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateNamespaceResponse](#schemav1alpha1updatenamespaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteNamespace deletes a namespace from the system by given namespace name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified namespace belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchNamespace patches a namespace from the system by given namespace name + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name} + +> Body Parameters + +```json +{ + "data": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified namespace belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|body|body|object| no ||none| +|» data|body|object| no ||The data is the namespace YAML details.| +|»» **additionalProperties**|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetNamespaceJSON gets a namespace json from the system by given namespace +name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the namespace belongs to.| +|name|path|string| yes ||Name represents for the requested namespace name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST DisableNamespacePodSecurity enables pod security policy of a namespace + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}/podsecurity:disable + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster of the namespace.| +|name|path|string| yes ||Name represents for the resource name.| +|body|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST EnableNamespacePodSecurity enables pod security policy of a namespace + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}/podsecurity:enable + +> Body Parameters + +```json +{ + "podSecurity": [ + {} + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster of the namespace.| +|name|path|string| yes ||Name represents for the resource name.| +|body|body|object| no ||none| +|» podSecurity|body|[object]| no ||PodSecurity is a list of label combinations of mode plus level.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterNamespaceSummary gets a list of namespace simple information +from the system by given cluster name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespacesummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the namespace summary list belong to.| +|phase|query|string| no ||Phases is used for filter.| + +#### Description + +**phase**: Phases is used for filter. + + - NAMESPACE_PHASE_UNSPECIFIED: The namespace state is unspecified. + - Active: NamespaceActive means the namespace is available for use in the system + - Terminating: NamespaceTerminating means the namespace is undergoing graceful termination + +#### Enum + +|Name|Value| +|---|---| +|phase|NAMESPACE_PHASE_UNSPECIFIED| +|phase|Active| +|phase|Terminating| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListNodes lists the node in specified cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the node belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|phase|query|array[string]| no ||Phase represents the current phase of node.| +|nodeIp|query|string| no ||nodeIp represents node's ip address| +|sortBy|query|string| no ||SortBy determines the job list order reference.| +|sortDir|query|string| no ||OrderBy determines the job list order.| +|name|query|string| no ||Name is to filter nodes by node name| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|role|query|string| no ||Role is used for filter by node role.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|excludeMetrics|query|boolean| no ||exclude_metrics| + +#### Description + +**phase**: Phase represents the current phase of node. + + - NODE_PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Ready: The node is ready to work. + - Not_Ready: The node is not ready. + - Unknown: The node state is unknown. + +**sortBy**: SortBy determines the job list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the job list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**role**: Role is used for filter by node role. + + - NODE_ROLE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - CONTROL_PLANE: The control plane manages the worker nodes and the Pods in the cluster. + - WORKER: The worker node(s) host the Pods that are the components of the +application workload. + +**excludeMetrics**: exclude_metrics +If false, contains metrics-related information +If true, metrics-related information is not included + +#### Enum + +|Name|Value| +|---|---| +|phase|NODE_PHASE_UNSPECIFIED| +|phase|Ready| +|phase|Not_Ready| +|phase|Unknown| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|role|NODE_ROLE_UNSPECIFIED| +|role|CONTROL_PLANE| +|role|WORKER| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetNode gets a node from the system by given node name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the node belongs to.| +|name|path|string| yes ||Node name.| +|showPods|query|boolean| no ||ShowPods is to control whether returned data contains| +|excludeMetrics|query|boolean| no ||exclude_metrics| + +#### Description + +**showPods**: ShowPods is to control whether returned data contains +node.status.PodAllocated. Default false. + +**excludeMetrics**: exclude_metrics +If false, contains metrics-related information +If true, metrics-related information is not included + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateNode updates a node from the system by given node name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified node belongs to.| +|name|path|string| yes ||The name represents for the node name.| +|body|body|object| no ||none| +|» data|body|string| no ||The data is the node YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateNodeResponse](#schemav1alpha1updatenoderesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GetNodeJSON gets a node's json from the system by given node name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified node belongs to.| +|name|path|string| yes ||Name represents for the node name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST UnbindNodeToNamespace makes the specified node to shared. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{name}:unbindNamespace + +> Body Parameters + +```json +{ + "namespace": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the cluster for namespace and node.| +|name|path|string| yes ||Name is the node name for node which needs to| +|body|body|object| no ||none| +|» namespace|body|string| no ||Namespace is the namespace for node to unbind.| + +#### Description + +**name**: Name is the node name for node which needs to +be unbound with namespace. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateNodeAnnotations edits annotations of specified node. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/annotations + +> Body Parameters + +```json +{ + "annotations": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified node belongs to.| +|node|path|string| yes ||Node name.| +|body|body|object| no ||none| +|» annotations|body|object| no ||Annotations requested.| +|»» **additionalProperties**|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "annotations": { + "property1": "string", + "property2": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateNodeAnnotationsResponse](#schemav1alpha1updatenodeannotationsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST CordonNode makes the specified node to unschedulable. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/cordon + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified node belongs to.| +|node|path|string| yes ||Node name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateNodeGPUMode updates single the gpu mode with cluster node + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/gpu-mode + +> Body Parameters + +```json +{ + "mode": {}, + "migSpec": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|node|path|string| yes ||none| +|body|body|object| no ||none| +|» mode|body|object| no ||none| +|» migSpec|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "mode": {} +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateNodeGPUModeResponse](#schemav1alpha1updatenodegpumoderesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GetNodeGPUStats get node gpu stats + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/gpu-stats + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|node|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET listNodeGPU gets all the gpu info with cluster node + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/gpus + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|node|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT PutNodeLabels puts the specified node's labels + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/labels + +> Body Parameters + +```json +{ + "labels": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the node belongs to.| +|node|path|string| yes ||Node name.| +|body|body|object| no ||none| +|» labels|body|object| no ||the labels of node.| +|»» **additionalProperties**|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListPodsByNode lists pods info by given node in a specific +cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/pods + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the node belongs to.| +|node|path|string| yes ||Node represents which node the pod belongs to.| +|name|query|string| no ||Name is to filter pods by pod name| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the job list order reference.| +|sortDir|query|string| no ||OrderBy determines the job list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|status|query|string| no ||status is filter with pod status ,the status is composite state| + +#### Description + +**sortBy**: SortBy determines the job list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the job list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|status|FILTER_POD_STATUS_UNSPECIFIED| +|status|FILTER_POD_STATUS_RUNNING| +|status|FILTER_POD_STATUS_ERROR| +|status|FILTER_POD_STATUS_COMPLETED| +|status|FILTER_POD_STATUS_WAITING| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT PutNodeTaints puts a node's taints in a specific cluster + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/taints + +> Body Parameters + +```json +{ + "taints": [ + {} + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||// Cluster the specified node belongs to.| +|node|path|string| yes ||Node name.| +|body|body|object| no ||none| +|» taints|body|[object]| no ||If specified, the node's taints.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST UnCordonNode makes the specified node to schedulable. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes/{node}/uncordon + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified node belongs to.| +|node|path|string| yes ||Node name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST BatchBindNodeToNamespace makes the specified node to exclusive. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodes:batchBindNamespace + +> Body Parameters + +```json +{ + "namespace": "string", + "nodeNames": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the cluster for namespace and node.| +|body|body|object| no ||none| +|» namespace|body|string| no ||Namespace is the namespace for node to be bound.| +|» nodeNames|body|[string]| no ||NodeNames is the list of node name which| + +#### Description + +**» nodeNames**: NodeNames is the list of node name which +needs to be bound with namespace. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterNodeSummary lists the node summary in specified cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/nodesummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListPersistentVolumeClaims gets the pvcs from the system + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumeclaims + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|phase|query|string| no ||Phase is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|accessMode|query|string| no ||AccessMode is used searching PVC by accessMode.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**accessMode**: AccessMode is used searching PVC by accessMode. + + - PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - ReadWriteOnce: ReadWriteOnce can be mounted in read/write mode to exactly 1 host. + - ReadOnlyMany: ReadOnlyMany can be mounted in read-only mode to many hosts. + - ReadWriteMany: ReadWriteMany can be mounted in read/write mode to many hosts. + - ReadWriteOncePod: ReadWriteOncePod can be mounted in read/write mode to exactly 1 pod. +ReadWriteOncePod cannot be used in combination with other access modes. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|accessMode|PERSISTENT_VOLUME_ACCESS_MODE_UNSPECIFIED| +|accessMode|ReadWriteOnce| +|accessMode|ReadOnlyMany| +|accessMode|ReadWriteMany| +|accessMode|ReadWriteOncePod| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListPersistentVolumes lists persistentvolumes in the specified cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the PersistentVolumes belongs to.| +|name|query|string| no ||Name stands for PersistentVolume name, used for fuzzy search.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the PersistentVolume list order reference.| +|sortDir|query|string| no ||OrderBy determines the PersistentVolume list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter.| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| + +#### Description + +**sortBy**: SortBy determines the PersistentVolume list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the PersistentVolume list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreatePersistentVolume creates a persistentvolume to the system by given persistentvolume data + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified persistentVolume belongs to.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the persistentVolume YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetPersistentVolume gets a persistentvolume from the system by given persistentvolume name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified persistentVolume belongs to.| +|name|path|string| yes ||Name of the specified persistentVolume.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdatePersistentVolume updates a persistentvolume from the system by given persistentvolume name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified persistentVolume belongs to.| +|name|path|string| yes ||Name of the specified persistentVolume.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the persistentVolume YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdatePersistentVolumeResponse](#schemav1alpha1updatepersistentvolumeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeletePersistentVolume deletes a persistentvolume from the system by given persistentvolume name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the PersistentVolume belongs to.| +|name|path|string| yes ||Name represents for the PersistentVolume name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetPersistentVolumeJSON gets a persistentvolume json from the system by given persistentvolume name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/persistentvolumes/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified persistentVolume belongs to.| +|name|path|string| yes ||Name represents for the persistentVolume name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterPods will list all pod by given cluster and regardless of +namespaces + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/pods + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the pod belongs to.| +|namespace|query|string| no ||Namespace is the metadata.namespace of the referenced pod.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|phase|query|string| no ||Phases is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|status|query|string| no ||status is filter with pod status ,the status is composite state| +|excludeMetrics|query|boolean| no ||exclude_metrics| +|gpuType|query|string| no ||gpu_type is filter with pods resources, when value is * search all| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +**phase**: Phases is used for filter. + + - PHASE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Unknown: PodUnknown means that for some reason the state of the pod could not be +obtained, typically due to an error in communicating with the host of the +pod. + - Pending: PodPending means the pod has been accepted by the system, but one or more +of the containers has not been started. This includes time before being +bound to a node, as well as time spent pulling images onto the host. + - Running: PodRunning means the pod has been bound to a node and all of the +containers have been started. At least one container is still running or +is in the process of being restarted. PodSucceeded means that all +containers in the pod have voluntarily terminated with a container exit +code of 0, and the system is not going to restart any of these +containers. + - Succeeded: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + - Failed: PodFailed means that all containers in the pod have terminated, and at +least one container has terminated in a failure (exited with a non-zero +exit code or was stopped by the system). + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**excludeMetrics**: exclude_metrics +If false, contains metrics-related information +If true, metrics-related information is not included + +#### Enum + +|Name|Value| +|---|---| +|phase|PHASE_UNSPECIFIED| +|phase|Unknown| +|phase|Pending| +|phase|Running| +|phase|Succeeded| +|phase|Failed| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|status|FILTER_POD_STATUS_UNSPECIFIED| +|status|FILTER_POD_STATUS_RUNNING| +|status|FILTER_POD_STATUS_ERROR| +|status|FILTER_POD_STATUS_COMPLETED| +|status|FILTER_POD_STATUS_WAITING| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterSecrets lists a secret in a specific cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/secrets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the secret belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||The name use to search specific secret| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|type|query|string| no ||Type is used to filter secrets by type.| +|onlyMetadata|query|boolean| no ||OnlyMetadata lists only metadata of secrets, default false.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListNamespaces gets all the namespaces across clusters + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/serviceaccounts + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of sa to belongs to.| +|namesapce|query|string| no ||Namespace is the current namespace.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateServiceAccount updates a sa from the system by given sa name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/serviceaccounts/{name} + +> Body Parameters + +```json +{ + "namespace": "string", + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of ServiceAccount to belongs to.| +|name|path|string| yes ||name represents the name of ServiceAccount to belongs to.| +|body|body|object| no ||none| +|» namespace|body|string| no ||Namespace is the metadata.namespace of the referenced pod.| +|» data|body|string| no | The data is the ServiceAccount YAML details|none| + +#### Description + +**» namespace**: Namespace is the metadata.namespace of the referenced pod. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateServiceAccountResponse](#schemav1alpha1updateserviceaccountresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET ListClusterServices lists all services in the specified cluster, regardless +of namespace + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/services + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified service belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the service list order reference.| +|sortDir|query|string| no ||OrderBy determines the service list order.| +|name|query|string| no ||Name is used for query.| +|type|query|array[string]| no ||Type is a array used for frontend filter.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|ports|query|array[integer]| no ||Ports is used to filter by port.| + +#### Description + +**sortBy**: SortBy determines the service list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the service list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**type**: Type is a array used for frontend filter. +Use examples: type=CLUSTER_IP&type=NODE_PORT + + - SERVICE_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - ClusterIP: ClusterIP means a service will only be accessible inside the cluster, via +the cluster IP. + - NodePort: NodePort means a service will be exposed on one port of every node, in +addition to 'ClusterIP' type. + - LoadBalancer: LoadBalancer means a service will be exposed via an external load balancer +(if the cloud provider supports it), in addition to 'NodePort' type. + - ExternalName: ExternalName means a service consists of only a reference to an external +name that kubedns or equivalent will return as a CNAME record, with no +exposing or proxying of any pods involved. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|type|SERVICE_TYPE_UNSPECIFIED| +|type|ClusterIP| +|type|NodePort| +|type|LoadBalancer| +|type|ExternalName| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Core_ListClusterSriovAllocatedResources + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/sriovnodesresources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/CloudShell + + + +## POST CreateCloudShell create a cloudshell in golobal cluster. + +POST /apis/kpanda.io/v1alpha1/cloudshells + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCloudShell get a cloudshell in golobal cluster. + +GET /apis/kpanda.io/v1alpha1/cloudshells/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||name specified the cloudshell name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteCloudShell delete a cloudshell in golobal cluster. + +DELETE /apis/kpanda.io/v1alpha1/cloudshells/{name} + +> Body Parameters + +```json +{ + "type": {}, + "cluster": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||name specified the cloudshell name.| +|body|body|object| no ||none| +|» type|body|object| no ||none| +|» cluster|body|string| no ||cluster specified the cluster name for cloudshell.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Clusterlcm + + + +## POST Clusterlcm_CreateCluster + +POST /apis/kpanda.io/v1alpha1/cluster-lcm + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Clusterlcm_ListKubeVersions + +GET /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/available-kube-versions + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Clusterlcm_ListRuntimeVersions + +GET /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/available-runtime-versions + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|kubeVersion|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Clusterlcm_BatchAddNode + +POST /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/nodes + +> Body Parameters + +```json +{ + "role": {}, + "nodeInfos": [ + {} + ], + "type": {}, + "kubesprayArgs": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|body|body|object| no ||none| +|» role|body|object| no ||none| +|» nodeInfos|body|[object]| no ||none| +|» type|body|object| no ||none| +|» kubesprayArgs|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Clusterlcm_RemoveNode + +DELETE /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/nodes/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Clusterlcm_ListClusterlcmOps + +GET /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The name of the cluster.| +|name|query|string| no ||The fuzzy-name of the clusterclmOps.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||SortDir determines the order of the data.| +|targetCluster|query|string| no ||none| +|action|query|string| no ||none| +|phase|query|string| no ||none| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| + +#### Description + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: SortDir determines the order of the data. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| +|action|ACTION_UNSPECIFIED| +|action|CREATE_CLUSTER| +|action|UPGRADE_CLUSTER| +|action|RESET_CLUSTER| +|action|ADD_NODE| +|action|REMOVE_NODE| +|phase|STATUS_UNSPECIFIED| +|phase|Running| +|phase|Succeeded| +|phase|Failed| +|phase|Blocked| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Clusterlcm_GetClusterlcmOps + +GET /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The name of the cluster.| +|name|path|string| yes ||The name of the clusterclmOps.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Clusterlcm_DeleteClusterlcmOps + +DELETE /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The name of the manger cluster.| +|name|path|string| yes ||The name of the cluster which needs to be create.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Clusterlcm_GetClusterlcmOpsJSON + +GET /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/ops/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The name of the cluster.| +|name|path|string| yes ||The name of the clusterclmOps.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Clusterlcm_GetClusterlcmSettings + +GET /apis/kpanda.io/v1alpha1/cluster-lcm/{cluster}/settings + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The name of the cluster which needs to be create.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Clusterlcm_GetPreCheckClusterInfo + +POST /apis/kpanda.io/v1alpha1/cluster-lcm/{name}/precheck-infos + +> Body Parameters + +```json +{ + "dkgClusterName": "string", + "kubeVersion": "string", + "operation": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||The name of the cluster which needs to be create.| +|body|body|object| no ||none| +|» dkgClusterName|body|string| no ||The name of the manger cluster.| +|» kubeVersion|body|string| no | kubernetes version of cluster to be created|none| +|» operation|body|string| no ||operation represents the kubean operation name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Clusterlcm_CheckCluster + +POST /apis/kpanda.io/v1alpha1/cluster-lcm/{name}:check + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|body|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Clusterlcm_PreCheckCluster + +POST /apis/kpanda.io/v1alpha1/cluster-lcm/{name}:precheck + +> Body Parameters + +```json +{ + "dkgClusterName": "string", + "kubeVersion": "string", + "nodeConfig": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||The name of the cluster which needs to be create.| +|body|body|object| no ||none| +|» dkgClusterName|body|string| no ||The name of the manger cluster.| +|» kubeVersion|body|string| no ||none| +|» nodeConfig|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Clusterlcm_ResetCluster + +POST /apis/kpanda.io/v1alpha1/cluster-lcm/{name}:reset + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|body|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Clusterlcm_UpgradeCluster + +POST /apis/kpanda.io/v1alpha1/cluster-lcm/{name}:upgrade + +> Body Parameters + +```json +{ + "kubernetesVersion": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||The name of the cluster which needs to upgrade.| +|body|body|object| no ||none| +|» kubernetesVersion|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Cluster + + + +## GET ListClusters lists kpanda cr resources + +GET /apis/kpanda.io/v1alpha1/clusters + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|query|string| no ||Name is the user-specified identifier.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|role|query|string| no ||none| +|kubernetesVersion|query|string| no ||KUBERNETESVERSION cluster k8s version use to support search sub cluster at| +|phase|query|string| no ||Phase is used for filter.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter clusters.| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter the clusters.| +|managedBy|query|string| no ||ManagedBy represents who manages the cluster| +|sortBy|query|string| no ||SortBy determines the cluster list order reference.| +|sortDir|query|string| no ||OrderBy determines the cluster list order.| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether returned data contains| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by cluster name or cluster alias name.| +|excludeMetrics|query|boolean| no ||exclude_metrics| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**kubernetesVersion**: KUBERNETESVERSION cluster k8s version use to support search sub cluster at +ListClusters + +**phase**: Phase is used for filter. + + - CLUSTER_PHASE_UNSPECIFIED: The cluster state is unspecified. + - Unknown: The cluster state is unknown. + - Creating: The cluster is being created. + - Running: The cluster is running. + - Updating: The cluster is updating. + - Deleting: The cluster is being deleted. + - Failed: The cluster create failed. + - DeleteFailed: The cluster delete failed. + +**sortBy**: SortBy determines the cluster list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the cluster list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**showVirtualCluster**: ShowVirtualCluster is used to control whether returned data contains +virtualCluster. Default false. + +**excludeMetrics**: exclude_metrics +If false, contains metrics-related information +If true, metrics-related information is not included + +#### Enum + +|Name|Value| +|---|---| +|role|CLUSTER_ROLE_UNSPECIFIED| +|role|CLUSTER_ROLE_MANAGER| +|role|CLUSTER_ROLE_GLOBAL_SERVICE| +|role|CLUSTER_ROLE_WORKER| +|role|CLUSTER_ROLE_THIRD_PARTY| +|phase|CLUSTER_PHASE_UNSPECIFIED| +|phase|Unknown| +|phase|Creating| +|phase|Running| +|phase|Updating| +|phase|Deleting| +|phase|Failed| +|phase|DeleteFailed| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateCluster creates a cluster + +POST /apis/kpanda.io/v1alpha1/clusters + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Cluster_ValidateKubeConfig + +POST /apis/kpanda.io/v1alpha1/clusters/validate + +> Body Parameters + +```json +{ + "kubeConfigString": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[v1alpha1ValidateKubeConfigRequest](#schemav1alpha1validatekubeconfigrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "validateResult": true, + "errMsg": "string", + "kubeconfigExpireTime": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1ValidateKubeConfigResponse](#schemav1alpha1validatekubeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST CreateOpenAPIClusterCert creates openAPI cluster cert + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/clustercert + +> Body Parameters + +```json +{ + "kubeSystemID": "string", + "expirationSeconds": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||one of cluster or kubeSystemID has value| +|body|body|object| no ||none| +|» kubeSystemID|body|string| no ||kubeSystemID is the cluster system ID.| +|» expirationSeconds|body|integer(int32)| no ||ExpirationSeconds is the requested duration of validity of the request.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetClusterKubeConfig gets the specified cluster's kubeconfig + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/kubeconfig + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Cluster_ListClusterPreferredResources + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/preferredresources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster belongs to.| +|namespaced|query|boolean| no ||namespaced indicates whether this resource is cluster or namespace scoped.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCluster gets the details of the specified kpanda cr + +GET /apis/kpanda.io/v1alpha1/clusters/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||Name is the user-specified identifier.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|status|query|array[string]| no ||Status represents the current state of cluster.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|excludeMetrics|query|boolean| no ||exclude_metrics| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**excludeMetrics**: exclude_metrics +If false, contains metrics-related information +If true, metrics-related information is not included + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateClusters updates a cluster by cluster name + +PUT /apis/kpanda.io/v1alpha1/clusters/{name} + +> Body Parameters + +```json +{ + "aliasName": "string", + "provider": {}, + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "describe": "string", + "region": "string", + "zone": "string", + "kubeConfigString": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||Name is the user-specified identifier.| +|body|body|object| no ||none| +|» aliasName|body|string| no ||It is an alias given by the user and can be changed at will. It cannot be| +|» provider|body|object| no ||none| +|» labels|body|object| no ||Labels are key/value pairs that are attached to objects.| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||Annotations to attach arbitrary metadata to objects.| +|»» **additionalProperties**|body|string| no ||none| +|» describe|body|string| no ||Describe represents the details of the member cluster.| +|» region|body|string| no ||Region represents the region of the member cluster locate in.| +|» zone|body|string| no ||Zone represents the zone of the member cluster locate in.| +|» kubeConfigString|body|string| no ||KubeConfig of the cluster.| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**» aliasName**: It is an alias given by the user and can be changed at will. It cannot be +empty. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteCluster deletes the specified cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{name} + +> Body Parameters + +```json +{ + "deleteKpandaNamespace": true, + "deleteInsightAgent": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||Name is the user-specified identifier.| +|body|body|object| no ||none| +|» deleteKpandaNamespace|body|boolean| no ||DeleteKpandaNamespace represents whether to delete namespace of kpanda.| +|» deleteInsightAgent|body|boolean| no | DeleteInsightAgent represents whether to delete insight agent server.``|none| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT EditClusterLabels edits the specified cluster's labels + +PUT /apis/kpanda.io/v1alpha1/clusters/{name}/labels + +> Body Parameters + +```json +{ + "labels": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||Name is the user-specified identifier.| +|body|body|object| no ||none| +|» labels|body|object| no ||Labels are key/value pairs that are attached to objects.| +|»» **additionalProperties**|body|string| no ||none| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ValidateCluster checks if residuals which affect integrating exist in a cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{name}/validate + +> Body Parameters + +```json +{ + "unjoinCluster": true, + "kubeConfigString": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||Name is the user-specified identifier.| +|body|body|object| no ||none| +|» unjoinCluster|body|boolean| no ||JoinCluster represents whther the request is to join cluster.| +|» kubeConfigString|body|string| no ||KubeConfig of the cluster.| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**» unjoinCluster**: JoinCluster represents whther the request is to join cluster. +if true, the kube_config_string is required param, otherwise, the name is required. + +> Response Examples + +> 200 Response + +```json +{ + "dceComponents": { + "property1": true, + "property2": true + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1ValidateClusterResponse](#schemav1alpha1validateclusterresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET listClusterSummary lists cluster summary + +GET /apis/kpanda.io/v1alpha1/clustersummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|showVirtualCluster|query|boolean| no ||ShowVirtualCluster is used to control whether returned data contains| +|filterByStrategy|query|boolean| no ||FilterByStrategy is to list all the clusters without strategies if true, default false.| +|filterBySnapshot|query|boolean| no ||FilterBySnapshot is to list all the clusters which has snapshot if true, default false.| + +#### Description + +**showVirtualCluster**: ShowVirtualCluster is used to control whether returned data contains +virtualCluster. Default false. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusters lists kpanda cr resources + +GET /apis/kpanda.io/v1alpha1/gpus + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateOpenAPIClusterCertByKubeSystemID creates openAPI cluster cert by +kubeSystemID + +POST /apis/kpanda.io/v1alpha1/kubesystemid/{kubeSystemID}/clustercert + +> Body Parameters + +```json +{ + "cluster": "string", + "expirationSeconds": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|kubeSystemID|path|string| yes ||kubeSystemID is the cluster system ID.| +|body|body|object| no ||none| +|» cluster|body|string| no | one of cluster or kubeSystemID has value|none| +|» expirationSeconds|body|integer(int32)| no ||ExpirationSeconds is the requested duration of validity of the request.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Storage + + + +## GET ListAccessibleStorageClasses lists all storageclasses in accessible clusters + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/accessiblestorageclasses + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|provisioner|query|string| no ||Provisioner is used for fuzzy search by provisioner.| +|reclaimPolicy|query|string| no ||ReclaimPolicy is used for fuzzy search by reclaimPolicy.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListVolumeSnapshots list volume snapshot in single cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of VolumeSnapshot to belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the VolumeSnapshot belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateVolumeSnapshot create volume snapshot in single cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of VolumeSnapshot to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of VolumeSnapshot to belongs to.| +|body|body|object| no ||none| +|» data|body|string| no ||name represents the name of VolumeSnapshot to snapshot belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateVolumeSnapshot update volume snapshot + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of Volume snapshot to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of volume snapshot to belongs to.| +|name|path|string| yes ||name represents the name of volume snapshot to belongs to.| +|body|body|object| no ||none| +|» data|body|string| no | data represents the data of volume snapshot JSON|none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateVolumeSnapshotResponse](#schemav1alpha1updatevolumesnapshotresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteVolumeSnapshot delete volume snapshot in single cluster + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of VolumeSnapshot to belongs to.| +|namespace|path|string| yes ||namespace represents the namespace of VolumeSnapshot to belongs to.| +|name|path|string| yes ||name represents the name of VolumeSnapshot to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetVolumeSnapshotJSON list StorageClass in single cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/volumesnapshots/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of VolumeSnapshots belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the VolumeSnapshots belongs to.| +|name|path|string| yes ||Name represents the name of VolumeSnapshots to search| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListStorageClass list StorageClass in single cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|provisioner|query|string| no ||Provisioner is used for fuzzy search by provisioner.| +|reclaimPolicy|query|string| no ||ReclaimPolicy is used for fuzzy search by reclaimPolicy.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateStorageClass + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents the cluster of StorageClass to belongs to.| +|body|body|object| no ||none| +|» data|body|string| no | The data is the StorageClass YAML details|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetStorageClass get StorageClass in single cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|name|path|string| yes ||name represents the name of StorageClass to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateStorageClass update storage class + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the cluster of StorageClass to belongs to.| +|name|path|string| yes ||name represents the name of StorageClass to belongs to.| +|body|body|object| no ||none| +|» data|body|string| no | The data is the StorageClass YAML details|none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateStorageClassResponse](#schemav1alpha1updatestorageclassresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteStorageClass + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the StorageClass belongs to.| +|name|path|string| yes ||Name represents the name of StorageClass| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetStorageClassJSON get StorageClass json in single cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/storageclasses/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of PVC to belongs to.| +|name|path|string| yes ||name represents the name of StorageClass to belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterVolumeSnapshots will list all VolumeSnapshot by given cluster and regardless of +namespaces + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/volumesnapshots + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents the name of VolumeSnapshot to belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|name|query|string| no ||Name is used for filter.| +|sortBy|query|string| no ||SortBy determines the list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| + +#### Description + +**sortBy**: SortBy determines the list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Autoscaling + + + +## PUT UpdateClusterResourceOverride updates a cro by given json. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterresourceoverride + +> Body Parameters + +```json +{ + "data": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster defines the cluster name.| +|body|body|object| no ||none| +|» data|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateClusterResourceOverride creates a cro by given json. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterresourceoverride + +> Body Parameters + +```json +{ + "data": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster defines the cluster name.| +|body|body|object| no ||none| +|» data|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetClusterResourceOverride gets a cro by name. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterresourceoverride/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster defines the cluster name.| +|name|path|string| yes ||name defines the name of ClusterResourceOverride.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteClusterResourceOverride deletes a cro by name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/clusterresourceoverride/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster defines the cluster name.| +|name|path|string| yes ||name defines the name of ClusterResourceOverride.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListCustomMetricsSummary return the custom metrics for specified +resource. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/custommetricsummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the custom metrics belongs to.| +|kind|query|string| no ||The kind of hpa targetRef.| + +#### Description + +**kind**: The kind of hpa targetRef. + + - Pod: The custom metrics for service. + - Service: The custom metrics for service. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Pod| +|kind|Service| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListCronHorizontalPodAutoscalers lists cron hpas in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the hpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced hpa.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|kind|query|string| no ||The kind of hpa targetRef.| +|name|query|string| no ||The workload name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced hpa. +This field is required in all cases. + +**kind**: The kind of hpa targetRef. + + - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Deployment: A hpa which targetRef kind is Deployment. + - StatefulSet: A hpa which targetRef kind is StatefulSet. + - ReplicaSet: A hpa which targetRef kind is ReplicaSet. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|kind|StatefulSet| +|kind|ReplicaSet| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateCronHorizontalPodAutoscaler creates a cron hpa by given json. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified hpa belongs to.| +|namespace|path|string| yes ||When the current namespace is named, the priority is higher than that in yaml| +|body|body|object| no ||none| +|» data|body|string| no | The data field is the hpa YAML details|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateCronHorizontalPodAutoscaler updates the specified cron hpa, the body must +be a JSON string. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified hpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced hpa.| +|name|path|string| yes ||name represents for the resource name| +|body|body|object| no ||none| +|» data|body|string| no | data The data field is the hpa YAML details|none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced hpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteCronHorizontalPodAutoscaler deletes a cron hpa by given name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the hpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced hpa.| +|name|path|string| yes ||Name is the metadata.name of the referenced hpa.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced hpa. +This field is required in all cases. + +**name**: Name is the metadata.name of the referenced hpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCronHorizontalPodAutoscalerJSON gets the cron hpa by namespace and name, +returns a string in JSON format. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/cronhorizontalpodautoscalers/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the pod belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced HorizontalPodAutoscaler.| +|name|path|string| yes ||HorizontalPodAutoscaler name.| +|stable|query|boolean| no ||If stable is true, the v2 version under the corresponding package will be returned.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced HorizontalPodAutoscaler. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListHorizontalPodAutoscalers lists hpas in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the hpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced hpa.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|kind|query|string| no ||The kind of hpa targetRef.| +|name|query|string| no ||The workload name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced hpa. +This field is required in all cases. + +**kind**: The kind of hpa targetRef. + + - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Deployment: A hpa which targetRef kind is Deployment. + - StatefulSet: A hpa which targetRef kind is StatefulSet. + - ReplicaSet: A hpa which targetRef kind is ReplicaSet. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|kind|StatefulSet| +|kind|ReplicaSet| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateHorizontalPodAutoscaler creates a hpa by given json. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified hpa belongs to.| +|namespace|path|string| yes ||When the current namespace is named, the priority is higher than that in yaml| +|body|body|object| no ||none| +|» data|body|string| no | The data field is the hpa YAML details|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateHorizontalPodAutoscaler updates the specified hpa, the body must +be a JSON string. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified hpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced hpa.| +|name|path|string| yes ||name represents for the resource name| +|body|body|object| no ||none| +|» data|body|string| no | data The data field is the hpa YAML details|none| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced hpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateHorizontalPodAutoscalerResponse](#schemav1alpha1updatehorizontalpodautoscalerresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteHorizontalPodAutoscaler deletes a hpa by given name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the hpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced hpa.| +|name|path|string| yes ||Name is the metadata.name of the referenced hpa.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced hpa. +This field is required in all cases. + +**name**: Name is the metadata.name of the referenced hpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHorizontalPodAutoscalerJSON gets the hpa by namespace and name, +returns a string in JSON format. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/horizontalpodautoscalers/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the pod belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced HorizontalPodAutoscaler.| +|name|path|string| yes ||HorizontalPodAutoscaler name.| +|stable|query|boolean| no ||If stable is true, the v2 version under the corresponding package will be returned.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced HorizontalPodAutoscaler. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListMetricValueList returns a list of metrics values for a given +resource. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/metricvalues + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the hpa belongs to.| +|namespace|path|string| yes ||none| +|kind|query|string| no ||The kind of metrics.| +|kindName|query|string| no ||none| +|name|query|string| no ||The exact name of metric.| + +#### Description + +**kind**: The kind of metrics. + + - Pod: The custom metrics for service. + - Service: The custom metrics for service. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Pod| +|kind|Service| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListVerticalPodAutoscalers lists vpas in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the vpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced vpa.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|kind|query|string| no ||The kind of vpa targetRef.| +|kindName|query|string| no ||The name of the targetRef.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced vpa. +This field is required in all cases. + +**kind**: The kind of vpa targetRef. + + - KIND_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Deployment: A vpa which targetRef kind is Deployment. + - StatefulSet: A vpa which targetRef kind is StatefulSet. + - DaemonSet: A vpa which targetRef kind is DaemonSet. + - ReplicaSet: A vpa which targetRef kind is ReplicaSet. + - Job: A vpa which targetRef kind is Job. + - CronJob: A vpa which targetRef kind is CronJob. + - ReplicationController: A vpa which targetRef kind is ReplicationController. + +**kindName**: The name of the targetRef. +If the kind is StatefulSet, this presents the name of statefulset. + +#### Enum + +|Name|Value| +|---|---| +|kind|KIND_UNSPECIFIED| +|kind|Deployment| +|kind|StatefulSet| +|kind|DaemonSet| +|kind|ReplicaSet| +|kind|Job| +|kind|CronJob| +|kind|ReplicationController| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateVerticalPodAutoscaler creates a vpa by given json. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified vpa belongs to.| +|namespace|path|string| yes ||Namespace of the vpa.| +|body|body|object| no ||none| +|» data|body|string| no ||The data field is the vpa YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateVerticalPodAutoscaler updates the specified vpa, the body must +be a JSON string. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified vpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced vpa.| +|name|path|string| yes ||Name represents for the resource name.| +|body|body|object| no ||none| +|» data|body|string| no ||Data is the vpa YAML details.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced vpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateVerticalPodAutoscalerResponse](#schemav1alpha1updateverticalpodautoscalerresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteVerticalPodAutoscaler deletes a vpa by given name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the vpa belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced vpa.| +|name|path|string| yes ||Name is the metadata.name of the vpa.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced vpa. +This field is required in all cases. + +**name**: Name is the metadata.name of the vpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetVerticalPodAutoscalerJSON gets a vpa by namespace and name, returning a string in JSON format. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/verticalpodautoscalers/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the vpa belongs to.| +|namespace|path|string| yes ||Namespace of the vpa.| +|name|path|string| yes ||Name of the vpa.| +|stable|query|boolean| no ||If stable is true, the v2 version under the corresponding package will be returned.| + +#### Description + +**namespace**: Namespace of the vpa. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Apiextensions + + + +## GET ListCustomResourceDefinitionGroups lists all groups of customResourceDefinitions in the specified cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/crd-groups + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster to request| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListCustomResourceDefinitions lists customResourceDefinitions in the specified cluster + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster cluster to be queried| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||Name search the custom resource definitions fo name| +|status|query|array[string]| no ||Status search the custom resource definitions fo status| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|group|query|string| no ||Group is to filter customResourceDefinitions by group.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateCustomResourceDefinition creates a customResourceDefinition to the +system by given customResourceDefinition data + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified customResourceDefinition belongs to.| +|body|body|object| no | CreateCustomResourceDefinitionRequest represents post request to a +customResourceDefinition|none| +|» data|body|string| no ||The data field is the customResourceDefinition YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCustomResourceDefinition gets a customResourceDefinition from +the system by given customResourceDefinition name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResourceDefinition belongs to.| +|name|path|string| yes ||Name represents the name of CustomResourceDefinition.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateCustomResourceDefinition updates a customResourceDefinition from the +system by given customResourceDefinition name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified customResourceDefinition belongs to.| +|name|path|string| yes ||Name represents for the resource name.| +|body|body|object| no | UpdateCustomResourceDefinitionRequest represents put request to a +customResourceDefinition|none| +|» data|body|string| no ||The data field is the customResourceDefinition YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteCustomResourceDefinition deletes a customResourceDefinition from the +system by given customResourceDefinition name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified customResourceDefinition belongs to.| +|name|path|string| yes ||Name is the metadata.name of the referenced customResourceDefinition.| + +#### Description + +**name**: Name is the metadata.name of the referenced customResourceDefinition. +This field is required in all cases. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCustomResourceDefinitionJSON gets a customResourceDefinition json from +the system by given customResourceDefinition name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/customresourcedefinitions/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResourceDefinition belongs to.| +|name|path|string| yes ||Name represents the name of CustomResourceDefinition.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListCustomResources lists customResources of namespaced scope from the +system + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResources belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResources.| +|version|path|string| yes ||Version represents the resource version of CustomResources.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResources belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResources, which is plural.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||name is used for query.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|showDetail|query|boolean| no ||ShowDetail is the presentation details, including metadata, spec, and status| +|ownerReference|query|string| no ||OwnerReference indicates that the query is based on the OwnerReference.| + +#### Description + +**resource**: Resource represents the resource name of CustomResources, which is plural. +You can find it in plural field of related CRD definition. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateCustomResource creates a customResource of namespaced scope to the +system by given customResource data + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|body|body|object| no | CreateCustomResourceRequest represents create request to create one +CustomResource of namespaced scope|none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCustomResource gets a customResource of namespaced scope from +the system + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|showDetail|query|boolean| no ||ShowDetail is the presentation details, including metadata, spec, and status| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateCustomResource updates a customResource of namespaced scope from the +system by given customResource name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|body|body|object| no | UpdateCustomResourceRequest represents update request to update one +CustomResource of namespaced scope|none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteCustomResource deletes a customResource of namespaced scope from the +system by given customResource name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|deletionPropagation|query|string| no || - DELETION_PROPAGATION_ORPHAN: Orphans the dependents.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +**deletionPropagation**: - DELETION_PROPAGATION_ORPHAN: Orphans the dependents. + - DELETION_PROPAGATION_BACKGROUND: Deletes the object from the key-value store, the garbage collector will +delete the dependents in the background. + - DELETION_PROPAGATION_FOREGROUND: The object exists in the key-value store until the garbage collector +deletes all the dependents whose ownerReference.blockOwnerDeletion=true +from the key-value store. API sever will put the "foregroundDeletion" +finalizer on the object, and sets its deletionTimestamp. This policy is +cascading, i.e., the dependents will be deleted with Foreground. + +#### Enum + +|Name|Value| +|---|---| +|deletionPropagation|DELETION_PROPAGATION_UNSPECIFIED| +|deletionPropagation|DELETION_PROPAGATION_ORPHAN| +|deletionPropagation|DELETION_PROPAGATION_BACKGROUND| +|deletionPropagation|DELETION_PROPAGATION_FOREGROUND| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchCustomResource patches a customResource of cluster scope from +the system by given customResource name + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name} + +> Body Parameters + +```json +{ + "patchType": {}, + "data": "string", + "subResources": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|body|body|object| no | PatchCustomResourceRequest represents patch request to update one +CustomResource of cluster scope|none| +|» patchType|body|object| no ||none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| +|» subResources|body|[string]| no ||none| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetCustomResourceJSON gets a customResource of namespaced scope json from +the system + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateCustomResourceStatus updates the status of a customResource + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/namespaces/{namespace}/{resource}/{name}/status + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|namespace|path|string| yes ||Namespace represents which namespace the CustomResource belongs to.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|body|body|object| no | UpdateCustomResourceStatusRequest requests to update the status of a customResource of namespaced scope|none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterCustomResources lists customResources of cluster scope + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResources belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResources.| +|version|path|string| yes ||Version represents the resource version of CustomResources.| +|resource|path|string| yes ||Resource represents the resource name of CustomResources, which is plural.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|name|query|string| no ||name is used for query.| +|sortBy|query|string| no ||SortBy determines the data list order reference.| +|sortDir|query|string| no ||OrderBy determines the data list order.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|showDetail|query|boolean| no ||ShowDetail is the presentation details, including metadata, spec, and status| + +#### Description + +**resource**: Resource represents the resource name of CustomResources, which is plural. +You can find it in plural field of related CRD definition. + +**sortBy**: SortBy determines the data list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the data list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateClusterCustomResource creates a customResource of cluster scope to +the system by given customResource data + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|body|body|object| no | CreateClusterCustomResourceRequest represents create request to create one +CustomResource of cluster scope|none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetClusterCustomResource gets a customResource of cluster scope + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|showDetail|query|boolean| no ||ShowDetail is the presentation details, including metadata, spec, and status| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateClusterCustomResource updates a customResource of cluster scope from +the system by given customResource name + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|body|body|object| no | UpdateClusterCustomResourceRequest represents update request to update one +CustomResource of cluster scope|none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteClusterCustomResource deletes a customResource of cluster scope from +the system by given customResource name + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|deletionPropagation|query|string| no || - DELETION_PROPAGATION_ORPHAN: Orphans the dependents.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +**deletionPropagation**: - DELETION_PROPAGATION_ORPHAN: Orphans the dependents. + - DELETION_PROPAGATION_BACKGROUND: Deletes the object from the key-value store, the garbage collector will +delete the dependents in the background. + - DELETION_PROPAGATION_FOREGROUND: The object exists in the key-value store until the garbage collector +deletes all the dependents whose ownerReference.blockOwnerDeletion=true +from the key-value store. API sever will put the "foregroundDeletion" +finalizer on the object, and sets its deletionTimestamp. This policy is +cascading, i.e., the dependents will be deleted with Foreground. + +#### Enum + +|Name|Value| +|---|---| +|deletionPropagation|DELETION_PROPAGATION_UNSPECIFIED| +|deletionPropagation|DELETION_PROPAGATION_ORPHAN| +|deletionPropagation|DELETION_PROPAGATION_BACKGROUND| +|deletionPropagation|DELETION_PROPAGATION_FOREGROUND| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetClusterCustomResourceJSON gets a customResource json of cluster scope + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateClusterCustomResourceStatus updates the status of a customResource of cluster scope + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/gvr/{group}/{version}/{resource}/{name}/status + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the CustomResource belongs to.| +|group|path|string| yes ||Group represents the resource group of CustomResource.| +|version|path|string| yes ||Version represents the resource version of CustomResource.| +|resource|path|string| yes ||Resource represents the resource name of CustomResource, which is plural.| +|name|path|string| yes ||Name represents the name of CustomResource.| +|body|body|object| no | UpdateClusterCustomResourceStatusRequest requests to update the status of a CustomResource of cluster scope|none| +|» data|body|string| no ||The data field is the CustomResource YAML details.| + +#### Description + +**resource**: Resource represents the resource name of CustomResource, which is plural. +You can find it in plural field of related CRD definition. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateResource creates a list of resources of a given yaml + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/resources + +> Body Parameters + +```json +{ + "data": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the resources belong to.| +|namespace|path|string| yes ||Namespace represents which namespace the resources belong to.| +|body|body|object| no | CreateResourceRequest represents create request to create resources from yaml|none| +|» data|body|[string]| no ||The data field is the resource YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/EtcdBackupRestore + + + +## POST VerifyEtcdConnection verifies the etcd connection. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/etcd:verify + +> Body Parameters + +```json +{ + "etcdConnectionConfig": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd snapstore belongs to.| +|body|body|object| no ||none| +|» etcdConnectionConfig|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "success": true, + "errMsg": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1VerifyEtcdConnectionResponse](#schemav1alpha1verifyetcdconnectionresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VerifySnapStore verifies the SnapStore config. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/snapstores:verify + +> Body Parameters + +```json +{ + "accessKeyId": "string", + "secretAccessKey": "string", + "bucket": "string", + "endpoint": "string", + "region": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd snapstore belongs to.| +|body|body|object| no ||none| +|» accessKeyId|body|string| no ||username or access key id for S3.| +|» secretAccessKey|body|string| no ||password or secret key for S3.| +|» bucket|body|string| no ||the bucket name for S3.| +|» endpoint|body|string| no ||endpoint for S3.| +|» region|body|string| no ||region for S3.| + +> Response Examples + +> 200 Response + +```json +{ + "success": true, + "errMsg": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1VerifySnapStoreConfigResponse](#schemav1alpha1verifysnapstoreconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST CreateEtcdBackupStrategy creates a etcd backup strategy. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies + +> Body Parameters + +```json +{ + "name": "string", + "strategy": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified etcd backup strategy belongs to.| +|body|body|object| no ||none| +|» name|body|string| no ||The name for EtcdBackupStrategy.| +|» strategy|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetEtcdBackupStrategy get a etcd backup strategy in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified etcd backup strategy belongs to.| +|name|path|string| yes ||Name represents for the etcd backup strategy name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateEtcdBackupStrategy updates tcd backup strategy under the cluster + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name} + +> Body Parameters + +```json +{ + "strategy": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified etcd backup strategy belongs to.| +|name|path|string| yes ||The name for EtcdBackupStrategy.| +|body|body|object| no ||none| +|» strategy|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteEtcdBackupStrategy delete a etcd backup strategy in cluster. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd backup strategy belongs to.| +|name|path|string| yes ||Name represents the name of etcd backup strategy| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetEtcdBackupStrategyJSON get a etcd backup strategy json in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified etcd backup strategy belongs to.| +|name|path|string| yes ||Name represents for the etcd backup strategy name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ExecuteEtcdBackupStrategy executes a etcd backup strategy under the cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}:execute + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd backup strategy belongs to.| +|name|path|string| yes ||Name represents the name of etcd backup strategy.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST PauseEtcdBackupStrategy pauses a etcd backup strategy under the cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}:pause + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd backup strategy belongs to.| +|name|path|string| yes ||Name represents the name of etcd backup strategy| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ResumeEtcdBackupStrategy resumes a etcd backup strategy under the cluster + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{name}:resume + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd backup strategy belongs to.| +|name|path|string| yes ||Name represents the name of etcd backup strategy| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListEtcdSnapshots list etcd backup snapshots . + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{strategy}/snapshots + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd backup strategy belongs to.| +|strategy|path|string| yes ||strategy represents the name of etcd backup strategy.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteEtcdBackup delete a etcd backup. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/etcdbackuprestore/strategies/{strategy}/snapshots/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the etcd backup strategy belongs to.| +|strategy|path|string| yes ||strategy represents the name of etcd backup strategy.| +|name|path|string| yes ||Name represents the name of etcd snapshot.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListEtcdBackupStrategies list etcd backup strategies. + +GET /apis/kpanda.io/v1alpha1/etcdbackuprestore/strategies + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||cluster represents which cluster the repository belongs to.| +|name|query|string| no ||Name is the user-specified identifier.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the repository list order reference.| +|sortDir|query|string| no ||OrderBy determines the repository list order.| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**sortBy**: SortBy determines the repository list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the repository list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Addon + + + +## GET ListCharts list chart from repositories. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmcharts + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the chart belongs to.| +|name|query|string| no ||Helm chart name.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|category|query|string| no ||Category is used for query.| +|repo|query|array[string]| no ||The repo name which the charts belongs to.| +|required|query|boolean| no ||Required indicates whether to display the charts, which are required to install the cluster.| + +#### Description + +**category**: Category is used for query. + + - CATEGORY_UNSPECIFIED: The Category is unspecified. + +#### Enum + +|Name|Value| +|---|---| +|category|CATEGORY_UNSPECIFIED| +|category|CATEGORY_OTHERS| +|category|CATEGORY_STORAGE| +|category|CATEGORY_NETWORKING| +|category|CATEGORY_MONITORING| +|category|CATEGORY_DATABASE| +|category|CATEGORY_DATASERVICE| +|category|CATEGORY_ECOAPP| +|category|CATEGORY_BIGDATA| +|category|CATEGORY_SECURITY| +|category|CATEGORY_IOTEDGE| +|category|CATEGORY_INFRA| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterInstalledHelmChart list the charts which installed belong to repo + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmcharts/installed + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the chart belongs to.| +|repoName|query|array[string]| no ||repo_name represents which helm repo's name use to list installed helm chart| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterHelmOperations list operation in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmoperations + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified operation belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the event list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||name is used for query.| +|releaseName|query|string| no ||Filter helm_operation by release_name,| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the event list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**name**: name is used for query. ++optional + +**releaseName**: Filter helm_operation by release_name, +The release_name is exactly. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterHelmReleases list apps in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmreleases + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster the specified operation belongs to.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the event list order reference.| +|sortDir|query|string| no ||OrderBy determines the list order.| +|name|query|string| no ||name is used for query.| +|helmChartName|query|string| no ||the helm releases's chart name| +|helmChartRepo|query|string| no ||the helm releases's chart repo name| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**sortBy**: SortBy determines the event list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**name**: name is used for query. ++optional + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListHelmRepos list repo in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|name|query|string| no ||Name is the user-specified identifier.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the repository list order reference.| +|sortDir|query|string| no ||OrderBy determines the repository list order.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|builtIn|query|boolean| no ||builtin indicates whether to display the repos required to install the cluster.| + +#### Description + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**sortBy**: SortBy determines the repository list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the repository list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateHelmRepo create a repo in cluster. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos + +> Body Parameters + +```json +{ + "name": "string", + "description": "string", + "url": "string", + "verificationMethod": "VERIFICATION_METHOD_UNSPECIFIED", + "userName": "string", + "password": "string", + "token": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "insecureSkipTLSVerify": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|body|body|object| no ||none| +|» name|body|string| no ||The name represents for the resource name.| +|» description|body|string| no ||The description represents for the resource.| +|» url|body|string| no | url A http url of the repo to connect to|none| +|» verificationMethod|body|[v1alpha1VerificationMethod](#schemav1alpha1verificationmethod)| no | Repository verification method|- VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified.| +|» userName|body|string| no | Repository user name|none| +|» password|body|string| no | Repository user password|none| +|» token|body|string| no | Repository token|none| +|» labels|body|object| no ||Labels are key/value pairs that are attached to objects.| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||Annotations to attach arbitrary metadata to objects.| +|»» **additionalProperties**|body|string| no ||none| +|» insecureSkipTLSVerify|body|boolean| no ||InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index.| + +#### Description + +**» verificationMethod**: - VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified. + - None: The repository is public and does not require authentication. + - BasicAuth: BasicAuth contains data needed for basic authentication. + +#### Enum + +|Name|Value| +|---|---| +|» verificationMethod|VERIFICATION_METHOD_UNSPECIFIED| +|» verificationMethod|None| +|» verificationMethod|BasicAuth| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmRepo get a repo in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateHelmRepo update repo + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name} + +> Body Parameters + +```json +{ + "description": "string", + "url": "string", + "verificationMethod": "VERIFICATION_METHOD_UNSPECIFIED", + "userName": "string", + "password": "string", + "token": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "insecureSkipTLSVerify": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|body|body|object| no ||none| +|» description|body|string| no ||The description represents for the resource.| +|» url|body|string| no | url A http url of the repo to connect to|none| +|» verificationMethod|body|[v1alpha1VerificationMethod](#schemav1alpha1verificationmethod)| no | Repository verification method|- VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified.| +|» userName|body|string| no | Repository user name|none| +|» password|body|string| no | Repository user password|none| +|» token|body|string| no | Repository token|none| +|» labels|body|object| no ||Labels are key/value pairs that are attached to objects.| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||Annotations to attach arbitrary metadata to objects.| +|»» **additionalProperties**|body|string| no ||none| +|» insecureSkipTLSVerify|body|boolean| no ||InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index.| + +#### Description + +**» verificationMethod**: - VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified. + - None: The repository is public and does not require authentication. + - BasicAuth: BasicAuth contains data needed for basic authentication. + +#### Enum + +|Name|Value| +|---|---| +|» verificationMethod|VERIFICATION_METHOD_UNSPECIFIED| +|» verificationMethod|None| +|» verificationMethod|BasicAuth| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteHelmRepo delete a repo in cluster. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmRepoJSON get a repo json in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ValidateHelmRepo verifies if a repo is connectable. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}/validate + +> Body Parameters + +```json +{ + "url": "string", + "verificationMethod": "VERIFICATION_METHOD_UNSPECIFIED", + "userName": "string", + "password": "string", + "insecureSkipTLSVerify": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster of the repo| +|name|path|string| yes ||Name of the repo| +|body|body|object| no | ValidateHelmRepoRequest requests to validate the connection to a helm repo|none| +|» url|body|string| no | Url of the repo to connect to|none| +|» verificationMethod|body|[v1alpha1VerificationMethod](#schemav1alpha1verificationmethod)| no | Repository verification method|- VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified.| +|» userName|body|string| no | Repository user name|none| +|» password|body|string| no | Repository user password|none| +|» insecureSkipTLSVerify|body|boolean| no ||InsecureSkipTLSVerify will use insecure HTTPS to download the helmrepo's index.| + +#### Description + +**» verificationMethod**: - VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified. + - None: The repository is public and does not require authentication. + - BasicAuth: BasicAuth contains data needed for basic authentication. + +#### Enum + +|Name|Value| +|---|---| +|» verificationMethod|VERIFICATION_METHOD_UNSPECIFIED| +|» verificationMethod|None| +|» verificationMethod|BasicAuth| + +> Response Examples + +> 200 Response + +```json +{ + "success": true, + "error": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1ValidateHelmRepoResponse](#schemav1alpha1validatehelmreporesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST RefreshHelmRepo updates a helm repo's index. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{name}:refresh + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the helmrepo belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmChartVersion get a chart version info from repository. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|repo|path|string| yes ||The repo represents for the charts belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|version|query|string| no ||The version represents for the resource version.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmChartDisplay get a chart display info from repository. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/display + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|repo|path|string| yes ||The repo represents for the charts belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|version|query|string| no ||The version represents for the resource version.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmChartFiles get a chart files from repository. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/files + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|repo|path|string| yes ||The repo represents for the charts belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|version|query|string| no ||The version represents for the resource version.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST GetHelmChartManifest get a chart manifests info from repository. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/manifests + +> Body Parameters + +```json +{ + "version": "string", + "releaseName": "string", + "namespace": "string", + "values": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|repo|path|string| yes ||The repo represents for the charts belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|body|body|object| no ||none| +|» version|body|string| no ||The version represents for the resource version.| +|» releaseName|body|string| no ||release_name is the name of the release.| +|» namespace|body|string| no ||release_name is the name of the release namspace.| +|» values|body|string| no ||Config is the set of extra Values added to the chart.| + +#### Description + +**» values**: Config is the set of extra Values added to the chart. +These values override the default values inside of the chart. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmChartResources get the resources contained in charts. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}/resources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|repo|path|string| yes ||The repo represents for the charts belongs to.| +|name|path|string| yes ||The name represents for the resource name.| +|version|query|string| no ||The version represents for the resource version.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST GetHelmInstallConfig create a Release. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/helmrepos/{repo}/helmcharts/{name}:config + +> Body Parameters + +```json +{ + "version": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|repo|path|string| yes ||The repo represents for the charts belongs to.| +|name|path|string| yes ||Name represents the name of helmrelease| +|body|body|object| no ||none| +|» version|body|string| no ||Version is an int which represents the version of the chart.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListHelmOperations list operation in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|query|string| no ||Name is the user-specified identifier.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the repository list order reference.| +|sortDir|query|string| no ||OrderBy determines the repository list order.| +|releaseName|query|string| no ||Filter helm_operation by release_name,| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**sortBy**: SortBy determines the repository list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the repository list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +**releaseName**: Filter helm_operation by release_name, +The release_name is exactly. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmOperation get a operation in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the daemonSet belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteHelmOperation delete a operation in cluster. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the daemonSet belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmOperationJSON get a operation json in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmoperations/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the repository belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the daemonSet belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListHelmReleases lists apps in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the releases belongs to.| +|namespace|path|string| yes ||Namespace is the metadata.namespace of the referenced ConfigMap.| +|name|query|string| no ||Name is the user-specified identifier.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page requested.| +|sortBy|query|string| no ||SortBy determines the release list order reference.| +|sortDir|query|string| no ||OrderBy determines the release list order.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**namespace**: Namespace is the metadata.namespace of the referenced ConfigMap. +This field is required in all cases. + +**name**: Name is the user-specified identifier. +This field may not be updated. + +**sortBy**: SortBy determines the release list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy determines the release list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateHelmRelease creates a Release. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases + +> Body Parameters + +```json +{ + "repo": "string", + "timeout": "string", + "wait": true, + "atomic": true, + "debug": true, + "disableHooks": true, + "disableOpenApiValidation": true, + "createNamespace": true, + "checkReleaseName": true, + "chart": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the chart belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helm release belongs to.| +|body|body|object| no ||none| +|» repo|body|string| no ||The repo represents for the charts belongs to.| +|» timeout|body|string| no ||Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s).| +|» wait|body|boolean| no ||If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout.| +|» atomic|body|boolean| no ||If set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used.| +|» debug|body|boolean| no ||Enable verbose output.| +|» disableHooks|body|boolean| no ||Prevent hooks from running during install.| +|» disableOpenApiValidation|body|boolean| no ||If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema.| +|» createNamespace|body|boolean| no ||Create the release namespace if not present.| +|» checkReleaseName|body|boolean| no ||Check whether the release name entered during installation matches the release name in charts annotations.| +|» chart|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListHelmReleaseResources lists resources related to the specified helm release. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{helmrelease}/resources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the helmrelease belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|helmrelease|path|string| yes ||Name of the helmrelease.| +|name|query|string| no ||Name is used to fuzzy search resources which belongs to this helmrelease by resource name.| +|kind|query|string| no ||Kind is used to filter resources which belongs to this helmrelease by resource kind.| +|phase|query|string| no ||Phase is used to filter resources which belongs to this helmrelease by resource phase.| +|page|query|integer(int32)| no ||Page is current page.| +|pageSize|query|integer(int32)| no ||Size is the data number shown per page.| +|sortBy|query|string| no ||SortBy determines the resource list order reference.| +|sortDir|query|string| no ||SortDir determines the list order.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**phase**: Phase is used to filter resources which belongs to this helmrelease by resource phase. + + - RESOURCE_PHASE_UNSPECIFIED: ResourcePhase unspecified. + - InProgress: Resource in progress. + - Failed: Resource failed. + - Current: Resource current. + - Terminating: Resource terminating. + - Unknown: Resource unknown. + +**sortBy**: SortBy determines the resource list order reference. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: SortDir determines the list order. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|phase|RESOURCE_PHASE_UNSPECIFIED| +|phase|InProgress| +|phase|Failed| +|phase|Current| +|phase|Terminating| +|phase|Unknown| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListHelmReleaseRevisions lists revisions of the specified helm release. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{helmrelease}/revisions + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the helmrelease belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|helmrelease|path|string| yes ||Name of the helmrelease.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmRelease gets a release in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the helmrelease belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|name|path|string| yes ||Name of the helmrelease.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateHelmRelease updates a release. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name} + +> Body Parameters + +```json +{ + "repo": "string", + "timeout": "string", + "wait": true, + "atomic": true, + "debug": true, + "disableHooks": true, + "disableOpenApiValidation": true, + "force": true, + "maxHistory": 0, + "install": true, + "cleanupOnFail": true, + "chart": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the helmrelease belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|name|path|string| yes ||Name represents the name of helmrelease.| +|body|body|object| no ||none| +|» repo|body|string| no ||The repo represents for the charts belongs to.| +|» timeout|body|string| no ||Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s).| +|» wait|body|boolean| no ||If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout.| +|» atomic|body|boolean| no ||If set, the installation process deletes the installation on failure. The --wait flag will be set automatically if --atomic is used.| +|» debug|body|boolean| no ||Enable verbose output.| +|» disableHooks|body|boolean| no ||Prevent hooks from running during install.| +|» disableOpenApiValidation|body|boolean| no ||If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema.| +|» force|body|boolean| no ||Force resource updates through a replacement strategy.| +|» maxHistory|body|integer(int32)| no ||Limit the maximum number of revisions saved per release. Use 0 for no limit (default 10).| +|» install|body|boolean| no ||If a release by this name doesn't already exist, run an install.| +|» cleanupOnFail|body|boolean| no ||Allow deletion of new resources created in this upgrade when upgrade fails.| +|» chart|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE DeleteHelmRelease delete a release. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name} + +> Body Parameters + +```json +{ + "disableHooks": true, + "dryRun": true, + "keepHistory": true, + "timeout": "string", + "description": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the helmrelease belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|name|path|string| yes ||Name represents the name of helmrelease.| +|body|body|object| no ||none| +|» disableHooks|body|boolean| no ||none| +|» dryRun|body|boolean| no ||none| +|» keepHistory|body|boolean| no ||none| +|» timeout|body|string| no ||none| +|» description|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetHelmReleaseJSON gets a release in cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||cluster represents which cluster the release belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|name|path|string| yes ||The name represents for the resource name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST RollbackHelmRelease rollbacks a release. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/helmreleases/{name}:rollback + +> Body Parameters + +```json +{ + "revision": 0, + "timeout": "string", + "wait": true, + "debug": true, + "disableHooks": true, + "force": true, + "maxHistory": 0, + "cleanupOnFail": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster represents which cluster the helmrelease belongs to.| +|namespace|path|string| yes ||Namespace represents which namespace the helmrelease belongs to.| +|name|path|string| yes ||Name represents the name of helmrelease.| +|body|body|object| no ||none| +|» revision|body|integer(int32)| no ||Revision that needs to rollback to.| +|» timeout|body|string| no ||Time to wait for any individual Kubernetes operation (like Jobs for hooks) (default 5m0s).| +|» wait|body|boolean| no ||If set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment, StatefulSet, or ReplicaSet are in a ready state before marking the release as successful. It will wait for as long as timeout.| +|» debug|body|boolean| no ||Enable verbose output.| +|» disableHooks|body|boolean| no ||Prevent hooks from running during install.| +|» force|body|boolean| no ||Force resource updates through a replacement strategy.| +|» maxHistory|body|integer(int32)| no ||Limit the maximum number of revisions saved per release. Use 0 for no limit (default 10).| +|» cleanupOnFail|body|boolean| no ||Allow deletion of new resources created in this upgrade when upgrade fails.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Networking + + + +## GET ListIngressClassSummary gets a list of ingressClass simple information +from the system by given cluster name + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/ingressclasssummary + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the ingressClass belongs to.| +|namespace|query|string| no ||Namespace is the IngressClass to retrieve for a specific namespace scoped.| + +#### Description + +**namespace**: Namespace is the IngressClass to retrieve for a specific namespace scoped. +If left empty, it retrieves the cluster scoped IngressClass. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterIngresses lists all ingresses in the specified cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/ingresses + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, must be specified,| +|page|query|integer(int32)| no ||Page is the number of pages at the beginning.| +|pageSize|query|integer(int32)| no ||Size is the number of every page displayed.| +|sortBy|query|string| no ||SortBy defines sort field, please see message kpanda.io.api.types.SortBy.| +|sortDir|query|string| no ||OrderBy defines the type of sort, default type asc, can also specify desc.| +|name|query|string| no ||Name is the name of the ingress.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**cluster**: Cluster is the name of the cluster, must be specified, +will return all the ingress of the cluster. + +**sortBy**: SortBy defines sort field, please see message kpanda.io.api.types.SortBy. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy defines the type of sort, default type asc, can also specify desc. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST ValidateMetallbSharedIPPortConflict checks whether the service port of +the loadBalance service with using shared ip is conflict with other loadBalancer +services + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/metallb/check-serviceports + +> Body Parameters + +```json +{ + "sharedLoadBalancerIP": "string", + "servicePorts": [ + 0 + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|body|body|object| no ||none| +|» sharedLoadBalancerIP|body|string| no | sharedLoadBalancerIP is the shared IP address that needs to be checked +for service port conflicts|none| +|» servicePorts|body|[integer]| no | servicePorts is the list of service ports that need to be checked for +conflicts|none| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListMetallbIPPool lists all metallb in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/metallb/ippools + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|page|query|integer(int32)| no ||Page is the number of pages at the beginning.| +|pageSize|query|integer(int32)| no ||Size is the number of every page displayed.| +|sortBy|query|string| no ||SortBy defines sort field, please see message kpanda.io.api.types.SortBy.| +|sortDir|query|string| no ||OrderBy defines the type of sort, default type asc, can also specify desc.| +|name|query|string| no ||Name is the name of the ingress.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +**sortBy**: SortBy defines sort field, please see message kpanda.io.api.types.SortBy. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy defines the type of sort, default type asc, can also specify desc. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListIngresses lists all ingresses in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|page|query|integer(int32)| no ||Page is the number of pages at the beginning.| +|pageSize|query|integer(int32)| no ||Size is the number of every page displayed.| +|sortBy|query|string| no ||SortBy defines sort field, please see message kpanda.io.api.types.SortBy.| +|sortDir|query|string| no ||OrderBy defines the type of sort, default type asc, can also specify desc.| +|name|query|string| no ||Name is the name of the ingress.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +**sortBy**: SortBy defines sort field, please see message kpanda.io.api.types.SortBy. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy defines the type of sort, default type asc, can also specify desc. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateIngress creates a ingress in the specified cluster and namespace. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|body|body|object| no | CreateIngressRequest the request of create cluster ingresses|none| +|» data|body|string| no ||The data is the ingress YAML details.| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetIngress gets the ingress by namespace and name. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|name|path|string| yes ||Name is the name of the ingress.| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateIngress updates the specified ingress, the body must be a JSON +string. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|name|path|string| yes ||Name is the name of ingress.| +|body|body|object| no | UpdateIngressRequest the request of update cluster ingresses|none| +|» data|body|string| no ||The data is the ingress YAML details.| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateIngressResponse](#schemav1alpha1updateingressresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteIngress deletes the ingress by name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|name|path|string| yes ||Name is the name of ingress.| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PATCH PatchIngress patches the specified ingress, the body must be a JSON string. + +PATCH /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name} + +> Body Parameters + +```json +{ + "data": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|name|path|string| yes ||The name represents for the resource name.| +|body|body|object| no | PatchIngressRequest the request of patch cluster ingresses|none| +|» data|body|object| no ||The data defines the update details of ingress.| +|»» **additionalProperties**|body|string| no ||none| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetIngressJSON gets the ingress by namespace and name, returns a string in JSON +format. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/ingresses/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the ingress of the cluster| +|namespace|path|string| yes ||Namespace specified the namespace of ingress.| +|name|path|string| yes ||Name is the name of the ingress.| +|stable|query|boolean| no ||If stable is true, the v1 version under the corresponding package will be returned.| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the ingress of the cluster +be specified. + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListNetworkPolicies lists all networkpolicies in the specified cluster and namespace. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, return all the networkpolicies of the cluster| +|namespace|path|string| yes ||Namespace of networkpolicy list.| +|page|query|integer(int32)| no ||Page is current page number.| +|pageSize|query|integer(int32)| no ||Size is the number of every page displayed.| +|sortBy|query|string| no ||SortBy defines sort field, please see message kpanda.io.api.types.SortBy.| +|sortDir|query|string| no ||OrderBy defines the type of sort, default type asc, can also specify desc.| +|name|query|string| no ||Name is the name of the networkpolicy.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter| + +#### Description + +**cluster**: Cluster is the name of the cluster, return all the networkpolicies of the cluster +be specified. + +**sortBy**: SortBy defines sort field, please see message kpanda.io.api.types.SortBy. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy defines the type of sort, default type asc, can also specify desc. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST CreateNetworkPolicy creates a networkpolicy in the specified cluster and namespace. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster to request.| +|namespace|path|string| yes ||Namespace specified the namespace of networkpolicy.| +|body|body|object| no | CreateNetworkPolicyRequest the request of create cluster networkpolicies|none| +|» data|body|string| no ||The data is the networkpolicy YAML details.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetNetworkPolicy gets the networkpolicy by namespace and name. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster to request.| +|namespace|path|string| yes ||Namespace specifies the namespace of networkpolicy.| +|name|path|string| yes ||Name is the name of the networkpolicy.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateNetworkPolicy updates the specified networkpolicy, the body must be a JSON +string. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies/{name} + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster to request.| +|namespace|path|string| yes ||Namespace specified the namespace of networkpolicy.| +|name|path|string| yes ||Name is the name of networkpolicy.| +|body|body|object| no | UpdateNetworkPolicyRequest the request of update cluster networkpolicies|none| +|» data|body|string| no ||The data is the networkpolicy YAML details.| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1UpdateNetworkPolicyResponse](#schemav1alpha1updatenetworkpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE DeleteNetworkPolicy deletes the networkpolicy by name. + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster to request.| +|namespace|path|string| yes ||Namespace specified the namespace of networkpolicy.| +|name|path|string| yes ||Name is the name of networkpolicy.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetNetworkPolicyJSON gets the networkpolicy by namespace and name, returns a string in JSON +format. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/networkpolicies/{name}/json + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster to request.| +|namespace|path|string| yes ||Namespace specified the namespace of networkpolicy.| +|name|path|string| yes ||Name is the name of the networkpolicy.| +|stable|query|boolean| no ||If stable is true, the v1 version under the corresponding package will be returned.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListClusterNetworkPolicies lists all networkpolicies in the specified cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/networkpolicies + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Cluster is the name of the cluster, must be specified,| +|page|query|integer(int32)| no ||Page is current page number.| +|pageSize|query|integer(int32)| no ||Size is the number of every page displayed.| +|sortBy|query|string| no ||SortBy defines sort field, please see message kpanda.io.api.types.SortBy.| +|sortDir|query|string| no ||OrderBy defines the type of sort, default type asc, can also specify desc.| +|name|query|string| no ||Name is the name of the networkpolicy.| +|labelSelector|query|string| no ||LabelSelector is the format after labels.FormatLabels used to filter.| +|fieldSelector|query|string| no ||FieldSelector is the format after labels.FormatLabels used to filter.| + +#### Description + +**cluster**: Cluster is the name of the cluster, must be specified, +will return all the networkpolicies of the cluster. + +**sortBy**: SortBy defines sort field, please see message kpanda.io.api.types.SortBy. + + - SORT_BY_UNSPECIFIED: Unspecified is default, no sorting. + - field_name: Sort result by name. + - state: TODO: Sort result by state not supported yet. + - workspace: TODO: Sort result by workspace not supported yet. + - cluster: Sort result by cluster name. + - namespace: Sort result by namespace. + - created_at: Sort result by creationTimestamp. + +**sortDir**: OrderBy defines the type of sort, default type asc, can also specify desc. + + - desc: Desc stands for descending order. + - asc: Asc stands for ascending order. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|SORT_BY_UNSPECIFIED| +|sortBy|field_name| +|sortBy|state| +|sortBy|workspace| +|sortBy|cluster| +|sortBy|namespace| +|sortBy|created_at| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/insight + + + +## POST insight_QueryClusterMetrics + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/metric + +> Body Parameters + +```json +{ + "param": {}, + "matchLabels": { + "property1": "string", + "property2": "string" + }, + "queryList": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The name of the cluster| +|body|body|object| no | ClusterMetricsRequest represents the request of get cluster metrics|none| +|» param|body|object| no ||none| +|» matchLabels|body|object| no | The labels of match|none| +|»» **additionalProperties**|body|string| no ||none| +|» queryList|body|[string]| no | The query of List|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST insight_QueryClusterMetricsRange + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/metricrange + +> Body Parameters + +```json +{ + "param": {}, + "matchLabels": { + "property1": "string", + "property2": "string" + }, + "queryList": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||the name of the cluster| +|body|body|object| no | ClusterMetricsRangeRequest represents the request of get cluster metrics range|none| +|» param|body|object| no ||none| +|» matchLabels|body|object| no | The labels of match|none| +|»» **additionalProperties**|body|string| no ||none| +|» queryList|body|[string]| no | The query of List|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET GetPodContainerLog gets pod contianer log + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/pods/{name}/log + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Name of the cluster where the Pod is located| +|namespace|path|string| yes ||Name of the namespace where the Pod is located| +|name|path|string| yes ||Name of pod| +|workload|query|string| no ||workload refers to the name of a workload| +|container|query|string| no ||Name of the pod where the container is located| +|startTime|query|string| no ||Start time of get pod container log| +|endTime|query|string| no ||End time of get pod container log| +|page|query|integer(int32)| no ||Number of page.| +|pageSize|query|integer(int32)| no ||Log number shown per page.| +|logSearch|query|string| no ||for fuzzy query| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST insight_QueryPublicUsage + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/publicmetric + +> Body Parameters + +```json +{ + "namespace": "string", + "param": {}, + "labels": { + "property1": "string", + "property2": "string" + }, + "queryList": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Name of the cluster where the workload is located| +|body|body|object| no ||none| +|» namespace|body|string| no | Name of the namespace where the workload is located|none| +|» param|body|object| no ||none| +|» labels|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» queryList|body|[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST insight_QueryPublicRangeUsage + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/publicmetricrange + +> Body Parameters + +```json +{ + "namespace": "string", + "param": {}, + "labels": { + "property1": "string", + "property2": "string" + }, + "queryList": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||Name of the cluster where the workload is located| +|body|body|object| no ||none| +|» namespace|body|string| no | Name of the namespace where the workload is located|none| +|» param|body|object| no ||none| +|» labels|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» queryList|body|[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Workspace + + + +## POST Workspace_BindResourceToWorkspace + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}:bind + +> Body Parameters + +```json +{ + "workspaceId": 0, + "workspaceAlias": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» workspaceId|body|integer(int32)| no ||none| +|» workspaceAlias|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Workspace_UnbindResourceFromWorkspace + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}/namespaces/{name}:unbind + +> Body Parameters + +```json +{ + "workspaceId": 0, + "workspaceAlias": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» workspaceId|body|integer(int32)| no ||none| +|» workspaceAlias|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Workspace_BindClusterToWorkspace + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}:bind + +> Body Parameters + +```json +{ + "workspaceId": 0, + "workspaceAlias": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|body|body|object| no ||none| +|» workspaceId|body|integer(int32)| no ||none| +|» workspaceAlias|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## DELETE Workspace_UnBindClusterFromWorkspace + +DELETE /apis/kpanda.io/v1alpha1/clusters/{cluster}:unbind + +> Body Parameters + +```json +{ + "workspaceId": 0, + "workspaceAlias": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|body|body|object| no ||none| +|» workspaceId|body|integer(int32)| no ||none| +|» workspaceAlias|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Workspace_ListGlobalRolesForCurrentUser + +GET /apis/kpanda.io/v1alpha1/globalroles + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Workspace_ListWorkspaces + +GET /apis/kpanda.io/v1alpha1/workspaces + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Workspace_GetWorkspaceResourceQuotaAllocatable + +GET /apis/kpanda.io/v1alpha1/workspaces/{workspaceId}/workspacesharedresourcequota + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|workspaceAlias|query|string| no ||none| +|cluster|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/ClusterSetting + + + +## GET Gets the setting under a given cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/settings + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster name of the clustersetting.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## PUT UpdateClusterSetting will update the cluster setting and returns the settings +after updating. + +PUT /apis/kpanda.io/v1alpha1/clusters/{cluster}/settings + +> Body Parameters + +```json +{ + "settings": {} +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||one of cluster or kubeSystemID has value| +|body|body|object| no ||none| +|» settings|body|object| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ClusterSetting_ListGPUSetting + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/gpu + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster name of the clustersetting.| +|availableEnable|query|boolean| no ||if available_enable is true will return available gpu number| + +#### Description + +**availableEnable**: if available_enable is true will return available gpu number +if available_enable is false AvailableResource return nil + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET Lists plugins under a given cluster. + +GET /apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/plugins + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster name of the clustersetting.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Disable a plugin so that it can be shown by the frontend. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/plugins/{name}:disable + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster name of the clustersetting.| +|name|path|string| yes ||The name of the plugin which needs to disable.| + +#### Enum + +|Name|Value| +|---|---| +|name|PLUGIN_NAME_UNSPECIFIED| +|name|HPA| +|name|Insight| +|name|GPU| +|name|METALLB| +|name|Spiderpool| +|name|CustomMetrics| +|name|CronHPA| +|name|VPA| +|name|Hwameistor| +|name|Flannel| +|name|KubeOvn| +|name|OLM| +|name|EgressGateway| +|name|Snapshot| +|name|DRA| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Enable a plugin so that it can be shown by the frontend. + +POST /apis/kpanda.io/v1alpha1/clusters/{cluster}/settings/plugins/{name}:enable + +> Body Parameters + +```json +{} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||The cluster name of the clustersetting.| +|name|path|string| yes ||The name of the plugin which needs to enable.| +|body|body|object| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|name|PLUGIN_NAME_UNSPECIFIED| +|name|HPA| +|name|Insight| +|name|GPU| +|name|METALLB| +|name|Spiderpool| +|name|CustomMetrics| +|name|CronHPA| +|name|VPA| +|name|Hwameistor| +|name|Flannel| +|name|KubeOvn| +|name|OLM| +|name|EgressGateway| +|name|Snapshot| +|name|DRA| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/FeatureGate + + + +## GET FeatureGate_ListFeatureGates + +GET /apis/kpanda.io/v1alpha1/featuregates + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Image + + + +## GET ListRegistries returns a list of registries + +GET /apis/kpanda.io/v1alpha1/registries + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|global|query|boolean| no ||Global is to list all global registries.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| +|public|query|boolean| no ||Public is distinguish public images and private images.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by registry name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET DetectKangaroo returns whether the kangaroo is installed. + +GET /apis/kpanda.io/v1alpha1/registries/kangaroo + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListProjects returns a list of projects of specified registry + +GET /apis/kpanda.io/v1alpha1/registries/{registry}/projects + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|registry|path|string| yes ||Registry is registry name.| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|public|query|boolean| no ||Public is distinguish public projects and private projects.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by project name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListRepositories returns a list of image names of specified project + +GET /apis/kpanda.io/v1alpha1/registries/{registry}/repositories + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|registry|path|string| yes ||Registry is registry name.| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|project|query|string| no ||Project is the project to request, "/" is a possible value.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| +|public|query|boolean| no ||Public is distinguish public images and private images.| +|showArtifacts|query|boolean| no ||ShowArtifacts is to list artifacts of per image, default false.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## GET ListArtifacts returns a list of tags of specified image + +GET /apis/kpanda.io/v1alpha1/registries/{registry}/repositories/{repository}/artifacts + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|registry|path|string| yes ||Registry is registry name.| +|repository|path|string| yes ||Repository is image name.| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|project|query|string| no ||Project is the project to request.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| +|public|query|boolean| no ||Public is distinguish public images and private images.| +|fuzzyTagName|query|string| no ||FuzzyTagName is used to fuzzy search by tag name.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# ContainerManagement/Registry + + + +## GET Registry_ListImageTags + +GET /apis/kpanda.io/v1alpha1/registry/tags + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster presents the cluster of dockeconfig belongs to.| +|namespace|query|string| no ||Namespace presents the namespace of dockeconfig belongs to.| +|secret|query|string| no ||Secret is the name of dockeconfig.| +|image|query|string| no ||Image is the name of repository which needs verify.| +|registryHost|query|string| no ||The registry host which the repository belongs to.| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + + + +## POST Registry_VerifyRegistry + +POST /apis/kpanda.io/v1alpha1/registry/verify + +> Body Parameters + +```json +{ + "registryHost": "string", + "username": "string", + "password": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[v1alpha1VerifyRegistryRequest](#schemav1alpha1verifyregistryrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "success": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1VerifyRegistryResponse](#schemav1alpha1verifyregistryresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Registry_VerifyImage + +GET /apis/kpanda.io/v1alpha1/registry/verifyImage + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster presents the cluster of dockeconfig belongs to.| +|namespace|query|string| no ||Namespace presents the namespace of dockeconfig belongs to.| +|secret|query|string| no ||Secret is the name of dockeconfig.| +|image|query|string| no ||Image is the name of repository which needs to list tags.| +|registryHost|query|string| no ||The registry host which the repository belongs to.| + +> Response Examples + +> 200 Response + +```json +{ + "success": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1VerifyImageResponse](#schemav1alpha1verifyimageresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# ContainerManagement/SettingService + + + +## GET SettingService_GPUSetting + +GET /apis/kpanda.io/v1alpha1/settings/gpu + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|Inline| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +### Responses Data Schema + +# CloudVM/Cluster + + + +## GET Cluster_ListClusters + +GET /apis/virtnest.io/v1alpha1/clusters + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "status": "running", + "isKubevirtInstalled": true, + "isInsightAgentReady": true, + "spiderpool": { + "isInstalled": true, + "enableIpv4": true, + "enableIpv6": true + }, + "gpuInfo": { + "type": [ + "Nvidia_GPU" + ], + "gpus": [ + { + "type": null, + "deviceName": null + } + ] + } + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clusterListClustersResponse](#schemaclusterlistclustersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Cluster_ListClusterNamespaces + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + "string" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clusterListClusterNamespacesResponse](#schemaclusterlistclusternamespacesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Cluster_IsVMMonitorReady + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/vm-monitor/ready + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "ready": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clusterIsVMMonitorReadyResponse](#schemaclusterisvmmonitorreadyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# CloudVM/VM + + + +## POST VM_CreateCustomResource + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/custom-resource + +> Body Parameters + +```json +{ + "data": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|body|body|object| no ||none| +|» data|body|[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmCreateCustomResourceResponse](#schemavmcreatecustomresourceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_CreateVM + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vm + +> Body Parameters + +```json +{ + "name": "string", + "aliasName": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "imageSource": "docker", + "imageUrl": "string", + "disks": { + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] + }, + "cpu": 0, + "memory": "string", + "ssh": { + "username": "string", + "password": "string", + "sshKey": "string" + }, + "osFamily": "string", + "osVersion": "string", + "secret": "string", + "network": { + "networkMode": "string", + "items": [ + { + "interface": "string", + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "ipPoolNames": [ + "string" + ], + "ipPoolNamesV6": [ + "string" + ] + } + ] + }, + "createPowerOn": true, + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 + } + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|body|body|object| no ||none| +|» name|body|string| no ||none| +|» aliasName|body|string| no ||none| +|» labels|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» imageSource|body|[v1alpha1vmImageSource](#schemav1alpha1vmimagesource)| no | TODO:|none| +|» imageUrl|body|string| no ||none| +|» disks|body|[v1alpha1vmVMDisks](#schemav1alpha1vmvmdisks)| no ||none| +|»» systemVolume|body|[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|»» dataVolumes|body|[[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)]| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|» cpu|body|integer(int64)| no ||none| +|» memory|body|string(int64)| no | 单位:字节|none| +|» ssh|body|[vmSSH](#schemavmssh)| no ||none| +|»» username|body|string| no ||none| +|»» password|body|string| no ||none| +|»» sshKey|body|string| no ||none| +|» osFamily|body|string| no ||none| +|» osVersion|body|string| no ||none| +|» secret|body|string| no ||none| +|» network|body|[vmMultusNetwork](#schemavmmultusnetwork)| no ||none| +|»» networkMode|body|string| no ||none| +|»» items|body|[[vmMultusNetworkItem](#schemavmmultusnetworkitem)]| no ||none| +|»»» interface|body|string| no ||none| +|»»» multusConfig|body|[v1alpha1vmMultusConfigInfo](#schemav1alpha1vmmultusconfiginfo)| no ||none| +|»»»» name|body|string| no ||none| +|»»»» namespace|body|string| no ||none| +|»»»» cniType|body|string| no ||none| +|»»»» hasDefaultIppool|body|boolean| no ||none| +|»»» ipPoolNames|body|[string]| no ||none| +|»»» ipPoolNamesV6|body|[string]| no ||none| +|» createPowerOn|body|boolean| no ||none| +|» gpus|body|[[v1alpha1vmGPU](#schemav1alpha1vmgpu)]| no ||none| +|»» type|body|[v1alpha1vmGPUType](#schemav1alpha1vmgputype)| no ||none| +|»» deviceName|body|string| no ||none| +|»» count|body|integer(int32)| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|» imageSource|docker| +|» imageSource|http| +|» imageSource|s3| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|»» type|Nvidia_GPU| +|»» type|Nvidia_vGPU| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmCreateVMResponse](#schemavmcreatevmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_CreateVMWithVMTemplate + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vm-with-vmtemplate/{vmtemplateName} + +> Body Parameters + +```json +{ + "name": "string", + "aliasName": "string", + "cpu": 0, + "memory": "string", + "disks": { + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] + }, + "ssh": { + "username": "string", + "password": "string", + "sshKey": "string" + }, + "imageSource": "docker", + "imageUrl": "string", + "osFamily": "string", + "osVersion": "string", + "secret": "string", + "network": { + "networkMode": "string", + "items": [ + { + "interface": "string", + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "ipPoolNames": [ + "string" + ], + "ipPoolNamesV6": [ + "string" + ] + } + ] + }, + "createPowerOn": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|vmtemplateName|path|string| yes ||none| +|body|body|object| no ||none| +|» name|body|string| no ||none| +|» aliasName|body|string| no ||none| +|» cpu|body|integer(int64)| no ||none| +|» memory|body|string(int64)| no | 单位:字节|none| +|» disks|body|[v1alpha1vmVMDisks](#schemav1alpha1vmvmdisks)| no ||none| +|»» systemVolume|body|[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|»» dataVolumes|body|[[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)]| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|» ssh|body|[vmSSH](#schemavmssh)| no ||none| +|»» username|body|string| no ||none| +|»» password|body|string| no ||none| +|»» sshKey|body|string| no ||none| +|» imageSource|body|[v1alpha1vmImageSource](#schemav1alpha1vmimagesource)| no | TODO:|none| +|» imageUrl|body|string| no ||none| +|» osFamily|body|string| no ||none| +|» osVersion|body|string| no ||none| +|» secret|body|string| no ||none| +|» network|body|[vmMultusNetwork](#schemavmmultusnetwork)| no ||none| +|»» networkMode|body|string| no ||none| +|»» items|body|[[vmMultusNetworkItem](#schemavmmultusnetworkitem)]| no ||none| +|»»» interface|body|string| no ||none| +|»»» multusConfig|body|[v1alpha1vmMultusConfigInfo](#schemav1alpha1vmmultusconfiginfo)| no ||none| +|»»»» name|body|string| no ||none| +|»»»» namespace|body|string| no ||none| +|»»»» cniType|body|string| no ||none| +|»»»» hasDefaultIppool|body|boolean| no ||none| +|»»» ipPoolNames|body|[string]| no ||none| +|»»» ipPoolNamesV6|body|[string]| no ||none| +|» createPowerOn|body|boolean| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|» imageSource|docker| +|» imageSource|http| +|» imageSource|s3| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmCreateVMWithVMTemplateResponse](#schemavmcreatevmwithvmtemplateresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_GetVM + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "cluster": "string", + "namespace": "string", + "name": "string", + "aliasName": "string", + "describe": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "ips": [ + "string" + ], + "status": "running", + "createdAt": "string", + "username": "string", + "password": "string", + "sshKey": "string", + "cpu": 0, + "memory": "string", + "vmErrorMessage": { + "message": "string", + "reason": "string" + }, + "imageSource": "docker", + "osFamily": "string", + "osVersion": "string", + "imageUrl": "string", + "node": "string", + "allowedOperation": [ + "allowed_operation_snapshot" + ], + "secret": "string", + "network": { + "networkMode": "string", + "items": [ + { + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string" + } + ] + }, + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmGetVMResponse](#schemavmgetvmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT VM_UpdateVM + +PUT /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name} + +> Body Parameters + +```json +{ + "aliasName": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "cpu": 0, + "memory": "string", + "disks": { + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] + }, + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 + } + ], + "network": { + "networkMode": "string", + "items": [ + { + "interface": "string", + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "ipPoolNames": [ + "string" + ], + "ipPoolNamesV6": [ + "string" + ] + } + ] + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» aliasName|body|string| no ||none| +|» labels|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» annotations|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| +|» cpu|body|integer(int64)| no ||none| +|» memory|body|string(int64)| no | 单位:字节|none| +|» disks|body|[v1alpha1vmVMDisks](#schemav1alpha1vmvmdisks)| no ||none| +|»» systemVolume|body|[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|»» dataVolumes|body|[[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)]| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|» gpus|body|[[v1alpha1vmGPU](#schemav1alpha1vmgpu)]| no ||none| +|»» type|body|[v1alpha1vmGPUType](#schemav1alpha1vmgputype)| no ||none| +|»» deviceName|body|string| no ||none| +|»» count|body|integer(int32)| no ||none| +|» network|body|[vmMultusNetwork](#schemavmmultusnetwork)| no ||none| +|»» networkMode|body|string| no ||none| +|»» items|body|[[vmMultusNetworkItem](#schemavmmultusnetworkitem)]| no ||none| +|»»» interface|body|string| no ||none| +|»»» multusConfig|body|[v1alpha1vmMultusConfigInfo](#schemav1alpha1vmmultusconfiginfo)| no ||none| +|»»»» name|body|string| no ||none| +|»»»» namespace|body|string| no ||none| +|»»»» cniType|body|string| no ||none| +|»»»» hasDefaultIppool|body|boolean| no ||none| +|»»» ipPoolNames|body|[string]| no ||none| +|»»» ipPoolNamesV6|body|[string]| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|»» type|Nvidia_GPU| +|»» type|Nvidia_vGPU| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmUpdateVMResponse](#schemavmupdatevmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE VM_DeleteVM + +DELETE /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmDeleteVMResponse](#schemavmdeletevmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_CloneVM + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/clone + +> Body Parameters + +```json +{ + "cloneName": "string", + "aliasName": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» cloneName|body|string| no ||none| +|» aliasName|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmCloneVMResponse](#schemavmclonevmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_ColdMigration + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/cold-migration + +> Body Parameters + +```json +{ + "targetNode": "string", + "disks": { + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] + }, + "powerOn": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» targetNode|body|string| no | 空值表示随机选择节点|none| +|» disks|body|[v1alpha1vmVMDisks](#schemav1alpha1vmvmdisks)| no ||none| +|»» systemVolume|body|[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|»» dataVolumes|body|[[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)]| no ||none| +|»»» storageClass|body|string| no ||none| +|»»» capacity|body|string(int64)| no ||none| +|»»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»»» name|body|string| no ||none| +|» powerOn|body|boolean| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| +|»»» pvAccessMode|ReadWriteOnce| +|»»» pvAccessMode|ReadOnlyMany| +|»»» pvAccessMode|ReadWriteMany| +|»»» pvAccessMode|ReadWriteOncePod| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmColdMigrationResponse](#schemavmcoldmigrationresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_GetCustomResource + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/custom-resource + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1vmGetCustomResourceResponse](#schemav1alpha1vmgetcustomresourceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT VM_UpdateCustomResource + +PUT /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/custom-resource + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» data|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1vmUpdateCustomResourceResponse](#schemav1alpha1vmupdatecustomresourceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_AddDiskVolumeToVM + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/disk-volume + +> Body Parameters + +```json +{ + "diskVolumes": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "hotplug": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» diskVolumes|body|[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)| no ||none| +|»» storageClass|body|string| no ||none| +|»» capacity|body|string(int64)| no ||none| +|»» pvAccessMode|body|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)| no ||none| +|»» name|body|string| no ||none| +|» hotplug|body|boolean| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|»» pvAccessMode|ReadWriteOnce| +|»» pvAccessMode|ReadOnlyMany| +|»» pvAccessMode|ReadWriteMany| +|»» pvAccessMode|ReadWriteOncePod| + +> Response Examples + +> 200 Response + +```json +{ + "needRestart": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmAddDiskVolumeToVMResponse](#schemavmadddiskvolumetovmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE VM_RemoveVMDiskVolume + +DELETE /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/disk-volume/{diskName} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|diskName|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmRemoveVMDiskVolumeResponse](#schemavmremovevmdiskvolumeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT VM_ExpandVMDiskCapacity + +PUT /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/disk-volume/{diskName}/expand-capacity + +> Body Parameters + +```json +{ + "capacity": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|diskName|path|string| yes ||none| +|body|body|object| no ||none| +|» capacity|body|string(int64)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "needRestart": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmExpandVMDiskCapacityResponse](#schemavmexpandvmdiskcapacityresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListVMEvents + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/events + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "level": "UNSPECIFIED", + "component": "string", + "object": { + "name": "string", + "kind": "string" + }, + "name": "string", + "detail": "string", + "time": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListVMEventsResponse](#schemavmlistvmeventsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_LiveMigrateVM + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/live-migration + +> Body Parameters + +```json +{ + "targetNode": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» targetNode|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmLiveMigrateVMResponse](#schemavmlivemigratevmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListVMNetworks + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/networks + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "type": "string", + "ip": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListVMNetworksResponse](#schemavmlistvmnetworksresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_RestoreVMSnapshot + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/restore + +> Body Parameters + +```json +{ + "snapshotName": "string", + "restoreName": "string", + "restoreDescription": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» snapshotName|body|string| no ||none| +|» restoreName|body|string| no ||none| +|» restoreDescription|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmRestoreVMSnapshotResponse](#schemavmrestorevmsnapshotresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE VM_DeleteVMRestore + +DELETE /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/restores/{restoreName} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|restoreName|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmDeleteVMRestoreResponse](#schemavmdeletevmrestoreresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT VM_UpdateVMRunningStatus + +PUT /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/running-status + +> Body Parameters + +```json +{ + "vmOperation": "start" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» vmOperation|body|[vmVMOperation](#schemavmvmoperation)| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|» vmOperation|start| +|» vmOperation|stop| +|» vmOperation|restart| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmUpdateVMRunningStatusResponse](#schemavmupdatevmrunningstatusresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST VM_CreateVMSnapshot + +POST /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshot + +> Body Parameters + +```json +{ + "snapshotName": "string", + "snapshotDescription": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» snapshotName|body|string| no ||none| +|» snapshotDescription|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmCreateVMSnapshotResponse](#schemavmcreatevmsnapshotresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListVMSnapshots + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "description": "string", + "createdAt": "string", + "status": "snapshot_succeeded", + "restoreTime": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListVMSnapshotsResponse](#schemavmlistvmsnapshotsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT VM_UpdateVMSnapshot + +PUT /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots/{snapshotName} + +> Body Parameters + +```json +{ + "snapshotDescription": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|snapshotName|path|string| yes ||none| +|body|body|object| no ||none| +|» snapshotDescription|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmUpdateVMSnapshotResponse](#schemavmupdatevmsnapshotresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE VM_DeleteVMSnapshot + +DELETE /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots/{snapshotName} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|snapshotName|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmDeleteVMSnapshotResponse](#schemavmdeletevmsnapshotresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListVMRestores + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/snapshots/{snapshotName}/restores + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|snapshotName|path|string| yes ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "description": "string", + "complete": true, + "createdAt": "string", + "restoreTime": "string", + "lastRestore": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListVMRestoresResponse](#schemavmlistvmrestoresresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListVMStorages + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/vms/{name}/storages + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "type": "system", + "capacity": "string", + "status": "storage_processing", + "storageClass": "string", + "allowExpand": true, + "pvAccessMode": "ReadWriteOnce", + "hotpluggable": true + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListVMStoragesResponse](#schemavmlistvmstoragesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListNetworkInterfaces + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/network-interfaces + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "ipPools": [ + "string" + ], + "interfaces": [ + { + "networkInterface": "string", + "multusConfigs": [ + { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + } + ] + } + ], + "ipPoolsV6": [ + "string" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListNetworkInterfacesResponse](#schemavmlistnetworkinterfacesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListClusterNodes + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/nodes + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "phase": "PhaseUnspecified" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListClusterNodesResponse](#schemavmlistclusternodesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListClusterStorageClasses + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/storageclasses + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "supportAccessMode": [ + "ReadWriteOnce" + ] + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListClusterStorageClassesResponse](#schemavmlistclusterstorageclassesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListSystemImages + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/system-images + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "osFamily": "string", + "version": [ + { + "version": "string", + "url": "string" + } + ] + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListSystemImagesResponse](#schemavmlistsystemimagesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VM_ListClusterVMs + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/vms + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| +|search|query|string| no ||none| +|sortBy|query|string| no ||none| +|sortDir|query|string| no ||none| +|namespace|query|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|sortBy|created_at| +|sortBy|field_name| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "status": "running", + "namespace": "string", + "ips": [ + "string" + ], + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "vmErrorMessage": { + "message": "string", + "reason": "string" + }, + "allowedOperation": [ + "allowed_operation_snapshot" + ], + "node": "string", + "gpus": [ + "Nvidia_GPU" + ], + "migNodeSelector": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmListClusterVmsResponse](#schemavmlistclustervmsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# CloudVM/Image + + + +## GET Image_ListSecrets + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "uid": "string", + "cluster": "string", + "namespace": "string", + "type": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[imageListSecretsResponse](#schemaimagelistsecretsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Image_CheckSecret + +GET /apis/virtnest.io/v1alpha1/clusters/{cluster}/namespaces/{namespace}/secrets/{name}/check + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|path|string| yes ||none| +|namespace|path|string| yes ||none| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "canUse": true, + "message": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[imageCheckSecretResponse](#schemaimagechecksecretresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Image_ListProjects + +GET /apis/virtnest.io/v1alpha1/projects + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|registry|query|string| no ||Registry is registry name.| +|public|query|boolean| no ||Public is distinguish public projects and private projects.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + "string" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[imageListProjectsResponse](#schemaimagelistprojectsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Image_ListRegistries + +GET /apis/virtnest.io/v1alpha1/registries + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| +|public|query|boolean| no ||Public is distinguish public images and private images.| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "alias": "string", + "host": "string", + "name": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[imageListRegistriesResponse](#schemaimagelistregistriesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Image_ListRepositories + +GET /apis/virtnest.io/v1alpha1/repositories + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|cluster|query|string| no ||Cluster is the current cluster.| +|namespace|query|string| no ||Namespace is the current namespace.| +|registry|query|string| no ||Registry is registry name.| +|project|query|string| no ||Project is the project to request, "/" is a possible value.| +|fuzzyName|query|string| no ||FuzzyName is used to fuzzy search by multiple parameters including name.| +|page|query|integer(int32)| no ||Page requested.| +|pageSize|query|integer(int32)| no ||Size per page.| +|public|query|boolean| no ||Public is distinguish public images and private images.| +|showArtifacts|query|boolean| no ||ShowArtifacts is to list artifacts of per image, default false.| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "artifacts": [ + { + "digest": "string", + "tags": [ + {} + ], + "imageSize": "string", + "pushTime": "string" + } + ] + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[imageListRepositoriesResponse](#schemaimagelistrepositoriesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# CloudVM/FeatureGate + + + +## GET FeatureGate_ListFeatureGates + +GET /apis/virtnest.io/v1alpha1/feature-gate + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "CreateUserInWorkspace", + "description": "string", + "enabled": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[feature_gateListFeatureGatesResponse](#schemafeature_gatelistfeaturegatesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# CloudVM/Role + + + +## GET Role_GetUserRoles + +GET /apis/virtnest.io/v1alpha1/roles + +> Response Examples + +> 200 Response + +```json +{ + "platformRoles": [ + "admin" + ], + "clusterRoles": { + "property1": { + "roles": [ + "admin" + ], + "nsRoles": { + "property1": { + "roles": [ + "[" + ] + }, + "property2": { + "roles": [ + "[" + ] + } + } + }, + "property2": { + "roles": [ + "admin" + ], + "nsRoles": { + "property1": { + "roles": [ + "[" + ] + }, + "property2": { + "roles": [ + "[" + ] + } + } + } + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleGetUserRolesResponse](#schemarolegetuserrolesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# CloudVM/VMTemplate + + + +## POST rpc UpdateVMTemplate(UpdateVMTemplateRequest) returns (UpdateVMTemplateResponse) { + option (google.api.http) = { + put: "/apis/virtnest.io/v1alpha1/vmtemplates/{name}" + body: "*" + }; + } + +POST /apis/virtnest.io/v1alpha1/vmtemplate-by-vm + +> Body Parameters + +```json +{ + "cluster": "string", + "namespace": "string", + "vmName": "string", + "vmtemplateName": "string", + "description": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[vmtemplateCreateVMTemplateByVMRequest](#schemavmtemplatecreatevmtemplatebyvmrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmtemplateCreateVMTemplateByVMResponse](#schemavmtemplatecreatevmtemplatebyvmresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VMTemplate_ListVMTemplates + +GET /apis/virtnest.io/v1alpha1/vmtemplates + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| +|search|query|string| no ||none| +|sortBy|query|string| no || - UNSPECIFIED: Unspecified is default, no sorting.| +|sortDir|query|string| no ||none| + +#### Description + +**sortBy**: - UNSPECIFIED: Unspecified is default, no sorting. + - created_at: Sort result by creationTimestamp. + - field_name: Sort result by name. + +#### Enum + +|Name|Value| +|---|---| +|sortBy|UNSPECIFIED| +|sortBy|created_at| +|sortBy|field_name| +|sortDir|desc| +|sortDir|asc| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "type": "custom", + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "gpus": [ + "Nvidia_GPU" + ] + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmtemplateListVMTemplatesResponse](#schemavmtemplatelistvmtemplatesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VMTemplate_GetVMTemplate + +GET /apis/virtnest.io/v1alpha1/vmtemplates/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "name": "string", + "description": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "imageUrl": "string", + "type": "custom", + "systemDiskCapacity": "string", + "imageSource": "docker", + "osVersion": "string", + "network": "string", + "disks": { + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] + }, + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 + } + ], + "networks": { + "networkMode": "string", + "items": [ + { + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string", + "ipPool": { + "ipv4": [ + null + ], + "ipv6": [ + null + ] + } + } + ] + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmtemplateGetVMTemplateResponse](#schemavmtemplategetvmtemplateresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE rpc CreateVMTemplate(CreateVMTemplateRequest) returns (CreateVMTemplateResponse) { + option (google.api.http) = { + post: "/apis/virtnest.io/v1alpha1/vmtemplates" + body: "*" + }; + } + +DELETE /apis/virtnest.io/v1alpha1/vmtemplates/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[vmtemplateDeleteVMTemplateResponse](#schemavmtemplatedeletevmtemplateresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET VMTemplate_GetCustomResource + +GET /apis/virtnest.io/v1alpha1/vmtemplates/{name}/custom-resource + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "data": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1vmtemplateGetCustomResourceResponse](#schemav1alpha1vmtemplategetcustomresourceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT VMTemplate_UpdateCustomResource + +PUT /apis/virtnest.io/v1alpha1/vmtemplates/{name}/custom-resource + +> Body Parameters + +```json +{ + "data": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» data|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1vmtemplateUpdateCustomResourceResponse](#schemav1alpha1vmtemplateupdatecustomresourceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/OIDC + + + +## GET OIDC_WellKnown + +GET /apis/ghippo.io/v1alpha1/.well-known/openid-configuration + +> Response Examples + +> 200 Response + +```json +{ + "issuer": "string", + "authorizationEndpoint": "string", + "tokenEndpoint": "string", + "jwksUri": "string", + "userinfoEndpoint": "string", + "introspectionEndpoint": "string", + "idTokenSigningAlgValuesSupported": [ + "string" + ], + "endSessionEndpoint": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oidcWellKnownResponse](#schemaoidcwellknownresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET OIDC_GhippoClientConfig + +GET /apis/ghippo.io/v1alpha1/oidc/ghippo-client-config + +> Response Examples + +> 200 Response + +```json +{ + "clientId": "string", + "endpoint": "string", + "groupsClaim": "string", + "name": "string", + "scope": "string", + "userClaim": "string", + "clientSecret": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oidcGhippoClientConfigResponse](#schemaoidcghippoclientconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET OIDC_RedirectFrontendLogout + +GET /apis/ghippo.io/v1alpha1/oidc/logout + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oidcRedirectFrontendLogoutResponse](#schemaoidcredirectfrontendlogoutresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE OIDC_OIDCLogout + +DELETE /apis/ghippo.io/v1alpha1/oidc/logout + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oidcOIDCLogoutResponse](#schemaoidcoidclogoutresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST OIDC_OIDCToken + +POST /apis/ghippo.io/v1alpha1/oidc/token + +> Body Parameters + +```json +{ + "clientId": "string", + "grantType": "string", + "clientSecret": "string", + "code": "string", + "redirectUri": "string", + "username": "string", + "password": "string", + "refreshToken": "string", + "scope": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[oidcOIDCTokenRequest](#schemaoidcoidctokenrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "accessToken": "string", + "idToken": "string", + "expiresIn": 0, + "refreshExpiresIn": 0, + "refreshToken": "string", + "tokenType": "string", + "notBeforePolicy": 0, + "sessionState": "string", + "scope": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oidcOIDCTokenResponse](#schemaoidcoidctokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET OIDC_OIDCUserInfo + +GET /apis/ghippo.io/v1alpha1/oidc/userinfo + +> Response Examples + +> 200 Response + +```json +{ + "sub": "string", + "preferredUsername": "string", + "email": "string", + "locale": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oidcOIDCUserInfoResponse](#schemaoidcoidcuserinforesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/About + + + +## GET About_ListDevelopers + +GET /apis/ghippo.io/v1alpha1/about/developers + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "message": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[aboutListDevelopersResponse](#schemaaboutlistdevelopersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET About_ListOpenSources + +GET /apis/ghippo.io/v1alpha1/about/opensources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|page|query|integer(int32)| no ||page: 当前页码,默认值为1| +|pageSize|query|integer(int32)| no ||每页数量,默认为 10| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "license": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[aboutListOpenSourcesResponse](#schemaaboutlistopensourcesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET About_ListGProductVersions + +GET /apis/ghippo.io/v1alpha1/about/versions + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "version": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[aboutListGProductVersionsResponse](#schemaaboutlistgproductversionsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/BatchAudits + + + +## POST BatchAudits_BatchInsertAudits + +POST /apis/ghippo.io/v1alpha1/audits/batch + +> Body Parameters + +```json +{ + "audits": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[batchauditBatchInsertAuditsRequest](#schemabatchauditbatchinsertauditsrequest)| no | @openapiv2-ignore|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[batchauditBatchInsertAuditsResponse](#schemabatchauditbatchinsertauditsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Audit + + + +## GET Audit_GetAutoClearAuditTime + +GET /apis/ghippo.io/v1alpha1/audits/clear + +> Response Examples + +> 200 Response + +```json +{ + "kubeDays": 0, + "ghippoDays": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetAutoClearAuditTimeResponse](#schemaauditgetautoclearaudittimeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET 来自外部传递进来的审计日志,用于不经过apiserver的请求,例如直接请求keycloak的请求,由前端埋点调用 + +GET /apis/ghippo.io/v1alpha1/audits/external + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|externalType|query|string| no ||none| +|resourceName|query|string| no ||none| +|code|query|integer(int32)| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|externalType|loginFailed| +|externalType|forgetPassword| +|externalType|resetPassword| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditExternalAuditResponse](#schemaauditexternalauditresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_GetLimitRangeTime + +GET /apis/ghippo.io/v1alpha1/audits/limit-range + +> Response Examples + +> 200 Response + +```json +{ + "day": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetLimitRangeTimeResponse](#schemaauditgetlimitrangetimeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_GetAuditResourceReport + +GET /apis/ghippo.io/v1alpha1/audits/reports/resources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|start|query|string| no ||none| +|end|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "ResourceType": "string", + "EventName": "string", + "Count": 0 + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetAuditResourceReportResponse](#schemaauditgetauditresourcereportresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_GetAuditUserReport + +GET /apis/ghippo.io/v1alpha1/audits/reports/users + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|start|query|string| no ||none| +|end|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "UserName": "string", + "TotalCount": 0, + "SuccessCount": 0, + "FailedCount": 0 + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetAuditUserReportResponse](#schemaauditgetaudituserreportresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_ListAudits + +GET /apis/ghippo.io/v1alpha3/audits + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|sourceType|query|string| no ||none| +|sourceName|query|string| no ||none| +|clusterName|query|string| no ||none| +|status|query|string| no ||none| +|searchType|query|string| no ||none| +|searchUser|query|string| no ||none| +|gproduct|query|string| no ||none| +|start|query|string| no ||none| +|end|query|string| no ||none| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +#### Enum + +|Name|Value| +|---|---| +|status|all| +|status|succeeded| +|status|failed| +|searchType|fuzzy| +|searchType|exact| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "auditName": "string", + "resourceType": "string", + "resourceName": "string", + "clusterName": "string", + "gproduct": "string", + "status": "all", + "user": "string", + "client": "string", + "ip": "string", + "createdAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditListAuditsResponse](#schemaauditlistauditsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Audit_ClearAuditsNow + +POST /apis/ghippo.io/v1alpha3/audits/clear + +> Body Parameters + +```json +{ + "days": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[auditClearAuditsNowRequest](#schemaauditclearauditsnowrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditClearAuditsNowResponse](#schemaauditclearauditsnowresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_ExportAudits + +GET /apis/ghippo.io/v1alpha3/audits/export + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|start|query|string| no ||none| +|end|query|string| no ||none| +|sourceType|query|string| no ||none| +|sourceName|query|string| no ||none| +|clusterName|query|string| no ||none| +|gproduct|query|string| no ||none| +|status|query|string| no ||none| +|searchType|query|string| no ||none| +|searchUser|query|string| no ||none| +|exportType|query|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|status|all| +|status|succeeded| +|status|failed| +|searchType|fuzzy| +|searchType|exact| +|exportType|Csv| +|exportType|Excel| + +> Response Examples + +> 200 Response + +```json +{ + "contentType": "string", + "data": "string", + "extensions": [ + { + "@type": "string", + "property1": {}, + "property2": {} + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[apiHttpBody](#schemaapihttpbody)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_GetExportURI + +GET /apis/ghippo.io/v1alpha3/audits/export/uri + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|module|query|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|module|audit| +|module|kube_audit| + +> Response Examples + +> 200 Response + +```json +{ + "uri": "string", + "method": "GET" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetExportURIResponse](#schemaauditgetexporturiresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_ListKubeAudits + +GET /apis/ghippo.io/v1alpha3/audits/kube + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|sourceType|query|string| no ||none| +|sourceName|query|string| no ||none| +|clusterName|query|string| no ||none| +|status|query|string| no ||none| +|searchType|query|string| no ||none| +|searchUser|query|string| no ||none| +|start|query|string| no ||none| +|end|query|string| no ||none| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +#### Enum + +|Name|Value| +|---|---| +|status|all| +|status|succeeded| +|status|failed| +|searchType|fuzzy| +|searchType|exact| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "auditName": "string", + "resourceType": "string", + "resourceName": "string", + "clusterName": "string", + "status": "all", + "user": "string", + "client": "string", + "ip": "string", + "createdAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditListKubeAuditsResponse](#schemaauditlistkubeauditsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Audit_ClearKubeAuditsNow + +POST /apis/ghippo.io/v1alpha3/audits/kube/clear + +> Body Parameters + +```json +{ + "days": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[auditClearKubeAuditsNowRequest](#schemaauditclearkubeauditsnowrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditClearKubeAuditsNowResponse](#schemaauditclearkubeauditsnowresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_ExportKubeAudits + +GET /apis/ghippo.io/v1alpha3/audits/kube/export + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|start|query|string| no ||none| +|end|query|string| no ||none| +|sourceType|query|string| no ||none| +|sourceName|query|string| no ||none| +|clusterName|query|string| no ||none| +|status|query|string| no ||none| +|searchType|query|string| no ||none| +|searchUser|query|string| no ||none| +|exportType|query|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|status|all| +|status|succeeded| +|status|failed| +|searchType|fuzzy| +|searchType|exact| +|exportType|Csv| +|exportType|Excel| + +> Response Examples + +> 200 Response + +```json +{ + "contentType": "string", + "data": "string", + "extensions": [ + { + "@type": "string", + "property1": {}, + "property2": {} + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[apiHttpBody](#schemaapihttpbody)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_GetKubeAuditDetail + +GET /apis/ghippo.io/v1alpha3/audits/kube/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "audit": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetKubeAuditDetailResponse](#schemaauditgetkubeauditdetailresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Audit_SetAutoClearAuditSetting + +PUT /apis/ghippo.io/v1alpha3/audits/set-auto-clear + +> Body Parameters + +```json +{ + "days": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[auditSetAutoClearAuditSettingRequest](#schemaauditsetautoclearauditsettingrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditSetAutoClearAuditSettingResponse](#schemaauditsetautoclearauditsettingresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Audit_SetAutoClearKubeAuditSetting + +PUT /apis/ghippo.io/v1alpha3/audits/set-auto-clear/kube + +> Body Parameters + +```json +{ + "days": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[auditSetAutoClearKubeAuditSettingRequest](#schemaauditsetautoclearkubeauditsettingrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditSetAutoClearKubeAuditSettingResponse](#schemaauditsetautoclearkubeauditsettingresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Audit_GetAuditDetail + +GET /apis/ghippo.io/v1alpha3/audits/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "audit": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditGetAuditDetailResponse](#schemaauditgetauditdetailresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Openapi + + + +## GET Openapi_AuthToken + +GET /apis/ghippo.io/v1alpha1/auth-token + +> Response Examples + +> 200 Response + +```json +{ + "message": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditAuthTokenResponse](#schemaauditauthtokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Openapi_Certs + +GET /apis/ghippo.io/v1alpha1/certs + +> Response Examples + +> 200 Response + +```json +{ + "keys": [ + { + "kid": "string", + "kty": "string", + "e": "string", + "n": "string", + "alg": "string", + "use": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[auditCertsResponse](#schemaauditcertsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Login + + + +## POST gRPC 调用,不暴露给 OpenAPI + +POST /apis/ghippo.io/v1alpha1/authenticate-with-password + +> Body Parameters + +```json +{ + "username": "string", + "password": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[loginAuthenticateWithPasswordRequest](#schemaloginauthenticatewithpasswordrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "idToken": "string", + "refreshToken": "string", + "username": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginAuthenticateWithPasswordResponse](#schemaloginauthenticatewithpasswordresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Login_RedirectLogin + +GET /apis/ghippo.io/v1alpha1/login + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|callbackUrl|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginLoginGetResponse](#schemaloginlogingetresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Login_OIDCLogin + +POST /apis/ghippo.io/v1alpha1/login + +> Body Parameters + +```json +{ + "code": "string", + "state": "string", + "sessionState": "string", + "callbackUrl": "string", + "useSso": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[loginLoginPostRequest](#schemaloginloginpostrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "idToken": "string", + "refreshToken": "string", + "username": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginLoginPostResponse](#schemaloginloginpostresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Login_OIDCLogout + +DELETE /apis/ghippo.io/v1alpha1/logout + +> Response Examples + +> 200 Response + +```json +{ + "externalLogoutUrl": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginLogoutResponse](#schemaloginlogoutresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Login_RefreshToken + +POST /apis/ghippo.io/v1alpha1/refresh-token + +> Body Parameters + +```json +{ + "refreshToken": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[loginRefreshTokenRequest](#schemaloginrefreshtokenrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "idToken": "string", + "refreshToken": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginRefreshTokenResponse](#schemaloginrefreshtokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Login_CheckSessionLimit + +POST /apis/ghippo.io/v1alpha1/session-limit + +> Body Parameters + +```json +{ + "username": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[loginCheckSessionLimitRequest](#schemaloginchecksessionlimitrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginCheckSessionLimitResponse](#schemaloginchecksessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Client + + + +## GET Client_ListClients + +GET /apis/ghippo.io/v1alpha1/clients + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|clientId|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "clientId": "string", + "name": "string", + "secret": "string", + "baseUrl": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clientListClientsResponse](#schemaclientlistclientsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Client_CreateClient + +POST /apis/ghippo.io/v1alpha1/clients + +> Body Parameters + +```json +{ + "clientId": "string", + "baseUrl": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[clientCreateClientRequest](#schemaclientcreateclientrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clientCreateClientResponse](#schemaclientcreateclientresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Client_GetClient + +GET /apis/ghippo.io/v1alpha1/clients/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "client": { + "id": "string", + "clientId": "string", + "name": "string", + "secret": "string", + "baseUrl": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clientGetClientResponse](#schemaclientgetclientresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Client_UpdateClient + +PUT /apis/ghippo.io/v1alpha1/clients/{id} + +> Body Parameters + +```json +{ + "clientId": "string", + "name": "string", + "baseUrl": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» clientId|body|string| no ||none| +|» name|body|string| no ||none| +|» baseUrl|body|string| no | repeated string redirect_uris = 4 [(validate.rules).repeated.min_items = 1];|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clientUpdateClientResponse](#schemaclientupdateclientresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Client_DeleteClient + +DELETE /apis/ghippo.io/v1alpha1/clients/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[clientDeleteClientResponse](#schemaclientdeleteclientresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Account + + + +## GET Account_GetUser + +GET /apis/ghippo.io/v1alpha1/current-user + +> Response Examples + +> 200 Response + +```json +{ + "uid": "string", + "username": "string", + "email": "string", + "locale": "string", + "source": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1currentuserGetUserResponse](#schemav1alpha1currentusergetuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Account_CreateAccessToken + +POST /apis/ghippo.io/v1alpha1/current-user/accesstoken + +> Body Parameters + +```json +{ + "name": "string", + "expiredAt": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[currentuserCreateAccessTokenRequest](#schemacurrentusercreateaccesstokenrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "token": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserCreateAccessTokenResponse](#schemacurrentusercreateaccesstokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Account_ListAccessTokens + +GET /apis/ghippo.io/v1alpha1/current-user/accesstokens + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserListAccessTokensResponse](#schemacurrentuserlistaccesstokensresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Account_DeleteAccessToken + +DELETE /apis/ghippo.io/v1alpha1/current-user/accesstokens/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserDeleteAccessTokenResponse](#schemacurrentuserdeleteaccesstokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Account_UpdateEmail + +PUT /apis/ghippo.io/v1alpha1/current-user/email + +> Body Parameters + +```json +{ + "email": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[currentuserUpdateEmailRequest](#schemacurrentuserupdateemailrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserUpdateEmailResponse](#schemacurrentuserupdateemailresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Account_GetGlobalPermissions + +GET /apis/ghippo.io/v1alpha1/current-user/global-permissions + +> Response Examples + +> 200 Response + +```json +{ + "permissions": [ + "Unknown" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserGetGlobalPermissionsResponse](#schemacurrentusergetglobalpermissionsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Account_UpdateLanguage + +PUT /apis/ghippo.io/v1alpha1/current-user/language + +> Body Parameters + +```json +{ + "locale": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[currentuserUpdateLanguageRequest](#schemacurrentuserupdatelanguagerequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserUpdateLanguageResponse](#schemacurrentuserupdatelanguageresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Account_UpdatePassword + +PUT /apis/ghippo.io/v1alpha1/current-user/password + +> Body Parameters + +```json +{ + "password": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[currentuserUpdatePasswordRequest](#schemacurrentuserupdatepasswordrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserUpdatePasswordResponse](#schemacurrentuserupdatepasswordresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Account_PasswordDescription + +GET /apis/ghippo.io/v1alpha1/current-user/password-description + +> Response Examples + +> 200 Response + +```json +{ + "allowModify": true, + "emptyPassword": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserPasswordDescriptionResponse](#schemacurrentuserpassworddescriptionresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Account_SetCurrentUserPassword + +PUT /apis/ghippo.io/v1alpha1/current-user/set-password + +> Body Parameters + +```json +{ + "oldPassword": "string", + "newPassword": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[currentuserSetCurrentUserPasswordRequest](#schemacurrentusersetcurrentuserpasswordrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserSetCurrentUserPasswordResponse](#schemacurrentusersetcurrentuserpasswordresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Account_ListSSHKeys + +GET /apis/ghippo.io/v1alpha1/current-user/sshkeys + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": 0, + "sshKeyName": "string", + "publicKey": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserListSSHKeysResponse](#schemacurrentuserlistsshkeysresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Account_CreateSSHKey + +POST /apis/ghippo.io/v1alpha1/current-user/sshkeys + +> Body Parameters + +```json +{ + "sshKeyName": "string", + "publicKey": "string", + "expiredAt": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[currentuserCreateSSHKeyRequest](#schemacurrentusercreatesshkeyrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserCreateSSHKeyResponse](#schemacurrentusercreatesshkeyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Account_UpdateSSHKey + +PUT /apis/ghippo.io/v1alpha1/current-user/sshkeys/{sshkeyId} + +> Body Parameters + +```json +{ + "sshKeyName": "string", + "publicKey": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|sshkeyId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» sshKeyName|body|string| no ||none| +|» publicKey|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserUpdateSSHKeyResponse](#schemacurrentuserupdatesshkeyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Account_DeleteSSHKey + +DELETE /apis/ghippo.io/v1alpha1/current-user/sshkeys/{sshkeyId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|sshkeyId|path|integer(int32)| yes ||none| +|id|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[currentuserDeleteSSHKeyResponse](#schemacurrentuserdeletesshkeyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Workspace + + + +## GET Workspace_ListExclusiveResourceTypes + +GET /apis/ghippo.io/v1alpha1/exclusiveresource-types + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + "string" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListExclusiveResourceTypesResponse](#schemaworkspacelistexclusiveresourcetypesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListFolders + +GET /apis/ghippo.io/v1alpha1/folders + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": 0, + "name": "string", + "alias": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListFoldersResponse](#schemaworkspacelistfoldersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_CreateFolder + +POST /apis/ghippo.io/v1alpha1/folders + +> Body Parameters + +```json +{ + "name": "string", + "alias": "string", + "parentFolderId": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[workspaceCreateFolderRequest](#schemaworkspacecreatefolderrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "folderId": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceCreateFolderResponse](#schemaworkspacecreatefolderresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListFolderTree + +GET /apis/ghippo.io/v1alpha1/folders-tree + +> Response Examples + +> 200 Response + +```json +{ + "folderTree": { + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + { + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + { + "id": null, + "name": null, + "alias": null, + "isWorkspace": null, + "parentId": null, + "children": null, + "permissions": null, + "resourceKind": null + } + ], + "permissions": [ + "Unknown" + ], + "resourceKind": [ + "resource_group" + ] + } + ], + "permissions": [ + "Unknown" + ], + "resourceKind": [ + "resource_group" + ] + }, + "defaultId": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListFolderTreeResponse](#schemaworkspacelistfoldertreeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_GetFolder + +GET /apis/ghippo.io/v1alpha1/folders/{folderId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "folder": { + "id": 0, + "name": "string", + "alias": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceGetFolderResponse](#schemaworkspacegetfolderresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Workspace_UpdateFolder + +PUT /apis/ghippo.io/v1alpha1/folders/{folderId} + +> Body Parameters + +```json +{ + "alias": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» alias|body|string| no | string name = 1 [(validate.rules).string.min_len = 1];|none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceUpdateFolderResponse](#schemaworkspaceupdatefolderresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE TODO: sub folder删不删? + +DELETE /apis/ghippo.io/v1alpha1/folders/{folderId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceDeleteFolderResponse](#schemaworkspacedeletefolderresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_Authorize + +POST /apis/ghippo.io/v1alpha1/folders/{folderId}/authorize + +> Body Parameters + +```json +{ + "memberName": "string", + "memberType": "string", + "memberId": "string", + "roleNames": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» memberName|body|string| no | string role_name = 2;|none| +|» memberType|body|string| no ||none| +|» memberId|body|string| no ||none| +|» roleNames|body|[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceAuthorizeResponse](#schemaworkspaceauthorizeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Workspace_Deauthorize + +PUT /apis/ghippo.io/v1alpha1/folders/{folderId}/deauthorize + +> Body Parameters + +```json +{ + "roleName": "string", + "memberName": "string", + "memberType": "string", + "memberId": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» roleName|body|string| no ||none| +|» memberName|body|string| no ||none| +|» memberType|body|string| no ||none| +|» memberId|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceDeauthorizeResponse](#schemaworkspacedeauthorizeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_FolderListGroups + +GET /apis/ghippo.io/v1alpha1/folders/{folderId}/groups + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|search|query|string| no ||搜索关键字| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true, + "authorized": true + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceFolderListGroupsResponse](#schemaworkspacefolderlistgroupsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListMembersRolesByFolder + +GET /apis/ghippo.io/v1alpha1/folders/{folderId}/members-roles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|memberName|query|string| no ||none| +|memberType|query|string| no ||none| +|roleName|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "roleName": "string", + "folderId": 0, + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListMembersRolesByFolderResponse](#schemaworkspacelistmembersrolesbyfolderresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_FolderListPermissions + +GET /apis/ghippo.io/v1alpha1/folders/{folderId}/permissions + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "permissions": [ + "Unknown" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceFolderListPermissionsResponse](#schemaworkspacefolderlistpermissionsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Workspace_Reauthorize + +PUT /apis/ghippo.io/v1alpha1/folders/{folderId}/reauthorize + +> Body Parameters + +```json +{ + "oldRoleName": "string", + "newRoleName": "string", + "memberName": "string", + "memberType": "string", + "memberId": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» oldRoleName|body|string| no ||none| +|» newRoleName|body|string| no ||none| +|» memberName|body|string| no ||none| +|» memberType|body|string| no ||none| +|» memberId|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceReauthorizeResponse](#schemaworkspacereauthorizeresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_FolderListUsers + +GET /apis/ghippo.io/v1alpha1/folders/{folderId}/users + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|folderId|path|integer(int32)| yes ||none| +|search|query|string| no ||搜索关键字| +|pageSize|query|integer(int32)| no ||每页条数| +|page|query|integer(int32)| no ||当前页| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "canAuthorize": true, + "authorized": true + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceFolderListUsersResponse](#schemaworkspacefolderlistusersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListResourceQuotaTypes + +GET /apis/ghippo.io/v1alpha1/resourcequota-types + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + "string" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListResourceQuotaTypesResponse](#schemaworkspacelistresourcequotatypesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListSharedResourceTypes + +GET /apis/ghippo.io/v1alpha1/sharedresource-types + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + "string" + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListSharedResourceTypesResponse](#schemaworkspacelistsharedresourcetypesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_UpdateQuotaCheck + +POST /apis/ghippo.io/v1alpha1/update-quota-check + +> Body Parameters + +```json +{ + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "workspaceId": 0, + "quotaHard": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[workspaceUpdateQuotaCheckRequest](#schemaworkspaceupdatequotacheckrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "passed": true, + "reason": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceUpdateQuotaCheckResponse](#schemaworkspaceupdatequotacheckresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_GetWorkspaceSharedResourceQuota + +GET /apis/ghippo.io/v1alpha1/workspace-sharedresource-quota + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|query|integer(int32)| no ||none| +|resourceName|query|string| no ||none| +|resourceType|query|string| no ||none| +|notFormatted|query|boolean| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "setting": { + "property1": "string", + "property2": "string" + }, + "allocatable": { + "property1": "string", + "property2": "string" + }, + "used": { + "property1": "string", + "property2": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceGetWorkspaceSharedResourceQuotaResponse](#schemaworkspacegetworkspacesharedresourcequotaresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Workspace_SetQuotaHardForWorkspaceSharedResource + +PUT /apis/ghippo.io/v1alpha1/workspace-sharedresource-quota-hard + +> Body Parameters + +```json +{ + "workspaceResourceId": 0, + "quotaHard": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[workspaceSetQuotaHardForWorkspaceSharedResourceRequest](#schemaworkspacesetquotahardforworkspacesharedresourcerequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceSetQuotaHardForWorkspaceSharedResourceResponse](#schemaworkspacesetquotahardforworkspacesharedresourceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListWorkspaces + +GET /apis/ghippo.io/v1alpha1/workspaces + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": 0, + "name": "string", + "alias": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListWorkspacesResponse](#schemaworkspacelistworkspacesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_CreateWorkspace + +POST /apis/ghippo.io/v1alpha1/workspaces + +> Body Parameters + +```json +{ + "alias": "string", + "parentFolderId": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[workspaceCreateWorkspaceRequest](#schemaworkspacecreateworkspacerequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "workspaceId": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceCreateWorkspaceResponse](#schemaworkspacecreateworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_GetWorkspace + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "workspace": { + "id": 0, + "name": "string", + "alias": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceGetWorkspaceResponse](#schemaworkspacegetworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE TODO: sub ws删不删? + +DELETE /apis/ghippo.io/v1alpha1/workspaces/{workspaceId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceDeleteWorkspaceResponse](#schemaworkspacedeleteworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListAvailableExclusiveResourcesByWorkspace + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/available-exclusiveresources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|resourceName|query|string| no ||none| +|resourceType|query|array[string]| no ||none| +|resourceScope|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "bound": true, + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListAvailableExclusiveResourcesByWorkspaceResponse](#schemaworkspacelistavailableexclusiveresourcesbyworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListAvailableSharedResourcesByWorkspace + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/available-sharedresources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|resourceName|query|string| no ||none| +|resourceType|query|array[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "bound": true, + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListAvailableSharedResourcesByWorkspaceResponse](#schemaworkspacelistavailablesharedresourcesbyworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_BindExclusiveResourceToWorkspace + +POST /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/bind-exclusiveresource + +> Body Parameters + +```json +{ + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» resourceName|body|string| no ||none| +|» resourceType|body|string| no ||none| +|» resourceScope|body|string| no ||none| +|» gproduct|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceBindExclusiveResourceToWorkspaceResponse](#schemaworkspacebindexclusiveresourcetoworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_BindSharedResourceToWorkspace + +POST /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/bind-sharedresource + +> Body Parameters + +```json +{ + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» resourceName|body|string| no ||none| +|» resourceType|body|string| no ||none| +|» resourceScope|body|string| no ||none| +|» gproduct|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceBindSharedResourceToWorkspaceResponse](#schemaworkspacebindsharedresourcetoworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_BindSharedResourceAndSetQuotaHardToWorkspace + +POST /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/bind-sharedresource-setquota + +> Body Parameters + +```json +{ + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "quotaHard": { + "property1": "string", + "property2": "string" + } +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||cluster 资源 resource_scope 为空| +|body|body|object| no ||none| +|» resourceName|body|string| no ||none| +|» resourceType|body|string| no ||none| +|» gproduct|body|string| no ||none| +|» quotaHard|body|object| no ||none| +|»» **additionalProperties**|body|string| no ||none| + +#### Description + +**workspaceId**: cluster 资源 resource_scope 为空 +string resource_scope = 4 [(validate.rules).string.min_len = 1]; + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceBindSharedResourceAndSetQuotaHardToWorkspaceResponse](#schemaworkspacebindsharedresourceandsetquotahardtoworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListExclusiveResourcesByWorkspace + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/exclusiveresources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|resourceName|query|string| no ||none| +|resourceType|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string", + "workspaceId": 0, + "workspaceResourceId": 0, + "module": "string", + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListExclusiveResourcesByWorkspaceResponse](#schemaworkspacelistexclusiveresourcesbyworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListMembersRolesByWorkspace + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/members-roles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|memberName|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "roleName": "string", + "workspaceId": 0, + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListMembersRolesByWorkspaceResponse](#schemaworkspacelistmembersrolesbyworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Workspace_MoveWorkspace + +POST /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/move + +> Body Parameters + +```json +{ + "destFolderId": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» destFolderId|body|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceMoveWorkspaceResponse](#schemaworkspacemoveworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_MoveWorkspaceFolderList + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/move-folders + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|folder|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "folderId": 0, + "folderAlias": "string", + "parentId": 0, + "parentAlias": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceMoveWorkspaceFolderListResponse](#schemaworkspacemoveworkspacefolderlistresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListWorkspaceShareResourceQuotaTypes + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/sharedresource/{resourceName}/quota-types + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|resourceName|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "gpus": [ + { + "type": "string", + "alias": "string", + "resource": [ + { + "key": "string", + "alias": "string", + "aliasZh": "string" + } + ] + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListWorkspaceShareResourceQuotaTypesResponse](#schemaworkspacelistworkspaceshareresourcequotatypesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Workspace_ListSharedResourcesByWorkspace + +GET /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/sharedresources + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|resourceName|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string", + "workspaceId": 0, + "workspaceResourceId": 0, + "module": "string", + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceListSharedResourcesByWorkspaceResponse](#schemaworkspacelistsharedresourcesbyworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Workspace_UnbindResourceFromWorkspace + +PUT /apis/ghippo.io/v1alpha1/workspaces/{workspaceId}/unbind-resource + +> Body Parameters + +```json +{ + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|workspaceId|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» resourceName|body|string| no ||none| +|» resourceType|body|string| no ||none| +|» resourceScope|body|string| no ||none| +|» gproduct|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[workspaceUnbindResourceFromWorkspaceResponse](#schemaworkspaceunbindresourcefromworkspaceresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/FeatureGate + + + +## GET FeatureGate_ListFeatureGates + +GET /apis/ghippo.io/v1alpha1/feature-gate + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "CreateUserInWorkspace", + "description": "string", + "enabled": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[feature_gateListFeatureGatesResponse](#schemafeature_gatelistfeaturegatesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Role + + + +## GET Role_ListFolderRoleNames + +GET /apis/ghippo.io/v1alpha1/folderrolenames + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "authScope": "platform", + "description": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListFolderRoleNamesResponse](#schemarolelistfolderrolenamesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_ListMembersFoldersByFolderRole + +GET /apis/ghippo.io/v1alpha1/folderroles/{name}/members-folders + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "folderId": 0, + "folderAlias": "string", + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListMembersFoldersByFolderRoleResponse](#schemarolelistmembersfoldersbyfolderroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_ListAllPermissions + +GET /apis/ghippo.io/v1alpha1/permissions + +> Response Examples + +> 200 Response + +```json +{ + "gproductPerms": [ + { + "gproduct": { + "gproduct": "string", + "localizedName": "string" + }, + "authscopePerms": [ + { + "authScope": "platform", + "categoryPerms": [ + {} + ] + } + ] + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListAllPermissionsResponse](#schemarolelistallpermissionsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_ListMembersByPlatformRole + +GET /apis/ghippo.io/v1alpha1/platformroles/{name}/members + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "type": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListMembersByPlatformRoleResponse](#schemarolelistmembersbyplatformroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_ListRoles + +GET /apis/ghippo.io/v1alpha1/roles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|search|query|string| no ||搜索关键字| +|pageSize|query|integer(int32)| no ||每页条数| +|page|query|integer(int32)| no ||当前页| +|roleType|query|string| no ||none| +|scope|query|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|roleType|query_all_role_type| +|roleType|query_system| +|roleType|query_custom| +|scope|query_all_auth_scope| +|scope|query_platform| +|scope|query_folder| +|scope|query_workspace| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "type": "system", + "description": "string", + "scope": "platform", + "createdAt": "string", + "updatedAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListRolesResponse](#schemarolelistrolesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Role_CreateRole + +POST /apis/ghippo.io/v1alpha1/roles + +> Body Parameters + +```json +{ + "name": "string", + "description": "string", + "scope": "platform", + "perms": [ + { + "action": "string", + "resourceType": "string", + "gproduct": "string" + } + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[roleCreateRoleRequest](#schemarolecreaterolerequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleCreateRoleResponse](#schemarolecreateroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_CheckRoleName + +GET /apis/ghippo.io/v1alpha1/roles/check-role-name/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "exist": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleCheckRoleNameResponse](#schemarolecheckrolenameresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_GetRoleMemberCount + +GET /apis/ghippo.io/v1alpha1/roles/role-member-count/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "userCount": 0, + "groupCount": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleGetRoleMemberCountResponse](#schemarolegetrolemembercountresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_GetRole + +GET /apis/ghippo.io/v1alpha1/roles/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "name": "string", + "type": "system", + "description": "string", + "scope": "platform", + "createdAt": "string", + "updatedAt": "string", + "gproductPerms": [ + { + "gproduct": { + "gproduct": "string", + "localizedName": "string" + }, + "categoryPerms": [ + { + "category": { + "name": null, + "localizedName": null + }, + "resourcePerms": [ + {} + ] + } + ] + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleGetRoleResponse](#schemarolegetroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Role_UpdateRole + +PUT /apis/ghippo.io/v1alpha1/roles/{name} + +> Body Parameters + +```json +{ + "description": "string", + "perms": [ + { + "action": "string", + "resourceType": "string", + "gproduct": "string" + } + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|body|body|object| no ||none| +|» description|body|string| no | globalRoleType type = 2;|none| +|» perms|body|[[rolePermission](#schemarolepermission)]| no | AuthScope scope = 3;|none| +|»» action|body|string| no ||none| +|»» resourceType|body|string| no ||none| +|»» gproduct|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleUpdateRoleResponse](#schemaroleupdateroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Role_DeleteRole + +DELETE /apis/ghippo.io/v1alpha1/roles/{name} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleDeleteRoleResponse](#schemaroledeleteroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_ListWorkspaceRoleNames + +GET /apis/ghippo.io/v1alpha1/workspacerolenames + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "name": "string", + "authScope": "platform", + "description": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListWorkspaceRoleNamesResponse](#schemarolelistworkspacerolenamesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Role_ListMembersWorkspacesByWorkspaceRole + +GET /apis/ghippo.io/v1alpha1/workspaceroles/{name}/members-workspaces + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|name|path|string| yes ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| +|search|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "workspaceId": 0, + "workspaceAlias": "string", + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[roleListMembersWorkspacesByWorkspaceRoleResponse](#schemarolelistmembersworkspacesbyworkspaceroleresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/GProductLicenses + + + +## GET GProductLicenses_ListGProductLicenses + +GET /apis/ghippo.io/v1alpha1/gproduct-licenses + +> Response Examples + +> 200 Response + +```json +{ + "licenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseListGProductLicensesResponse](#schemagproductlicenselistgproductlicensesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT GProductLicenses_UpdateGProductLicenses + +PUT /apis/ghippo.io/v1alpha1/gproduct-licenses + +> Body Parameters + +```json +{ + "yaml": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[gproductlicenseUpdateGProductLicensesRequest](#schemagproductlicenseupdategproductlicensesrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "message": "string", + "licenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseUpdateGProductLicensesResponse](#schemagproductlicenseupdategproductlicensesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GProductLicenses_GetGProductLicensesESN + +GET /apis/ghippo.io/v1alpha1/gproduct-licenses/esn + +> Response Examples + +> 200 Response + +```json +{ + "esn": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseGetGProductLicensesESNResponse](#schemagproductlicensegetgproductlicensesesnresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GProductLicenses_GetGProductLicensesOverQuota + +GET /apis/ghippo.io/v1alpha1/gproduct-licenses/over-quota + +> Response Examples + +> 200 Response + +```json +{ + "expireSoonLicenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ], + "expiredLicenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseGetGProductLicensesOverQuotaResponse](#schemagproductlicensegetgproductlicensesoverquotaresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GProductLicenses_GetGProductLicensesYaml + +GET /apis/ghippo.io/v1alpha1/gproduct-licenses/yaml + +> Response Examples + +> 200 Response + +```json +{ + "yaml": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseGetGProductLicenseYamlResponse](#schemagproductlicensegetgproductlicenseyamlresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET GProductLicenses_GetGProductLicenses + +GET /apis/ghippo.io/v1alpha1/gproduct-licenses/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "license": { + "id": "string", + "name": "string", + "module": "string", + "licenseKey": "string", + "licenseLevel": "string", + "physicalUsedCpu": "string", + "physicalMaxCpu": "string", + "virtualUsedCpu": "string", + "virtualMaxCpu": "string", + "expiredAt": "string", + "usedNode": "string", + "maxNode": "string", + "physicalUsedGpu": "string", + "physicalMaxGpu": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseGetGProductLicensesResponse](#schemagproductlicensegetgproductlicensesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE GProductLicenses_DeleteGProductLicenses + +DELETE /apis/ghippo.io/v1alpha1/gproduct-licenses/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductlicenseDeleteProductLicensesResponse](#schemagproductlicensedeleteproductlicensesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/GProducts + + + +## GET GProducts_ListGProducts + +GET /apis/ghippo.io/v1alpha1/gproducts + +> Response Examples + +> 200 Response + +```json +{ + "data": [ + { + "id": "string", + "title": "string", + "url": "string", + "uiAssetsUrl": "string", + "needImportLicense": true, + "needUpdateExpiredLicense": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[gproductListGProductsResponse](#schemagproductlistgproductsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Group + + + +## GET Group_ListGroups + +GET /apis/ghippo.io/v1alpha1/groups + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|search|query|string| no ||搜索关键字| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupListGroupsResponse](#schemagrouplistgroupsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Group_CreateGroup + +POST /apis/ghippo.io/v1alpha1/groups + +> Body Parameters + +```json +{ + "name": "string", + "description": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[groupCreateGroupRequest](#schemagroupcreategrouprequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupCreateGroupResponse](#schemagroupcreategroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Group_GetGroup + +GET /apis/ghippo.io/v1alpha1/groups/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "group": { + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupGetGroupResponse](#schemagroupgetgroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Group_UpdateGroup + +PUT /apis/ghippo.io/v1alpha1/groups/{id} + +> Body Parameters + +```json +{ + "name": "string", + "description": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» name|body|string| no ||none| +|» description|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupUpdateGroupResponse](#schemagroupupdategroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Group_DeleteGroup + +DELETE /apis/ghippo.io/v1alpha1/groups/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupDeleteGroupResponse](#schemagroupdeletegroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Group_GroupMembers + +GET /apis/ghippo.io/v1alpha1/groups/{id}/members + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|search|query|string| no ||搜索关键字| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupGroupMembersResponse](#schemagroupgroupmembersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Group_AddUserToGroup + +POST /apis/ghippo.io/v1alpha1/groups/{id}/members/{userId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|userId|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupAddUserToGroupResponse](#schemagroupaddusertogroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Group_DeleteUserFromGroup + +DELETE /apis/ghippo.io/v1alpha1/groups/{id}/members/{userId} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|userId|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupDeleteUserFromGroupResponse](#schemagroupdeleteuserfromgroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Group_ListGroupRoles + +GET /apis/ghippo.io/v1alpha1/groups/{id}/roles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|search|query|string| no ||搜索关键字| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| +|type|query|string| no ||role type| +|authorized|query|boolean| no ||是否授权| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "authorizedCount": 0, + "items": [ + { + "name": "string", + "type": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string", + "authorized": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupListGroupRolesResponse](#schemagrouplistgrouprolesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Group_UpdateGroupRoles + +PUT /apis/ghippo.io/v1alpha1/groups/{id}/roles + +> Body Parameters + +```json +{ + "addRoles": [ + "string" + ], + "removeRoles": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» addRoles|body|[string]| no ||none| +|» removeRoles|body|[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupUpdateGroupRolesResponse](#schemagroupupdategrouprolesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Group_ListGroupSubjects + +GET /apis/ghippo.io/v1alpha1/groups/{id}/subjects + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|search|query|string| no ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "roleId": "string", + "type": "string", + "roleName": "string", + "subjectName": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[groupListGroupSubjectResponse](#schemagrouplistgroupsubjectresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/IDP + + + +## GET IDP_ListIDPs + +GET /apis/ghippo.io/v1alpha1/idp + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpListIDPsResponse](#schemaidplistidpsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST IDP_CreateIDP + +POST /apis/ghippo.io/v1alpha1/idp + +> Body Parameters + +```json +{ + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[idpCreateIDPRequest](#schemaidpcreateidprequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpCreateIDPResponse](#schemaidpcreateidpresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET IDP_GetWellKnownUrl + +GET /apis/ghippo.io/v1alpha1/idp/wellknown-url + +> Response Examples + +> 200 Response + +```json +{ + "url": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpGetWellKnownUrlResponse](#schemaidpgetwellknownurlresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET IDP_GetIDP + +GET /apis/ghippo.io/v1alpha1/idp/{alias} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|alias|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "idpInfo": { + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpGetIDPResponse](#schemaidpgetidpresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT IDP_UpdateIDP + +PUT /apis/ghippo.io/v1alpha1/idp/{alias} + +> Body Parameters + +```json +{ + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "enabled": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|alias|path|string| yes ||none| +|body|body|object| no ||none| +|» displayName|body|string| no ||none| +|» clientId|body|string| no ||none| +|» clientSecret|body|string| no ||none| +|» clientAuthentications|body|[idpClientAuthentications](#schemaidpclientauthentications)| no ||none| +|» providerId|body|[v1alpha1idpProviderType](#schemav1alpha1idpprovidertype)| no ||none| +|» authorizationUrl|body|string| no ||none| +|» userInfoUrl|body|string| no ||none| +|» tokenUrl|body|string| no ||none| +|» logoutUrl|body|string| no ||none| +|» enableAutoLinkFlow|body|boolean| no ||none| +|» enabled|body|boolean| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|» clientAuthentications|client_secret_post| +|» clientAuthentications|client_secret_basic| +|» clientAuthentications|client_secret_jwt| +|» clientAuthentications|private_key_jwt| +|» providerId|oidc| + +> Response Examples + +> 200 Response + +```json +{ + "alias": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpUpdateIDPResponse](#schemaidpupdateidpresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE IDP_DeleteIDP + +DELETE /apis/ghippo.io/v1alpha1/idp/{alias} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|alias|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpDeleteIDPResponse](#schemaidpdeleteidpresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET IDP_GetRedirectUrl + +GET /apis/ghippo.io/v1alpha1/idp/{alias}/redirect-url + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|alias|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "url": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[idpGetRedirectUrlResponse](#schemaidpgetredirecturlresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/KeycloakEvent + + + +## POST KeycloakEvent_KeycloakEvent + +POST /apis/ghippo.io/v1alpha1/keycloak-event + +> Body Parameters + +```json +{ + "realmId": "string", + "resourceType": "string", + "operationType": "string", + "resourcePath": "string", + "representation": "string", + "uid": "string", + "authDetails": { + "clientId": "string", + "ipAddress": "string", + "realmId": "string", + "userId": "string", + "username": "string", + "sessionId": "string" + }, + "type": "string", + "details": { + "property1": "string", + "property2": "string" + }, + "error": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[keycloakeventKeycloakEventRequest](#schemakeycloakeventkeycloakeventrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[keycloakeventKeycloakEventResponse](#schemakeycloakeventkeycloakeventresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/LoginPage + + + +## GET LoginPage_GetInfo + +GET /apis/ghippo.io/v1alpha1/login-page/info + +> Response Examples + +> 200 Response + +```json +{ + "version": 0, + "platformName": "string", + "copyright": "string", + "tabName": "string", + "icon": "string", + "favicon": "string", + "background": "string", + "customBg": true, + "isVideo": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginpageGetLoginPageInfoResponse](#schemaloginpagegetloginpageinforesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT LoginPage_UpdateInfo + +PUT /apis/ghippo.io/v1alpha1/login-page/info + +> Body Parameters + +```json +{ + "platformName": "string", + "copyright": "string", + "tabName": "string", + "icon": "string", + "favicon": "string", + "background": "string", + "isVideo": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[loginpageUpdateLoginPageInfoRequest](#schemaloginpageupdateloginpageinforequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginpageUpdateLoginPageInfoResponse](#schemaloginpageupdateloginpageinforesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST LoginPage_ResetInfo + +POST /apis/ghippo.io/v1alpha1/login-page/reset + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginpageResetLoginPageInfoResponse](#schemaloginpageresetloginpageinforesponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET LoginPage_GetVersion + +GET /apis/ghippo.io/v1alpha1/login-page/version + +> Response Examples + +> 200 Response + +```json +{ + "version": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[loginpageGetLoginPageVersionResponse](#schemaloginpagegetloginpageversionresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Message + + + +## GET Message_ListMessages + +GET /apis/ghippo.io/v1alpha1/messages + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|unreadCount|query|boolean| no ||是否只返回统计未读数量| +|search|query|string| no ||搜索关键字| +|read|query|string| no ||是否只返回已读或未读,传"read"或"unread"来区分,不传返回已读和未读的消息| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +#### Enum + +|Name|Value| +|---|---| +|read|all| +|read|read| +|read|unread| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageListMessagesResponse](#schemamessagelistmessagesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Message_GetMessagesCount + +GET /apis/ghippo.io/v1alpha1/messages/count + +> Response Examples + +> 200 Response + +```json +{ + "total": 0, + "readTotal": 0, + "unreadTotal": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageGetMessagesCountResponse](#schemamessagegetmessagescountresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Message_DeleteMessages + +POST /apis/ghippo.io/v1alpha1/messages/delete + +> Body Parameters + +```json +{ + "ids": [ + 0 + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[messageDeleteMessagesRequest](#schemamessagedeletemessagesrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageDeleteMessagesResponse](#schemamessagedeletemessagesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Message_GetSystemMessage + +GET /apis/ghippo.io/v1alpha1/messages/system/system-message + +> Response Examples + +> 200 Response + +```json +{ + "message": "string", + "show": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageGetSystemMessageResponse](#schemamessagegetsystemmessageresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Message_ToggleUnreadMessage + +GET /apis/ghippo.io/v1alpha1/messages/toggle-unread + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|query|integer(int32)| no ||none| +|next|query|boolean| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "message": { + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageToggleUnreadMessageResponse](#schemamessagetoggleunreadmessageresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Message_GetMessage + +GET /apis/ghippo.io/v1alpha1/messages/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "message": { + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageGetMessageResponse](#schemamessagegetmessageresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Message_SetReadMessages + +POST /apis/ghippo.io/v1alpha1/read-messages + +> Body Parameters + +```json +{ + "all": true, + "ids": [ + 0 + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[messageSetReadMessagesRequest](#schemamessagesetreadmessagesrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[messageSetReadMessagesResponse](#schemamessagesetreadmessagesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Oauth2 + + + +## GET Oauth2_GetOauth2 + +GET /apis/ghippo.io/v1alpha1/oauth2 + +> Response Examples + +> 200 Response + +```json +{ + "providerType": "wechatwork", + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "agentId": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oauthGetOauth2Response](#schemaoauthgetoauth2response)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Oauth2_UpdateOauth2 + +PUT /apis/ghippo.io/v1alpha1/oauth2 + +> Body Parameters + +```json +{ + "providerType": "wechatwork", + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "agentId": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[oauthUpdateOauth2Request](#schemaoauthupdateoauth2request)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oauthUpdateOauth2Response](#schemaoauthupdateoauth2response)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Oauth2_CreateOauth2 + +POST /apis/ghippo.io/v1alpha1/oauth2 + +> Body Parameters + +```json +{ + "providerType": "wechatwork", + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "agentId": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[oauthCreateOauth2Request](#schemaoauthcreateoauth2request)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oauthCreateOauth2Response](#schemaoauthcreateoauth2response)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Oauth2_DeleteOauth2 + +DELETE /apis/ghippo.io/v1alpha1/oauth2 + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|providerType|query|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|providerType|wechatwork| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oauthDeleteOauth2Response](#schemaoauthdeleteoauth2response)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Oauth2_GetOauth2RedirectDomain + +GET /apis/ghippo.io/v1alpha1/oauth2/redirect-domain + +> Response Examples + +> 200 Response + +```json +{ + "redirectDomain": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[oauthGetOauth2RedirectDomainResponse](#schemaoauthgetoauth2redirectdomainresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/ProductNavigator + + + +## GET ProductNavigator_Info + +GET /apis/ghippo.io/v1alpha1/product-nav/info + +> Response Examples + +> 200 Response + +```json +{ + "categories": [ + { + "name": "string", + "menus": [ + { + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + {} + ] + } + ] + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[productnavProductNavResponse](#schemaproductnavproductnavresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Publish + + + +## POST Publish_PublishMessage + +POST /apis/ghippo.io/v1alpha1/publish/messages + +> Body Parameters + +```json +{ + "userId": "string", + "type": "string", + "subject": "string", + "message": "string", + "messageUid": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[publishPublishMessageRequest](#schemapublishpublishmessagerequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[publishPublishMessageResponse](#schemapublishpublishmessageresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/SecurityPolicy + + + +## GET SecurityPolicy_GetAccountLockoutPolicy + +GET /apis/ghippo.io/v1alpha1/securitypolicy/accountlockout + +> Response Examples + +> 200 Response + +```json +{ + "enabled": true, + "maxLoginFailures": 0, + "maxFailuresWaitSeconds": 0, + "failureResetSeconds": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetAccountLockoutPolicyResponse](#schemasecuritypolicygetaccountlockoutpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetAccountLockoutPolicy + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/accountlockout + +> Body Parameters + +```json +{ + "enabled": true, + "maxLoginFailures": 0, + "maxFailuresWaitSeconds": 0, + "failureResetSeconds": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetAccountLockoutPolicyRequest](#schemasecuritypolicysetaccountlockoutpolicyrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetAccountLockoutPolicyResponse](#schemasecuritypolicysetaccountlockoutpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetLogoutPolicy + +GET /apis/ghippo.io/v1alpha1/securitypolicy/logout + +> Response Examples + +> 200 Response + +```json +{ + "enabled": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetLogoutPolicyResponse](#schemasecuritypolicygetlogoutpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetLogoutPolicy + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/logout + +> Body Parameters + +```json +{ + "enabled": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetLogoutPolicyRequest](#schemasecuritypolicysetlogoutpolicyrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetLogoutPolicyResponse](#schemasecuritypolicysetlogoutpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetMFA + +GET /apis/ghippo.io/v1alpha1/securitypolicy/mfa + +> Response Examples + +> 200 Response + +```json +{ + "enabled": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetMFAResponse](#schemasecuritypolicygetmfaresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetMFA + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/mfa + +> Body Parameters + +```json +{ + "enabled": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetMFARequest](#schemasecuritypolicysetmfarequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetMFAResponse](#schemasecuritypolicysetmfaresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetPasswordPolicy + +GET /apis/ghippo.io/v1alpha1/securitypolicy/password + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "type": "MinimumLengthLabel", + "value": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetPasswordPolicyResponse](#schemasecuritypolicygetpasswordpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetPasswordPolicy + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/password + +> Body Parameters + +```json +{ + "items": [ + { + "type": "MinimumLengthLabel", + "value": "string" + } + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetPasswordPolicyRequest](#schemasecuritypolicysetpasswordpolicyrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetPasswordPolicyResponse](#schemasecuritypolicysetpasswordpolicyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetSystemSessionLimit + +GET /apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/system + +> Response Examples + +> 200 Response + +```json +{ + "enabled": true, + "number": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetSystemSessionLimitResponse](#schemasecuritypolicygetsystemsessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetSystemSessionLimit + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/system + +> Body Parameters + +```json +{ + "enabled": true, + "number": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetSystemSessionLimitRequest](#schemasecuritypolicysetsystemsessionlimitrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetSystemSessionLimitResponse](#schemasecuritypolicysetsystemsessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetTimeSessionLimit + +GET /apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/time + +> Response Examples + +> 200 Response + +```json +{ + "enabled": true, + "start": "string", + "end": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetTimeSessionLimitResponse](#schemasecuritypolicygettimesessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetTimeSessionLimit + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/time + +> Body Parameters + +```json +{ + "enabled": true, + "start": "string", + "end": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetTimeSessionLimitRequest](#schemasecuritypolicysettimesessionlimitrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetTimeSessionLimitResponse](#schemasecuritypolicysettimesessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetUserSessionLimit + +GET /apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/user + +> Response Examples + +> 200 Response + +```json +{ + "enabled": true, + "number": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetUserSessionLimitResponse](#schemasecuritypolicygetusersessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetUserSessionLimit + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/sessionlimit/user + +> Body Parameters + +```json +{ + "enabled": true, + "number": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetUserSessionLimitRequest](#schemasecuritypolicysetusersessionlimitrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetUserSessionLimitResponse](#schemasecuritypolicysetusersessionlimitresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET SecurityPolicy_GetSessionTimeout + +GET /apis/ghippo.io/v1alpha1/securitypolicy/sessiontimeout + +> Response Examples + +> 200 Response + +```json +{ + "timeoutSeconds": 0 +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicyGetSessionTimeoutResponse](#schemasecuritypolicygetsessiontimeoutresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SecurityPolicy_SetSessionTimeout + +PUT /apis/ghippo.io/v1alpha1/securitypolicy/sessiontimeout + +> Body Parameters + +```json +{ + "timeoutSeconds": 0 +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[securitypolicySetSessionTimeoutRequest](#schemasecuritypolicysetsessiontimeoutrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[securitypolicySetSessionTimeoutResponse](#schemasecuritypolicysetsessiontimeoutresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/SmtpSetting + + + +## GET SmtpSetting_GetSmtpServer + +GET /apis/ghippo.io/v1alpha1/smtp-setting + +> Response Examples + +> 200 Response + +```json +{ + "host": "string", + "port": 0, + "ssl": true, + "starttls": true, + "from": "string", + "user": "string", + "password": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[smtpsettingGetSmtpServerResponse](#schemasmtpsettinggetsmtpserverresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT SmtpSetting_SetSmtpServer + +PUT /apis/ghippo.io/v1alpha1/smtp-setting + +> Body Parameters + +```json +{ + "host": "string", + "port": 0, + "ssl": true, + "starttls": true, + "from": "string", + "user": "string", + "password": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[smtpsettingSetSmtpServerRequest](#schemasmtpsettingsetsmtpserverrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[smtpsettingSetSmtpServerResponse](#schemasmtpsettingsetsmtpserverresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST SmtpSetting_SmtpServerConnTest + +POST /apis/ghippo.io/v1alpha1/smtp-setting/conn-test + +> Body Parameters + +```json +{ + "host": "string", + "port": 0, + "ssl": true, + "starttls": true, + "from": "string", + "to": "string", + "user": "string", + "password": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[smtpsettingSmtpConnTestRequest](#schemasmtpsettingsmtpconntestrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[smtpsettingSmtpConnTestResponse](#schemasmtpsettingsmtpconntestresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Theme + + + +## GET Theme_GetFooterThemeConfig + +GET /apis/ghippo.io/v1alpha1/themes/footer-theme + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "css": "string", + "createdAt": "string", + "updatedAt": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeGetFooterThemeConfigResponse](#schemathemegetfooterthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Theme_SetFooterThemeConfig + +POST /apis/ghippo.io/v1alpha1/themes/footer-theme + +> Body Parameters + +```json +{ + "css": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[themeSetFooterThemeConfigRequest](#schemathemesetfooterthemeconfigrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeSetFooterThemeConfigResponse](#schemathemesetfooterthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Theme_ResetFooterThemeConfig + +POST /apis/ghippo.io/v1alpha1/themes/footer/reset + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeResetFooterThemeConfigResponse](#schemathemeresetfooterthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Theme_GetLoginThemeConfig + +GET /apis/ghippo.io/v1alpha1/themes/login_page + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "css": "string", + "createdAt": "string", + "updatedAt": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeGetLoginThemeConfigResponse](#schemathemegetloginthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Theme_SetLoginThemeConfig + +POST /apis/ghippo.io/v1alpha1/themes/login_page + +> Body Parameters + +```json +{ + "css": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[themeSetLoginThemeConfigRequest](#schemathemesetloginthemeconfigrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeSetLoginThemeConfigResponse](#schemathemesetloginthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Theme_GetLoginThemeCSS + +GET /apis/ghippo.io/v1alpha1/themes/login_page.css + +> Response Examples + +> 200 Response + +```json +{ + "contentType": "string", + "data": "string", + "extensions": [ + { + "@type": "string", + "property1": {}, + "property2": {} + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[apiHttpBody](#schemaapihttpbody)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Theme_ResetLoginThemeConfig + +POST /apis/ghippo.io/v1alpha1/themes/login_page/reset + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeResetLoginThemeConfigResponse](#schemathemeresetloginthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Theme_GetThemeConfig + +GET /apis/ghippo.io/v1alpha1/themes/theme + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "css": "string", + "createdAt": "string", + "updatedAt": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeGetThemeConfigResponse](#schemathemegetthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Theme_SetThemeConfig + +POST /apis/ghippo.io/v1alpha1/themes/theme + +> Body Parameters + +```json +{ + "css": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[themeSetThemeConfigRequest](#schemathemesetthemeconfigrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeSetThemeConfigResponse](#schemathemesetthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Theme_GetThemeCSS + +GET /apis/ghippo.io/v1alpha1/themes/theme.css + +> Response Examples + +> 200 Response + +```json +{ + "contentType": "string", + "data": "string", + "extensions": [ + { + "@type": "string", + "property1": {}, + "property2": {} + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[apiHttpBody](#schemaapihttpbody)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Theme_ResetThemeConfig + +POST /apis/ghippo.io/v1alpha1/themes/theme/reset + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[themeResetThemeConfigResponse](#schemathemeresetthemeconfigresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/TopNavigator + + + +## POST TopNavigator_SetTopNav + +POST /apis/ghippo.io/v1alpha1/top-nav + +> Body Parameters + +```json +{ + "icon": "string", + "favicon": "string", + "tabName": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[topnavSetTopNavRequest](#schematopnavsettopnavrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[topnavSetTopNavResponse](#schematopnavsettopnavresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET TopNavigator_Info + +GET /apis/ghippo.io/v1alpha1/top-nav/info + +> Response Examples + +> 200 Response + +```json +{ + "icon": "string", + "favicon": "string", + "tabName": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[topnavTopNavResponse](#schematopnavtopnavresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST TopNavigator_ResetTopNav + +POST /apis/ghippo.io/v1alpha1/top-nav/reset + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[topnavResetTopNavResponse](#schematopnavresettopnavresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Users + + + +## GET Users_ListUsers + +GET /apis/ghippo.io/v1alpha1/users + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|search|query|string| no ||搜索关键字| +|pageSize|query|integer(int32)| no ||每页条数| +|page|query|integer(int32)| no ||当前页| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "createdAt": "string", + "updatedAt": "string", + "lastLoginAt": "string", + "canAuthorize": true + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userListUsersResponse](#schemauserlistusersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Users_CreateUser + +POST /apis/ghippo.io/v1alpha1/users + +> Body Parameters + +```json +{ + "name": "string", + "password": "string", + "description": "string", + "temporary": true +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[userCreateUserRequest](#schemausercreateuserrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userCreateUserResponse](#schemausercreateuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_CheckUserEmail + +GET /apis/ghippo.io/v1alpha1/users/check-user-email/{username} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|username|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "existed": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userCheckUserEmailResponse](#schemausercheckuseremailresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_CheckUser + +GET /apis/ghippo.io/v1alpha1/users/check/{username} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|username|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "existed": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userCheckUserResponse](#schemausercheckuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_GetUserByName + +GET /apis/ghippo.io/v1alpha1/users/username/{username} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|username|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "createdAt": "string", + "updatedAt": "string", + "lastLoginAt": "string", + "canAuthorize": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1userGetUserResponse](#schemav1alpha1usergetuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Users_CreateUserWithoutPassword + +POST /apis/ghippo.io/v1alpha1/users/without-password + +> Body Parameters + +```json +{ + "name": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[userCreateUserWithoutPasswordRequest](#schemausercreateuserwithoutpasswordrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userCreateUserWithoutPasswordResponse](#schemausercreateuserwithoutpasswordresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_GetUser + +GET /apis/ghippo.io/v1alpha1/users/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "createdAt": "string", + "updatedAt": "string", + "lastLoginAt": "string", + "canAuthorize": true +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[v1alpha1userGetUserResponse](#schemav1alpha1usergetuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Users_UpdateUser + +PUT /apis/ghippo.io/v1alpha1/users/{id} + +> Body Parameters + +```json +{ + "enabled": true, + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» enabled|body|boolean| no ||none| +|» email|body|string| no ||none| +|» description|body|string| no ||none| +|» firstname|body|string| no ||none| +|» lastname|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userUpdateUserResponse](#schemauserupdateuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Users_DeleteUser + +DELETE /apis/ghippo.io/v1alpha1/users/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userDeleteUserResponse](#schemauserdeleteuserresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Users_CreateUserAccessToken + +POST /apis/ghippo.io/v1alpha1/users/{id}/accesstoken + +> Body Parameters + +```json +{ + "name": "string", + "expiredAt": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» name|body|string| no ||none| +|» expiredAt|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "token": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userCreateUserAccessTokenResponse](#schemausercreateuseraccesstokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_ListUserAccessTokens + +GET /apis/ghippo.io/v1alpha1/users/{id}/accesstokens + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userListUserAccessTokensResponse](#schemauserlistuseraccesstokensresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Users_DeleteUserAccessToken + +DELETE /apis/ghippo.io/v1alpha1/users/{id}/accesstokens/{aid} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|aid|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userDeleteUserAccessTokenResponse](#schemauserdeleteuseraccesstokenresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_ListUserGroups + +GET /apis/ghippo.io/v1alpha1/users/{id}/groups + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|search|query|string| no ||搜索关键字| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "name": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userListUserGroupsResponse](#schemauserlistusergroupsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Users_ResetUserMFA + +DELETE /apis/ghippo.io/v1alpha1/users/{id}/mfa + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userResetUserMFAResponse](#schemauserresetusermfaresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Users_SetUserPassword + +PUT /apis/ghippo.io/v1alpha1/users/{id}/password + +> Body Parameters + +```json +{ + "password": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» password|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userSetUserPasswordResponse](#schemausersetuserpasswordresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_ListUserRoles + +GET /apis/ghippo.io/v1alpha1/users/{id}/roles + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|search|query|string| no ||搜索关键字| +|page|query|integer(int32)| no ||搜索偏移量| +|pageSize|query|integer(int32)| no ||分页大小| +|type|query|string| no ||role type| +|authorized|query|boolean| no ||是否授权| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "authorizedCount": 0, + "items": [ + { + "name": "string", + "type": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string", + "authorized": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userListUserRolesResponse](#schemauserlistuserrolesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Users_UpdateUserRoles + +PUT /apis/ghippo.io/v1alpha1/users/{id}/roles + +> Body Parameters + +```json +{ + "addRoles": [ + "string" + ], + "removeRoles": [ + "string" + ] +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» addRoles|body|[string]| no ||none| +|» removeRoles|body|[string]| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userUpdateUserRolesResponse](#schemauserupdateuserrolesresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Users_ListUserSubjects + +GET /apis/ghippo.io/v1alpha1/users/{id}/subjects + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|search|query|string| no ||none| +|page|query|integer(int32)| no ||none| +|pageSize|query|integer(int32)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "type": "string", + "roleName": "string", + "subjectName": "string" + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userListUserSubjectResponse](#schemauserlistusersubjectresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Users_VerifyUserSSHPublicKey + +POST /apis/ghippo.io/v1alpha1/users/{username}/sshkeys/verify + +> Body Parameters + +```json +{ + "publicKey": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|username|path|string| yes ||none| +|body|body|object| no ||none| +|» publicKey|body|string(byte)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[userVerifyUserSSHPublicKeyResponse](#schemauserverifyusersshpublickeyresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Webhook + + + +## GET Webhook_ListWebhooksByClientId + +GET /apis/ghippo.io/v1alpha1/webhook + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|search|query|string| no ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| +|clientId|query|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": 0, + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string", + "createdAt": "string", + "updatedAt": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookListWebhooksByClientIdResponse](#schemawebhooklistwebhooksbyclientidresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Webhook_CreateWebhook + +POST /apis/ghippo.io/v1alpha1/webhook + +> Body Parameters + +```json +{ + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[webhookCreateWebhookRequest](#schemawebhookcreatewebhookrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookCreateWebhookResponse](#schemawebhookcreatewebhookresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Webhook_ListWebhookRecordsByClientId + +GET /apis/ghippo.io/v1alpha1/webhook-record + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|clientId|query|string| no ||none| +|search|query|string| no ||none| +|status|query|string| no ||none| +|pageSize|query|integer(int32)| no ||none| +|page|query|integer(int32)| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|status|all| +|status|successful| +|status|failed| + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": 0, + "clientId": "string", + "webhookId": 0, + "webhookName": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "eventTime": "string", + "eventData": "string", + "statusCode": 0, + "status": "response_unknown", + "requestedAt": "string", + "request": "string", + "respondedAt": "string", + "response": "string", + "errMessage": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookListWebhookRecordsByClientIdResponse](#schemawebhooklistwebhookrecordsbyclientidresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Webhook_GetWebhookRecord + +GET /apis/ghippo.io/v1alpha1/webhook-record/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "webhookRecordInfo": { + "id": 0, + "clientId": "string", + "webhookId": 0, + "webhookName": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "eventTime": "string", + "eventData": "string", + "statusCode": 0, + "status": "response_unknown", + "requestedAt": "string", + "request": "string", + "respondedAt": "string", + "response": "string", + "errMessage": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookGetWebhookRecordResponse](#schemawebhookgetwebhookrecordresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Webhook_GetWebhook + +GET /apis/ghippo.io/v1alpha1/webhook/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "webhookInfo": { + "id": 0, + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string", + "createdAt": "string", + "updatedAt": "string" + } +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookGetWebhookResponse](#schemawebhookgetwebhookresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Webhook_UpdateWebhook + +PUT /apis/ghippo.io/v1alpha1/webhook/{id} + +> Body Parameters + +```json +{ + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|integer(int32)| yes ||none| +|body|body|object| no ||none| +|» name|body|string| no ||none| +|» clientId|body|string| no ||none| +|» resourceType|body|[v1alpha1webhookResourceType](#schemav1alpha1webhookresourcetype)| no ||none| +|» action|body|[webhookAction](#schemawebhookaction)| no ||none| +|» url|body|string| no ||none| +|» method|body|[webhookMethod](#schemawebhookmethod)| no ||none| +|» headers|body|string| no | map headers = 8;|none| +|» requestParameter|body|string| no ||none| + +#### Enum + +|Name|Value| +|---|---| +|» resourceType|resource_type_user| +|» action|action_create| +|» action|action_update| +|» action|action_delete| +|» action|action_login| +|» action|action_logout| +|» method|method_get| +|» method|method_post| +|» method|method_put| +|» method|method_delete| +|» method|method_patch| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookUpdateWebhookResponse](#schemawebhookupdatewebhookresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Webhook_DeleteWebhook + +DELETE /apis/ghippo.io/v1alpha1/webhook/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|integer(int32)| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[webhookDeleteWebhookResponse](#schemawebhookdeletewebhookresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# GlobalManagement/Ldap + + + +## POST Ldap_CreateLdap + +POST /apis/ghippo.io/v1alpha2/ldap + +> Body Parameters + +```json +{ + "name": "string", + "vendor": "other", + "startTls": "string", + "connectionUrl": "string", + "usersDn": "string", + "bindDn": "string", + "bindCredential": "string", + "userObjectClasses": "string", + "usernameLdapAttribute": "string", + "fullSyncPeriod": "string", + "rdnLdapAttribute": "string", + "uuidLdapAttribute": "string", + "editMode": "string", + "readTimeout": "string", + "firstName": "string", + "lastName": "string", + "email": "string", + "enabled": true, + "username": "string", + "userLdapFilter": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[ldapCreateLdapRequest](#schemaldapcreateldaprequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapCreateLdapResponse](#schemaldapcreateldapresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Ldap_ListLdaps + +GET /apis/ghippo.io/v1alpha2/ldaps + +> Response Examples + +> 200 Response + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "vendor": "string", + "enabled": true + } + ] +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapListLdapsResponse](#schemaldaplistldapsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Ldap_GetLdap + +GET /apis/ghippo.io/v1alpha2/ldaps/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "name": "string", + "vendor": "other", + "startTls": "string", + "connectionUrl": "string", + "usersDn": "string", + "bindDn": "string", + "bindCredential": "string", + "userObjectClasses": "string", + "usernameLdapAttribute": "string", + "fullSyncPeriod": "string", + "rdnLdapAttribute": "string", + "uuidLdapAttribute": "string", + "editMode": "string", + "readTimeout": "string", + "firstName": "string", + "lastName": "string", + "email": "string", + "enabled": true, + "username": "string", + "userLdapFilter": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapGetLdapResponse](#schemaldapgetldapresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Ldap_UpdateLdap + +PUT /apis/ghippo.io/v1alpha2/ldaps/{id} + +> Body Parameters + +```json +{ + "name": "string", + "vendor": "other", + "startTls": "string", + "connectionUrl": "string", + "usersDn": "string", + "bindDn": "string", + "bindCredential": "string", + "userObjectClasses": "string", + "usernameLdapAttribute": "string", + "fullSyncPeriod": "string", + "rdnLdapAttribute": "string", + "uuidLdapAttribute": "string", + "editMode": "string", + "readTimeout": "string", + "firstName": "string", + "lastName": "string", + "email": "string", + "enabled": true, + "username": "string", + "userLdapFilter": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» name|body|string| no ||none| +|» vendor|body|[ldapLdapVendor](#schemaldapldapvendor)| no ||none| +|» startTls|body|string| no ||Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling.| +|» connectionUrl|body|string| no ||none| +|» usersDn|body|string| no | Full DN of LDAP tree where your users are. This DN is the parent of LDAP users. +It could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have DN like 'uid=john,ou=users,dc=example,dc=com'|none| +|» bindDn|body|string| no | DN of LDAP admin, which will be used by Keycloak to access LDAP server|none| +|» bindCredential|body|string| no ||Password of LDAP admin.| +|» userObjectClasses|body|string| no ||All values of LDAP objectClass attribute for users in LDAP divided by comma.| +|» usernameLdapAttribute|body|string| no | Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server vendors it can be 'uid'. +For Active directory it can be 'sAMAccountName' or 'cn'. +The attribute should be filled for all LDAP user records you want to import from LDAP to Keycloak|none| +|» fullSyncPeriod|body|string| no | Period for full synchronization in seconds: -1 手动同步|none| +|» rdnLdapAttribute|body|string| no ||Name of the LDAP attribute, which is used as RDN (top attribute) of typical user DN.| +|» uuidLdapAttribute|body|string| no ||Name of the LDAP attribute, which is used as a unique object identifier (UUID) for objects in LDAP.| +|» editMode|body|string| no ||READ_ONLY is a read-only LDAP store.| +|» readTimeout|body|string| no ||LDAP read timeout in milliseconds. This timeout applies for LDAP read operations.| +|» firstName|body|string| no ||none| +|» lastName|body|string| no ||none| +|» email|body|string| no ||none| +|» enabled|body|boolean| no ||none| +|» username|body|string| no ||none| +|» userLdapFilter|body|string| no ||none| + +#### Description + +**» userObjectClasses**: All values of LDAP objectClass attribute for users in LDAP divided by comma. +For example: 'inetOrgPerson, organizationalPerson' . +Newly created Keycloak users will be written to LDAP with all those object classes and existing LDAP user records are found just if they contain all those object classes. + +**» rdnLdapAttribute**: Name of the LDAP attribute, which is used as RDN (top attribute) of typical user DN. +Usually it's the same as the Username LDAP attribute, however it is not required. +For example for Active directory, it is common to use 'cn' as RDN attribute when username attribute might be 'sAMAccountName'. + +**» uuidLdapAttribute**: Name of the LDAP attribute, which is used as a unique object identifier (UUID) for objects in LDAP. +For many LDAP server vendors, it is 'entryUUID'; however some are different. +For example, for Active directory it should be 'objectGUID'. +If your LDAP server does not support the notion of UUID, you can use any other attribute that is supposed to be unique among LDAP users in tree. +For example 'uid' or 'entryDN'. + +**» editMode**: READ_ONLY is a read-only LDAP store. +WRITABLE means data will be synced back to LDAP on demand. + +#### Enum + +|Name|Value| +|---|---| +|» vendor|other| +|» vendor|ad| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapUpdateLdapResponse](#schemaldapupdateldapresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Ldap_DeleteLdap + +DELETE /apis/ghippo.io/v1alpha2/ldaps/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapDeleteLdapResponse](#schemaldapdeleteldapresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Ldap_GetLdapGroup + +GET /apis/ghippo.io/v1alpha2/ldaps/{id}/group + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string", + "groupDn": "string", + "groupObjectClasses": "string", + "groupNameLdapAttribute": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapGetLdapGroupResponse](#schemaldapgetldapgroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Ldap_CreateLdapGroup + +POST /apis/ghippo.io/v1alpha2/ldaps/{id}/group + +> Body Parameters + +```json +{ + "groupDn": "string", + "groupObjectClasses": "string", + "groupNameLdapAttribute": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» groupDn|body|string| no ||none| +|» groupObjectClasses|body|string| no ||none| +|» groupNameLdapAttribute|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{ + "id": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapCreateLdapGroupResponse](#schemaldapcreateldapgroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Ldap_SyncUsers + +GET /apis/ghippo.io/v1alpha2/ldaps/{id}/sync + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "ignored": true, + "added": 0, + "updated": 0, + "removed": 0, + "failed": 0, + "status": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapSyncUsersResponse](#schemaldapsyncusersresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## PUT Ldap_UpdateLdapGroup + +PUT /apis/ghippo.io/v1alpha2/ldaps/{ldapId}/group/{id} + +> Body Parameters + +```json +{ + "groupDn": "string", + "groupObjectClasses": "string", + "groupNameLdapAttribute": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|ldapId|path|string| yes ||none| +|id|path|string| yes ||none| +|body|body|object| no ||none| +|» groupDn|body|string| no ||none| +|» groupObjectClasses|body|string| no ||none| +|» groupNameLdapAttribute|body|string| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapUpdateLdapGroupResponse](#schemaldapupdateldapgroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## DELETE Ldap_DeleteLdapGroup + +DELETE /apis/ghippo.io/v1alpha2/ldaps/{ldapId}/group/{id} + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|ldapId|path|string| yes ||none| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapDeleteLdapGroupResponse](#schemaldapdeleteldapgroupresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## GET Ldap_SyncLdapGroups + +GET /apis/ghippo.io/v1alpha2/ldaps/{ldapId}/group/{id}/sync + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|ldapId|path|string| yes ||none| +|id|path|string| yes ||none| + +> Response Examples + +> 200 Response + +```json +{ + "ignored": true, + "added": 0, + "updated": 0, + "removed": 0, + "failed": 0, + "status": "string" +} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapSyncLdapGroupsResponse](#schemaldapsyncldapgroupsresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Ldap_TestLdapAuthentication + +POST /apis/ghippo.io/v1alpha2/testLdapAuthentication + +> Body Parameters + +```json +{ + "bindDn": "string", + "bindCredential": "string", + "connectionUrl": "string", + "connectionTimeout": "string", + "action": "string", + "startTls": "string", + "useTruststoreSpi": "string", + "componentId": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[ldapTestLdapAuthenticationRequest](#schemaldaptestldapauthenticationrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapTestLdapAuthenticationResponse](#schemaldaptestldapauthenticationresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + + + +## POST Ldap_TestLdapConnection + +POST /apis/ghippo.io/v1alpha2/testLdapConnection + +> Body Parameters + +```json +{ + "connectionUrl": "string", + "bindDn": "string", + "bindCredential": "string", + "connectionTimeout": "string", + "action": "string", + "startTls": "string", + "useTruststoreSpi": "string", + "componentId": "string" +} +``` + +### Params + +|Name|Location|Type|Required|Title|Description| +|---|---|---|---|---|---| +|body|body|[ldapTestLdapConnectionRequest](#schemaldaptestldapconnectionrequest)| no ||none| + +> Response Examples + +> 200 Response + +```json +{} +``` + +### Responses + +|HTTP Status Code |Meaning|Description|Data schema| +|---|---|---|---| +|200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|A successful response.|[ldapTestLdapConnectionResponse](#schemaldaptestldapconnectionresponse)| +|500|[Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1)|An unexpected error response.|[googlerpcStatus](#schemagooglerpcstatus)| + +# Data Schema + +

googlerpcStatus

+ + + + + + +```json +{ + "code": 0, + "message": "string", + "details": [ + { + "@type": "string", + "property1": {}, + "property2": {} + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|code|integer(int32)|false|none||none| +|message|string|false|none||none| +|details|[[protobufAny](#schemaprotobufany)]|false|none||[`Any` contains an arbitrary serialized protocol buffer message along with a
URL that describes the type of the serialized message.

Protobuf library provides support to pack/unpack Any values in the form
of utility functions or additional generated methods of the Any type.

Example 1: Pack and unpack a message in C++.

Foo foo = ...;
Any any;
any.PackFrom(foo);
...
if (any.UnpackTo(&foo)) {
...
}

Example 2: Pack and unpack a message in Java.

Foo foo = ...;
Any any = Any.pack(foo);
...
if (any.is(Foo.class)) {
foo = any.unpack(Foo.class);
}

Example 3: Pack and unpack a message in Python.

foo = Foo(...)
any = Any()
any.Pack(foo)
...
if any.Is(Foo.DESCRIPTOR):
any.Unpack(foo)
...

Example 4: Pack and unpack a message in Go

foo := &pb.Foo{...}
any, err := anypb.New(foo)
if err != nil {
...
}
...
foo := &pb.Foo{}
if err := any.UnmarshalTo(foo); err != nil {
...
}

The pack methods provided by protobuf library will by default use
'type.googleapis.com/full.type.name' as the type URL and the unpack
methods only use the fully qualified type name after the last '/'
in the type URL, for example "foo.bar.com/x/y.z" will yield type
name "y.z".


JSON
====
The JSON representation of an `Any` value uses the regular
representation of the deserialized, embedded message, with an
additional field `@type` which contains the type URL. Example:

package google.profile;
message Person {
string first_name = 1;
string last_name = 2;
}

{
"@type": "type.googleapis.com/google.profile.Person",
"firstName": ,
"lastName":
}

If the embedded message type is well-known and has a custom JSON
representation, that representation will be embedded adding a field
`value` which holds the custom JSON in addition to the `@type`
field. Example (for message [google.protobuf.Duration][]):

{
"@type": "type.googleapis.com/google.protobuf.Duration",
"value": "1.212s"
}]| + +

protobufAny

+ + + + + + +```json +{ + "@type": "string", + "property1": {}, + "property2": {} +} + +``` + +`Any` contains an arbitrary serialized protocol buffer message along with a +URL that describes the type of the serialized message. + +Protobuf library provides support to pack/unpack Any values in the form +of utility functions or additional generated methods of the Any type. + +Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + +Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := anypb.New(foo) + if err != nil { + ... + } + ... + foo := &pb.Foo{} + if err := any.UnmarshalTo(foo); err != nil { + ... + } + +The pack methods provided by protobuf library will by default use +'type.googleapis.com/full.type.name' as the type URL and the unpack +methods only use the fully qualified type name after the last '/' +in the type URL, for example "foo.bar.com/x/y.z" will yield type +name "y.z". + +JSON +==== +The JSON representation of an `Any` value uses the regular +representation of the deserialized, embedded message, with an +additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + +If the embedded message type is well-known and has a custom JSON +representation, that representation will be embedded adding a field +`value` which holds the custom JSON in addition to the `@type` +field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|**additionalProperties**|object|false|none||none| +|@type|string|false|none||A URL/resource name that uniquely identifies the type of the serialized
protocol buffer message. This string must contain at least
one "/" character. The last segment of the URL's path must represent
the fully qualified name of the type (as in
`path/google.protobuf.Duration`). The name should be in a canonical form
(e.g., leading "." is not accepted).

In practice, teams usually precompile into the binary all types that they
expect it to use in the context of Any. However, for URLs which use the
scheme `http`, `https`, or no scheme, one can optionally set up a type
server that maps type URLs to message definitions as follows:

* If no scheme is provided, `https` is assumed.
* An HTTP GET on the URL must yield a [google.protobuf.Type][]
value in binary format, or produce an error.
* Applications are allowed to cache lookup results based on the
URL, or have them precompiled into a binary to avoid any
lookup. Therefore, binary compatibility needs to be preserved
on changes to types. (Use versioned type names to manage
breaking changes.)

Note: this functionality is not currently available in the official
protobuf release, and it is not used for type URLs beginning with
type.googleapis.com.

Schemes other than `http`, `https` (or the empty scheme) might be
used with implementation specific semantics.| + +

v1alpha1UpdateHorizontalPodAutoscalerResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|The data is the hpa YAML details|none| + +

v1alpha1UpdateIngressResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateIngressRequest the response of update cluster ingresses + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||The data is the ingress YAML details.| + +

v1alpha1UpdateLimitRangeResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateLimitRangeResponse returns the created LimitRange data information. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||Data is the LimitRange YAML details.| + +

v1alpha1UpdateMode

+ + + + + + +```json +"UPDATE_MODE_UNSPECIFIED" + +``` + +UpdateMode controls when autoscaler applies changes to the pod resoures. + + - UPDATE_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - Off: UpdateModeOff means that autoscaler never changes Pod resources. +The recommender still sets the recommended resources in the +VerticalPodAutoscaler object. This can be used for a "dry run". + - Initial: UpdateModeInitial means that autoscaler only assigns resources on pod +creation and does not change them during the lifetime of the pod. + - Recreate: UpdateModeRecreate means that autoscaler assigns resources on pod +creation and additionally can update them during the lifetime of the +pod by deleting and recreating the pod. + - Auto: UpdateModeAuto means that autoscaler assigns resources on pod creation +and additionally can update them during the lifetime of the pod, +using any available update method. Currently this is equivalent to +Recreate, which is the only available update method. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||UpdateMode controls when autoscaler applies changes to the pod resoures.

- UPDATE_MODE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.
- Off: UpdateModeOff means that autoscaler never changes Pod resources.
The recommender still sets the recommended resources in the
VerticalPodAutoscaler object. This can be used for a "dry run".
- Initial: UpdateModeInitial means that autoscaler only assigns resources on pod
creation and does not change them during the lifetime of the pod.
- Recreate: UpdateModeRecreate means that autoscaler assigns resources on pod
creation and additionally can update them during the lifetime of the
pod by deleting and recreating the pod.
- Auto: UpdateModeAuto means that autoscaler assigns resources on pod creation
and additionally can update them during the lifetime of the pod,
using any available update method. Currently this is equivalent to
Recreate, which is the only available update method.| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|UPDATE_MODE_UNSPECIFIED| +|*anonymous*|Off| +|*anonymous*|Initial| +|*anonymous*|Recreate| +|*anonymous*|Auto| + +

v1alpha1UpdateNamespaceResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +Update Namespace data. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||none| + +

v1alpha1UpdateNetworkPolicyResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateNetworkPolicyResponse the response of update cluster networkpolicies + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||The data is the networkpolicy YAML details.| + +

v1alpha1UpdateNodeAnnotationsResponse

+ + + + + + +```json +{ + "annotations": { + "property1": "string", + "property2": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|annotations|object|false|none||Annotations returned.| +|» **additionalProperties**|string|false|none||none| + +

v1alpha1UpdateNodeGPUModeResponse

+ + + + + + +```json +{ + "mode": {} +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|mode|object|false|none||none| + +

v1alpha1UpdateNodeResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateNodeResponse return's a node's json. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||none| + +

v1alpha1UpdatePersistentVolumeClaimAnnotationsResponse

+ + + + + + +```json +{ + "annotations": { + "property1": "string", + "property2": "string" + } +} + +``` + +UpdatePersistentVolumeClaimLabelsResponse represents the response of put PVC annotations Response + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|annotations|object|false|none|labels represents the Annotations of pvc|none| +|» **additionalProperties**|string|false|none||none| + +

v1alpha1UpdatePersistentVolumeClaimLabelsResponse

+ + + + + + +```json +{ + "labels": { + "property1": "string", + "property2": "string" + } +} + +``` + +UpdateNodeLabelsResponse represents the response of put pvc's labels + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|labels|object|false|none|labels represents the labels of pvc|none| +|» **additionalProperties**|string|false|none||none| + +

v1alpha1UpdatePersistentVolumeClaimResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|data represents the data of PVC JSON|none| + +

v1alpha1UpdatePersistentVolumeResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdatePersistentVolumeResponse returns the created PersistentVolume data information. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||Data is the PersistentVolume YAML details.| + +

v1alpha1UpdateReplicaSetResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateReplicaSetResponse returns the created ReplicaSet data information. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||Data is the ReplicaSet YAML details.| + +

v1alpha1UpdateResourceQuotaResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateResourceQuotaResponse returns the created ResourceQuota data information. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||Data is the ResourceQuota YAML details.| + +

v1alpha1UpdateRoleResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateRoleResponse the response of update role + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||none| + +

v1alpha1UpdateSecretResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +It returns updated secret information. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|The data field is the Secret YAML details|none| + +

v1alpha1UpdateServiceAccountResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateServiceAccount represents the response of delete sa. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|The data is the StorageClass YAML details|none| + +

v1alpha1UpdateServiceResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +It returns the Updated Service data information. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|Data is the Service YAML details|none| + +

v1alpha1UpdateStorageClassResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateStorageClassResponse represents the response of delete storage class + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|The data is the StorageClass YAML details|none| + +

v1alpha1UpdateVerticalPodAutoscalerResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateVerticalPodAutoscalerResponse returns the updated json data. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||The data is the vpa YAML details.| + +

v1alpha1UpdateVolumeSnapshotResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +UpdateVolumeSnapshotResponse represents the response of update volume snapshot. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|data represents the data of volume snapshot JSON|none| + +

v1alpha1User

+ + + + + + +```json +{ + "id": "string", + "name": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||id is the unique identification of the user.| +|name|string|false|none||the name of the user.| + +

v1alpha1VGPUNodeStats

+ + + + + + +```json +{ + "physicalGpuNumber": 0, + "totalVirtualGpuNumber": 0, + "allocatedVirtualGpuNumber": 0, + "allocatedComputePower": "string", + "totalComputePower": "string", + "totalGpuMemory": "string", + "allocatedGpuMemory": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|physicalGpuNumber|integer(int32)|false|none|Number of physical Gpus|none| +|totalVirtualGpuNumber|integer(int32)|false|none|Number of virtual Gpus|none| +|allocatedVirtualGpuNumber|integer(int32)|false|none|Number of allocated virtual Gpus|none| +|allocatedComputePower|string(int64)|false|none||none| +|totalComputePower|string(int64)|false|none|total compute power|none| +|totalGpuMemory|string(int64)|false|none|Number of gpu memory|none| +|allocatedGpuMemory|string(int64)|false|none|Number of allocated gpu memory|none| + +

v1alpha1ValidateClusterResponse

+ + + + + + +```json +{ + "dceComponents": { + "property1": true, + "property2": true + } +} + +``` + +ValidateClusterResponse returns the result of residuals existence. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|dceComponents|object|false|none||Components is to show if components exist in target cluster, e.g. kpanda-system namespace, insight-system namespace, and mspider mesh.| +|» **additionalProperties**|boolean|false|none||none| + +

v1alpha1ValidateHelmRepoResponse

+ + + + + + +```json +{ + "success": true, + "error": "string" +} + +``` + +ValidateHelmRepoResponse returns the result of connecting to a helm repo + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|success|boolean|false|none||Successfully connected to the repo.| +|error|string|false|none||If connecting to the repo failed, return the reason.| + +

v1alpha1ValidateKubeConfigRequest

+ + + + + + +```json +{ + "kubeConfigString": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|kubeConfigString|string|false|none||KubeConfig of the cluster.| + +

v1alpha1ValidateKubeConfigResponse

+ + + + + + +```json +{ + "validateResult": true, + "errMsg": "string", + "kubeconfigExpireTime": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|validateResult|boolean|false|none||none| +|errMsg|string|false|none||err_msg if validate_result is false , err_msg will has no-empty value.| +|kubeconfigExpireTime|string(int64)|false|none||none| + +

v1alpha1VerificationMethod

+ + + + + + +```json +"VERIFICATION_METHOD_UNSPECIFIED" + +``` + +Repository verification method + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|Repository verification method|string|false|none|Repository verification method|- VERIFICATION_METHOD_UNSPECIFIED: The repository verification method is unspecified.
- None: The repository is public and does not require authentication.
- BasicAuth: BasicAuth contains data needed for basic authentication.| + +#### Enum + +|Name|Value| +|---|---| +|Repository verification method|VERIFICATION_METHOD_UNSPECIFIED| +|Repository verification method|None| +|Repository verification method|BasicAuth| + +

v1alpha1VerifyEtcdConnectionResponse

+ + + + + + +```json +{ + "success": true, + "errMsg": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|success|boolean|false|none||This field indicates whether or not the verification operation for
verifying etcd connection successful.| +|errMsg|string|false|none||err_msg if validate_result is false , err_msg will has no-empty value.| + +

v1alpha1VerifyImageResponse

+ + + + + + +```json +{ + "success": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|success|boolean|false|none||This field indicates whether or not the verification operation for
verifying image successful.| + +

v1alpha1VerifyRegistryRequest

+ + + + + + +```json +{ + "registryHost": "string", + "username": "string", + "password": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|registryHost|string|false|none||The registry host which needs to verify.| +|username|string|false|none||The username of the registry.| +|password|string|false|none||The password of the registry.| + +

v1alpha1VerifyRegistryResponse

+ + + + + + +```json +{ + "success": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|success|boolean|false|none||This field indicates whether or not the verification operation for
verifying registery successful.| + +

v1alpha1VerifySnapStoreConfigResponse

+ + + + + + +```json +{ + "success": true, + "errMsg": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|success|boolean|false|none||This field indicates whether or not the verification operation for
verifying SnapStore successful.| +|errMsg|string|false|none||err_msg if validate_result is false , err_msg will has no-empty value.| + +

v1alpha1VerticalPodAutoscaler

+ + + + + + +```json +{ + "metadata": {}, + "spec": { + "targetRef": {}, + "updatePolicy": {}, + "resourcePolicy": {}, + "recommenders": [ + { + "name": "string" + } + ] + }, + "status": { + "recommendation": {}, + "conditions": [ + { + "type": "VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED", + "status": {}, + "lastTransitionTime": "string", + "reason": "string", + "message": "string" + } + ] + } +} + +``` + +VerticalPodAutoscaler is the configuration for a vertical pod autoscaler, which automatically manages pod resources based on historical and real time resource utilization. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|metadata|object|false|none||none| +|spec|[v1alpha1VerticalPodAutoscalerSpec](#schemav1alpha1verticalpodautoscalerspec)|false|none||VerticalPodAutoscalerSpec is the specification of the behavior of the autoscaler.| +|status|[v1alpha1VerticalPodAutoscalerStatus](#schemav1alpha1verticalpodautoscalerstatus)|false|none||VerticalPodAutoscalerStatus describes the runtime state of the autoscaler.| + +

v1alpha1VerticalPodAutoscalerCondition

+ + + + + + +```json +{ + "type": "VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED", + "status": {}, + "lastTransitionTime": "string", + "reason": "string", + "message": "string" +} + +``` + +VerticalPodAutoscalerCondition describes the state of a VerticalPodAutoscaler at a certain point. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|[v1alpha1VerticalPodAutoscalerConditionType](#schemav1alpha1verticalpodautoscalerconditiontype)|false|none||VerticalPodAutoscalerConditionType is the valid conditions of a VerticalPodAutoscaler.

- VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.
- RecommendationProvided: RecommendationProvided indicates whether the VPA recommender was able to calculate a recommendation.
- LowConfidence: LowConfidence indicates whether the VPA recommender has low confidence in the recommendation for some of containers.
- NoPodsMatched: NoPodsMatched indicates that label selector used with VPA object didn't match any pods.
- FetchingHistory: FetchingHistory indicates that VPA recommender is in the process of loading additional history samples.
- ConfigDeprecated: ConfigDeprecated indicates that this VPA configuration is deprecated and will stop being supported soon.
- ConfigUnsupported: ConfigUnsupported indicates that this VPA configuration is unsupported and recommendations will not be provided for it.| +|status|object|false|none||none| +|lastTransitionTime|string(int64)|false|none||LastTransitionTime is the last time the condition transitioned from one status to another.| +|reason|string|false|none||Reason is the reason for the condition's last transition.| +|message|string|false|none||message is a human-readable explanation containing details about the transition.| + +

v1alpha1VerticalPodAutoscalerConditionType

+ + + + + + +```json +"VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED" + +``` + +VerticalPodAutoscalerConditionType is the valid conditions of a VerticalPodAutoscaler. + + - VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + - RecommendationProvided: RecommendationProvided indicates whether the VPA recommender was able to calculate a recommendation. + - LowConfidence: LowConfidence indicates whether the VPA recommender has low confidence in the recommendation for some of containers. + - NoPodsMatched: NoPodsMatched indicates that label selector used with VPA object didn't match any pods. + - FetchingHistory: FetchingHistory indicates that VPA recommender is in the process of loading additional history samples. + - ConfigDeprecated: ConfigDeprecated indicates that this VPA configuration is deprecated and will stop being supported soon. + - ConfigUnsupported: ConfigUnsupported indicates that this VPA configuration is unsupported and recommendations will not be provided for it. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||VerticalPodAutoscalerConditionType is the valid conditions of a VerticalPodAutoscaler.

- VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.
- RecommendationProvided: RecommendationProvided indicates whether the VPA recommender was able to calculate a recommendation.
- LowConfidence: LowConfidence indicates whether the VPA recommender has low confidence in the recommendation for some of containers.
- NoPodsMatched: NoPodsMatched indicates that label selector used with VPA object didn't match any pods.
- FetchingHistory: FetchingHistory indicates that VPA recommender is in the process of loading additional history samples.
- ConfigDeprecated: ConfigDeprecated indicates that this VPA configuration is deprecated and will stop being supported soon.
- ConfigUnsupported: ConfigUnsupported indicates that this VPA configuration is unsupported and recommendations will not be provided for it.| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED| +|*anonymous*|RecommendationProvided| +|*anonymous*|LowConfidence| +|*anonymous*|NoPodsMatched| +|*anonymous*|FetchingHistory| +|*anonymous*|ConfigDeprecated| +|*anonymous*|ConfigUnsupported| + +

v1alpha1VerticalPodAutoscalerRecommenderSelector

+ + + + + + +```json +{ + "name": "string" +} + +``` + +VerticalPodAutoscalerRecommenderSelector points to a specific Vertical Pod Autoscaler recommender. +In the future it might pass parameters to the recommender. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||Name of the recommender responsible for generating recommendation for this object.| + +

v1alpha1VerticalPodAutoscalerSpec

+ + + + + + +```json +{ + "targetRef": {}, + "updatePolicy": {}, + "resourcePolicy": {}, + "recommenders": [ + { + "name": "string" + } + ] +} + +``` + +VerticalPodAutoscalerSpec is the specification of the behavior of the autoscaler. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|targetRef|object|false|none||none| +|updatePolicy|object|false|none||none| +|resourcePolicy|object|false|none||none| +|recommenders|[[v1alpha1VerticalPodAutoscalerRecommenderSelector](#schemav1alpha1verticalpodautoscalerrecommenderselector)]|false|none||Recommender responsible for generating recommendation for this object.
List should be empty (then the default recommender will generate the recommendation) or contain exactly one recommender.| + +

v1alpha1VerticalPodAutoscalerStatus

+ + + + + + +```json +{ + "recommendation": {}, + "conditions": [ + { + "type": "VERTICAL_POD_AUTOSCALER_CONDITION_TYPE_UNSPECIFIED", + "status": {}, + "lastTransitionTime": "string", + "reason": "string", + "message": "string" + } + ] +} + +``` + +VerticalPodAutoscalerStatus describes the runtime state of the autoscaler. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|recommendation|object|false|none||none| +|conditions|[[v1alpha1VerticalPodAutoscalerCondition](#schemav1alpha1verticalpodautoscalercondition)]|false|none||Conditions is the set of conditions required for this autoscaler to scale its target,
and indicates whether or not those conditions are met.| + +

v1alpha1Volume

+ + + + + + +```json +{ + "name": "string", + "hostPath": {}, + "emptyDir": {}, + "secret": {}, + "persistentVolumeClaim": {}, + "downwardAPI": {}, + "configMap": {} +} + +``` + +Volume represents a named volume in a pod that may be accessed by any +container in the pod. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|hostPath|object|false|none||none| +|emptyDir|object|false|none||none| +|secret|object|false|none||none| +|persistentVolumeClaim|object|false|none||none| +|downwardAPI|object|false|none||none| +|configMap|object|false|none||none| + +

v1alpha1VolumeMount

+ + + + + + +```json +{ + "name": "string", + "readOnly": true, + "mountPath": "string", + "subPath": "string", + "mountPropagation": "string", + "subPathExpr": "string" +} + +``` + +VolumeMount for this container. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||This must match the Name of a Volume.| +|readOnly|boolean|false|none|Mounted read-only if true, read-write otherwise (false or unspecified). +Defaults to false. ++optional|none| +|mountPath|string|false|none||Full path to the mount volume path.| +|subPath|string|false|none|Path within the volume from which the container's volume should be mounted. +Defaults to "" (volume's root). ++optional|none| +|mountPropagation|string|false|none|mountPropagation determines how mounts are propagated from the host +to container and the other way around. +When not set, MountPropagationNone is used. +This field is beta in 1.10. ++optional|none| +|subPathExpr|string|false|none|Expanded path within the volume from which the container's volume should be +mounted. Behaves similarly to SubPath but environment variable references +$(VAR_NAME) are expanded using the container's environment. Defaults to "" +(volume's root). SubPathExpr and SubPath are mutually exclusive. +optional|none| + +

v1alpha1VolumeNodeAffinity

+ + + + + + +```json +{ + "required": {} +} + +``` + +VolumeNodeAffinity defines constraints that limit what nodes this volume can be accessed from. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|required|object|false|none||none| + +

v1alpha1VolumeSnapshot

+ + + + + + +```json +{ + "metadata": {}, + "spec": { + "source": { + "persistentVolumeClaimName": "string", + "volumeSnapshotContentName": "string" + }, + "volumeSnapshotClassName": "string" + }, + "status": { + "creationTime": "string", + "readyToUse": true, + "restoreSize": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|metadata|object|false|none||none| +|spec|[v1alpha1VolumeSnapshotSpec](#schemav1alpha1volumesnapshotspec)|false|none||none| +|status|[v1alpha1VolumeSnapshotStatus](#schemav1alpha1volumesnapshotstatus)|false|none||VolumeSnapshotStatus is the status of the VolumeSnapshot
Note that CreationTime, RestoreSize, ReadyToUse, and Error are in both
VolumeSnapshotStatus and VolumeSnapshotContentStatus. Fields in VolumeSnapshotStatus
are updated based on fields in VolumeSnapshotContentStatus. They are eventual
consistency. These fields are duplicate in both objects due to the following reasons:
- Fields in VolumeSnapshotContentStatus can be used for filtering when importing a
volumesnapshot.
- VolumsnapshotStatus is used by end users because they cannot see VolumeSnapshotContent.
- CSI snapshotter sidecar is light weight as it only watches VolumeSnapshotContent
object, not VolumeSnapshot object.| + +

v1alpha1VolumeSnapshotSource

+ + + + + + +```json +{ + "persistentVolumeClaimName": "string", + "volumeSnapshotContentName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|persistentVolumeClaimName|string|false|none|persistentVolumeClaimName specifies the name of the PersistentVolumeClaim +object representing the volume from which a snapshot should be created. +This PVC is assumed to be in the same namespace as the VolumeSnapshot +object. +This field should be set if the snapshot does not exists, and needs to be +created. +This field is immutable. ++optional|none| +|volumeSnapshotContentName|string|false|none|volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent +object representing an existing volume snapshot. +This field should be set if the snapshot already exists and only needs a representation in Kubernetes. +This field is immutable. ++optional|none| + +

v1alpha1VolumeSnapshotSpec

+ + + + + + +```json +{ + "source": { + "persistentVolumeClaimName": "string", + "volumeSnapshotContentName": "string" + }, + "volumeSnapshotClassName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|source|[v1alpha1VolumeSnapshotSource](#schemav1alpha1volumesnapshotsource)|false|none||none| +|volumeSnapshotClassName|string|false|none|VolumeSnapshotClassName is the name of the VolumeSnapshotClass +requested by the VolumeSnapshot. +VolumeSnapshotClassName may be left nil to indicate that the default +SnapshotClass should be used. +A given cluster may have multiple default Volume SnapshotClasses: one +default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, +VolumeSnapshotSource will be checked to figure out what the associated +CSI Driver is, and the default VolumeSnapshotClass associated with that +CSI Driver will be used. If more than one VolumeSnapshotClass exist for +a given CSI Driver and more than one have been marked as default, +CreateSnapshot will fail and generate an event. +Empty string is not allowed for this field. ++optional|none| + +

v1alpha1VolumeSnapshotStatus

+ + + + + + +```json +{ + "creationTime": "string", + "readyToUse": true, + "restoreSize": "string" +} + +``` + +VolumeSnapshotStatus is the status of the VolumeSnapshot +Note that CreationTime, RestoreSize, ReadyToUse, and Error are in both +VolumeSnapshotStatus and VolumeSnapshotContentStatus. Fields in VolumeSnapshotStatus +are updated based on fields in VolumeSnapshotContentStatus. They are eventual +consistency. These fields are duplicate in both objects due to the following reasons: + - Fields in VolumeSnapshotContentStatus can be used for filtering when importing a + volumesnapshot. + - VolumsnapshotStatus is used by end users because they cannot see VolumeSnapshotContent. + - CSI snapshotter sidecar is light weight as it only watches VolumeSnapshotContent + object, not VolumeSnapshot object. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|creationTime|string(int64)|false|none|creationTime is the timestamp when the point-in-time snapshot is taken +by the underlying storage system. +In dynamic snapshot creation case, this field will be filled in by the +snapshot controller with the "creation_time" value returned from CSI +"CreateSnapshot" gRPC call. +For a pre-existing snapshot, this field will be filled with the "creation_time" +value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. +If not specified, it may indicate that the creation time of the snapshot is unknown. ++optional|none| +|readyToUse|boolean|false|none|readyToUse indicates if the snapshot is ready to be used to restore a volume. +In dynamic snapshot creation case, this field will be filled in by the +snapshot controller with the "ready_to_use" value returned from CSI +"CreateSnapshot" gRPC call. +For a pre-existing snapshot, this field will be filled with the "ready_to_use" +value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, +otherwise, this field will be set to "True". +If not specified, it means the readiness of a snapshot is unknown. ++optional|none| +|restoreSize|string|false|none|restoreSize represents the minimum size of volume required to create a volume +from this snapshot. +In dynamic snapshot creation case, this field will be filled in by the +snapshot controller with the "size_bytes" value returned from CSI +"CreateSnapshot" gRPC call. +For a pre-existing snapshot, this field will be filled with the "size_bytes" +value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. +When restoring a volume from this snapshot, the size of the volume MUST NOT +be smaller than the restoreSize if it is specified, otherwise the restoration will fail. +If not specified, it indicates that the size is unknown. ++optional|none| + +

v1alpha1WeightedPodAffinityTerm

+ + + + + + +```json +{ + "weight": 0, + "podAffinityTerm": {} +} + +``` + +The weights of all of the matched WeightedPodAffinityTerm fields are added +per-node to find the most preferred node(s) + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|weight|integer(int32)|false|none||weight associated with matching the corresponding podAffinityTerm,
in the range 1-100.| +|podAffinityTerm|object|false|none||none| + +

v1alpha1WorkloadJSON

+ + + + + + +```json +{ + "data": "string" +} + +``` + +WorkloadJSON messages of workload YAML details + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none|data The data field is the Workload YAML details|none| + +

v1alpha1WorkspaceInfo

+ + + + + + +```json +{ + "id": 0, + "alias": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|alias|string|false|none||none| + +

clusterClusterInfo

+ + + + + + +```json +{ + "name": "string", + "status": "running", + "isKubevirtInstalled": true, + "isInsightAgentReady": true, + "spiderpool": { + "isInstalled": true, + "enableIpv4": true, + "enableIpv6": true + }, + "gpuInfo": { + "type": [ + "Nvidia_GPU" + ], + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string" + } + ] + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|status|[v1alpha1clusterStatus](#schemav1alpha1clusterstatus)|false|none||none| +|isKubevirtInstalled|boolean|false|none||none| +|isInsightAgentReady|boolean|false|none||none| +|spiderpool|[clusterSpiderPool](#schemaclusterspiderpool)|false|none||none| +|gpuInfo|[clusterGPUInfo](#schemaclustergpuinfo)|false|none||none| + +

clusterGPUInfo

+ + + + + + +```json +{ + "type": [ + "Nvidia_GPU" + ], + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|[[v1alpha1clusterGPUType](#schemav1alpha1clustergputype)]|false|none||none| +|gpus|[[v1alpha1clusterGPU](#schemav1alpha1clustergpu)]|false|none||none| + +

clusterIsVMMonitorReadyResponse

+ + + + + + +```json +{ + "ready": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ready|boolean|false|none||none| + +

clusterListClusterNamespacesResponse

+ + + + + + +```json +{ + "items": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[string]|false|none||none| + +

clusterListClustersResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "status": "running", + "isKubevirtInstalled": true, + "isInsightAgentReady": true, + "spiderpool": { + "isInstalled": true, + "enableIpv4": true, + "enableIpv6": true + }, + "gpuInfo": { + "type": [ + "Nvidia_GPU" + ], + "gpus": [ + { + "type": null, + "deviceName": null + } + ] + } + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[clusterClusterInfo](#schemaclusterclusterinfo)]|false|none||none| + +

clusterSpiderPool

+ + + + + + +```json +{ + "isInstalled": true, + "enableIpv4": true, + "enableIpv6": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|isInstalled|boolean|false|none||none| +|enableIpv4|boolean|false|none||none| +|enableIpv6|boolean|false|none||none| + +

feature_gateFeatureGateID

+ + + + + + +```json +"CreateUserInWorkspace" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|CreateUserInWorkspace| + +

feature_gateFeatureGateInfo

+ + + + + + +```json +{ + "id": "CreateUserInWorkspace", + "description": "string", + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|[feature_gateFeatureGateID](#schemafeature_gatefeaturegateid)|false|none||none| +|description|string|false|none|关于此 FeatureGate 的描述|none| +|enabled|boolean|false|none|是否启用|none| + +

feature_gateListFeatureGatesResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "CreateUserInWorkspace", + "description": "string", + "enabled": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[feature_gateFeatureGateInfo](#schemafeature_gatefeaturegateinfo)]|false|none||none| + +

imageArtifact

+ + + + + + +```json +{ + "digest": "string", + "tags": [ + { + "name": "string", + "pushTime": "string" + } + ], + "imageSize": "string", + "pushTime": "string" +} + +``` + +Artifact is the concept of harbor artifact + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|digest|string|false|none||Digest is artifact digest.| +|tags|[[imageTag](#schemaimagetag)]|false|none||Tags is a list of tags.| +|imageSize|string(int64)|false|none||Size of artifact. Unit: byte. 1024 GenericBinary.| +|pushTime|string(int64)|false|none||First push time.| + +

imageCheckSecretResponse

+ + + + + + +```json +{ + "canUse": true, + "message": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|canUse|boolean|false|none||none| +|message|string|false|none||none| + +

imageListProjectsResponse

+ + + + + + +```json +{ + "items": [ + "string" + ] +} + +``` + +ListProjectsResponse returns a list of projects of a registry + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[string]|false|none||Items is a list of project names.| + +

imageListRegistriesResponse

+ + + + + + +```json +{ + "items": [ + { + "alias": "string", + "host": "string", + "name": "string" + } + ] +} + +``` + +ListRegistriesResponse returns a list of registries + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[imageRegistry](#schemaimageregistry)]|false|none|items is registry host|none| + +

imageListRepositoriesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "artifacts": [ + { + "digest": "string", + "tags": [ + {} + ], + "imageSize": "string", + "pushTime": "string" + } + ] + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +ListRepositoriesResponse returns a list of projects of a registry + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[imageRepository](#schemaimagerepository)]|false|none||Items is a list of repositories.| +|pagination|[v1alpha1imagePagination](#schemav1alpha1imagepagination)|false|none||none| + +

imageListSecretsResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "uid": "string", + "cluster": "string", + "namespace": "string", + "type": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[imageSecret](#schemaimagesecret)]|false|none||none| + +

imageRegistry

+ + + + + + +```json +{ + "alias": "string", + "host": "string", + "name": "string" +} + +``` + +Registry contains necessary info + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|alias|string|false|none||Alias is an alias for the registry, showed in list.| +|host|string|false|none||Host is registry host.| +|name|string|false|none||Name is registry name, use to query project lists.| + +

imageRepository

+ + + + + + +```json +{ + "name": "string", + "artifacts": [ + { + "digest": "string", + "tags": [ + { + "name": "string", + "pushTime": "string" + } + ], + "imageSize": "string", + "pushTime": "string" + } + ] +} + +``` + +Repository concept from Harbor + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||Name of repository.| +|artifacts|[[imageArtifact](#schemaimageartifact)]|false|none||Artifacts of repository.| + +

imageSecret

+ + + + + + +```json +{ + "name": "string", + "uid": "string", + "cluster": "string", + "namespace": "string", + "type": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|uid|string|false|none||none| +|cluster|string|false|none||none| +|namespace|string|false|none||none| +|type|string|false|none||none| + +

imageTag

+ + + + + + +```json +{ + "name": "string", + "pushTime": "string" +} + +``` + +Tag of an image. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||Name of the tag.| +|pushTime|string(int64)|false|none||Tag push time.| + +

roleClusterRoles

+ + + + + + +```json +{ + "roles": [ + "admin" + ], + "nsRoles": { + "property1": { + "roles": [ + "admin" + ] + }, + "property2": { + "roles": [ + "admin" + ] + } + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|roles|[[roleRoleEnum](#schemaroleroleenum)]|false|none||none| +|nsRoles|object|false|none||none| +|» **additionalProperties**|[roleNSRoles](#schemarolensroles)|false|none||none| + +

roleGetUserRolesResponse

+ + + + + + +```json +{ + "platformRoles": [ + "admin" + ], + "clusterRoles": { + "property1": { + "roles": [ + "admin" + ], + "nsRoles": { + "property1": { + "roles": [ + "[" + ] + }, + "property2": { + "roles": [ + "[" + ] + } + } + }, + "property2": { + "roles": [ + "admin" + ], + "nsRoles": { + "property1": { + "roles": [ + "[" + ] + }, + "property2": { + "roles": [ + "[" + ] + } + } + } + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|platformRoles|[[roleRoleEnum](#schemaroleroleenum)]|false|none||none| +|clusterRoles|object|false|none||none| +|» **additionalProperties**|[roleClusterRoles](#schemaroleclusterroles)|false|none||none| + +

roleNSRoles

+ + + + + + +```json +{ + "roles": [ + "admin" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|roles|[[roleRoleEnum](#schemaroleroleenum)]|false|none||none| + +

roleRoleEnum

+ + + + + + +```json +"admin" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|admin| +|*anonymous*|cluster_admin| +|*anonymous*|cluster_edit| +|*anonymous*|cluster_view| +|*anonymous*|ns_admin| +|*anonymous*|ns_edit| +|*anonymous*|ns_view| + +

v1alpha1clusterGPU

+ + + + + + +```json +{ + "type": "Nvidia_GPU", + "deviceName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|[v1alpha1clusterGPUType](#schemav1alpha1clustergputype)|false|none||none| +|deviceName|string|false|none||none| + +

v1alpha1clusterGPUType

+ + + + + + +```json +"Nvidia_GPU" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|Nvidia_GPU| +|*anonymous*|Nvidia_vGPU| + +

v1alpha1clusterStatus

+ + + + + + +```json +"running" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|running| +|*anonymous*|failed| + +

v1alpha1imagePagination

+ + + + + + +```json +{ + "page": 0, + "pageSize": 0, + "total": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| +|total|integer(int32)|false|none||none| + +

v1alpha1vmDiskVolume

+ + + + + + +```json +{ + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|storageClass|string|false|none||none| +|capacity|string(int64)|false|none||none| +|pvAccessMode|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)|false|none||none| +|name|string|false|none||none| + +

v1alpha1vmGPU

+ + + + + + +```json +{ + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|[v1alpha1vmGPUType](#schemav1alpha1vmgputype)|false|none||none| +|deviceName|string|false|none||none| +|count|integer(int32)|false|none||none| + +

v1alpha1vmGPUType

+ + + + + + +```json +"Nvidia_GPU" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|Nvidia_GPU| +|*anonymous*|Nvidia_vGPU| + +

v1alpha1vmGetCustomResourceResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||none| + +

v1alpha1vmImageSource

+ + + + + + +```json +"docker" + +``` + +TODO: + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|TODO:|string|false|none|TODO:|none| + +#### Enum + +|Name|Value| +|---|---| +|TODO:|docker| +|TODO:|http| +|TODO:|s3| + +

v1alpha1vmMultusConfigInfo

+ + + + + + +```json +{ + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|namespace|string|false|none||none| +|cniType|string|false|none||none| +|hasDefaultIppool|boolean|false|none||none| + +

v1alpha1vmMultusNetworkInfo

+ + + + + + +```json +{ + "networkMode": "string", + "items": [ + { + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|networkMode|string|false|none||none| +|items|[[v1alpha1vmMultusNetworkInfoItem](#schemav1alpha1vmmultusnetworkinfoitem)]|false|none||none| + +

v1alpha1vmMultusNetworkInfoItem

+ + + + + + +```json +{ + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|multusConfig|[v1alpha1vmMultusConfigInfo](#schemav1alpha1vmmultusconfiginfo)|false|none||none| +|interface|string|false|none||none| +|ips|[string]|false|none||none| +|mac|string|false|none||none| +|subnet|string|false|none||none| +|gateway|string|false|none||none| +|vlanId|string|false|none||none| + +

v1alpha1vmNetworkInterfaceInfo

+ + + + + + +```json +{ + "networkInterface": "string", + "multusConfigs": [ + { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|networkInterface|string|false|none||none| +|multusConfigs|[[v1alpha1vmMultusConfigInfo](#schemav1alpha1vmmultusconfiginfo)]|false|none||none| + +

v1alpha1vmPagination

+ + + + + + +```json +{ + "page": 0, + "pageSize": 0, + "total": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| +|total|integer(int32)|false|none||none| + +

v1alpha1vmPersistentVolumeAccessMode

+ + + + + + +```json +"ReadWriteOnce" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|ReadWriteOnce| +|*anonymous*|ReadOnlyMany| +|*anonymous*|ReadWriteMany| +|*anonymous*|ReadWriteOncePod| + +

v1alpha1vmSortBy

+ + + + + + +```json +"created_at" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|created_at| +|*anonymous*|field_name| + +

v1alpha1vmSortDir

+ + + + + + +```json +"desc" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|desc| +|*anonymous*|asc| + +

v1alpha1vmUpdateCustomResourceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

v1alpha1vmVMDisks

+ + + + + + +```json +{ + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|systemVolume|[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)|false|none||none| +|dataVolumes|[[v1alpha1vmDiskVolume](#schemav1alpha1vmdiskvolume)]|false|none||none| + +

v1alpha1vmtemplateDiskVolume

+ + + + + + +```json +{ + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|storageClass|string|false|none||none| +|capacity|string(int64)|false|none||none| +|pvAccessMode|[v1alpha1vmtemplatePersistentVolumeAccessMode](#schemav1alpha1vmtemplatepersistentvolumeaccessmode)|false|none||none| +|name|string|false|none||none| + +

v1alpha1vmtemplateGPU

+ + + + + + +```json +{ + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|[v1alpha1vmtemplateGPUType](#schemav1alpha1vmtemplategputype)|false|none||none| +|deviceName|string|false|none||none| +|count|integer(int32)|false|none||none| + +

v1alpha1vmtemplateGPUType

+ + + + + + +```json +"Nvidia_GPU" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|Nvidia_GPU| +|*anonymous*|Nvidia_vGPU| + +

v1alpha1vmtemplateGetCustomResourceResponse

+ + + + + + +```json +{ + "data": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|string|false|none||none| + +

v1alpha1vmtemplateImageSource

+ + + + + + +```json +"docker" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|docker| +|*anonymous*|http| +|*anonymous*|s3| + +

v1alpha1vmtemplateMultusConfigInfo

+ + + + + + +```json +{ + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|namespace|string|false|none||none| +|cniType|string|false|none||none| +|hasDefaultIppool|boolean|false|none||none| + +

v1alpha1vmtemplateMultusNetworkInfo

+ + + + + + +```json +{ + "networkMode": "string", + "items": [ + { + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string", + "ipPool": { + "ipv4": [ + "string" + ], + "ipv6": [ + "string" + ] + } + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|networkMode|string|false|none||none| +|items|[[v1alpha1vmtemplateMultusNetworkInfoItem](#schemav1alpha1vmtemplatemultusnetworkinfoitem)]|false|none||none| + +

v1alpha1vmtemplateMultusNetworkInfoItem

+ + + + + + +```json +{ + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string", + "ipPool": { + "ipv4": [ + "string" + ], + "ipv6": [ + "string" + ] + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|multusConfig|[v1alpha1vmtemplateMultusConfigInfo](#schemav1alpha1vmtemplatemultusconfiginfo)|false|none||none| +|interface|string|false|none||none| +|ips|[string]|false|none||none| +|mac|string|false|none||none| +|subnet|string|false|none||none| +|gateway|string|false|none||none| +|vlanId|string|false|none||none| +|ipPool|[vmtemplateIPPool](#schemavmtemplateippool)|false|none||none| + +

v1alpha1vmtemplatePagination

+ + + + + + +```json +{ + "page": 0, + "pageSize": 0, + "total": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| +|total|integer(int32)|false|none||none| + +

v1alpha1vmtemplatePersistentVolumeAccessMode

+ + + + + + +```json +"ReadWriteOnce" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|ReadWriteOnce| +|*anonymous*|ReadOnlyMany| +|*anonymous*|ReadWriteMany| +|*anonymous*|ReadWriteOncePod| + +

v1alpha1vmtemplateSortBy

+ + + + + + +```json +"UNSPECIFIED" + +``` + + - UNSPECIFIED: Unspecified is default, no sorting. + - created_at: Sort result by creationTimestamp. + - field_name: Sort result by name. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||- UNSPECIFIED: Unspecified is default, no sorting.
- created_at: Sort result by creationTimestamp.
- field_name: Sort result by name.| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|UNSPECIFIED| +|*anonymous*|created_at| +|*anonymous*|field_name| + +

v1alpha1vmtemplateSortDir

+ + + + + + +```json +"desc" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|desc| +|*anonymous*|asc| + +

v1alpha1vmtemplateUpdateCustomResourceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

v1alpha1vmtemplateVMDisks

+ + + + + + +```json +{ + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|systemVolume|[v1alpha1vmtemplateDiskVolume](#schemav1alpha1vmtemplatediskvolume)|false|none||none| +|dataVolumes|[[v1alpha1vmtemplateDiskVolume](#schemav1alpha1vmtemplatediskvolume)]|false|none||none| + +

vmAddDiskVolumeToVMResponse

+ + + + + + +```json +{ + "needRestart": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|needRestart|boolean|false|none||none| + +

vmAllowedOperation

+ + + + + + +```json +"allowed_operation_snapshot" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|allowed_operation_snapshot| +|*anonymous*|allowed_operation_clone| +|*anonymous*|allowed_operation_live_migration| + +

vmCloneVMResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmColdMigrationResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmCreateCustomResourceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmCreateVMResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmCreateVMSnapshotResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmCreateVMWithVMTemplateResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmDeleteVMResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmDeleteVMRestoreResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmDeleteVMSnapshotResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmEventLevel

+ + + + + + +```json +"UNSPECIFIED" + +``` + + - UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||- UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|UNSPECIFIED| +|*anonymous*|Normal| +|*anonymous*|Warning| + +

vmExpandVMDiskCapacityResponse

+ + + + + + +```json +{ + "needRestart": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|needRestart|boolean|false|none||none| + +

vmGetVMResponse

+ + + + + + +```json +{ + "cluster": "string", + "namespace": "string", + "name": "string", + "aliasName": "string", + "describe": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "ips": [ + "string" + ], + "status": "running", + "createdAt": "string", + "username": "string", + "password": "string", + "sshKey": "string", + "cpu": 0, + "memory": "string", + "vmErrorMessage": { + "message": "string", + "reason": "string" + }, + "imageSource": "docker", + "osFamily": "string", + "osVersion": "string", + "imageUrl": "string", + "node": "string", + "allowedOperation": [ + "allowed_operation_snapshot" + ], + "secret": "string", + "network": { + "networkMode": "string", + "items": [ + { + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string" + } + ] + }, + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|cluster|string|false|none||none| +|namespace|string|false|none||none| +|name|string|false|none||none| +|aliasName|string|false|none||none| +|describe|string|false|none||none| +|labels|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|annotations|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|ips|[string]|false|none||none| +|status|[vmVMStatus](#schemavmvmstatus)|false|none||none| +|createdAt|string|false|none||none| +|username|string|false|none||none| +|password|string|false|none||none| +|sshKey|string|false|none||none| +|cpu|integer(int64)|false|none||none| +|memory|string(int64)|false|none|单位:字节|none| +|vmErrorMessage|[vmVmErrorMessage](#schemavmvmerrormessage)|false|none||none| +|imageSource|[v1alpha1vmImageSource](#schemav1alpha1vmimagesource)|false|none||none| +|osFamily|string|false|none||none| +|osVersion|string|false|none||none| +|imageUrl|string|false|none||none| +|node|string|false|none||none| +|allowedOperation|[[vmAllowedOperation](#schemavmallowedoperation)]|false|none||none| +|secret|string|false|none||none| +|network|[v1alpha1vmMultusNetworkInfo](#schemav1alpha1vmmultusnetworkinfo)|false|none||none| +|gpus|[[v1alpha1vmGPU](#schemav1alpha1vmgpu)]|false|none||none| + +

vmListClusterNodesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "phase": "PhaseUnspecified" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmNode](#schemavmnode)]|false|none||none| + +

vmListClusterStorageClassesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "supportAccessMode": [ + "ReadWriteOnce" + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmStorageClass](#schemavmstorageclass)]|false|none||none| + +

vmListClusterVmsInfo

+ + + + + + +```json +{ + "name": "string", + "status": "running", + "namespace": "string", + "ips": [ + "string" + ], + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "vmErrorMessage": { + "message": "string", + "reason": "string" + }, + "allowedOperation": [ + "allowed_operation_snapshot" + ], + "node": "string", + "gpus": [ + "Nvidia_GPU" + ], + "migNodeSelector": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|status|[vmVMStatus](#schemavmvmstatus)|false|none||none| +|namespace|string|false|none||none| +|ips|[string]|false|none||none| +|cpu|integer(int64)|false|none||none| +|memory|string(int64)|false|none|单位:字节|none| +|createdAt|string|false|none||none| +|osFamily|string|false|none||none| +|vmErrorMessage|[vmVmErrorMessage](#schemavmvmerrormessage)|false|none||none| +|allowedOperation|[[vmAllowedOperation](#schemavmallowedoperation)]|false|none||none| +|node|string|false|none||none| +|gpus|[[v1alpha1vmGPUType](#schemav1alpha1vmgputype)]|false|none||none| +|migNodeSelector|string|false|none||none| + +

vmListClusterVmsResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "status": "running", + "namespace": "string", + "ips": [ + "string" + ], + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "vmErrorMessage": { + "message": "string", + "reason": "string" + }, + "allowedOperation": [ + "allowed_operation_snapshot" + ], + "node": "string", + "gpus": [ + "Nvidia_GPU" + ], + "migNodeSelector": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmListClusterVmsInfo](#schemavmlistclustervmsinfo)]|false|none||none| +|pagination|[v1alpha1vmPagination](#schemav1alpha1vmpagination)|false|none||none| + +

vmListNetworkInterfacesResponse

+ + + + + + +```json +{ + "ipPools": [ + "string" + ], + "interfaces": [ + { + "networkInterface": "string", + "multusConfigs": [ + { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + } + ] + } + ], + "ipPoolsV6": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ipPools|[string]|false|none||none| +|interfaces|[[v1alpha1vmNetworkInterfaceInfo](#schemav1alpha1vmnetworkinterfaceinfo)]|false|none||none| +|ipPoolsV6|[string]|false|none||none| + +

vmListSystemImagesResponse

+ + + + + + +```json +{ + "items": [ + { + "osFamily": "string", + "version": [ + { + "version": "string", + "url": "string" + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmSystemImage](#schemavmsystemimage)]|false|none||none| + +

vmListVMEventsResponse

+ + + + + + +```json +{ + "items": [ + { + "level": "UNSPECIFIED", + "component": "string", + "object": { + "name": "string", + "kind": "string" + }, + "name": "string", + "detail": "string", + "time": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmVmEvents](#schemavmvmevents)]|false|none||none| +|pagination|[v1alpha1vmPagination](#schemav1alpha1vmpagination)|false|none||none| + +

vmListVMNetworksResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "type": "string", + "ip": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmVMNetwork](#schemavmvmnetwork)]|false|none||none| + +

vmListVMRestoresResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "description": "string", + "complete": true, + "createdAt": "string", + "restoreTime": "string", + "lastRestore": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmVMRestore](#schemavmvmrestore)]|false|none||none| + +

vmListVMSnapshotsResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "description": "string", + "createdAt": "string", + "status": "snapshot_succeeded", + "restoreTime": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmVMSnapshot](#schemavmvmsnapshot)]|false|none||none| +|pagination|[v1alpha1vmPagination](#schemav1alpha1vmpagination)|false|none||none| + +

vmListVMStoragesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "type": "system", + "capacity": "string", + "status": "storage_processing", + "storageClass": "string", + "allowExpand": true, + "pvAccessMode": "ReadWriteOnce", + "hotpluggable": true + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmVMStorage](#schemavmvmstorage)]|false|none||none| +|pagination|[v1alpha1vmPagination](#schemav1alpha1vmpagination)|false|none||none| + +

vmLiveMigrateVMResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmMultusNetwork

+ + + + + + +```json +{ + "networkMode": "string", + "items": [ + { + "interface": "string", + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "ipPoolNames": [ + "string" + ], + "ipPoolNamesV6": [ + "string" + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|networkMode|string|false|none||none| +|items|[[vmMultusNetworkItem](#schemavmmultusnetworkitem)]|false|none||none| + +

vmMultusNetworkItem

+ + + + + + +```json +{ + "interface": "string", + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "ipPoolNames": [ + "string" + ], + "ipPoolNamesV6": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|interface|string|false|none||none| +|multusConfig|[v1alpha1vmMultusConfigInfo](#schemav1alpha1vmmultusconfiginfo)|false|none||none| +|ipPoolNames|[string]|false|none||none| +|ipPoolNamesV6|[string]|false|none||none| + +

vmNode

+ + + + + + +```json +{ + "name": "string", + "phase": "PhaseUnspecified" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|phase|[vmNodePhase](#schemavmnodephase)|false|none||none| + +

vmNodePhase

+ + + + + + +```json +"PhaseUnspecified" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|PhaseUnspecified| +|*anonymous*|PhaseReady| +|*anonymous*|PhaseNotReady| +|*anonymous*|PhaseUnknown| + +

vmObject

+ + + + + + +```json +{ + "name": "string", + "kind": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|kind|string|false|none||none| + +

vmRemoveVMDiskVolumeResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmRestoreVMSnapshotResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmSSH

+ + + + + + +```json +{ + "username": "string", + "password": "string", + "sshKey": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|username|string|false|none||none| +|password|string|false|none||none| +|sshKey|string|false|none||none| + +

vmSnapshotStatus

+ + + + + + +```json +"snapshot_succeeded" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|snapshot_succeeded| +|*anonymous*|snapshot_failed| +|*anonymous*|snapshot_deleting| +|*anonymous*|snapshot_processing| +|*anonymous*|snapshot_unknown| + +

vmStorageClass

+ + + + + + +```json +{ + "name": "string", + "supportAccessMode": [ + "ReadWriteOnce" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|supportAccessMode|[[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)]|false|none||none| + +

vmStorageStatus

+ + + + + + +```json +"storage_processing" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|storage_processing| +|*anonymous*|storage_ready| +|*anonymous*|storage_failed| + +

vmStorageType

+ + + + + + +```json +"system" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|system| +|*anonymous*|data| + +

vmSystemImage

+ + + + + + +```json +{ + "osFamily": "string", + "version": [ + { + "version": "string", + "url": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|osFamily|string|false|none||none| +|version|[[vmSystemImageVersion](#schemavmsystemimageversion)]|false|none||none| + +

vmSystemImageVersion

+ + + + + + +```json +{ + "version": "string", + "url": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|version|string|false|none||none| +|url|string|false|none||none| + +

vmUpdateVMResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmUpdateVMRunningStatusResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmUpdateVMSnapshotResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmVMNetwork

+ + + + + + +```json +{ + "name": "string", + "type": "string", + "ip": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|string|false|none||none| +|ip|string|false|none||none| + +

vmVMOperation

+ + + + + + +```json +"start" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|start| +|*anonymous*|stop| +|*anonymous*|restart| + +

vmVMRestore

+ + + + + + +```json +{ + "name": "string", + "description": "string", + "complete": true, + "createdAt": "string", + "restoreTime": "string", + "lastRestore": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|description|string|false|none||none| +|complete|boolean|false|none||none| +|createdAt|string|false|none||none| +|restoreTime|string|false|none||none| +|lastRestore|boolean|false|none||none| + +

vmVMSnapshot

+ + + + + + +```json +{ + "name": "string", + "description": "string", + "createdAt": "string", + "status": "snapshot_succeeded", + "restoreTime": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|description|string|false|none||none| +|createdAt|string|false|none||none| +|status|[vmSnapshotStatus](#schemavmsnapshotstatus)|false|none||none| +|restoreTime|string|false|none||none| + +

vmVMStatus

+ + + + + + +```json +"running" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|running| +|*anonymous*|processing| +|*anonymous*|error| +|*anonymous*|poweroff| + +

vmVMStorage

+ + + + + + +```json +{ + "name": "string", + "type": "system", + "capacity": "string", + "status": "storage_processing", + "storageClass": "string", + "allowExpand": true, + "pvAccessMode": "ReadWriteOnce", + "hotpluggable": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|[vmStorageType](#schemavmstoragetype)|false|none||none| +|capacity|string(int64)|false|none||none| +|status|[vmStorageStatus](#schemavmstoragestatus)|false|none||none| +|storageClass|string|false|none||none| +|allowExpand|boolean|false|none||none| +|pvAccessMode|[v1alpha1vmPersistentVolumeAccessMode](#schemav1alpha1vmpersistentvolumeaccessmode)|false|none||none| +|hotpluggable|boolean|false|none||none| + +

vmVmErrorMessage

+ + + + + + +```json +{ + "message": "string", + "reason": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|message|string|false|none||none| +|reason|string|false|none||none| + +

vmVmEvents

+ + + + + + +```json +{ + "level": "UNSPECIFIED", + "component": "string", + "object": { + "name": "string", + "kind": "string" + }, + "name": "string", + "detail": "string", + "time": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|level|[vmEventLevel](#schemavmeventlevel)|false|none||- UNSPECIFIED: This is only a meaningless placeholder, to avoid zero not return.| +|component|string|false|none||none| +|object|[vmObject](#schemavmobject)|false|none||none| +|name|string|false|none||none| +|detail|string|false|none||none| +|time|string|false|none||none| + +

vmtemplateCreateVMTemplateByVMRequest

+ + + + + + +```json +{ + "cluster": "string", + "namespace": "string", + "vmName": "string", + "vmtemplateName": "string", + "description": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|cluster|string|false|none||none| +|namespace|string|false|none||none| +|vmName|string|false|none||none| +|vmtemplateName|string|false|none||none| +|description|string|false|none||none| + +

vmtemplateCreateVMTemplateByVMResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmtemplateDeleteVMTemplateResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

vmtemplateGetVMTemplateResponse

+ + + + + + +```json +{ + "name": "string", + "description": "string", + "labels": { + "property1": "string", + "property2": "string" + }, + "annotations": { + "property1": "string", + "property2": "string" + }, + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "imageUrl": "string", + "type": "custom", + "systemDiskCapacity": "string", + "imageSource": "docker", + "osVersion": "string", + "network": "string", + "disks": { + "systemVolume": { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + }, + "dataVolumes": [ + { + "storageClass": "string", + "capacity": "string", + "pvAccessMode": "ReadWriteOnce", + "name": "string" + } + ] + }, + "gpus": [ + { + "type": "Nvidia_GPU", + "deviceName": "string", + "count": 0 + } + ], + "networks": { + "networkMode": "string", + "items": [ + { + "multusConfig": { + "name": "string", + "namespace": "string", + "cniType": "string", + "hasDefaultIppool": true + }, + "interface": "string", + "ips": [ + "string" + ], + "mac": "string", + "subnet": "string", + "gateway": "string", + "vlanId": "string", + "ipPool": { + "ipv4": [ + null + ], + "ipv6": [ + null + ] + } + } + ] + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|description|string|false|none||none| +|labels|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|annotations|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|cpu|integer(int64)|false|none||none| +|memory|string(int64)|false|none|单位:字节|none| +|createdAt|string|false|none||none| +|osFamily|string|false|none||none| +|imageUrl|string|false|none||none| +|type|[vmtemplateTemplateType](#schemavmtemplatetemplatetype)|false|none||none| +|systemDiskCapacity|string(int64)|false|none||none| +|imageSource|[v1alpha1vmtemplateImageSource](#schemav1alpha1vmtemplateimagesource)|false|none||none| +|osVersion|string|false|none||none| +|network|string|false|none||none| +|disks|[v1alpha1vmtemplateVMDisks](#schemav1alpha1vmtemplatevmdisks)|false|none||none| +|gpus|[[v1alpha1vmtemplateGPU](#schemav1alpha1vmtemplategpu)]|false|none||none| +|networks|[v1alpha1vmtemplateMultusNetworkInfo](#schemav1alpha1vmtemplatemultusnetworkinfo)|false|none||none| + +

vmtemplateIPPool

+ + + + + + +```json +{ + "ipv4": [ + "string" + ], + "ipv6": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ipv4|[string]|false|none||none| +|ipv6|[string]|false|none||none| + +

vmtemplateListVMTemplatesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "type": "custom", + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "gpus": [ + "Nvidia_GPU" + ] + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[vmtemplateVMTemplateInfo](#schemavmtemplatevmtemplateinfo)]|false|none||none| +|pagination|[v1alpha1vmtemplatePagination](#schemav1alpha1vmtemplatepagination)|false|none||none| + +

vmtemplateTemplateType

+ + + + + + +```json +"custom" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|custom| +|*anonymous*|internal| + +

vmtemplateVMTemplateInfo

+ + + + + + +```json +{ + "name": "string", + "type": "custom", + "cpu": 0, + "memory": "string", + "createdAt": "string", + "osFamily": "string", + "gpus": [ + "Nvidia_GPU" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|[vmtemplateTemplateType](#schemavmtemplatetemplatetype)|false|none||none| +|cpu|integer(int64)|false|none||none| +|memory|string(int64)|false|none|单位:字节|none| +|createdAt|string|false|none||none| +|osFamily|string|false|none||none| +|gpus|[[v1alpha1vmtemplateGPUType](#schemav1alpha1vmtemplategputype)]|false|none||none| + +

aboutDeveloper

+ + + + + + +```json +{ + "name": "string", + "message": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|message|string|false|none||none| + +

aboutGProductVersion

+ + + + + + +```json +{ + "name": "string", + "version": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|version|string|false|none||none| + +

aboutListDevelopersResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "message": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[aboutDeveloper](#schemaaboutdeveloper)]|false|none||none| + +

aboutListGProductVersionsResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "version": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[aboutGProductVersion](#schemaaboutgproductversion)]|false|none||none| + +

aboutListOpenSourcesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "license": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[aboutOpenSource](#schemaaboutopensource)]|false|none||none| +|pagination|[v1alpha1aboutPagination](#schemav1alpha1aboutpagination)|false|none||none| + +

aboutOpenSource

+ + + + + + +```json +{ + "name": "string", + "license": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none|开源软件名称|none| +|license|string|false|none|开源协议|none| + +

apiHttpBody

+ + + + + + +```json +{ + "contentType": "string", + "data": "string", + "extensions": [ + { + "@type": "string", + "property1": {}, + "property2": {} + } + ] +} + +``` + +Message that represents an arbitrary HTTP body. It should only be used for +payload formats that can't be represented as JSON, such as raw binary or +an HTML page. + +This message can be used both in streaming and non-streaming API methods in +the request as well as the response. + +It can be used as a top-level request field, which is convenient if one +wants to extract parameters from either the URL or HTTP template into the +request fields and also want access to the raw HTTP body. + +Example: + + message GetResourceRequest { + // A unique request id. + string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + +Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + +Use of this type only changes how the request and response bodies are +handled, all other features will continue to work unchanged. + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|contentType|string|false|none||The HTTP Content-Type header value specifying the content type of the body.| +|data|string(byte)|false|none||The HTTP request/response body as raw binary.| +|extensions|[[protobufAny](#schemaprotobufany)]|false|none||Application specific response metadata. Must be set in the first response
for streaming APIs.| + +

auditAuditInfo

+ + + + + + +```json +{ + "id": "string", + "auditName": "string", + "resourceType": "string", + "resourceName": "string", + "clusterName": "string", + "gproduct": "string", + "status": "all", + "user": "string", + "client": "string", + "ip": "string", + "createdAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|auditName|string|false|none||none| +|resourceType|string|false|none||none| +|resourceName|string|false|none||none| +|clusterName|string|false|none||none| +|gproduct|string|false|none||none| +|status|[v1alpha3auditStatusType](#schemav1alpha3auditstatustype)|false|none||none| +|user|string|false|none||none| +|client|string|false|none||none| +|ip|string|false|none||none| +|createdAt|string|false|none||none| + +

auditAuthTokenResponse

+ + + + + + +```json +{ + "message": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|message|string|false|none||none| + +

auditCertsResponse

+ + + + + + +```json +{ + "keys": [ + { + "kid": "string", + "kty": "string", + "e": "string", + "n": "string", + "alg": "string", + "use": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|keys|[[auditKey](#schemaauditkey)]|false|none||none| + +

auditClearAuditsNowRequest

+ + + + + + +```json +{ + "days": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|days|integer(int32)|false|none||none| + +

auditClearAuditsNowResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

auditClearKubeAuditsNowRequest

+ + + + + + +```json +{ + "days": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|days|integer(int32)|false|none||none| + +

auditClearKubeAuditsNowResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

auditExportTypes

+ + + + + + +```json +"Csv" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|Csv| +|*anonymous*|Excel| + +

auditExternalAuditResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

auditExternalType

+ + + + + + +```json +"loginFailed" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|loginFailed| +|*anonymous*|forgetPassword| +|*anonymous*|resetPassword| + +

auditGetAuditDetailResponse

+ + + + + + +```json +{ + "audit": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|audit|string|false|none||none| + +

auditGetAuditResourceReportResponse

+ + + + + + +```json +{ + "items": [ + { + "ResourceType": "string", + "EventName": "string", + "Count": 0 + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[auditResourceReport](#schemaauditresourcereport)]|false|none||none| + +

auditGetAuditUserReportResponse

+ + + + + + +```json +{ + "items": [ + { + "UserName": "string", + "TotalCount": 0, + "SuccessCount": 0, + "FailedCount": 0 + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[auditUserReport](#schemaaudituserreport)]|false|none||none| + +

auditGetAutoClearAuditTimeResponse

+ + + + + + +```json +{ + "kubeDays": 0, + "ghippoDays": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|kubeDays|integer(int32)|false|none||none| +|ghippoDays|integer(int32)|false|none||none| + +

auditGetExportURIResponse

+ + + + + + +```json +{ + "uri": "string", + "method": "GET" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|uri|string|false|none||none| +|method|[auditRequestMethod](#schemaauditrequestmethod)|false|none||none| + +

auditGetKubeAuditDetailResponse

+ + + + + + +```json +{ + "audit": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|audit|string|false|none||none| + +

auditGetLimitRangeTimeResponse

+ + + + + + +```json +{ + "day": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|day|integer(int32)|false|none||none| + +

auditKey

+ + + + + + +```json +{ + "kid": "string", + "kty": "string", + "e": "string", + "n": "string", + "alg": "string", + "use": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|kid|string|false|none||none| +|kty|string|false|none||none| +|e|string|false|none||none| +|n|string|false|none||none| +|alg|string|false|none||none| +|use|string|false|none||none| + +

auditKubeAuditInfo

+ + + + + + +```json +{ + "id": "string", + "auditName": "string", + "resourceType": "string", + "resourceName": "string", + "clusterName": "string", + "status": "all", + "user": "string", + "client": "string", + "ip": "string", + "createdAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|auditName|string|false|none||none| +|resourceType|string|false|none||none| +|resourceName|string|false|none||none| +|clusterName|string|false|none||none| +|status|[v1alpha3auditStatusType](#schemav1alpha3auditstatustype)|false|none||none| +|user|string|false|none||none| +|client|string|false|none||none| +|ip|string|false|none||none| +|createdAt|string|false|none||none| + +

auditListAuditsResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "auditName": "string", + "resourceType": "string", + "resourceName": "string", + "clusterName": "string", + "gproduct": "string", + "status": "all", + "user": "string", + "client": "string", + "ip": "string", + "createdAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[auditAuditInfo](#schemaauditauditinfo)]|false|none||none| +|pagination|[v1alpha3auditPagination](#schemav1alpha3auditpagination)|false|none||none| + +

auditListKubeAuditsResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "auditName": "string", + "resourceType": "string", + "resourceName": "string", + "clusterName": "string", + "status": "all", + "user": "string", + "client": "string", + "ip": "string", + "createdAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[auditKubeAuditInfo](#schemaauditkubeauditinfo)]|false|none||none| +|pagination|[v1alpha3auditPagination](#schemav1alpha3auditpagination)|false|none||none| + +

auditModules

+ + + + + + +```json +"audit" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|audit| +|*anonymous*|kube_audit| + +

auditRequestMethod

+ + + + + + +```json +"GET" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|GET| +|*anonymous*|POST| +|*anonymous*|PUT| +|*anonymous*|DELETE| +|*anonymous*|PATCH| + +

auditResourceReport

+ + + + + + +```json +{ + "ResourceType": "string", + "EventName": "string", + "Count": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ResourceType|string|false|none||none| +|EventName|string|false|none||none| +|Count|integer(int32)|false|none||none| + +

auditSetAutoClearAuditSettingRequest

+ + + + + + +```json +{ + "days": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|days|integer(int32)|false|none||none| + +

auditSetAutoClearAuditSettingResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

auditSetAutoClearKubeAuditSettingRequest

+ + + + + + +```json +{ + "days": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|days|integer(int32)|false|none||none| + +

auditSetAutoClearKubeAuditSettingResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

auditUserReport

+ + + + + + +```json +{ + "UserName": "string", + "TotalCount": 0, + "SuccessCount": 0, + "FailedCount": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|UserName|string|false|none||none| +|TotalCount|integer(int32)|false|none||none| +|SuccessCount|integer(int32)|false|none||none| +|FailedCount|integer(int32)|false|none||none| + +

batchauditBatchInsertAuditsRequest

+ + + + + + +```json +{ + "audits": "string" +} + +``` + +@openapiv2-ignore + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|audits|string|false|none||none| + +

batchauditBatchInsertAuditsResponse

+ + + + + + +```json +{} + +``` + +@openapiv2-ignore + +### Attribute + +*None* + +

clientClientInfo

+ + + + + + +```json +{ + "id": "string", + "clientId": "string", + "name": "string", + "secret": "string", + "baseUrl": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|clientId|string|false|none||none| +|name|string|false|none||none| +|secret|string|false|none|bool enabled = 4; +repeated string redirect_uris = 5;|none| +|baseUrl|string|false|none||none| + +

clientCreateClientRequest

+ + + + + + +```json +{ + "clientId": "string", + "baseUrl": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|clientId|string|false|none||none| +|baseUrl|string|false|none||none| + +

clientCreateClientResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

clientDeleteClientResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

clientGetClientResponse

+ + + + + + +```json +{ + "client": { + "id": "string", + "clientId": "string", + "name": "string", + "secret": "string", + "baseUrl": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|client|[clientClientInfo](#schemaclientclientinfo)|false|none||none| + +

clientListClientsResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "clientId": "string", + "name": "string", + "secret": "string", + "baseUrl": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[clientClientInfo](#schemaclientclientinfo)]|false|none||none| + +

clientUpdateClientResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserCreateAccessTokenRequest

+ + + + + + +```json +{ + "name": "string", + "expiredAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|expiredAt|string|false|none||none| + +

currentuserCreateAccessTokenResponse

+ + + + + + +```json +{ + "id": "string", + "token": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|token|string|false|none||none| + +

currentuserCreateSSHKeyRequest

+ + + + + + +```json +{ + "sshKeyName": "string", + "publicKey": "string", + "expiredAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|sshKeyName|string|false|none||none| +|publicKey|string|false|none||none| +|expiredAt|string|false|none||none| + +

currentuserCreateSSHKeyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserDeleteAccessTokenResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserDeleteSSHKeyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserGetGlobalPermissionsResponse

+ + + + + + +```json +{ + "permissions": [ + "Unknown" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|permissions|[[currentuserGlobalPermission](#schemacurrentuserglobalpermission)]|false|none||none| + +

currentuserGlobalPermission

+ + + + + + +```json +"Unknown" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|Unknown| +|*anonymous*|ListUser| +|*anonymous*|CreateUser| +|*anonymous*|UpdateUser| +|*anonymous*|DeleteUser| +|*anonymous*|AuthorizeUser| +|*anonymous*|ListGroup| +|*anonymous*|CreateGroup| +|*anonymous*|UpdateGroup| +|*anonymous*|DeleteGroup| +|*anonymous*|UpdateGroupUser| +|*anonymous*|AuthorizeGroup| +|*anonymous*|GetRole| +|*anonymous*|GetIdp| +|*anonymous*|CreateIdp| +|*anonymous*|UpdateIdp| +|*anonymous*|DeleteIdp| +|*anonymous*|GetAudit| +|*anonymous*|DeleteAudit| +|*anonymous*|GetSecurityPolicy| +|*anonymous*|UpdateSecurityPolicy| +|*anonymous*|GetSMTP| +|*anonymous*|UpdateSMTP| +|*anonymous*|GetAppearance| +|*anonymous*|UpdateAppearance| +|*anonymous*|GetLicense| +|*anonymous*|UpdateLicense| +|*anonymous*|DeleteLicense| +|*anonymous*|GetWorkspace| +|*anonymous*|GetAboutPlatform| +|*anonymous*|DeleteRole| +|*anonymous*|UpdateRole| +|*anonymous*|CreateRole| +|*anonymous*|AccountingAndBilling| +|*anonymous*|ReportManagement| +|*anonymous*|GetClient| +|*anonymous*|DeleteClient| +|*anonymous*|UpdateClient| +|*anonymous*|CreateClient| +|*anonymous*|EditCluster| +|*anonymous*|GetAccountingBilling| +|*anonymous*|UpdateAccountingBilling| +|*anonymous*|GetReportManagement| +|*anonymous*|UpdateReportManagement| +|*anonymous*|GetBillingSetting| +|*anonymous*|UpdateBillingSetting| + +

currentuserListAccessTokensResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[v1alpha1currentuserAccessToken](#schemav1alpha1currentuseraccesstoken)]|false|none||none| + +

currentuserListSSHKeysResponse

+ + + + + + +```json +{ + "items": [ + { + "id": 0, + "sshKeyName": "string", + "publicKey": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[currentuserSSHKey](#schemacurrentusersshkey)]|false|none||none| + +

currentuserPasswordDescriptionResponse

+ + + + + + +```json +{ + "allowModify": true, + "emptyPassword": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|allowModify|boolean|false|none||none| +|emptyPassword|boolean|false|none||none| + +

currentuserSSHKey

+ + + + + + +```json +{ + "id": 0, + "sshKeyName": "string", + "publicKey": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|sshKeyName|string|false|none||none| +|publicKey|string|false|none||none| +|updatedAt|string|false|none||none| +|createdAt|string|false|none||none| +|expiredAt|string|false|none||none| + +

currentuserSetCurrentUserPasswordRequest

+ + + + + + +```json +{ + "oldPassword": "string", + "newPassword": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|oldPassword|string|false|none||none| +|newPassword|string|false|none||none| + +

currentuserSetCurrentUserPasswordResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserUpdateEmailRequest

+ + + + + + +```json +{ + "email": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|email|string|false|none||none| + +

currentuserUpdateEmailResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserUpdateLanguageRequest

+ + + + + + +```json +{ + "locale": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|locale|string|false|none||none| + +

currentuserUpdateLanguageResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserUpdatePasswordRequest

+ + + + + + +```json +{ + "password": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|password|string|false|none||none| + +

currentuserUpdatePasswordResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

currentuserUpdateSSHKeyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

gproductListGProductsResponse

+ + + + + + +```json +{ + "data": [ + { + "id": "string", + "title": "string", + "url": "string", + "uiAssetsUrl": "string", + "needImportLicense": true, + "needUpdateExpiredLicense": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|data|[[v1alpha1gproductGProduct](#schemav1alpha1gproductgproduct)]|false|none||none| + +

gproductlicenseDeleteProductLicensesResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

gproductlicenseGProductLicense

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|module|string|false|none||none| +|level|string|false|none||none| +|status|string|false|none||none| +|expiredAt|string|false|none||none| + +

gproductlicenseGProductLicenseInfo

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "module": "string", + "licenseKey": "string", + "licenseLevel": "string", + "physicalUsedCpu": "string", + "physicalMaxCpu": "string", + "virtualUsedCpu": "string", + "virtualMaxCpu": "string", + "expiredAt": "string", + "usedNode": "string", + "maxNode": "string", + "physicalUsedGpu": "string", + "physicalMaxGpu": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|module|string|false|none||none| +|licenseKey|string|false|none||none| +|licenseLevel|string|false|none||none| +|physicalUsedCpu|string|false|none||none| +|physicalMaxCpu|string|false|none||none| +|virtualUsedCpu|string|false|none||none| +|virtualMaxCpu|string|false|none||none| +|expiredAt|string|false|none||none| +|usedNode|string|false|none||none| +|maxNode|string|false|none||none| +|physicalUsedGpu|string|false|none||none| +|physicalMaxGpu|string|false|none||none| + +

gproductlicenseGetGProductLicenseYamlResponse

+ + + + + + +```json +{ + "yaml": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|yaml|string|false|none||none| + +

gproductlicenseGetGProductLicensesESNResponse

+ + + + + + +```json +{ + "esn": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|esn|string|false|none||none| + +

gproductlicenseGetGProductLicensesOverQuotaResponse

+ + + + + + +```json +{ + "expireSoonLicenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ], + "expiredLicenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|expireSoonLicenses|[[gproductlicenseGProductLicense](#schemagproductlicensegproductlicense)]|false|none||none| +|expiredLicenses|[[gproductlicenseGProductLicense](#schemagproductlicensegproductlicense)]|false|none||none| + +

gproductlicenseGetGProductLicensesResponse

+ + + + + + +```json +{ + "license": { + "id": "string", + "name": "string", + "module": "string", + "licenseKey": "string", + "licenseLevel": "string", + "physicalUsedCpu": "string", + "physicalMaxCpu": "string", + "virtualUsedCpu": "string", + "virtualMaxCpu": "string", + "expiredAt": "string", + "usedNode": "string", + "maxNode": "string", + "physicalUsedGpu": "string", + "physicalMaxGpu": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|license|[gproductlicenseGProductLicenseInfo](#schemagproductlicensegproductlicenseinfo)|false|none||none| + +

gproductlicenseListGProductLicensesResponse

+ + + + + + +```json +{ + "licenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|licenses|[[gproductlicenseGProductLicense](#schemagproductlicensegproductlicense)]|false|none||none| + +

gproductlicenseUpdateGProductLicensesRequest

+ + + + + + +```json +{ + "yaml": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|yaml|string|false|none||none| + +

gproductlicenseUpdateGProductLicensesResponse

+ + + + + + +```json +{ + "message": "string", + "licenses": [ + { + "id": "string", + "name": "string", + "module": "string", + "level": "string", + "status": "string", + "expiredAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|message|string|false|none||none| +|licenses|[[gproductlicenseGProductLicense](#schemagproductlicensegproductlicense)]|false|none||none| + +

groupAddUserToGroupResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

groupCreateGroupRequest

+ + + + + + +```json +{ + "name": "string", + "description": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|description|string|false|none||none| + +

groupCreateGroupResponse

+ + + + + + +```json +{ + "id": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| + +

groupDeleteGroupResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

groupDeleteUserFromGroupResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

groupGetGroupResponse

+ + + + + + +```json +{ + "group": { + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|group|[groupGroupInfo](#schemagroupgroupinfo)|false|none||none| + +

groupGroupInfo

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|userCount|integer(int64)|false|none||none| +|description|string|false|none||none| +|createdAt|string|false|none||none| +|canAuthorize|boolean|false|none||none| + +

groupGroupMembersResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1groupPagination](#schemav1alpha1grouppagination)|false|none||none| +|items|[[v1alpha1groupUser](#schemav1alpha1groupuser)]|false|none||none| + +

groupGroupSubject

+ + + + + + +```json +{ + "id": "string", + "roleId": "string", + "type": "string", + "roleName": "string", + "subjectName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|roleId|string|false|none||none| +|type|string|false|none||none| +|roleName|string|false|none||none| +|subjectName|string|false|none||none| + +

groupListGroupRolesResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "authorizedCount": 0, + "items": [ + { + "name": "string", + "type": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string", + "authorized": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1groupPagination](#schemav1alpha1grouppagination)|false|none||none| +|authorizedCount|integer(int64)|false|none||none| +|items|[[v1alpha1groupRoleInfo](#schemav1alpha1grouproleinfo)]|false|none||none| + +

groupListGroupSubjectResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "roleId": "string", + "type": "string", + "roleName": "string", + "subjectName": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1groupPagination](#schemav1alpha1grouppagination)|false|none||none| +|items|[[groupGroupSubject](#schemagroupgroupsubject)]|false|none||none| + +

groupListGroupsResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1groupPagination](#schemav1alpha1grouppagination)|false|none||none| +|items|[[groupGroupInfo](#schemagroupgroupinfo)]|false|none||none| + +

groupUpdateGroupResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

groupUpdateGroupRolesResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

idpClientAuthentications

+ + + + + + +```json +"client_secret_post" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|client_secret_post| +|*anonymous*|client_secret_basic| +|*anonymous*|client_secret_jwt| +|*anonymous*|private_key_jwt| + +

idpCreateIDPRequest

+ + + + + + +```json +{ + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|displayName|string|false|none|string id = 1;|none| +|clientId|string|false|none||none| +|clientSecret|string|false|none||none| +|clientAuthentications|[idpClientAuthentications](#schemaidpclientauthentications)|false|none||none| +|providerId|[v1alpha1idpProviderType](#schemav1alpha1idpprovidertype)|false|none||none| +|authorizationUrl|string|false|none||none| +|userInfoUrl|string|false|none||none| +|tokenUrl|string|false|none||none| +|logoutUrl|string|false|none||none| +|enableAutoLinkFlow|boolean|false|none||none| +|alias|string|false|none||none| +|enabled|boolean|false|none||none| + +

idpCreateIDPResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

idpDeleteIDPResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

idpGetIDPResponse

+ + + + + + +```json +{ + "idpInfo": { + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|idpInfo|[idpIDPInfo](#schemaidpidpinfo)|false|none||none| + +

idpGetRedirectUrlResponse

+ + + + + + +```json +{ + "url": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|url|string|false|none||none| + +

idpGetWellKnownUrlResponse

+ + + + + + +```json +{ + "url": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|url|string|false|none||none| + +

idpIDPInfo

+ + + + + + +```json +{ + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|displayName|string|false|none|string id = 1;|none| +|clientId|string|false|none||none| +|clientSecret|string|false|none||none| +|clientAuthentications|[idpClientAuthentications](#schemaidpclientauthentications)|false|none||none| +|providerId|[v1alpha1idpProviderType](#schemav1alpha1idpprovidertype)|false|none||none| +|authorizationUrl|string|false|none||none| +|userInfoUrl|string|false|none||none| +|tokenUrl|string|false|none||none| +|logoutUrl|string|false|none||none| +|enableAutoLinkFlow|boolean|false|none||none| +|alias|string|false|none||none| +|enabled|boolean|false|none||none| + +

idpListIDPsResponse

+ + + + + + +```json +{ + "items": [ + { + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "clientAuthentications": "client_secret_post", + "providerId": "oidc", + "authorizationUrl": "string", + "userInfoUrl": "string", + "tokenUrl": "string", + "logoutUrl": "string", + "enableAutoLinkFlow": true, + "alias": "string", + "enabled": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[idpIDPInfo](#schemaidpidpinfo)]|false|none||none| + +

idpUpdateIDPResponse

+ + + + + + +```json +{ + "alias": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|alias|string|false|none||none| + +

keycloakeventAuthDetails

+ + + + + + +```json +{ + "clientId": "string", + "ipAddress": "string", + "realmId": "string", + "userId": "string", + "username": "string", + "sessionId": "string" +} + +``` + +参考 ExtendedAuthDetails 类的定义 + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|clientId|string|false|none||none| +|ipAddress|string|false|none||none| +|realmId|string|false|none||none| +|userId|string|false|none||none| +|username|string|false|none||none| +|sessionId|string|false|none||none| + +

keycloakeventKeycloakEventRequest

+ + + + + + +```json +{ + "realmId": "string", + "resourceType": "string", + "operationType": "string", + "resourcePath": "string", + "representation": "string", + "uid": "string", + "authDetails": { + "clientId": "string", + "ipAddress": "string", + "realmId": "string", + "userId": "string", + "username": "string", + "sessionId": "string" + }, + "type": "string", + "details": { + "property1": "string", + "property2": "string" + }, + "error": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|realmId|string|false|none||none| +|resourceType|string|false|none||none| +|operationType|string|false|none||none| +|resourcePath|string|false|none||none| +|representation|string|false|none|json string|none| +|uid|string|false|none||none| +|authDetails|[keycloakeventAuthDetails](#schemakeycloakeventauthdetails)|false|none||none| +|type|string|false|none||none| +|details|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|error|string|false|none||none| + +

keycloakeventKeycloakEventResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

ldapCreateLdapGroupResponse

+ + + + + + +```json +{ + "id": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| + +

ldapCreateLdapRequest

+ + + + + + +```json +{ + "name": "string", + "vendor": "other", + "startTls": "string", + "connectionUrl": "string", + "usersDn": "string", + "bindDn": "string", + "bindCredential": "string", + "userObjectClasses": "string", + "usernameLdapAttribute": "string", + "fullSyncPeriod": "string", + "rdnLdapAttribute": "string", + "uuidLdapAttribute": "string", + "editMode": "string", + "readTimeout": "string", + "firstName": "string", + "lastName": "string", + "email": "string", + "enabled": true, + "username": "string", + "userLdapFilter": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|vendor|[ldapLdapVendor](#schemaldapldapvendor)|false|none||none| +|startTls|string|false|none||Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling.| +|connectionUrl|string|false|none||none| +|usersDn|string|false|none|Full DN of LDAP tree where your users are. This DN is the parent of LDAP users. +It could be for example 'ou=users,dc=example,dc=com' assuming that your typical user will have DN like 'uid=john,ou=users,dc=example,dc=com'|none| +|bindDn|string|false|none|DN of LDAP admin, which will be used by Keycloak to access LDAP server|none| +|bindCredential|string|false|none||Password of LDAP admin.| +|userObjectClasses|string|false|none||All values of LDAP objectClass attribute for users in LDAP divided by comma.
For example: 'inetOrgPerson, organizationalPerson' .
Newly created Keycloak users will be written to LDAP with all those object classes and existing LDAP user records are found just if they contain all those object classes.| +|usernameLdapAttribute|string|false|none|Name of LDAP attribute, which is mapped as Keycloak username. For many LDAP server vendors it can be 'uid'. +For Active directory it can be 'sAMAccountName' or 'cn'. +The attribute should be filled for all LDAP user records you want to import from LDAP to Keycloak|none| +|fullSyncPeriod|string|false|none|Period for full synchronization in seconds: -1 手动同步|none| +|rdnLdapAttribute|string|false|none||Name of the LDAP attribute, which is used as RDN (top attribute) of typical user DN.
Usually it's the same as the Username LDAP attribute, however it is not required.
For example for Active directory, it is common to use 'cn' as RDN attribute when username attribute might be 'sAMAccountName'.| +|uuidLdapAttribute|string|false|none||Name of the LDAP attribute, which is used as a unique object identifier (UUID) for objects in LDAP.
For many LDAP server vendors, it is 'entryUUID'; however some are different.
For example, for Active directory it should be 'objectGUID'.
If your LDAP server does not support the notion of UUID, you can use any other attribute that is supposed to be unique among LDAP users in tree.
For example 'uid' or 'entryDN'.| +|editMode|string|false|none||READ_ONLY is a read-only LDAP store.
WRITABLE means data will be synced back to LDAP on demand.| +|readTimeout|string|false|none||LDAP read timeout in milliseconds. This timeout applies for LDAP read operations.| +|firstName|string|false|none||none| +|lastName|string|false|none||none| +|email|string|false|none||none| +|enabled|boolean|false|none||none| +|username|string|false|none||none| +|userLdapFilter|string|false|none||none| + +

ldapCreateLdapResponse

+ + + + + + +```json +{ + "id": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| + +

ldapDeleteLdapGroupResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

ldapDeleteLdapResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

ldapGetLdapGroupResponse

+ + + + + + +```json +{ + "id": "string", + "groupDn": "string", + "groupObjectClasses": "string", + "groupNameLdapAttribute": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|groupDn|string|false|none||none| +|groupObjectClasses|string|false|none||none| +|groupNameLdapAttribute|string|false|none||none| + +

ldapGetLdapResponse

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "vendor": "other", + "startTls": "string", + "connectionUrl": "string", + "usersDn": "string", + "bindDn": "string", + "bindCredential": "string", + "userObjectClasses": "string", + "usernameLdapAttribute": "string", + "fullSyncPeriod": "string", + "rdnLdapAttribute": "string", + "uuidLdapAttribute": "string", + "editMode": "string", + "readTimeout": "string", + "firstName": "string", + "lastName": "string", + "email": "string", + "enabled": true, + "username": "string", + "userLdapFilter": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|vendor|[ldapLdapVendor](#schemaldapldapvendor)|false|none||none| +|startTls|string|false|none||none| +|connectionUrl|string|false|none||none| +|usersDn|string|false|none||none| +|bindDn|string|false|none||none| +|bindCredential|string|false|none||none| +|userObjectClasses|string|false|none||none| +|usernameLdapAttribute|string|false|none||none| +|fullSyncPeriod|string|false|none||none| +|rdnLdapAttribute|string|false|none||none| +|uuidLdapAttribute|string|false|none||none| +|editMode|string|false|none||none| +|readTimeout|string|false|none||none| +|firstName|string|false|none||none| +|lastName|string|false|none||none| +|email|string|false|none||none| +|enabled|boolean|false|none||none| +|username|string|false|none||none| +|userLdapFilter|string|false|none||none| + +

ldapLdapVendor

+ + + + + + +```json +"other" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|other| +|*anonymous*|ad| + +

ldapListLdap

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "vendor": "string", + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|vendor|string|false|none||none| +|enabled|boolean|false|none||none| + +

ldapListLdapsResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "vendor": "string", + "enabled": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[ldapListLdap](#schemaldaplistldap)]|false|none||none| + +

ldapSyncLdapGroupsResponse

+ + + + + + +```json +{ + "ignored": true, + "added": 0, + "updated": 0, + "removed": 0, + "failed": 0, + "status": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ignored|boolean|false|none||none| +|added|integer(int32)|false|none||none| +|updated|integer(int32)|false|none||none| +|removed|integer(int32)|false|none||none| +|failed|integer(int32)|false|none||none| +|status|string|false|none||none| + +

ldapSyncUsersResponse

+ + + + + + +```json +{ + "ignored": true, + "added": 0, + "updated": 0, + "removed": 0, + "failed": 0, + "status": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ignored|boolean|false|none||none| +|added|integer(int32)|false|none||none| +|updated|integer(int32)|false|none||none| +|removed|integer(int32)|false|none||none| +|failed|integer(int32)|false|none||none| +|status|string|false|none||none| + +

ldapTestLdapAuthenticationRequest

+ + + + + + +```json +{ + "bindDn": "string", + "bindCredential": "string", + "connectionUrl": "string", + "connectionTimeout": "string", + "action": "string", + "startTls": "string", + "useTruststoreSpi": "string", + "componentId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|bindDn|string|false|none|DN of LDAP admin, which will be used by Keycloak to access LDAP server|none| +|bindCredential|string|false|none||Password of LDAP admin.| +|connectionUrl|string|false|none|Connection URL to your LDAP server|none| +|connectionTimeout|string|false|none|LDAP Connection Timeout in milliseconds: 选填|none| +|action|string|false|none|测试事件类型: 选填, testAuthentication|none| +|startTls|string|false|none|Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling. 选填|none| +|useTruststoreSpi|string|false|none|Specifies whether LDAP connection will use the truststore SPI with the truststore configured. +'Always' means that it will always use it. +'Never' means that it will not use it. +'Only for ldaps' means that it will use if your connection URL use ldaps. +选填|none| +|componentId|string|false|none|Ldap id: 选填, uuid. 如果 bind_credential 的值等于 "**********", 则此字段是必填参|none| + +

ldapTestLdapAuthenticationResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

ldapTestLdapConnectionRequest

+ + + + + + +```json +{ + "connectionUrl": "string", + "bindDn": "string", + "bindCredential": "string", + "connectionTimeout": "string", + "action": "string", + "startTls": "string", + "useTruststoreSpi": "string", + "componentId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|connectionUrl|string|false|none|Connection URL to your LDAP server|none| +|bindDn|string|false|none|DN of LDAP admin, which will be used by Keycloak to access LDAP server: 选填|none| +|bindCredential|string|false|none|Password of LDAP admin. 选填|none| +|connectionTimeout|string|false|none|LDAP Connection Timeout in milliseconds: 选填|none| +|action|string|false|none|测试事件类型: 选填, testConnection|none| +|startTls|string|false|none||Encrypts the connection to LDAP using STARTTLS, which will disable connection pooling.| +|useTruststoreSpi|string|false|none|Specifies whether LDAP connection will use the truststore SPI with the truststore configured. +'Always' means that it will always use it. +'Never' means that it will not use it. +'Only for ldaps' means that it will use if your connection URL use ldaps. +选填|none| +|componentId|string|false|none|Ldap id: 选填, uuid|none| + +

ldapTestLdapConnectionResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

ldapUpdateLdapGroupResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

ldapUpdateLdapResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

loginAuthenticateWithPasswordRequest

+ + + + + + +```json +{ + "username": "string", + "password": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|username|string|false|none||none| +|password|string|false|none||none| + +

loginAuthenticateWithPasswordResponse

+ + + + + + +```json +{ + "idToken": "string", + "refreshToken": "string", + "username": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|idToken|string|false|none||none| +|refreshToken|string|false|none||none| +|username|string|false|none||none| + +

loginCheckSessionLimitRequest

+ + + + + + +```json +{ + "username": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|username|string|false|none||none| + +

loginCheckSessionLimitResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

loginLoginGetResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

loginLoginPostRequest

+ + + + + + +```json +{ + "code": "string", + "state": "string", + "sessionState": "string", + "callbackUrl": "string", + "useSso": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|code|string|false|none||none| +|state|string|false|none||none| +|sessionState|string|false|none||none| +|callbackUrl|string|false|none||none| +|useSso|string|false|none||none| + +

loginLoginPostResponse

+ + + + + + +```json +{ + "idToken": "string", + "refreshToken": "string", + "username": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|idToken|string|false|none||none| +|refreshToken|string|false|none||none| +|username|string|false|none||none| + +

loginLogoutResponse

+ + + + + + +```json +{ + "externalLogoutUrl": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|externalLogoutUrl|string|false|none||none| + +

loginRefreshTokenRequest

+ + + + + + +```json +{ + "refreshToken": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|refreshToken|string|false|none||none| + +

loginRefreshTokenResponse

+ + + + + + +```json +{ + "idToken": "string", + "refreshToken": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|idToken|string|false|none||none| +|refreshToken|string|false|none||none| + +

loginpageGetLoginPageInfoResponse

+ + + + + + +```json +{ + "version": 0, + "platformName": "string", + "copyright": "string", + "tabName": "string", + "icon": "string", + "favicon": "string", + "background": "string", + "customBg": true, + "isVideo": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|version|integer(int32)|false|none||none| +|platformName|string|false|none||none| +|copyright|string|false|none||none| +|tabName|string|false|none||none| +|icon|string|false|none||none| +|favicon|string|false|none||none| +|background|string|false|none||none| +|customBg|boolean|false|none||none| +|isVideo|boolean|false|none||none| + +

loginpageGetLoginPageVersionResponse

+ + + + + + +```json +{ + "version": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|version|integer(int32)|false|none||none| + +

loginpageResetLoginPageInfoResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

loginpageUpdateLoginPageInfoRequest

+ + + + + + +```json +{ + "platformName": "string", + "copyright": "string", + "tabName": "string", + "icon": "string", + "favicon": "string", + "background": "string", + "isVideo": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|platformName|string|false|none||none| +|copyright|string|false|none||none| +|tabName|string|false|none||none| +|icon|string|false|none||none| +|favicon|string|false|none||none| +|background|string|false|none||none| +|isVideo|boolean|false|none||none| + +

loginpageUpdateLoginPageInfoResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

messageDeleteMessagesRequest

+ + + + + + +```json +{ + "ids": [ + 0 + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|ids|[integer]|false|none||none| + +

messageDeleteMessagesResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

messageGetMessageResponse

+ + + + + + +```json +{ + "message": { + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|message|[messageMessageInfo](#schemamessagemessageinfo)|false|none||none| + +

messageGetMessagesCountResponse

+ + + + + + +```json +{ + "total": 0, + "readTotal": 0, + "unreadTotal": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|total|integer(int32)|false|none||none| +|readTotal|integer(int32)|false|none||none| +|unreadTotal|integer(int32)|false|none||none| + +

messageGetSystemMessageResponse

+ + + + + + +```json +{ + "message": "string", + "show": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|message|string|false|none||none| +|show|boolean|false|none||none| + +

messageListMessagesResponse

+ + + + + + +```json +{ + "items": [ + { + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[messageMessageInfo](#schemamessagemessageinfo)]|false|none||none| +|pagination|[v1alpha1messagePagination](#schemav1alpha1messagepagination)|false|none||none| + +

messageMessageInfo

+ + + + + + +```json +{ + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|type|string|false|none||none| +|subject|string|false|none||none| +|message|string|false|none||none| +|read|[messageReadType](#schemamessagereadtype)|false|none||none| +|createdAt|string|false|none||none| + +

messageReadType

+ + + + + + +```json +"all" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|all| +|*anonymous*|read| +|*anonymous*|unread| + +

messageSetReadMessagesRequest

+ + + + + + +```json +{ + "all": true, + "ids": [ + 0 + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|all|boolean|false|none||none| +|ids|[integer]|false|none||none| + +

messageSetReadMessagesResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

messageToggleUnreadMessageResponse

+ + + + + + +```json +{ + "message": { + "id": 0, + "type": "string", + "subject": "string", + "message": "string", + "read": "all", + "createdAt": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|message|[messageMessageInfo](#schemamessagemessageinfo)|false|none||none| + +

oauthCreateOauth2Request

+ + + + + + +```json +{ + "providerType": "wechatwork", + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "agentId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|providerType|[v1alpha1oauthProviderType](#schemav1alpha1oauthprovidertype)|false|none||none| +|displayName|string|false|none||none| +|clientId|string|false|none||none| +|clientSecret|string|false|none||none| +|agentId|string|false|none||none| + +

oauthCreateOauth2Response

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

oauthDeleteOauth2Response

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

oauthGetOauth2RedirectDomainResponse

+ + + + + + +```json +{ + "redirectDomain": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|redirectDomain|string|false|none||none| + +

oauthGetOauth2Response

+ + + + + + +```json +{ + "providerType": "wechatwork", + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "agentId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|providerType|[v1alpha1oauthProviderType](#schemav1alpha1oauthprovidertype)|false|none||none| +|displayName|string|false|none||none| +|clientId|string|false|none||none| +|clientSecret|string|false|none||none| +|agentId|string|false|none||none| + +

oauthUpdateOauth2Request

+ + + + + + +```json +{ + "providerType": "wechatwork", + "displayName": "string", + "clientId": "string", + "clientSecret": "string", + "agentId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|providerType|[v1alpha1oauthProviderType](#schemav1alpha1oauthprovidertype)|false|none||none| +|displayName|string|false|none||none| +|clientId|string|false|none||none| +|clientSecret|string|false|none||none| +|agentId|string|false|none||none| + +

oauthUpdateOauth2Response

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

oidcGhippoClientConfigResponse

+ + + + + + +```json +{ + "clientId": "string", + "endpoint": "string", + "groupsClaim": "string", + "name": "string", + "scope": "string", + "userClaim": "string", + "clientSecret": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|clientId|string|false|none||none| +|endpoint|string|false|none||none| +|groupsClaim|string|false|none||none| +|name|string|false|none||none| +|scope|string|false|none||none| +|userClaim|string|false|none||none| +|clientSecret|string|false|none||none| + +

oidcOIDCLogoutResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

oidcOIDCTokenRequest

+ + + + + + +```json +{ + "clientId": "string", + "grantType": "string", + "clientSecret": "string", + "code": "string", + "redirectUri": "string", + "username": "string", + "password": "string", + "refreshToken": "string", + "scope": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|clientId|string|false|none||none| +|grantType|string|false|none||none| +|clientSecret|string|false|none||none| +|code|string|false|none|string response_type = 4 [(validate.rules).string.min_len = 1];|none| +|redirectUri|string|false|none||none| +|username|string|false|none||none| +|password|string|false|none||none| +|refreshToken|string|false|none||none| +|scope|string|false|none||none| + +

oidcOIDCTokenResponse

+ + + + + + +```json +{ + "accessToken": "string", + "idToken": "string", + "expiresIn": 0, + "refreshExpiresIn": 0, + "refreshToken": "string", + "tokenType": "string", + "notBeforePolicy": 0, + "sessionState": "string", + "scope": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|accessToken|string|false|none||none| +|idToken|string|false|none||none| +|expiresIn|integer(int32)|false|none||none| +|refreshExpiresIn|integer(int32)|false|none||none| +|refreshToken|string|false|none||none| +|tokenType|string|false|none||none| +|notBeforePolicy|integer(int32)|false|none||none| +|sessionState|string|false|none||none| +|scope|string|false|none||none| + +

oidcOIDCUserInfoResponse

+ + + + + + +```json +{ + "sub": "string", + "preferredUsername": "string", + "email": "string", + "locale": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|sub|string|false|none||none| +|preferredUsername|string|false|none||none| +|email|string|false|none||none| +|locale|string|false|none||none| + +

oidcRedirectFrontendLogoutResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

oidcWellKnownResponse

+ + + + + + +```json +{ + "issuer": "string", + "authorizationEndpoint": "string", + "tokenEndpoint": "string", + "jwksUri": "string", + "userinfoEndpoint": "string", + "introspectionEndpoint": "string", + "idTokenSigningAlgValuesSupported": [ + "string" + ], + "endSessionEndpoint": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|issuer|string|false|none||none| +|authorizationEndpoint|string|false|none||none| +|tokenEndpoint|string|false|none||none| +|jwksUri|string|false|none||none| +|userinfoEndpoint|string|false|none||none| +|introspectionEndpoint|string|false|none||none| +|idTokenSigningAlgValuesSupported|[string]|false|none||none| +|endSessionEndpoint|string|false|none||none| + +

productnavProductMenu

+ + + + + + +```json +{ + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + { + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + { + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|url|string|false|none||none| +|iconUrl|string|false|none||none| +|target|string|false|none||none| +|menus|[[productnavProductMenu](#schemaproductnavproductmenu)]|false|none||none| + +

productnavProductNavCategory

+ + + + + + +```json +{ + "name": "string", + "menus": [ + { + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + { + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|menus|[[productnavProductMenu](#schemaproductnavproductmenu)]|false|none||none| + +

productnavProductNavResponse

+ + + + + + +```json +{ + "categories": [ + { + "name": "string", + "menus": [ + { + "name": "string", + "url": "string", + "iconUrl": "string", + "target": "string", + "menus": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|categories|[[productnavProductNavCategory](#schemaproductnavproductnavcategory)]|false|none||none| + +

publishPublishMessageRequest

+ + + + + + +```json +{ + "userId": "string", + "type": "string", + "subject": "string", + "message": "string", + "messageUid": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|userId|string|false|none||none| +|type|string|false|none||none| +|subject|string|false|none||none| +|message|string|false|none||none| +|messageUid|string|false|none||none| + +

publishPublishMessageResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

roleAuthScope

+ + + + + + +```json +"platform" + +``` + +- platform: unknown_auth_scope = 0; + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|- platform: unknown_auth_scope = 0;|string|false|none|- platform: unknown_auth_scope = 0;|none| + +#### Enum + +|Name|Value| +|---|---| +|- platform: unknown_auth_scope = 0;|platform| +|- platform: unknown_auth_scope = 0;|folder| +|- platform: unknown_auth_scope = 0;|workspace| + +

roleAuthScopeAllPermissions

+ + + + + + +```json +{ + "authScope": "platform", + "categoryPerms": [ + { + "category": { + "name": "string", + "localizedName": "string" + }, + "resourcePerms": [ + { + "resourceType": { + "name": null, + "localizedName": null + }, + "actions": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|authScope|[roleAuthScope](#schemaroleauthscope)|false|none||none| +|categoryPerms|[[roleCategoryAllPermissions](#schemarolecategoryallpermissions)]|false|none||none| + +

roleCategory

+ + + + + + +```json +{ + "name": "string", + "localizedName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|localizedName|string|false|none||none| + +

roleCategoryAllPermissions

+ + + + + + +```json +{ + "category": { + "name": "string", + "localizedName": "string" + }, + "resourcePerms": [ + { + "resourceType": { + "name": "string", + "localizedName": "string" + }, + "actions": [ + { + "action": { + "name": null, + "localizedName": null, + "tips": null + }, + "dependPerms": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|category|[roleCategory](#schemarolecategory)|false|none||none| +|resourcePerms|[[roleResourceAllPermissions](#schemaroleresourceallpermissions)]|false|none||none| + +

roleCategoryPermissions

+ + + + + + +```json +{ + "category": { + "name": "string", + "localizedName": "string" + }, + "resourcePerms": [ + { + "resourceType": { + "name": "string", + "localizedName": "string" + }, + "actions": [ + { + "name": "string", + "localizedName": "string", + "tips": [ + "string" + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|category|[roleCategory](#schemarolecategory)|false|none||none| +|resourcePerms|[[roleResourcePermissions](#schemaroleresourcepermissions)]|false|none||none| + +

roleCheckRoleNameResponse

+ + + + + + +```json +{ + "exist": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|exist|boolean|false|none||none| + +

roleCreateRoleRequest

+ + + + + + +```json +{ + "name": "string", + "description": "string", + "scope": "platform", + "perms": [ + { + "action": "string", + "resourceType": "string", + "gproduct": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|description|string|false|none|string gproduct = 2 [(validate.rules).string = {min_len: 1, max_len: 63}]; +globalRoleType type = 3;|none| +|scope|[roleAuthScope](#schemaroleauthscope)|false|none||none| +|perms|[[rolePermission](#schemarolepermission)]|false|none||none| + +

roleCreateRoleResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

roleDeleteRoleResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

roleGProductAllPermissions

+ + + + + + +```json +{ + "gproduct": { + "gproduct": "string", + "localizedName": "string" + }, + "authscopePerms": [ + { + "authScope": "platform", + "categoryPerms": [ + { + "category": { + "name": null, + "localizedName": null + }, + "resourcePerms": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|gproduct|[v1alpha1roleGProduct](#schemav1alpha1rolegproduct)|false|none||none| +|authscopePerms|[[roleAuthScopeAllPermissions](#schemaroleauthscopeallpermissions)]|false|none|map gproduct = 1;|none| + +

roleGProductPermissions

+ + + + + + +```json +{ + "gproduct": { + "gproduct": "string", + "localizedName": "string" + }, + "categoryPerms": [ + { + "category": { + "name": "string", + "localizedName": "string" + }, + "resourcePerms": [ + { + "resourceType": { + "name": null, + "localizedName": null + }, + "actions": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|gproduct|[v1alpha1roleGProduct](#schemav1alpha1rolegproduct)|false|none||none| +|categoryPerms|[[roleCategoryPermissions](#schemarolecategorypermissions)]|false|none||none| + +

roleGetRoleMemberCountResponse

+ + + + + + +```json +{ + "userCount": 0, + "groupCount": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|userCount|integer(int32)|false|none||none| +|groupCount|integer(int32)|false|none||none| + +

roleGetRoleResponse

+ + + + + + +```json +{ + "name": "string", + "type": "system", + "description": "string", + "scope": "platform", + "createdAt": "string", + "updatedAt": "string", + "gproductPerms": [ + { + "gproduct": { + "gproduct": "string", + "localizedName": "string" + }, + "categoryPerms": [ + { + "category": { + "name": null, + "localizedName": null + }, + "resourcePerms": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|[roleglobalRoleType](#schemaroleglobalroletype)|false|none||none| +|description|string|false|none||none| +|scope|[roleAuthScope](#schemaroleauthscope)|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| +|gproductPerms|[[roleGProductPermissions](#schemarolegproductpermissions)]|false|none||none| + +

roleListAllPermissionsResponse

+ + + + + + +```json +{ + "gproductPerms": [ + { + "gproduct": { + "gproduct": "string", + "localizedName": "string" + }, + "authscopePerms": [ + { + "authScope": "platform", + "categoryPerms": [ + {} + ] + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|gproductPerms|[[roleGProductAllPermissions](#schemarolegproductallpermissions)]|false|none||none| + +

roleListFolderRoleNamesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "authScope": "platform", + "description": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[roleRoleName](#schemarolerolename)]|false|none||none| +|pagination|[v1alpha1rolePagination](#schemav1alpha1rolepagination)|false|none||none| + +

roleListMembersByPlatformRoleResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "type": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[roleMember](#schemarolemember)]|false|none||none| +|pagination|[v1alpha1rolePagination](#schemav1alpha1rolepagination)|false|none||none| + +

roleListMembersFoldersByFolderRoleResponse

+ + + + + + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "folderId": 0, + "folderAlias": "string", + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[roleMemberFolder](#schemarolememberfolder)]|false|none||none| +|pagination|[v1alpha1rolePagination](#schemav1alpha1rolepagination)|false|none||none| + +

roleListMembersWorkspacesByWorkspaceRoleResponse

+ + + + + + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "workspaceId": 0, + "workspaceAlias": "string", + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[roleMemberWorkspace](#schemarolememberworkspace)]|false|none||none| +|pagination|[v1alpha1rolePagination](#schemav1alpha1rolepagination)|false|none||none| + +

roleListRolesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "type": "system", + "description": "string", + "scope": "platform", + "createdAt": "string", + "updatedAt": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[v1alpha1roleRoleInfo](#schemav1alpha1roleroleinfo)]|false|none||none| +|pagination|[v1alpha1rolePagination](#schemav1alpha1rolepagination)|false|none||none| + +

roleListWorkspaceRoleNamesResponse

+ + + + + + +```json +{ + "items": [ + { + "name": "string", + "authScope": "platform", + "description": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[roleRoleName](#schemarolerolename)]|false|none||none| +|pagination|[v1alpha1rolePagination](#schemav1alpha1rolepagination)|false|none||none| + +

roleMember

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "type": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|type|string|false|none||none| + +

roleMemberFolder

+ + + + + + +```json +{ + "memberName": "string", + "memberType": "string", + "folderId": 0, + "folderAlias": "string", + "memberId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|memberName|string|false|none||none| +|memberType|string|false|none||none| +|folderId|integer(int32)|false|none||none| +|folderAlias|string|false|none||none| +|memberId|string|false|none||none| + +

roleMemberWorkspace

+ + + + + + +```json +{ + "memberName": "string", + "memberType": "string", + "workspaceId": 0, + "workspaceAlias": "string", + "memberId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|memberName|string|false|none||none| +|memberType|string|false|none||none| +|workspaceId|integer(int32)|false|none||none| +|workspaceAlias|string|false|none||none| +|memberId|string|false|none||none| + +

rolePermission

+ + + + + + +```json +{ + "action": "string", + "resourceType": "string", + "gproduct": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|action|string|false|none||none| +|resourceType|string|false|none||none| +|gproduct|string|false|none||none| + +

roleQueryAuthScope

+ + + + + + +```json +"query_all_auth_scope" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|query_all_auth_scope| +|*anonymous*|query_platform| +|*anonymous*|query_folder| +|*anonymous*|query_workspace| + +

roleQueryRoleType

+ + + + + + +```json +"query_all_role_type" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|query_all_role_type| +|*anonymous*|query_system| +|*anonymous*|query_custom| + +

roleResourceAction

+ + + + + + +```json +{ + "name": "string", + "localizedName": "string", + "tips": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|localizedName|string|false|none||none| +|tips|[string]|false|none||none| + +

roleResourceActionWithDependency

+ + + + + + +```json +{ + "action": { + "name": "string", + "localizedName": "string", + "tips": [ + "string" + ] + }, + "dependPerms": [ + { + "action": "string", + "resourceType": "string", + "gproduct": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|action|[roleResourceAction](#schemaroleresourceaction)|false|none||none| +|dependPerms|[[rolePermission](#schemarolepermission)]|false|none||none| + +

roleResourceAllPermissions

+ + + + + + +```json +{ + "resourceType": { + "name": "string", + "localizedName": "string" + }, + "actions": [ + { + "action": { + "name": "string", + "localizedName": "string", + "tips": [ + "string" + ] + }, + "dependPerms": [ + { + "action": "string", + "resourceType": "string", + "gproduct": "string" + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|resourceType|[v1alpha1roleResourceType](#schemav1alpha1roleresourcetype)|false|none||none| +|actions|[[roleResourceActionWithDependency](#schemaroleresourceactionwithdependency)]|false|none||none| + +

roleResourcePermissions

+ + + + + + +```json +{ + "resourceType": { + "name": "string", + "localizedName": "string" + }, + "actions": [ + { + "name": "string", + "localizedName": "string", + "tips": [ + "string" + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|resourceType|[v1alpha1roleResourceType](#schemav1alpha1roleresourcetype)|false|none||none| +|actions|[[roleResourceAction](#schemaroleresourceaction)]|false|none||none| + +

roleRoleName

+ + + + + + +```json +{ + "name": "string", + "authScope": "platform", + "description": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|authScope|[roleAuthScope](#schemaroleauthscope)|false|none||none| +|description|string|false|none||none| + +

roleUpdateRoleResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

roleglobalRoleType

+ + + + + + +```json +"system" + +``` + +TODO: 改为 RoleType + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|TODO: 改为 RoleType|string|false|none|TODO: 改为 RoleType|none| + +#### Enum + +|Name|Value| +|---|---| +|TODO: 改为 RoleType|system| +|TODO: 改为 RoleType|custom| + +

securitypolicyGetAccountLockoutPolicyResponse

+ + + + + + +```json +{ + "enabled": true, + "maxLoginFailures": 0, + "maxFailuresWaitSeconds": 0, + "failureResetSeconds": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|maxLoginFailures|integer(int32)|false|none||none| +|maxFailuresWaitSeconds|integer(int32)|false|none||none| +|failureResetSeconds|integer(int32)|false|none||none| + +

securitypolicyGetLogoutPolicyResponse

+ + + + + + +```json +{ + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| + +

securitypolicyGetMFAResponse

+ + + + + + +```json +{ + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| + +

securitypolicyGetPasswordPolicyResponse

+ + + + + + +```json +{ + "items": [ + { + "type": "MinimumLengthLabel", + "value": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[securitypolicyPasswordPolicyInfo](#schemasecuritypolicypasswordpolicyinfo)]|false|none||none| + +

securitypolicyGetSessionTimeoutResponse

+ + + + + + +```json +{ + "timeoutSeconds": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|timeoutSeconds|integer(int32)|false|none||none| + +

securitypolicyGetSystemSessionLimitResponse

+ + + + + + +```json +{ + "enabled": true, + "number": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|number|integer(int32)|false|none||none| + +

securitypolicyGetTimeSessionLimitResponse

+ + + + + + +```json +{ + "enabled": true, + "start": "string", + "end": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|start|string|false|none||none| +|end|string|false|none||none| + +

securitypolicyGetUserSessionLimitResponse

+ + + + + + +```json +{ + "enabled": true, + "number": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|number|integer(int32)|false|none||none| + +

securitypolicyPasswordPolicyInfo

+ + + + + + +```json +{ + "type": "MinimumLengthLabel", + "value": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|[securitypolicyPasswordPolicyType](#schemasecuritypolicypasswordpolicytype)|false|none||none| +|value|string|false|none||none| + +

securitypolicyPasswordPolicyType

+ + + + + + +```json +"MinimumLengthLabel" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|MinimumLengthLabel| +|*anonymous*|NotRecentlyUsedLabel| +|*anonymous*|NotUsernameLabel| +|*anonymous*|NotEmailLabel| +|*anonymous*|DigitsLabel| +|*anonymous*|UppercaseCharactersLabel| +|*anonymous*|LowercaseCharactersLabel| +|*anonymous*|SpecialCharactersLabel| +|*anonymous*|ExpirePasswordLabel| + +

securitypolicySetAccountLockoutPolicyRequest

+ + + + + + +```json +{ + "enabled": true, + "maxLoginFailures": 0, + "maxFailuresWaitSeconds": 0, + "failureResetSeconds": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|maxLoginFailures|integer(int32)|false|none|failures count >= 0|none| +|maxFailuresWaitSeconds|integer(int32)|false|none|Lock time >= 60s|none| +|failureResetSeconds|integer(int32)|false|none|reset time >= 60s|none| + +

securitypolicySetAccountLockoutPolicyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetLogoutPolicyRequest

+ + + + + + +```json +{ + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| + +

securitypolicySetLogoutPolicyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetMFARequest

+ + + + + + +```json +{ + "enabled": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| + +

securitypolicySetMFAResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetPasswordPolicyRequest

+ + + + + + +```json +{ + "items": [ + { + "type": "MinimumLengthLabel", + "value": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[securitypolicyPasswordPolicyInfo](#schemasecuritypolicypasswordpolicyinfo)]|false|none||none| + +

securitypolicySetPasswordPolicyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetSessionTimeoutRequest

+ + + + + + +```json +{ + "timeoutSeconds": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|timeoutSeconds|integer(int32)|false|none|timeout > 3600s|none| + +

securitypolicySetSessionTimeoutResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetSystemSessionLimitRequest

+ + + + + + +```json +{ + "enabled": true, + "number": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|number|integer(int32)|false|none||none| + +

securitypolicySetSystemSessionLimitResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetTimeSessionLimitRequest

+ + + + + + +```json +{ + "enabled": true, + "start": "string", + "end": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|start|string|false|none||none| +|end|string|false|none||none| + +

securitypolicySetTimeSessionLimitResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

securitypolicySetUserSessionLimitRequest

+ + + + + + +```json +{ + "enabled": true, + "number": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|enabled|boolean|false|none||none| +|number|integer(int32)|false|none||none| + +

securitypolicySetUserSessionLimitResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

smtpsettingGetSmtpServerResponse

+ + + + + + +```json +{ + "host": "string", + "port": 0, + "ssl": true, + "starttls": true, + "from": "string", + "user": "string", + "password": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|host|string|false|none||none| +|port|integer(int32)|false|none||none| +|ssl|boolean|false|none||none| +|starttls|boolean|false|none||none| +|from|string|false|none||none| +|user|string|false|none||none| +|password|string|false|none||none| + +

smtpsettingSetSmtpServerRequest

+ + + + + + +```json +{ + "host": "string", + "port": 0, + "ssl": true, + "starttls": true, + "from": "string", + "user": "string", + "password": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|host|string|false|none||none| +|port|integer(int32)|false|none||none| +|ssl|boolean|false|none||none| +|starttls|boolean|false|none||none| +|from|string|false|none||none| +|user|string|false|none||none| +|password|string|false|none||none| + +

smtpsettingSetSmtpServerResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

smtpsettingSmtpConnTestRequest

+ + + + + + +```json +{ + "host": "string", + "port": 0, + "ssl": true, + "starttls": true, + "from": "string", + "to": "string", + "user": "string", + "password": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|host|string|false|none||none| +|port|integer(int32)|false|none||none| +|ssl|boolean|false|none||none| +|starttls|boolean|false|none||none| +|from|string|false|none||none| +|to|string|false|none||none| +|user|string|false|none||none| +|password|string|false|none||none| + +

smtpsettingSmtpConnTestResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

themeGetFooterThemeConfigResponse

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "css": "string", + "createdAt": "string", + "updatedAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|css|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| + +

themeGetLoginThemeConfigResponse

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "css": "string", + "createdAt": "string", + "updatedAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|css|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| + +

themeGetThemeConfigResponse

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "css": "string", + "createdAt": "string", + "updatedAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|css|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| + +

themeResetFooterThemeConfigResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

themeResetLoginThemeConfigResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

themeResetThemeConfigResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

themeSetFooterThemeConfigRequest

+ + + + + + +```json +{ + "css": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|css|string|false|none||none| + +

themeSetFooterThemeConfigResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

themeSetLoginThemeConfigRequest

+ + + + + + +```json +{ + "css": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|css|string|false|none||none| + +

themeSetLoginThemeConfigResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

themeSetThemeConfigRequest

+ + + + + + +```json +{ + "css": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|css|string|false|none||none| + +

themeSetThemeConfigResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

topnavResetTopNavResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

topnavSetTopNavRequest

+ + + + + + +```json +{ + "icon": "string", + "favicon": "string", + "tabName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|icon|string|false|none||none| +|favicon|string|false|none||none| +|tabName|string|false|none||none| + +

topnavSetTopNavResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

topnavTopNavResponse

+ + + + + + +```json +{ + "icon": "string", + "favicon": "string", + "tabName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|icon|string|false|none||none| +|favicon|string|false|none||none| +|tabName|string|false|none||none| + +

userCheckUserEmailResponse

+ + + + + + +```json +{ + "existed": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|existed|boolean|false|none||none| + +

userCheckUserResponse

+ + + + + + +```json +{ + "existed": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|existed|boolean|false|none||none| + +

userCreateUserAccessTokenResponse

+ + + + + + +```json +{ + "id": "string", + "token": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|token|string|false|none||none| + +

userCreateUserRequest

+ + + + + + +```json +{ + "name": "string", + "password": "string", + "description": "string", + "temporary": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|password|string|false|none||none| +|description|string|false|none||none| +|temporary|boolean|false|none||none| + +

userCreateUserResponse

+ + + + + + +```json +{ + "id": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| + +

userCreateUserWithoutPasswordRequest

+ + + + + + +```json +{ + "name": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| + +

userCreateUserWithoutPasswordResponse

+ + + + + + +```json +{ + "id": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| + +

userDeleteUserAccessTokenResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

userDeleteUserResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

userListUserAccessTokensResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[v1alpha1userAccessToken](#schemav1alpha1useraccesstoken)]|false|none||none| + +

userListUserGroupsResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "name": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1userPagination](#schemav1alpha1userpagination)|false|none||none| +|items|[[v1alpha1userGroup](#schemav1alpha1usergroup)]|false|none||none| + +

userListUserRolesResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "authorizedCount": 0, + "items": [ + { + "name": "string", + "type": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string", + "authorized": true + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1userPagination](#schemav1alpha1userpagination)|false|none||none| +|authorizedCount|integer(int64)|false|none||none| +|items|[[v1alpha1userRoleInfo](#schemav1alpha1userroleinfo)]|false|none||none| + +

userListUserSubjectResponse

+ + + + + + +```json +{ + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + }, + "items": [ + { + "id": "string", + "type": "string", + "roleName": "string", + "subjectName": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|pagination|[v1alpha1userPagination](#schemav1alpha1userpagination)|false|none||none| +|items|[[userUserSubject](#schemauserusersubject)]|false|none||none| + +

userListUsersResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "createdAt": "string", + "updatedAt": "string", + "lastLoginAt": "string", + "canAuthorize": true + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[v1alpha1userGetUserResponse](#schemav1alpha1usergetuserresponse)]|false|none||none| +|pagination|[v1alpha1userPagination](#schemav1alpha1userpagination)|false|none||none| + +

userResetUserMFAResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

userSetUserPasswordResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

userUpdateUserResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

userUpdateUserRolesResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

userUserSubject

+ + + + + + +```json +{ + "id": "string", + "type": "string", + "roleName": "string", + "subjectName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|type|string|false|none||none| +|roleName|string|false|none||none| +|subjectName|string|false|none||none| + +

userVerifyUserSSHPublicKeyResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

v1alpha1aboutPagination

+ + + + + + +```json +{ + "total": 0, + "page": 0, + "pageSize": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|total|integer(int32)|false|none||none| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| + +

v1alpha1currentuserAccessToken

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|updatedAt|string|false|none||none| +|createdAt|string|false|none||none| +|expiredAt|string|false|none||none| + +

v1alpha1currentuserGetUserResponse

+ + + + + + +```json +{ + "uid": "string", + "username": "string", + "email": "string", + "locale": "string", + "source": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|uid|string|false|none||none| +|username|string|false|none||none| +|email|string|false|none||none| +|locale|string|false|none||none| +|source|string|false|none||none| + +

v1alpha1gproductGProduct

+ + + + + + +```json +{ + "id": "string", + "title": "string", + "url": "string", + "uiAssetsUrl": "string", + "needImportLicense": true, + "needUpdateExpiredLicense": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|title|string|false|none||none| +|url|string|false|none||none| +|uiAssetsUrl|string|false|none||none| +|needImportLicense|boolean|false|none||none| +|needUpdateExpiredLicense|boolean|false|none||none| + +

v1alpha1groupPagination

+ + + + + + +```json +{ + "page": 0, + "pageSize": 0, + "total": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| +|total|integer(int32)|false|none||none| + +

v1alpha1groupRoleInfo

+ + + + + + +```json +{ + "name": "string", + "type": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string", + "authorized": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|string|false|none||none| +|description|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| +|authorized|boolean|false|none||none| + +

v1alpha1groupUser

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|email|string|false|none||none| +|description|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| + +

v1alpha1idpProviderType

+ + + + + + +```json +"oidc" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|oidc| + +

v1alpha1messagePagination

+ + + + + + +```json +{ + "total": 0, + "page": 0, + "pageSize": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|total|integer(int32)|false|none||none| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| + +

v1alpha1oauthProviderType

+ + + + + + +```json +"wechatwork" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|wechatwork| + +

v1alpha1roleGProduct

+ + + + + + +```json +{ + "gproduct": "string", + "localizedName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|gproduct|string|false|none||none| +|localizedName|string|false|none||none| + +

v1alpha1rolePagination

+ + + + + + +```json +{ + "total": 0, + "page": 0, + "pageSize": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|total|integer(int32)|false|none||none| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| + +

v1alpha1roleResourceType

+ + + + + + +```json +{ + "name": "string", + "localizedName": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|localizedName|string|false|none||none| + +

v1alpha1roleRoleInfo

+ + + + + + +```json +{ + "name": "string", + "type": "system", + "description": "string", + "scope": "platform", + "createdAt": "string", + "updatedAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|[roleglobalRoleType](#schemaroleglobalroletype)|false|none||none| +|description|string|false|none||none| +|scope|[roleAuthScope](#schemaroleauthscope)|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| + +

v1alpha1userAccessToken

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "updatedAt": "string", + "createdAt": "string", + "expiredAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|updatedAt|string|false|none||none| +|createdAt|string|false|none||none| +|expiredAt|string|false|none||none| + +

v1alpha1userGetUserResponse

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "createdAt": "string", + "updatedAt": "string", + "lastLoginAt": "string", + "canAuthorize": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|email|string|false|none||none| +|description|string|false|none||none| +|firstname|string|false|none||none| +|lastname|string|false|none||none| +|source|string|false|none||none| +|enabled|boolean|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| +|lastLoginAt|string|false|none||none| +|canAuthorize|boolean|false|none||none| + +

v1alpha1userGroup

+ + + + + + +```json +{ + "id": "string", + "name": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| + +

v1alpha1userPagination

+ + + + + + +```json +{ + "page": 0, + "pageSize": 0, + "total": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| +|total|integer(int32)|false|none||none| + +

v1alpha1userRoleInfo

+ + + + + + +```json +{ + "name": "string", + "type": "string", + "description": "string", + "createdAt": "string", + "updatedAt": "string", + "authorized": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|type|string|false|none||none| +|description|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| +|authorized|boolean|false|none||none| + +

v1alpha1webhookPagination

+ + + + + + +```json +{ + "page": 0, + "pageSize": 0, + "total": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| +|total|integer(int32)|false|none||none| + +

v1alpha1webhookResourceType

+ + + + + + +```json +"resource_type_user" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|resource_type_user| + +

v1alpha1webhookStatus

+ + + + + + +```json +"all" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|all| +|*anonymous*|successful| +|*anonymous*|failed| + +

v1alpha1workspaceGroup

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true, + "authorized": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|userCount|integer(int64)|false|none||none| +|description|string|false|none||none| +|createdAt|string|false|none||none| +|canAuthorize|boolean|false|none||none| +|authorized|boolean|false|none||none| + +

v1alpha1workspacePagination

+ + + + + + +```json +{ + "total": 0, + "page": 0, + "pageSize": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|total|integer(int32)|false|none||none| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| + +

v1alpha1workspaceUser

+ + + + + + +```json +{ + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "canAuthorize": true, + "authorized": true +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|string|false|none||none| +|name|string|false|none||none| +|email|string|false|none||none| +|description|string|false|none||none| +|firstname|string|false|none||none| +|lastname|string|false|none||none| +|source|string|false|none||none| +|enabled|boolean|false|none||none| +|canAuthorize|boolean|false|none||none| +|authorized|boolean|false|none||none| + +

v1alpha3auditPagination

+ + + + + + +```json +{ + "total": 0, + "page": 0, + "pageSize": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|total|integer(int32)|false|none||none| +|page|integer(int32)|false|none||none| +|pageSize|integer(int32)|false|none||none| + +

v1alpha3auditSearchType

+ + + + + + +```json +"fuzzy" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|fuzzy| +|*anonymous*|exact| + +

v1alpha3auditStatusType

+ + + + + + +```json +"all" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|all| +|*anonymous*|succeeded| +|*anonymous*|failed| + +

webhookAction

+ + + + + + +```json +"action_create" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|action_create| +|*anonymous*|action_update| +|*anonymous*|action_delete| +|*anonymous*|action_login| +|*anonymous*|action_logout| + +

webhookCreateWebhookRequest

+ + + + + + +```json +{ + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||none| +|clientId|string|false|none||none| +|resourceType|[v1alpha1webhookResourceType](#schemav1alpha1webhookresourcetype)|false|none||none| +|action|[webhookAction](#schemawebhookaction)|false|none||none| +|url|string|false|none||none| +|method|[webhookMethod](#schemawebhookmethod)|false|none||none| +|headers|string|false|none||none| +|requestParameter|string|false|none||none| + +

webhookCreateWebhookResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

webhookDeleteWebhookResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

webhookGetWebhookRecordResponse

+ + + + + + +```json +{ + "webhookRecordInfo": { + "id": 0, + "clientId": "string", + "webhookId": 0, + "webhookName": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "eventTime": "string", + "eventData": "string", + "statusCode": 0, + "status": "response_unknown", + "requestedAt": "string", + "request": "string", + "respondedAt": "string", + "response": "string", + "errMessage": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|webhookRecordInfo|[webhookWebhookRecordInfo](#schemawebhookwebhookrecordinfo)|false|none||none| + +

webhookGetWebhookResponse

+ + + + + + +```json +{ + "webhookInfo": { + "id": 0, + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string", + "createdAt": "string", + "updatedAt": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|webhookInfo|[webhookWebhookInfo](#schemawebhookwebhookinfo)|false|none||none| + +

webhookListWebhookRecordsByClientIdResponse

+ + + + + + +```json +{ + "items": [ + { + "id": 0, + "clientId": "string", + "webhookId": 0, + "webhookName": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "eventTime": "string", + "eventData": "string", + "statusCode": 0, + "status": "response_unknown", + "requestedAt": "string", + "request": "string", + "respondedAt": "string", + "response": "string", + "errMessage": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[webhookWebhookRecordInfo](#schemawebhookwebhookrecordinfo)]|false|none||none| +|pagination|[v1alpha1webhookPagination](#schemav1alpha1webhookpagination)|false|none||none| + +

webhookListWebhooksByClientIdResponse

+ + + + + + +```json +{ + "items": [ + { + "id": 0, + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string", + "createdAt": "string", + "updatedAt": "string" + } + ], + "pagination": { + "page": 0, + "pageSize": 0, + "total": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[webhookWebhookInfo](#schemawebhookwebhookinfo)]|false|none||none| +|pagination|[v1alpha1webhookPagination](#schemav1alpha1webhookpagination)|false|none||none| + +

webhookMethod

+ + + + + + +```json +"method_get" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|method_get| +|*anonymous*|method_post| +|*anonymous*|method_put| +|*anonymous*|method_delete| +|*anonymous*|method_patch| + +

webhookStatusResponse

+ + + + + + +```json +"response_unknown" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|response_unknown| +|*anonymous*|response_successful| +|*anonymous*|response_failed| + +

webhookUpdateWebhookResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

webhookWebhookInfo

+ + + + + + +```json +{ + "id": 0, + "name": "string", + "clientId": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "headers": "string", + "requestParameter": "string", + "createdAt": "string", + "updatedAt": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|name|string|false|none||none| +|clientId|string|false|none||none| +|resourceType|[v1alpha1webhookResourceType](#schemav1alpha1webhookresourcetype)|false|none||none| +|action|[webhookAction](#schemawebhookaction)|false|none||none| +|url|string|false|none||none| +|method|[webhookMethod](#schemawebhookmethod)|false|none||none| +|headers|string|false|none||none| +|requestParameter|string|false|none||none| +|createdAt|string|false|none||none| +|updatedAt|string|false|none||none| + +

webhookWebhookRecordInfo

+ + + + + + +```json +{ + "id": 0, + "clientId": "string", + "webhookId": 0, + "webhookName": "string", + "resourceType": "resource_type_user", + "action": "action_create", + "url": "string", + "method": "method_get", + "eventTime": "string", + "eventData": "string", + "statusCode": 0, + "status": "response_unknown", + "requestedAt": "string", + "request": "string", + "respondedAt": "string", + "response": "string", + "errMessage": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|clientId|string|false|none||none| +|webhookId|integer(int32)|false|none||none| +|webhookName|string|false|none||none| +|resourceType|[v1alpha1webhookResourceType](#schemav1alpha1webhookresourcetype)|false|none||none| +|action|[webhookAction](#schemawebhookaction)|false|none||none| +|url|string|false|none||none| +|method|[webhookMethod](#schemawebhookmethod)|false|none||none| +|eventTime|string|false|none||none| +|eventData|string|false|none||none| +|statusCode|integer(int32)|false|none||none| +|status|[webhookStatusResponse](#schemawebhookstatusresponse)|false|none||none| +|requestedAt|string|false|none||none| +|request|string|false|none||none| +|respondedAt|string|false|none||none| +|response|string|false|none||none| +|errMessage|string|false|none||none| + +

workspaceAuthorizeResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceBindExclusiveResourceToWorkspaceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceBindSharedResourceAndSetQuotaHardToWorkspaceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceBindSharedResourceToWorkspaceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceClusterStatus

+ + + + + + +```json +"StatusUnknown" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|StatusUnknown| +|*anonymous*|StatusRunning| +|*anonymous*|StatusNotRunning| + +

workspaceCreateFolderRequest

+ + + + + + +```json +{ + "name": "string", + "alias": "string", + "parentFolderId": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|name|string|false|none||Deprecated: Do not use.| +|alias|string|false|none||none| +|parentFolderId|integer(int32)|false|none||none| + +

workspaceCreateFolderResponse

+ + + + + + +```json +{ + "folderId": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|folderId|integer(int32)|false|none||none| + +

workspaceCreateWorkspaceRequest

+ + + + + + +```json +{ + "alias": "string", + "parentFolderId": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|alias|string|false|none|string name = 1 [(validate.rules).string.max_len = 64];|none| +|parentFolderId|integer(int32)|false|none||none| + +

workspaceCreateWorkspaceResponse

+ + + + + + +```json +{ + "workspaceId": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|workspaceId|integer(int32)|false|none||none| + +

workspaceDeauthorizeResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceDeleteFolderResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceDeleteWorkspaceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceFolderInfo

+ + + + + + +```json +{ + "id": 0, + "name": "string", + "alias": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|name|string|false|none||Deprecated: Do not use.| +|alias|string|false|none||none| + +

workspaceFolderListGroupsResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "userCount": 0, + "description": "string", + "createdAt": "string", + "canAuthorize": true, + "authorized": true + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[v1alpha1workspaceGroup](#schemav1alpha1workspacegroup)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceFolderListPermissionsResponse

+ + + + + + +```json +{ + "permissions": [ + "Unknown" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|permissions|[[workspaceFolderPermission](#schemaworkspacefolderpermission)]|false|none||none| + +

workspaceFolderListUsersResponse

+ + + + + + +```json +{ + "items": [ + { + "id": "string", + "name": "string", + "email": "string", + "description": "string", + "firstname": "string", + "lastname": "string", + "source": "string", + "enabled": true, + "canAuthorize": true, + "authorized": true + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[v1alpha1workspaceUser](#schemav1alpha1workspaceuser)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceFolderPermission

+ + + + + + +```json +"Unknown" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|Unknown| +|*anonymous*|CreateFolder| +|*anonymous*|UpdateFolder| +|*anonymous*|GetFolder| +|*anonymous*|DeleteFolder| +|*anonymous*|AuthorizeFolder| +|*anonymous*|CreateWorkspace| +|*anonymous*|UpdateWorkspace| +|*anonymous*|GetWorkspace| +|*anonymous*|DeleteWorkspace| +|*anonymous*|AuthorizeWorkspace| +|*anonymous*|ResourceBindingWorkspace| +|*anonymous*|UpdateResourceQuotaWorkspace| + +

workspaceFolderTree

+ + + + + + +```json +{ + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + { + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + { + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + {} + ], + "permissions": [ + "[" + ], + "resourceKind": [ + "[" + ] + } + ], + "permissions": [ + "Unknown" + ], + "resourceKind": [ + "resource_group" + ] + } + ], + "permissions": [ + "Unknown" + ], + "resourceKind": [ + "resource_group" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|name|string|false|none||none| +|alias|string|false|none||none| +|isWorkspace|boolean|false|none||none| +|parentId|integer(int32)|false|none||none| +|children|[[workspaceFolderTree](#schemaworkspacefoldertree)]|false|none||none| +|permissions|[[workspaceFolderPermission](#schemaworkspacefolderpermission)]|false|none||none| +|resourceKind|[[workspaceWorkspaceResourceKindEnum](#schemaworkspaceworkspaceresourcekindenum)]|false|none||none| + +

workspaceGetFolderResponse

+ + + + + + +```json +{ + "folder": { + "id": 0, + "name": "string", + "alias": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|folder|[workspaceFolderInfo](#schemaworkspacefolderinfo)|false|none||none| + +

workspaceGetWorkspaceResponse

+ + + + + + +```json +{ + "workspace": { + "id": 0, + "name": "string", + "alias": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|workspace|[workspaceWorkspaceInfo](#schemaworkspaceworkspaceinfo)|false|none||none| + +

workspaceGetWorkspaceSharedResourceQuotaResponse

+ + + + + + +```json +{ + "setting": { + "property1": "string", + "property2": "string" + }, + "allocatable": { + "property1": "string", + "property2": "string" + }, + "used": { + "property1": "string", + "property2": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|setting|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|allocatable|object|false|none||none| +|» **additionalProperties**|string|false|none||none| +|used|object|false|none||none| +|» **additionalProperties**|string|false|none||none| + +

workspaceListAvailableExclusiveResourcesByWorkspaceResponse

+ + + + + + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "bound": true, + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceResourceInfo](#schemaworkspaceresourceinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListAvailableSharedResourcesByWorkspaceResponse

+ + + + + + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "bound": true, + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceResourceInfo](#schemaworkspaceresourceinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListExclusiveResourceTypesResponse

+ + + + + + +```json +{ + "items": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[string]|false|none||none| + +

workspaceListExclusiveResourcesByWorkspaceResponse

+ + + + + + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string", + "workspaceId": 0, + "workspaceResourceId": 0, + "module": "string", + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceWorkspacesResourceInfo](#schemaworkspaceworkspacesresourceinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListFolderTreeResponse

+ + + + + + +```json +{ + "folderTree": { + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + { + "id": 0, + "name": "string", + "alias": "string", + "isWorkspace": true, + "parentId": 0, + "children": [ + { + "id": null, + "name": null, + "alias": null, + "isWorkspace": null, + "parentId": null, + "children": null, + "permissions": null, + "resourceKind": null + } + ], + "permissions": [ + "Unknown" + ], + "resourceKind": [ + "resource_group" + ] + } + ], + "permissions": [ + "Unknown" + ], + "resourceKind": [ + "resource_group" + ] + }, + "defaultId": 0 +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|folderTree|[workspaceFolderTree](#schemaworkspacefoldertree)|false|none||none| +|defaultId|integer(int32)|false|none||none| + +

workspaceListFoldersResponse

+ + + + + + +```json +{ + "items": [ + { + "id": 0, + "name": "string", + "alias": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceFolderInfo](#schemaworkspacefolderinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListMembersRolesByFolderResponse

+ + + + + + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "roleName": "string", + "folderId": 0, + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceMemberRoleFolderInfo](#schemaworkspacememberrolefolderinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListMembersRolesByWorkspaceResponse

+ + + + + + +```json +{ + "items": [ + { + "memberName": "string", + "memberType": "string", + "roleName": "string", + "workspaceId": 0, + "memberId": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceMemberRoleWorkspaceInfo](#schemaworkspacememberroleworkspaceinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListResourceQuotaTypesResponse

+ + + + + + +```json +{ + "items": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[string]|false|none||none| + +

workspaceListSharedResourceTypesResponse

+ + + + + + +```json +{ + "items": [ + "string" + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[string]|false|none||none| + +

workspaceListSharedResourcesByWorkspaceResponse

+ + + + + + +```json +{ + "items": [ + { + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string", + "workspaceId": 0, + "workspaceResourceId": 0, + "module": "string", + "clusterStatus": "StatusUnknown" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceWorkspacesResourceInfo](#schemaworkspaceworkspacesresourceinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceListWorkspaceShareResourceQuotaTypesResponse

+ + + + + + +```json +{ + "gpus": [ + { + "type": "string", + "alias": "string", + "resource": [ + { + "key": "string", + "alias": "string", + "aliasZh": "string" + } + ] + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|gpus|[[workspaceResourceQuotaType](#schemaworkspaceresourcequotatype)]|false|none||none| + +

workspaceListWorkspacesResponse

+ + + + + + +```json +{ + "items": [ + { + "id": 0, + "name": "string", + "alias": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceWorkspaceInfo](#schemaworkspaceworkspaceinfo)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceMemberRoleFolderInfo

+ + + + + + +```json +{ + "memberName": "string", + "memberType": "string", + "roleName": "string", + "folderId": 0, + "memberId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|memberName|string|false|none||none| +|memberType|string|false|none||none| +|roleName|string|false|none||none| +|folderId|integer(int32)|false|none||none| +|memberId|string|false|none||none| + +

workspaceMemberRoleWorkspaceInfo

+ + + + + + +```json +{ + "memberName": "string", + "memberType": "string", + "roleName": "string", + "workspaceId": 0, + "memberId": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|memberName|string|false|none||none| +|memberType|string|false|none||none| +|roleName|string|false|none||none| +|workspaceId|integer(int32)|false|none||none| +|memberId|string|false|none||none| + +

workspaceMoveWorkspaceFolderListResponse

+ + + + + + +```json +{ + "items": [ + { + "folderId": 0, + "folderAlias": "string", + "parentId": 0, + "parentAlias": "string" + } + ], + "pagination": { + "total": 0, + "page": 0, + "pageSize": 0 + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|items|[[workspaceMoverWorkspaceFolder](#schemaworkspacemoverworkspacefolder)]|false|none||none| +|pagination|[v1alpha1workspacePagination](#schemav1alpha1workspacepagination)|false|none||none| + +

workspaceMoveWorkspaceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceMoverWorkspaceFolder

+ + + + + + +```json +{ + "folderId": 0, + "folderAlias": "string", + "parentId": 0, + "parentAlias": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|folderId|integer(int32)|false|none||none| +|folderAlias|string|false|none||none| +|parentId|integer(int32)|false|none||none| +|parentAlias|string|false|none||none| + +

workspaceReauthorizeResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceResourceInfo

+ + + + + + +```json +{ + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "bound": true, + "clusterStatus": "StatusUnknown" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|resourceName|string|false|none||none| +|resourceType|string|false|none||none| +|gproduct|string|false|none||none| +|resourceScope|string|false|none||none| +|bound|boolean|false|none||none| +|clusterStatus|[workspaceClusterStatus](#schemaworkspaceclusterstatus)|false|none||none| + +

workspaceResourceQuotaType

+ + + + + + +```json +{ + "type": "string", + "alias": "string", + "resource": [ + { + "key": "string", + "alias": "string", + "aliasZh": "string" + } + ] +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|type|string|false|none||none| +|alias|string|false|none||none| +|resource|[[workspaceResourceQuotaTypeKey](#schemaworkspaceresourcequotatypekey)]|false|none||none| + +

workspaceResourceQuotaTypeKey

+ + + + + + +```json +{ + "key": "string", + "alias": "string", + "aliasZh": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|key|string|false|none||none| +|alias|string|false|none||none| +|aliasZh|string|false|none||none| + +

workspaceSetQuotaHardForWorkspaceSharedResourceRequest

+ + + + + + +```json +{ + "workspaceResourceId": 0, + "quotaHard": { + "property1": "string", + "property2": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|workspaceResourceId|integer(int32)|false|none||none| +|quotaHard|object|false|none||none| +|» **additionalProperties**|string|false|none||none| + +

workspaceSetQuotaHardForWorkspaceSharedResourceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceUnbindResourceFromWorkspaceResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceUpdateFolderResponse

+ + + + + + +```json +{} + +``` + +### Attribute + +*None* + +

workspaceUpdateQuotaCheckRequest

+ + + + + + +```json +{ + "resourceName": "string", + "resourceType": "string", + "gproduct": "string", + "resourceScope": "string", + "workspaceId": 0, + "quotaHard": { + "property1": "string", + "property2": "string" + } +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|resourceName|string|false|none||none| +|resourceType|string|false|none||none| +|gproduct|string|false|none||none| +|resourceScope|string|false|none|cluster 资源 resource_scope 为空|none| +|workspaceId|integer(int32)|false|none||none| +|quotaHard|object|false|none||none| +|» **additionalProperties**|string|false|none||none| + +

workspaceUpdateQuotaCheckResponse

+ + + + + + +```json +{ + "passed": true, + "reason": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|passed|boolean|false|none||none| +|reason|string|false|none||none| + +

workspaceWorkspaceInfo

+ + + + + + +```json +{ + "id": 0, + "name": "string", + "alias": "string" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|id|integer(int32)|false|none||none| +|name|string|false|none||none| +|alias|string|false|none||none| + +

workspaceWorkspaceResourceKindEnum

+ + + + + + +```json +"resource_group" + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|*anonymous*|string|false|none||none| + +#### Enum + +|Name|Value| +|---|---| +|*anonymous*|resource_group| +|*anonymous*|shared_resource| +|*anonymous*|registry| +|*anonymous*|kangaroo_registry| +|*anonymous*|kangaroo_project| + +

workspaceWorkspacesResourceInfo

+ + + + + + +```json +{ + "resourceName": "string", + "resourceType": "string", + "resourceScope": "string", + "gproduct": "string", + "workspaceId": 0, + "workspaceResourceId": 0, + "module": "string", + "clusterStatus": "StatusUnknown" +} + +``` + +### Attribute + +|Name|Type|Required|Restrictions|Title|Description| +|---|---|---|---|---|---| +|resourceName|string|false|none||none| +|resourceType|string|false|none||none| +|resourceScope|string|false|none||none| +|gproduct|string|false|none||none| +|workspaceId|integer(int32)|false|none||none| +|workspaceResourceId|integer(int32)|false|none||none| +|module|string|false|none||none| +|clusterStatus|[workspaceClusterStatus](#schemaworkspaceclusterstatus)|false|none||none| + diff --git a/resources/openapi/ai-isuanova-openapi.pdf b/resources/openapi/ai-isuanova-openapi.pdf new file mode 100644 index 0000000..4f285d6 Binary files /dev/null and b/resources/openapi/ai-isuanova-openapi.pdf differ